Annotation of nono/wx/wxtvrammonitor.cpp, revision 1.1

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2020 nono project
        !             4: // Licensed under nono-license.txt
        !             5: //
        !             6: 
        !             7: //
        !             8: // TVRAM モニタ (LUNA ではビットマップモニタ)
        !             9: //
        !            10: 
        !            11: #include "wxtvrammonitor.h"
        !            12: #include "wxuimessage.h"
        !            13: #include "wxtextscreen.h"
        !            14: #include "bt45x.h"
        !            15: #include "mainapp.h"
        !            16: #include "planevram.h"
        !            17: #include "videoctlr.h"
        !            18: 
        !            19: enum {
        !            20:        ID_PLANE0 = IDGROUP_TVRAM,
        !            21:        ID_PLANE1,
        !            22:        ID_PLANE2,
        !            23:        ID_PLANE3,
        !            24:        ID_PLANE4,
        !            25:        ID_PLANE5,
        !            26:        ID_PLANE6,
        !            27:        ID_PLANE7,
        !            28:        ID_PALETTE,
        !            29:        ID_SCALE,
        !            30: 
        !            31:        ID_local_end,   // 最後に置く (チェック用)
        !            32: };
        !            33: static_assert(ID_local_end - 1 <= (int)IDGROUP_TVRAM_END, "ID exceeded");
        !            34: 
        !            35: #define ID_PLANE(id)   (ID_PLANE0 + (id))
        !            36: 
        !            37: //
        !            38: // テキスト画面パネル (LUNA だとビットマップ画面パネル)
        !            39: //
        !            40: 
        !            41: // コンストラクタ
        !            42: WXTVRAMPanel::WXTVRAMPanel(wxWindow *parent)
        !            43:        : inherited(parent)
        !            44: {
        !            45:        // デバイスを取得。
        !            46:        planevram = GetPlaneVRAMDevice();
        !            47:        // どちらか一方は NULL のはず。
        !            48:        bt45x = gMainApp.FindObject<BT45xDevice>(OBJ_BT45x);
        !            49:        videoctlr = gMainApp.FindObject<VideoCtlrDevice>(OBJ_VIDEOCTLR);
        !            50: 
        !            51:        // サイズを取得して、コンストラクタの続き。
        !            52:        const auto& composite = planevram->GetComposite();
        !            53:        Ctor(composite.GetWidth(), composite.GetHeight());
        !            54: 
        !            55:        // VM からの通知を受け取る。
        !            56:        WXUIMessage::Connect(UIMessage::PALETTE, this,
        !            57:                wxCommandEventHandler(WXTVRAMPanel::OnPaletteChanged));
        !            58: }
        !            59: 
        !            60: // デストラクタ
        !            61: WXTVRAMPanel::~WXTVRAMPanel()
        !            62: {
        !            63:        WXUIMessage::Disconnect(UIMessage::PALETTE, this,
        !            64:                wxCommandEventHandler(WXTVRAMPanel::OnPaletteChanged));
        !            65: }
        !            66: 
        !            67: // XXX 実際にはこの辺かどこかで更新チェックをしないといけない。
        !            68: // 今は表示領域を毎回描画しているので無駄。
        !            69: 
        !            70: // ビットマッププレーンの内容を描画する
        !            71: void
        !            72: WXTVRAMPanel::Draw()
        !            73: {
        !            74:        assert(view.GetRight()  < virtual_width);
        !            75:        assert(view.GetBottom() < virtual_height);
        !            76: 
        !            77:        const BitmapI8& src = planevram->GetComposite();
        !            78: 
        !            79:        if (scale > 1) {
        !            80:                Rect dr(0, 0, bitmap.GetWidth(), bitmap.GetHeight());
        !            81:                bitmap.DrawBitmapI8Scale(dr, src, &pal[0],
        !            82:                        view.x, scale, 1,
        !            83:                        view.y, scale, 1);
        !            84:        } else {
        !            85:                bitmap.DrawBitmapI8(0, 0, src, &pal[0], view);
        !            86:        }
        !            87: }
        !            88: 
        !            89: // プレーン選択変更
        !            90: void
        !            91: WXTVRAMPanel::EnablePlane(int plane, bool value)
        !            92: {
        !            93:        if (value) {
        !            94:                planemask |= 1U << plane;
        !            95:        } else {
        !            96:                planemask &= ~(1U << plane);
        !            97:        }
        !            98: 
        !            99:        // パレット生成
        !           100:        GenPalette();
        !           101: }
        !           102: 
        !           103: // パレット適用変更
        !           104: void
        !           105: WXTVRAMPanel::EnablePalette(bool value)
        !           106: {
        !           107:        apply_palette = value;
        !           108: 
        !           109:        // パレット生成
        !           110:        GenPalette();
        !           111: }
        !           112: 
        !           113: // VM からのパレット変更通知
        !           114: void
        !           115: WXTVRAMPanel::OnPaletteChanged(wxCommandEvent& event)
        !           116: {
        !           117:        // パレット生成
        !           118:        GenPalette();
        !           119: }
        !           120: 
        !           121: // パレット生成
        !           122: void
        !           123: WXTVRAMPanel::GenPalette()
        !           124: {
        !           125:        if (apply_palette) {
        !           126:                // パレットを適用する場合
        !           127:                // (雑に X680x0/LUNA 対応)
        !           128:                const Color *vmpal;
        !           129:                uint vmpal_size;
        !           130:                if (videoctlr) {
        !           131:                        vmpal = videoctlr->GetHostPalettePtr(256);
        !           132:                        vmpal_size = 16;
        !           133:                } else {
        !           134:                        const std::vector<Color>& vec = bt45x->GetHostPalette();
        !           135:                        vmpal = &vec[0];
        !           136:                        vmpal_size = vec.size();
        !           137:                }
        !           138:                const Color bg = vmpal[0];
        !           139:                for (uint d = 0; d < pal.size(); d++) {
        !           140:                        uint s = d % vmpal_size;
        !           141:                        if ((s & planemask)) {
        !           142:                                pal[d] = vmpal[s];
        !           143:                        } else {
        !           144:                                pal[d] = bg;
        !           145:                        }
        !           146:                }
        !           147:        } else {
        !           148:                // パレットを適用しない場合
        !           149:                for (uint i = 0; i < pal.size(); i++) {
        !           150:                        if ((i & planemask)) {
        !           151:                                pal[i] = Color(255, 255, 255);
        !           152:                        } else {
        !           153:                                pal[i] = Color(0, 0, 0);
        !           154:                        }
        !           155:                }
        !           156:        }
        !           157: }
        !           158: 
        !           159: 
        !           160: //
        !           161: // テキスト画面ウィンドウ
        !           162: //
        !           163: 
        !           164: // イベントテーブル
        !           165: wxBEGIN_EVENT_TABLE(WXTVRAMWindow, inherited)
        !           166:        EVT_COMMAND_RANGE(ID_PLANE0, ID_PLANE7, wxEVT_CHECKBOX,
        !           167:                WXTVRAMWindow::OnPlane)
        !           168:        EVT_CHECKBOX(ID_PALETTE, WXTVRAMWindow::OnApplyPalette)
        !           169:        EVT_CHOICE(ID_SCALE, WXTVRAMWindow::OnScale)
        !           170: wxEND_EVENT_TABLE()
        !           171: 
        !           172: // コンストラクタ
        !           173: WXTVRAMWindow::WXTVRAMWindow(wxWindow *parent, const wxString& name)
        !           174:        : inherited(parent, name)
        !           175: {
        !           176:        // デバイスを取得
        !           177:        planevram = GetPlaneVRAMDevice();
        !           178: 
        !           179:        int nplane = planevram->GetPlaneCount();
        !           180: 
        !           181:        // コントロールパネル用の横 Sizer
        !           182:        auto *ctrlbox = new wxBoxSizer(wxHORIZONTAL);
        !           183: 
        !           184:        // プレーン選択チェックボックス
        !           185:        auto *csbox = new wxStaticBoxSizer(wxHORIZONTAL, ctrlpanel,
        !           186:                _("Planes to display"));
        !           187:        // GTK3 標準のレンダリングだとコントロールの周りの空きがなさすぎて
        !           188:        // 特にスタティックボックスは読みづらいので自力で少し空ける。どうして…。
        !           189:        ctrlbox->Add(csbox, 0, wxALIGN_CENTER | wxALL, 3);
        !           190:        // X68030 なら 4プレーン。
        !           191:        // LUNA で 1bpp なら 4プレーン (上位3つは Disabled)、
        !           192:        // LUNA で 4bpp なら 4プレーン、
        !           193:        // LUNA で 8bpp なら 8プレーン。
        !           194:        std::vector<wxCheckBox*> planesw {};
        !           195:        int nplane4 = (nplane == 1) ? 4 : nplane;
        !           196:        for (int i = 0; i < nplane4; i++) {
        !           197:                auto *ctrl = new wxCheckBox(ctrlpanel, ID_PLANE(i),
        !           198:                        string_format("%d", i));
        !           199:                planesw.push_back(ctrl);
        !           200:        }
        !           201:        // 降順に並べる
        !           202:        for (int i = nplane4 - 1; i >= 0; i--) {
        !           203:                csbox->Add(planesw[i]);
        !           204:        }
        !           205: 
        !           206:        // パレット合成チェックボックス
        !           207:        auto applysw = new wxCheckBox(ctrlpanel, ID_PALETTE, _("Apply palette"));
        !           208:        ctrlbox->Add(applysw, 0, wxALIGN_CENTER | wxALL, 3);
        !           209: 
        !           210:        // セパレータを出したいのだが…
        !           211:        ctrlbox->Add(new wxStaticText(ctrlpanel, wxID_ANY, "|"), 0,
        !           212:                wxALIGN_CENTER | wxALL, 3);
        !           213: 
        !           214:        // 倍率
        !           215:        wxString scale_choice[] = {
        !           216:                "x1",
        !           217:                "x2",
        !           218:                "x4",
        !           219:        };
        !           220:        auto scalesw = new wxChoice(ctrlpanel, ID_SCALE,
        !           221:                wxDefaultPosition, wxDefaultSize,
        !           222:                countof(scale_choice), scale_choice);
        !           223:        ctrlbox->Add(scalesw, 0, wxALIGN_CENTER | wxALL, 3);
        !           224: 
        !           225:        // sizer と下敷きパネルを紐付ける
        !           226:        ctrlpanel->SetSizer(ctrlbox);
        !           227:        ctrlbox->SetSizeHints(ctrlpanel);
        !           228: 
        !           229:        // 情報パネル。
        !           230:        constexpr int status_col = 60;
        !           231:        statuspanel = new WXTextScreen(this, nnSize(status_col, nplane));
        !           232:        statuspanel->SetMinSize(statuspanel->GetBestSize());
        !           233: 
        !           234:        // 表示パネル。
        !           235:        // 大きさは適当だがフォントサイズを大きくした後で再び小さくすると
        !           236:        // このパネルはどうしたらいいのか難しいのと、最初から広いほうが見やすい
        !           237:        // というのもあるしね…ということにして、とりあえずステータスパネルを
        !           238:        // 最初からフォントサイズ 24 の時の幅にしておいて誤魔化す。高さは適当。
        !           239:        viewpanel = new WXTVRAMPanel(this);
        !           240:        viewpanel->SetSize(wxSize(status_col * 12, status_col * 12 / 2));
        !           241: 
        !           242:        // コンストラクタの続き。
        !           243:        Ctor();
        !           244: 
        !           245:        // 1bpp ならプレーン選択はすべて無効、それ以外はすべて有効。
        !           246:        if (nplane == 1) {
        !           247:                for (int i = 0; i < planesw.size(); i++) {
        !           248:                        planesw[i]->Enable(false);
        !           249:                }
        !           250:        }
        !           251: 
        !           252:        // 初期値をコントロールにセットする
        !           253:        if (nplane == 1) {
        !           254:                // 初回 1bpp なら #0 プレーンのみオン。
        !           255:                for (int i = 0; i < planesw.size(); i++) {
        !           256:                        planesw[i]->SetValue((i == 0));
        !           257:                }
        !           258:                applysw->SetValue(true);
        !           259:        } else {
        !           260:                // 初回 4bpp なら全プレーンオン。
        !           261:                for (int i = 0; i < planesw.size(); i++) {
        !           262:                        planesw[i]->SetValue(true);
        !           263:                }
        !           264:                applysw->SetValue(true);
        !           265:        }
        !           266:        scalesw->SetSelection(0);
        !           267: 
        !           268:        // SetValue() ではイベントが飛ばないので、
        !           269:        // 直接呼び出してイベントが来たことにする。うーん…。
        !           270:        for (int i = 0; i < planesw.size(); i++) {
        !           271:                DoPlane(i, planesw[i]->IsChecked());
        !           272:        }
        !           273:        DoApplyPalette(applysw->IsChecked());
        !           274:        DoScale(scalesw->GetSelection());
        !           275: }
        !           276: 
        !           277: // デストラクタ
        !           278: WXTVRAMWindow::~WXTVRAMWindow()
        !           279: {
        !           280: }
        !           281: 
        !           282: // プレーン選択のチェックボックスイベント
        !           283: void
        !           284: WXTVRAMWindow::OnPlane(wxCommandEvent& event)
        !           285: {
        !           286:        int plane = event.GetId() - ID_PLANE0;
        !           287:        bool value = event.IsChecked();
        !           288: 
        !           289:        DoPlane(plane, value);
        !           290: }
        !           291: 
        !           292: // プレーン選択 ON/OFF 処理
        !           293: void
        !           294: WXTVRAMWindow::DoPlane(int plane, bool value)
        !           295: {
        !           296:        // コントロールに指示
        !           297:        auto textviewpanel = dynamic_cast<WXTVRAMPanel *>(viewpanel);
        !           298:        textviewpanel->EnablePlane(plane, value);
        !           299: }
        !           300: 
        !           301: // パレット合成のチェックボックスイベント
        !           302: void
        !           303: WXTVRAMWindow::OnApplyPalette(wxCommandEvent& event)
        !           304: {
        !           305:        bool value = event.IsChecked();
        !           306: 
        !           307:        DoApplyPalette(value);
        !           308: }
        !           309: 
        !           310: // パレット合成 ON/OFF 処理
        !           311: void
        !           312: WXTVRAMWindow::DoApplyPalette(bool value)
        !           313: {
        !           314:        // コントロールに指示
        !           315:        auto textviewpanel = dynamic_cast<WXTVRAMPanel *>(viewpanel);
        !           316:        textviewpanel->EnablePalette(value);
        !           317: }
        !           318: 
        !           319: // 情報パネル更新。
        !           320: void
        !           321: WXTVRAMWindow::UpdateInfo(TextScreen& screen, int x, int y)
        !           322: {
        !           323:        planevram->UpdateInfo(screen, x, y);
        !           324: }

unix.superglobalmegacorp.com

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