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

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

unix.superglobalmegacorp.com

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