Annotation of nono/util/viewcgrom/viewcgrom.cpp, revision 1.1.1.4

1.1       root        1: //
                      2: // X680x0 CGROM ビューア
                      3: //
                      4: // Copyright (C) 2012-2019 [email protected]
                      5: //
                      6: 
1.1.1.3   root        7: #include "wxheader.h"
1.1       root        8: #include <wx/aboutdlg.h>
                      9: #include <wx/cmdline.h>
                     10: #include <wx/file.h>
                     11: #include <wx/image.h>
                     12: #include <wx/statline.h>
                     13: 
1.1.1.2   root       14: #define TITLE  wxT("X680x0 CGROMビューア")
                     15: #define COPYRIGHT      wxT("Copyright (C) 2012-2019 [email protected]")
1.1       root       16: 
                     17: /* CGROM.DAT の大きさ(バイト単位) */
                     18: #define CGROM_SIZE     (768 * 1024)
                     19: 
                     20: /* キャンバス全体の大きさ (ピクセル単位) */
                     21: #define VIEW_WIDTH     (25 * 16)
                     22: #define VIEW_HEIGHT    (25 * 16)
                     23: 
                     24: /* 文字境界線の色 (これを3バイト並べる) */
                     25: #define BORDER_COLOR   (0xaa)
                     26: 
                     27: #define countof(x)     (sizeof(x) / sizeof(x[0]))
                     28: 
                     29: #define ROUND(x, y)    (((x) + (y - 1)) / (y))
                     30: #define ROUND8(x)      ROUND(x, 8)
                     31: 
                     32: class MyFrame;
                     33: 
                     34: struct ctxmenu_t {
                     35:        int id;
                     36:        int addr;
1.1.1.2   root       37:        wxString label;
1.1       root       38:        int size;
                     39: };
                     40: 
                     41: const wxSize view(VIEW_WIDTH, VIEW_HEIGHT);
                     42: 
                     43: class ViewCtrl : public wxWindow
                     44: {
                     45:        typedef wxWindow inherited;
                     46:  public:
                     47:        ViewCtrl(wxWindow *parent);
                     48: 
                     49:        unsigned char *imagebuf;
                     50:  private:
                     51:        void OnPaint(wxPaintEvent& event);
                     52:        DECLARE_EVENT_TABLE();
                     53: };
                     54: 
                     55: class MyFrame : public wxFrame
                     56: {
                     57:        typedef wxFrame inherited;
                     58:  public:
                     59:        MyFrame();
                     60: 
                     61:  private:
1.1.1.3   root       62:        void OnWindowCreate(wxWindowCreateEvent& event);
1.1       root       63:        void OnOpen(wxCommandEvent& event);
                     64:        void DoOpenDialog();
                     65:        void DoOpen();
                     66:        void OnExit(wxCommandEvent& event);
                     67:        void OnAbout(wxCommandEvent& event);
                     68:        void OnContextMenu(wxContextMenuEvent& event);
                     69:        void OnReloadUI(wxUpdateUIEvent& event);
                     70:        void OnReload(wxCommandEvent& event);
                     71:        bool DoReload();
                     72:        void OnAddr(wxCommandEvent& event);
                     73:        void OnMouseWheel(wxMouseEvent& event);
                     74:        void OnScroll(wxScrollEvent& event);
                     75:        void OnTextEnter(wxCommandEvent& event);
                     76:        void OnSizeBox(wxCommandEvent& event);
                     77:        void DoUpdateSize();
                     78:        void DoUpdateAddr();
                     79:        bool CreateImage();
                     80: 
                     81:        ViewCtrl *viewctrl;
                     82:        wxScrollBar *scrlbar;
                     83:        wxTextCtrl *addrctrl;
                     84:        wxChoice *sizectrl;
                     85:        wxMenu *menu;
                     86:        wxString filename;
                     87:        wxFile file;
                     88:        int start_addr;         /* 現在のサイズのフォントの開始アドレス */
                     89:        int start_offset;       /* 現在のサイズのフォントの開始オフセット */
                     90:        int start_line;         /* 現在のサイズのフォントの開始行 */
                     91:        int total_line;         /* 現在のサイズのフォントでの行数 */
                     92:        int line;                       /* 表示開始行 */
                     93:        int addr;               /* 表示開始アドレス */
                     94:        int size;               /* フォントサイズ (番号) */
                     95:        wxSize pxsz;    /* フォントサイズ (ピクセル数) */
                     96:        wxSize bdsz;    /* 境界線を含めた大きさ (ピクセル数) */
                     97:        wxSize num;             /* 1画面の文字数 */
                     98:        wxSize oct;             /* 1文字のバイト数(縦,横) */
                     99:        int bytes;              /* 1文字のバイト数 */
                    100:        int w_bytes;    /* 1行分のバイト数(スクロールバー用) */
                    101: 
                    102:        static ctxmenu_t ctxmenu[];
                    103: 
                    104:        DECLARE_EVENT_TABLE();
                    105: };
                    106: 
                    107: class MyApp : public wxApp
                    108: {
                    109:  public:
                    110:        virtual bool OnInit();
                    111:        wxString filename;
                    112: 
                    113:  private:
                    114:        MyFrame *frame;
                    115:        static const wxCmdLineEntryDesc desc[];
                    116: };
                    117: 
                    118: IMPLEMENT_APP(MyApp)
                    119: 
                    120: // ---
                    121: 
                    122: enum {
                    123:        ID_SCROLL,
                    124:        ID_ADDRBOX,
                    125:        ID_SIZEBOX,
                    126:        ID_RELOAD,
                    127:        ID_FONT_BEGIN,
                    128:        ID_FONT_16x16 = ID_FONT_BEGIN,
                    129:        ID_FONT_8x8,
                    130:        ID_FONT_8x16,
                    131:        ID_FONT_12x12,
                    132:        ID_FONT_12x24,
                    133:        ID_FONT_24x24,
                    134:        ID_FONT_6x12,
                    135:        ID_FONT_END,
                    136: };
                    137: 
                    138: enum {
                    139:        SIZE_8x8 = 0,
                    140:        SIZE_8x16,
                    141:        SIZE_12x12,
                    142:        SIZE_12x24,
                    143:        SIZE_16x16,
                    144:        SIZE_24x24,
                    145:        SIZE_6x12,
                    146:        SIZE_MAXxMAX,
                    147: };
                    148: 
                    149: const wxCmdLineEntryDesc MyApp::desc[] =
                    150: {
                    151:        { wxCMD_LINE_PARAM, NULL, NULL, "<path of CGROM.DAT>",
                    152:                wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL, },
                    153:        { wxCMD_LINE_NONE, },
                    154: };
                    155: 
                    156: bool MyApp::OnInit()
                    157: {
                    158:        wxCmdLineParser cmd(argc, argv);
                    159:        cmd.SetDesc(desc);
                    160:        if (cmd.Parse() != 0) {
                    161:                return false;
                    162:        }
                    163:        if (cmd.GetParamCount() > 0) {
                    164:                filename = cmd.GetParam(0);
                    165:        }
                    166: 
                    167:        frame = new MyFrame();
                    168:        frame->Show();
                    169:        SetTopWindow(frame);
                    170:     return true;
                    171: }
                    172: 
                    173: // イベントテーブル
1.1.1.4 ! root      174: wxBEGIN_EVENT_TABLE(MyFrame, inherited)
1.1       root      175:        EVT_CONTEXT_MENU(MyFrame::OnContextMenu)
                    176:        EVT_MENU(ID_RELOAD, MyFrame::OnReload)
                    177:        EVT_UPDATE_UI(ID_RELOAD, MyFrame::OnReloadUI)
                    178:        EVT_COMMAND_SCROLL(ID_SCROLL, MyFrame::OnScroll)
                    179:        EVT_MOUSEWHEEL(MyFrame::OnMouseWheel)
                    180:        EVT_TEXT_ENTER(ID_ADDRBOX, MyFrame::OnTextEnter)
                    181:        EVT_CHOICE(ID_SIZEBOX, MyFrame::OnSizeBox)
                    182:        EVT_BUTTON(ID_FONT_16x16, MyFrame::OnAddr)
                    183:        EVT_BUTTON(ID_FONT_8x8,   MyFrame::OnAddr)
                    184:        EVT_BUTTON(ID_FONT_8x16,  MyFrame::OnAddr)
                    185:        EVT_BUTTON(ID_FONT_12x12, MyFrame::OnAddr)
                    186:        EVT_BUTTON(ID_FONT_12x24, MyFrame::OnAddr)
                    187:        EVT_BUTTON(ID_FONT_24x24, MyFrame::OnAddr)
                    188:        EVT_BUTTON(ID_FONT_6x12,  MyFrame::OnAddr)
                    189:        EVT_MENU(wxID_OPEN, MyFrame::OnOpen)
                    190:        EVT_MENU(wxID_EXIT, MyFrame::OnExit)
                    191:        EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
1.1.1.3   root      192:        EVT_WINDOW_CREATE(MyFrame::OnWindowCreate)
1.1.1.4 ! root      193: wxEND_EVENT_TABLE()
1.1       root      194: 
                    195: // ショートカット用データ
                    196: struct ctxmenu_t MyFrame::ctxmenu[] = {
1.1.1.2   root      197:        { ID_FONT_16x16, 0x00000, wxT("16x16フォント"), SIZE_16x16, },
                    198:        { ID_FONT_8x8,   0x3a000, wxT("8x8フォント"),   SIZE_8x8,   },
                    199:        { ID_FONT_8x16,  0x3a800, wxT("8x16フォント"),  SIZE_8x16,  },
                    200:        { ID_FONT_12x12, 0x3b800, wxT("12x12フォント"), SIZE_12x12, },
                    201:        { ID_FONT_12x24, 0x3d000, wxT("12x24フォント"), SIZE_12x24, },
                    202:        { ID_FONT_24x24, 0x40000, wxT("24x24フォント"), SIZE_24x24, },
                    203:        { ID_FONT_6x12,  0xbf400, wxT("6x12フォント"),  SIZE_6x12, },
1.1       root      204: };
                    205: 
                    206: // コンストラクタ
                    207: MyFrame::MyFrame()
                    208:        : inherited(NULL, wxID_ANY, TITLE)
                    209: {
                    210:        wxMenuBar *menubar = new wxMenuBar();
                    211:        wxMenu *menuFile = new wxMenu();
                    212:        menuFile->Append(wxID_OPEN, wxT("開く(&O)"));
                    213:        menuFile->Append(wxID_EXIT, wxT("終了(&Q)"));
                    214: #if defined(__WXMAC__)
                    215:        /*
                    216:         * Macでは wxID_ABOUT は自動的にリンゴメニューのほうに移され、
                    217:         * 「ヘルプ」が子要素なしのメニューとして出来てしまう。
                    218:         * それを防ぐため Mac では「ヘルプ」メニューごとなくす。
                    219:         */
                    220:        menuFile->Append(wxID_ABOUT, wxT("バージョン(&A)"));
                    221: #endif
                    222:        menubar->Append(menuFile, wxT("ファイル(&F)"));
                    223: #if !defined(__WXMAC__)
                    224:        /* Mac以外なら「ヘルプ > バージョン」メニューを作成 */
                    225:        wxMenu *menuHelp = new wxMenu();
                    226:        menuHelp->Append(wxID_ABOUT, wxT("バージョン(&A)"));
                    227:        menubar->Append(menuHelp, wxT("ヘルプ(&H)"));
                    228: #endif
                    229:        SetMenuBar(menubar);
                    230: 
                    231:        wxPanel *panel = new wxPanel(this, wxID_ANY);
                    232: 
                    233:        wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
                    234: 
                    235:        /* ビュー */
                    236:        viewctrl = new ViewCtrl(panel);
                    237:        hbox->Add(viewctrl);
                    238: 
                    239:        /* スクロールバー */
                    240:        scrlbar = new wxScrollBar(panel, ID_SCROLL,
                    241:                wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL);
                    242:        hbox->Add(scrlbar, 0, wxEXPAND);
                    243: 
                    244:        hbox->AddSpacer(5);
                    245: 
                    246:        /* コントロールパネル */
                    247:        wxBoxSizer *ctrlbox = new wxBoxSizer(wxVERTICAL);
                    248:        hbox->Add(ctrlbox);
                    249: 
                    250:        /* 開始アドレス */
                    251:        ctrlbox->Add(new wxStaticText(panel, wxID_ANY, wxT("開始アドレス")));
                    252: 
                    253:        /* 開始アドレス(コントロール) */
1.1.1.2   root      254:        addrctrl = new wxTextCtrl(panel, ID_ADDRBOX, wxT(""),
1.1       root      255:                wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
                    256:        ctrlbox->Add(addrctrl);
                    257: 
                    258:        ctrlbox->AddSpacer(5);
                    259: 
                    260:        /* フォントサイズ */
1.1.1.2   root      261:        ctrlbox->Add(new wxStaticText(panel, wxID_ANY, wxT("フォントサイズ")));
1.1       root      262: 
                    263:        /* フォントサイズ(コントロール) */
                    264:        wxString sizelist[] = {
1.1.1.2   root      265:                wxT("8x8"),
                    266:                wxT("8x16"),
                    267:                wxT("12x12"),
                    268:                wxT("12x24"),
                    269:                wxT("16x16"),
                    270:                wxT("24x24"),
                    271:                wxT("6x12"),
1.1       root      272:        };
                    273:        sizectrl = new wxChoice(panel, ID_SIZEBOX,
                    274:                wxDefaultPosition, wxDefaultSize,
                    275:                countof(sizelist), sizelist);
                    276:        ctrlbox->Add(sizectrl);
                    277: 
                    278:        ctrlbox->AddSpacer(10);
                    279:        ctrlbox->Add(new wxStaticLine(panel), 0, wxEXPAND);
                    280:        ctrlbox->AddSpacer(10);
                    281: 
                    282:        /* ショートカットボタン */
                    283:        for (int i = 0; i < countof(ctxmenu); i++) {
                    284:                ctxmenu_t *c = &ctxmenu[i];
                    285:                wxString label;
                    286: 
1.1.1.2   root      287:                label.Printf(wxT("%05X: "), c->addr);
1.1       root      288:                label += c->label;
                    289:                wxButton *btn = new wxButton(panel, c->id, label,
                    290:                        wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
                    291:                ctrlbox->Add(btn, 0, wxEXPAND);
                    292:        }
                    293: 
                    294:        ctrlbox->AddSpacer(5);
                    295:        ctrlbox->Add(new wxStaticText(panel, wxID_ANY,
1.1.1.2   root      296:                wxT("(6x12 フォントは\nX68030 のみ)")));
1.1       root      297: 
                    298:        panel->SetSizer(hbox);
                    299:        hbox->SetSizeHints(this);
                    300: 
                    301:        /* コンテキストメニュー */
                    302:        menu = new wxMenu();
1.1.1.2   root      303:        menu->Append(ID_RELOAD, wxT("リロード"));
1.1       root      304: 
                    305:        /* 固定地 */
                    306:        num.x = 16;
                    307: 
                    308:        /* 初期値を入れて更新 */
                    309:        size = SIZE_16x16;
                    310:        DoUpdateSize();
                    311: 
                    312:        addr = 0;
                    313:        line = -1;
                    314:        DoUpdateAddr();
                    315: 
1.1.1.3   root      316:        Connect(wxEVT_CREATE,
                    317:                wxWindowCreateEventHandler(MyFrame::OnWindowCreate), NULL, this);
1.1       root      318: }
                    319: 
1.1.1.3   root      320: // ウィンドウ作成イベント
1.1       root      321: void
1.1.1.3   root      322: MyFrame::OnWindowCreate(wxWindowCreateEvent& event)
1.1       root      323: {
                    324:        if (!::wxGetApp().filename.IsEmpty()) {
                    325:                /* 引数でファイルが指定されていればそれを使う */
                    326:                filename = ::wxGetApp().filename;
                    327: 
                    328:                /* ファイルオープン */
                    329:                DoOpen();
                    330:        }
1.1.1.3   root      331: 
                    332:        // 一度処理したら抜いておく (こうしないと複数回呼ばれる)
                    333:        Disconnect(wxEVT_CREATE,
                    334:                wxWindowCreateEventHandler(MyFrame::OnWindowCreate));
1.1       root      335: }
                    336: 
                    337: // オープン
                    338: void
                    339: MyFrame::OnOpen(wxCommandEvent& event)
                    340: {
                    341:        DoOpenDialog();
                    342:        DoOpen();
                    343: }
                    344: 
                    345: // ファイルを開くダイアログ
                    346: void
                    347: MyFrame::DoOpenDialog()
                    348: {
1.1.1.2   root      349:        wxFileDialog dialog(this, wxT("Select a file"),
1.1       root      350:                ::wxGetCwd(), wxEmptyString,
1.1.1.2   root      351:                wxT("DAT files (*.DAT)|*.DAT;*.dat|すべてのファイル (*.*)|*.*"));
1.1       root      352: 
                    353:        if (dialog.ShowModal() != wxID_OK) {
                    354:                return;
                    355:        }
                    356: 
                    357:        filename = dialog.GetPath();
                    358: }
                    359: 
                    360: // オープン処理
                    361: void
                    362: MyFrame::DoOpen()
                    363: {
                    364:        /* すでにオープンしてあればそれは閉じる */
                    365:        if (file.IsOpened()) {
                    366:                file.Close();
                    367:        }
                    368: 
                    369:        /* ファイル名がなければ (タイトルを戻して) 帰る */
                    370:        if (filename.IsEmpty()) {
                    371:                SetTitle(TITLE);
                    372:                return;
                    373:        }
                    374: 
                    375:        if (!file.Open(filename, wxFile::read)) {
                    376:                Close();
                    377:                return;
                    378:        }
                    379: 
                    380:        /* オープンできたのでタイトルを変更 */
                    381:        wxString title;
                    382:        title = TITLE;
1.1.1.2   root      383:        title += wxT(" - ");
1.1       root      384:        title += filename;
                    385:        SetTitle(title);
                    386: 
                    387:        CreateImage();
                    388: }
                    389: 
                    390: // 終了
                    391: void
                    392: MyFrame::OnExit(wxCommandEvent& event)
                    393: {
                    394:        Close();
                    395: }
                    396: 
                    397: // ヘルプ
                    398: void
                    399: MyFrame::OnAbout(wxCommandEvent& event)
                    400: {
                    401:        wxAboutDialogInfo ab;
                    402: 
1.1.1.2   root      403:        ab.SetName(wxT("viewcgrom"));
                    404:        ab.SetVersion(wxT("1.1"));
1.1       root      405:        ab.SetDescription(TITLE);
                    406:        ab.SetCopyright(COPYRIGHT);
                    407: 
                    408:        wxAboutBox(ab);
                    409: }
                    410: 
                    411: // コンテキストメニュー
                    412: void
                    413: MyFrame::OnContextMenu(wxContextMenuEvent& event)
                    414: {
                    415:        PopupMenu(menu);
                    416: }
                    417: 
                    418: // リロード UI
                    419: void
                    420: MyFrame::OnReloadUI(wxUpdateUIEvent& event)
                    421: {
                    422:        event.Enable(file.IsOpened());
                    423: }
                    424: 
                    425: // リロードイベント
                    426: void
                    427: MyFrame::OnReload(wxCommandEvent& event)
                    428: {
                    429:        DoReload();
                    430: }
                    431: 
                    432: // リロード処理
                    433: bool
                    434: MyFrame::DoReload()
                    435: {
                    436:        if (file.IsOpened()) {
                    437:                file.Close();
                    438:        }
                    439: 
                    440:        if (!file.Open(filename, wxFile::read)) {
                    441:                return false;
                    442:        }
                    443: 
                    444:        CreateImage();
                    445:        return true;
                    446: }
                    447: 
                    448: // フォント帯変更
                    449: void
                    450: MyFrame::OnAddr(wxCommandEvent& event)
                    451: {
                    452:        ctxmenu_t *c;
                    453:        for (int i = 0; i < countof(ctxmenu); i++) {
                    454:                c = &ctxmenu[i];
                    455:                if (event.GetId() == c->id) {
                    456:                        /* 一致したら変更 */
                    457:                        size = c->size;
                    458:                        DoUpdateSize();
                    459: 
                    460:                        addr = c->addr;
                    461:                        line = -1;
                    462:                        DoUpdateAddr();
                    463:                        return;
                    464:                }
                    465:        }
                    466: }
                    467: 
                    468: // マウスホイール
                    469: void
                    470: MyFrame::OnMouseWheel(wxMouseEvent& event)
                    471: {
                    472:        if (event.GetWheelRotation() < 0) {
                    473:                line += 4;
                    474:                if (line > total_line - num.y) {
                    475:                        line = total_line - num.y;
                    476:                }
                    477:        } else {
                    478:                line -= 4;
                    479:                if (line < 0) {
                    480:                        line = 0;
                    481:                }
                    482:        }
                    483:        DoUpdateAddr();
                    484: }
                    485: 
                    486: // スクロール
                    487: void
                    488: MyFrame::OnScroll(wxScrollEvent& event)
                    489: {
                    490:        line = event.GetPosition();
                    491:        DoUpdateAddr();
                    492: }
                    493: 
                    494: // アドレス変更
                    495: void
                    496: MyFrame::OnTextEnter(wxCommandEvent& event)
                    497: {
                    498:        long val = 0;
                    499: 
                    500:        event.GetString().ToLong(&val, 16);
                    501:        line = -1;
                    502:        addr = val;
                    503:        DoUpdateAddr();
                    504: }
                    505: 
                    506: // サイズ変更
                    507: void
                    508: MyFrame::OnSizeBox(wxCommandEvent& event)
                    509: {
                    510:        size = event.GetSelection();
                    511:        DoUpdateSize();
                    512:        DoUpdateAddr();
                    513: }
                    514: 
                    515: // サイズ変更 (アドレス変更も呼び出す)
                    516: void
                    517: MyFrame::DoUpdateSize()
                    518: {
                    519:        /* 範囲チェック */
                    520:        if (size < 0 || size >= SIZE_MAXxMAX) {
                    521:                size = SIZE_16x16;
                    522:        }
                    523: 
                    524:        /* コントロールを更新 */
                    525:        sizectrl->SetSelection(size);
                    526: 
                    527:        /*
                    528:         * サイズに付随する変数を更新
                    529:         */
                    530:        /* ピクセルサイズ、開始アドレス、開始オフセット */
                    531:        start_offset = 0;
                    532:        switch (size) {
                    533:         case SIZE_6x12:
                    534:                pxsz = wxSize(6, 12);
                    535:                break;
                    536:         case SIZE_8x8:
                    537:                pxsz = wxSize(8, 8);
                    538:                start_addr = 0x3a000;
                    539:                break;
                    540:         case SIZE_8x16:
                    541:                pxsz = wxSize(8, 16);
                    542:                start_addr = 0x3a800;
                    543:                break;
                    544:         case SIZE_12x12:
                    545:                pxsz = wxSize(12, 12);
                    546:                start_addr = 0x3b800;
                    547:                start_offset = 128;
                    548:                break;
                    549:         case SIZE_12x24:
                    550:                pxsz = wxSize(12, 24);
                    551:                start_addr = 0x3d000;
                    552:                start_offset = 512;
                    553:                break;
                    554:         case SIZE_16x16:
                    555:                pxsz = wxSize(16, 16);
                    556:                start_addr = 0;
                    557:                break;
                    558:         case SIZE_24x24:
                    559:                pxsz = wxSize(24, 24);
                    560:                start_addr = 0x40000;
                    561:                start_offset = 512;
                    562:                break;
                    563:        }
                    564: 
                    565:        /* バイト数 */
                    566:        oct.x = (pxsz.x + 7) / 8;
                    567:        oct.y = pxsz.y;
                    568:        bytes = oct.x * oct.y;
                    569:        w_bytes = bytes * num.x;
                    570: 
                    571:        /* 境界線入りサイズ */
                    572:        bdsz.x = (oct.x * 8) + 1;
                    573:        bdsz.y = oct.y + 1;
                    574: 
                    575:        /* 縦文字数(1画面の行数)は計算 */
                    576:        num.y = view.y / bdsz.y;
                    577: 
                    578:        /* 負側の行数(端数行も含めるため round up) */
                    579:        /* これが基準行 */
                    580:        start_line = ROUND(start_addr, w_bytes);
                    581:        /* 正側の行数(端数行も含めるため round up) */
                    582:        int pline = ROUND(CGROM_SIZE - start_addr, w_bytes);
                    583:        /* 足したものが全行数 */
                    584:        total_line = pline + start_line;
                    585: 
                    586:        /* line は一旦無効に */
                    587:        line = -1;
                    588: 
                    589:        /* スクロールバーに反映 */
                    590:        /* 現在位置は後で計算するのではみださないように 0 にしておく */
                    591:        scrlbar->SetScrollbar(0, num.y, total_line, num.y - 1);
                    592: }
                    593: 
                    594: // アドレス変更
                    595: void
                    596: MyFrame::DoUpdateAddr()
                    597: {
                    598:        if (line < 0) {
                    599:                /* line が無効ならアドレスを近いところに */
                    600:                line = (addr + start_offset) / w_bytes;
                    601:        }
                    602: 
                    603:        /* 行からアドレスを求める */
                    604:        addr = line * w_bytes - start_offset;
                    605: 
                    606:        /* アドレス欄に反映 */
                    607:        wxString str;
1.1.1.2   root      608:        str.Printf(wxT("%05X"), addr);
1.1       root      609:        addrctrl->SetValue(str);
                    610: 
                    611:        /* スクロールバーに反映 */
                    612:        int current = scrlbar->GetThumbPosition();
                    613:        if (addr / w_bytes != current) {
                    614:                scrlbar->SetThumbPosition(line);
                    615:        }
                    616: 
                    617:        /* イメージ作成 */
                    618:        CreateImage();
                    619: }
                    620: 
                    621: // イメージ作成
                    622: bool
                    623: MyFrame::CreateImage()
                    624: {
                    625:        unsigned char *imagebuf;
                    626:        unsigned char buf[bytes];
                    627:        size_t n;
                    628:        int minus_addr;
                    629: 
                    630:        imagebuf = viewctrl->imagebuf;
                    631: 
                    632:        /* 全面クリア */
                    633:        memset(imagebuf, 0xff, view.x * view.y * 3);
                    634: 
                    635:        /* ファイルが準備できていなければ何もしない */
                    636:        if (!file.IsOpened()) {
                    637:                return true;
                    638:        }
                    639: 
                    640:        if (addr >= 0) {
                    641:                file.Seek(addr);
                    642:                minus_addr = 0;
                    643:        } else {
                    644:                file.Seek(0);
                    645:                minus_addr = addr;
                    646:        }
                    647: 
                    648:        for (int cy = 0; cy < num.y; cy++) {
                    649:                for (int cx = 0; cx < num.x; cx++) {
                    650:                        unsigned char *p =
                    651:                                &imagebuf[((view.x * bdsz.y) * cy + bdsz.x * cx) * 3];
                    652:                        /* ファイルオフセットが正なら1文字分読み込み */
                    653:                        if (minus_addr >= 0) {
                    654:                                n = file.Read(buf, bytes);
                    655:                        } else {
                    656:                                /* 負なら0バイト読んだことにしてカウントだけする */
                    657:                                /* 文字の途中でプラスに転じるケースは面倒なので無視 */
                    658:                                minus_addr += bytes;
                    659:                                n = 0;
                    660:                        }
                    661: 
                    662:                        /* 展開 */
                    663:                        for (int y = 0; y < oct.y; y++) {
                    664:                                for (int x = 0; x < oct.x; x++) {
                    665:                                        int offset = y * oct.x + x;
                    666:                                        if (offset >= n) {
                    667:                                                /* ファイルからはみ出る部分は塗りつぶし? */
                    668:                                                memset(p, BORDER_COLOR, 8 * 3);
                    669:                                                p += 8 * 3;
                    670:                                                continue;
                    671:                                        }
                    672:                                        unsigned char ch = buf[offset];
                    673:                                        for (int b = 0; b < 8; b++) {
                    674:                                                if ((ch & 0x80)) {
                    675:                                                        p[0] = 0;
                    676:                                                        p[1] = 0;
                    677:                                                        p[2] = 0;
                    678:                                                }
                    679:                                                ch <<= 1;
                    680:                                                p += 3;
                    681:                                        }
                    682:                                }
                    683:                                /* 右境界線 */
                    684:                                p[0] = BORDER_COLOR;
                    685:                                p[1] = BORDER_COLOR;
                    686:                                p[2] = BORDER_COLOR;
                    687:                                p += 3;
                    688: 
                    689:                                p -= bdsz.x * 3;
                    690:                                p += view.x * 3;
                    691:                        }
                    692:                        /* 下境界線 */
                    693:                        memset(p, BORDER_COLOR, bdsz.x * 3);
                    694:                }
                    695:        }
                    696: 
                    697:        /* 画面を再描画させる */
                    698:        viewctrl->Refresh(false);
                    699: 
                    700:        return true;
                    701: }
                    702: 
                    703: // イベントテーブル
1.1.1.4 ! root      704: wxBEGIN_EVENT_TABLE(ViewCtrl, inherited)
1.1       root      705:        EVT_PAINT(ViewCtrl::OnPaint)
1.1.1.4 ! root      706: wxEND_EVENT_TABLE()
1.1       root      707: 
                    708: // コンストラクタ
                    709: ViewCtrl::ViewCtrl(wxWindow *parent)
                    710:        : inherited(parent, wxID_ANY,
                    711:                wxDefaultPosition, wxSize(VIEW_WIDTH, VIEW_HEIGHT))
                    712: {
                    713:        imagebuf = new unsigned char [ VIEW_WIDTH * VIEW_HEIGHT * 3 ];
                    714: }
                    715: 
                    716: // ペイントイベント
                    717: void
                    718: ViewCtrl::OnPaint(wxPaintEvent& event)
                    719: {
                    720:        wxPaintDC dc(this);
                    721: 
                    722:        wxImage image(VIEW_WIDTH, VIEW_HEIGHT, imagebuf, true);
                    723:        wxBitmap bitmap(image);
                    724:        wxMemoryDC memDC(bitmap);
                    725: 
                    726:        dc.Blit(0, 0, VIEW_WIDTH, VIEW_HEIGHT, &memDC, 0, 0);
                    727: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.