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

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: 
        !            14: #define TITLE  "X680x0 CGROMビューア"
        !            15: #define COPYRIGHT      "Copyright (C) 2012-2019 [email protected]"
        !            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;
        !            41:        const char *label;
        !            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[] = {
        !           201:        { ID_FONT_16x16, 0x00000, "16x16フォント", SIZE_16x16, },
        !           202:        { ID_FONT_8x8,   0x3a000, "8x8フォント",   SIZE_8x8,   },
        !           203:        { ID_FONT_8x16,  0x3a800, "8x16フォント",  SIZE_8x16,  },
        !           204:        { ID_FONT_12x12, 0x3b800, "12x12フォント", SIZE_12x12, },
        !           205:        { ID_FONT_12x24, 0x3d000, "12x24フォント", SIZE_12x24, },
        !           206:        { ID_FONT_24x24, 0x40000, "24x24フォント", SIZE_24x24, },
        !           207:        { ID_FONT_6x12,  0xbf400, "6x12フォント",  SIZE_6x12, },
        !           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:        /* 開始アドレス(コントロール) */
        !           258:        addrctrl = new wxTextCtrl(panel, ID_ADDRBOX, "",
        !           259:                wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
        !           260:        ctrlbox->Add(addrctrl);
        !           261: 
        !           262:        ctrlbox->AddSpacer(5);
        !           263: 
        !           264:        /* フォントサイズ */
        !           265:        ctrlbox->Add(new wxStaticText(panel, wxID_ANY, "フォントサイズ"));
        !           266: 
        !           267:        /* フォントサイズ(コントロール) */
        !           268:        wxString sizelist[] = {
        !           269:                "8x8",
        !           270:                "8x16",
        !           271:                "12x12",
        !           272:                "12x24",
        !           273:                "16x16",
        !           274:                "24x24",
        !           275:                "6x12",
        !           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: 
        !           291:                label.Printf("%05X: ", c->addr);
        !           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,
        !           300:                "(6x12 フォントは\nX68030 のみ)"));
        !           301: 
        !           302:        panel->SetSizer(hbox);
        !           303:        hbox->SetSizeHints(this);
        !           304: 
        !           305:        /* コンテキストメニュー */
        !           306:        menu = new wxMenu();
        !           307:        menu->Append(ID_RELOAD, "リロード");
        !           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: {
        !           350:        wxFileDialog dialog(this, "Select a file",
        !           351:                ::wxGetCwd(), wxEmptyString,
        !           352:                "DAT files (*.DAT)|*.DAT;*.dat|すべてのファイル (*.*)|*.*");
        !           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;
        !           384:        title += " - ";
        !           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: 
        !           404:        ab.SetName("viewcgrom");
        !           405:        ab.SetVersion("1.1");
        !           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;
        !           609:        str.Printf("%05X", addr);
        !           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.