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

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

unix.superglobalmegacorp.com

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