Annotation of nono/wx/wxpalettemonitor.cpp, revision 1.1.1.5

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2022 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // パレットモニターウィンドウ
                      9: //
                     10: 
                     11: #include "wxpalettemonitor.h"
                     12: #include "wxcolor.h"
                     13: #include "wxtextscreen.h"
                     14: #include "wxuimessage.h"
                     15: #include "bt45x.h"
1.1.1.3   root       16: #include "mainapp.h"
1.1       root       17: #include "videoctlr.h"
                     18: 
                     19: //
                     20: // パレットビットマップ
                     21: //
                     22: //
                     23: // 情報欄は WXTextScreen 同様に上下と左に DefaultPadding を手動で入れてある。
                     24: //
                     25: //
                     26: //   +------------ DefaultPadding (情報欄の左側)
                     27: //   |
                     28: // +-|------
                     29: // | v          <- DefaultPadding (情報欄の上側)
                     30: // |  "Text"
                     31: // |            <- DefaultPadding (情報欄の下側、パレット欄の区切り)
                     32: // |  "+0 +1 …"
                     33: // |--------    <- pal_y0 (ここから以下がパレット領域)
                     34: // |  □‥
                     35: // :  :
                     36: // |  □‥
                     37: // |            <- DefaultPadding (パレットの下側)
                     38: // +-^-------^
                     39: //   |       |
                     40: //   +-------+---- DefaultPadding (パレットの左右)
                     41: //
                     42: // パレット欄は1マスが横 font_height (= font_width * 2)、縦 font_height [px]
                     43: // で、マスの右端と左端の1ピクセルを BGPANEL 色にして罫線にする。
                     44: 
1.1.1.5 ! root       45: // Bt454 は  16 色なので 16色 x 1行。
        !            46: // Bt458 は 256 色なので 16色 x 16行。
        !            47: // X68030 は 512 色なので 16色 x 16行 x 2列組。
        !            48: 
1.1       root       49: // イベントテーブル
                     50: wxBEGIN_EVENT_TABLE(WXPalettePanel, inherited)
                     51:        EVT_MOUSE_EVENTS(WXPalettePanel::OnMouse)
                     52: wxEND_EVENT_TABLE()
                     53: 
                     54: // コンストラクタ
                     55: WXPalettePanel::WXPalettePanel(wxWindow *parent)
                     56:        : inherited(parent)
                     57: {
1.1.1.4   root       58:        SetName("PalettePanel");
                     59: 
1.1       root       60:        // デバイスを取得
                     61:        bt45x = gMainApp.FindObject<BT45xDevice>(OBJ_BT45x);
                     62:        videoctlr = gMainApp.FindObject<VideoCtlrDevice>(OBJ_VIDEOCTLR);
                     63: 
                     64:        cursor = -1;
                     65: 
                     66:        // パレットは1行に16個で、行数 (1 or 16) が可変。
                     67:        // ここではサイズだけ確定させる。
1.1.1.2   root       68:        const std::vector<Color> *hpal;
1.1       root       69:        if (videoctlr) {
                     70:                hpal = &videoctlr->GetHostPalette();
1.1.1.5 ! root       71:                rows = 16;
        !            72:                idxlen = 3;
1.1       root       73:        } else {
                     74:                hpal = &bt45x->GetHostPalette();
1.1.1.5 ! root       75:                rows = hpal->size() / 16;
        !            76:                idxlen = (rows == 1) ? 1 : 2;
1.1       root       77:        }
                     78: 
                     79:        FontChanged();
                     80:        PaletteChanged();
                     81: 
                     82:        // VM からの通知を受け取る
                     83:        WXUIMessage::Connect(UIMessage::PALETTE, this,
                     84:                wxCommandEventHandler(WXPalettePanel::OnPaletteChanged));
                     85: }
                     86: 
                     87: // デストラクタ
                     88: WXPalettePanel::~WXPalettePanel()
                     89: {
                     90:        WXUIMessage::Disconnect(UIMessage::PALETTE, this,
                     91:                wxCommandEventHandler(WXPalettePanel::OnPaletteChanged));
                     92: }
                     93: 
                     94: void
                     95: WXPalettePanel::FontChanged()
                     96: {
                     97:        inherited::FontChanged();
                     98: 
                     99:        pal0x  = WXTextScreen::DefaultPadding;  // 左余白
                    100:        pal0x += font_width * 4;                                // "$00:"
                    101: 
                    102:        pal0y  = WXTextScreen::DefaultPadding;  // 上余白
                    103:        pal0y += font_height * 2;                               // テキスト
                    104:        pal0y += WXTextScreen::DefaultPadding;  // テキストとパレットの境界余白
                    105:        pal0y += font_height;                                   // ヘッダ("+0+1"…)
                    106: 
1.1.1.5 ! root      107:        if (videoctlr) {
        !           108:                pal1x = pal0x + 17 * font_height;
        !           109:                pal0y += font_height;                           // Text/Graphic の表示
        !           110:        }
        !           111: 
1.1       root      112:        wxSize size;
                    113:        size.x  = pal0x;                                                // パレットより左全部
                    114:        size.x += 16 * font_height;                             // パレット部
1.1.1.5 ! root      115:        if (videoctlr) {
        !           116:                size.x += 17 * font_height;                     // X68030 なら2列組。
        !           117:        }
1.1       root      118:        size.x += WXTextScreen::DefaultPadding; // 右余白
                    119: 
                    120:        size.y  = pal0y;                                                // パレットより上全部
                    121:        size.y += rows * font_height;                   // パレット部
                    122:        size.y += WXTextScreen::DefaultPadding; // 下余白
                    123: 
1.1.1.4   root      124:        // バックバッファのサイズを固定。
                    125:        SetMinBitmapSize(size);
                    126: 
                    127:        SetSize(size);
                    128:        SetMinSize(size);
1.1       root      129: }
                    130: 
                    131: // VM からのパレット変更通知
                    132: void
                    133: WXPalettePanel::OnPaletteChanged(wxCommandEvent& event)
                    134: {
                    135:        PaletteChanged();
                    136: }
                    137: 
                    138: void
                    139: WXPalettePanel::PaletteChanged()
                    140: {
1.1.1.5 ! root      141:        // ホスト/ゲストパレットをここでコピー。
1.1       root      142:        if (videoctlr) {
                    143:                pal = videoctlr->GetHostPalette();
1.1.1.5 ! root      144:                vcpal = videoctlr->GetGuestPalette();
1.1       root      145:        } else {
                    146:                pal = bt45x->GetHostPalette();
1.1.1.5 ! root      147:                btpal = bt45x->GetGuestPalette();
1.1       root      148:        }
                    149:        Refresh();
                    150: }
                    151: 
                    152: void
                    153: WXPalettePanel::Draw()
                    154: {
                    155:        bitmap.Fill(BGPANEL);
                    156: 
1.1.1.5 ! root      157:        // Bt454 (2 or 16色)
        !           158:        //  01234567
        !           159:        //  [$0]   Guest
        !           160:        //         Host
        !           161:        //
        !           162:        // Bt458 (256色)
        !           163:        //  01234567
        !           164:        //  [$00]  Guest
        !           165:        //         Host
        !           166:        //
        !           167:        // X68030 (512色)
        !           168:        //  01234567
        !           169:        //  [$000] Guest
        !           170:        //         Host
        !           171: 
1.1       root      172:        // テキスト (2行)
                    173:        // XXX snprintf が色々うるさくてアレ…
                    174:        char text1[36 + 1 + 40];
                    175:        char text2[36 + 1];
                    176:        if (cursor < 0) {
1.1.1.5 ! root      177:                strlcpy(text1, "[      Guest", sizeof(text1));
        !           178:                text1[idxlen + 2] = ']';
1.1       root      179:                strlcpy(text2, "Host  R:   G:   B:", sizeof(text2));
                    180:        } else {
                    181:                // この位置のパレット情報を取得
                    182:                if (videoctlr) {
1.1.1.5 ! root      183:                        // X68030 のパレットは %GGGGG'RRRRR'BBBBB'I の16ビット。
        !           184:                        assert(cursor <= 0x1ff);
        !           185:                        uint c = vcpal[cursor];
        !           186:                        uint r = (c >>  6) & 0x1f;
        !           187:                        uint g = (c >> 11) & 0x1f;
        !           188:                        uint b = (c >>  1) & 0x1f;
        !           189:                        uint i =  c        & 1;
        !           190:                        snprintf(text1, sizeof(text1),
        !           191:                                "[$%03x] Guest $%04x R:%02x G:%02x B:%02x I:%u",
        !           192:                                cursor, c, r, g, b, i);
1.1       root      193:                } else {
                    194:                        if (rows == 1) {
1.1.1.5 ! root      195:                                // Bt454 のパレットは $RR, $GG, $BB の3バイト。
        !           196:                                // ただし上位4ビットと下位4ビットは同じにしてある。
        !           197:                                assert(cursor <= 0xf);
        !           198:                                const uint8 *c = &btpal[cursor * 3];
        !           199:                                uint r = c[0] >> 4;
        !           200:                                uint g = c[1] >> 4;
        !           201:                                uint b = c[2] >> 4;
        !           202:                                snprintf(text1, sizeof(text1),
        !           203:                                        "[$%x]   Guest R:%x  G:%x  B:%x", cursor, r, g, b);
1.1       root      204:                        } else {
1.1.1.5 ! root      205:                                // Bt458 のパレットは $RR, $GG, $BB の3バイトで各8ビット。
        !           206:                                assert(cursor <= 0xff);
        !           207:                                const uint8 *c = &btpal[cursor * 3];
        !           208:                                uint r = c[0];
        !           209:                                uint g = c[1];
        !           210:                                uint b = c[2];
        !           211:                                snprintf(text1, sizeof(text1),
        !           212:                                        "[$%02x]  Guest R:%02x G:%02x B:%02x", cursor, r, g, b);
1.1       root      213:                        }
                    214:                }
                    215:                snprintf(text2, sizeof(text2), "Host  R:%02x G:%02x B:%02x",
                    216:                        pal[cursor].r,
                    217:                        pal[cursor].g,
                    218:                        pal[cursor].b);
                    219:        }
                    220:        const int padding = WXTextScreen::DefaultPadding;
                    221:        DrawStringSJIS(padding, padding, text1);
1.1.1.5 ! root      222:        DrawStringSJIS(padding + font_width * 7, padding + font_height, text2);
1.1       root      223: 
                    224:        // ヘッダ
1.1.1.5 ! root      225:        static const char xlabel[] = "+0+1+2+3+4+5+6+7+8+9+a+b+c+d+e+f";
        !           226:        DrawStringSJIS(pal0x, pal0y - font_height, xlabel);
1.1       root      227:        for (int y = 0; y < rows; y++) {
                    228:                char buf[8];
                    229:                __assume(y < 16);       // XXX snprintf 対策。うーん
                    230:                snprintf(buf, sizeof(buf), "$%02x:", y * 16);
                    231:                DrawStringSJIS(padding, pal0y + y * font_height, buf);
                    232:        }
                    233: 
                    234:        // パレット
                    235:        Rect rect(0, 0, font_height - 1, font_height - 1);
                    236:        for (int y = 0; y < rows; y++) {
                    237:                for (int x = 0; x < 16; x++) {
                    238:                        int cc = y * 16 + x;
                    239:                        rect.x = pal0x + x * font_height;
                    240:                        rect.y = pal0y + y * font_height;
1.1.1.2   root      241:                        bitmap.FillRect(pal[cc], rect);
1.1       root      242:                }
                    243:        }
1.1.1.5 ! root      244:        if (videoctlr) {
        !           245:                DrawStringSJIS(pal0x, pal0y - font_height * 2, "Graphic Palette");
        !           246:                DrawStringSJIS(pal1x, pal0y - font_height * 2,
        !           247:                        "Text/Sprite/BG Palette");
        !           248:                DrawStringSJIS(pal1x, pal0y - font_height, xlabel);
        !           249:                uint cc = 256;
        !           250:                rect.y = pal0y;
        !           251:                for (uint y = 0; y < rows; y++) {
        !           252:                        rect.x = pal1x;
        !           253:                        for (uint x = 0; x < 16; x++) {
        !           254:                                bitmap.FillRect(pal[cc++], rect);
        !           255:                                rect.x += font_height;
        !           256:                        }
        !           257:                        rect.y += font_height;
        !           258:                }
        !           259:        }
1.1       root      260: }
                    261: 
                    262: void
                    263: WXPalettePanel::OnMouse(wxMouseEvent& event)
                    264: {
                    265:        wxPoint pt = event.GetPosition();
                    266:        int new_cursor = -1;
                    267: 
                    268:        // pt がパネル内の座標なのに Leaving() になることがある。
                    269:        // pt がパネル外の座標なのに Leaving() にならないことがある。
                    270:        if (event.Leaving() == false && GetClientRect().Contains(pt)) {
                    271:                // マウスカーソルがパネル上にある
                    272: 
                    273:                int y = pt.y - pal0y;
1.1.1.5 ! root      274:                if (y < 0) {
1.1       root      275:                        goto next;
                    276:                }
                    277:                y /= font_height;
1.1.1.5 ! root      278:                if (y >= rows) {
        !           279:                        goto next;
        !           280:                }
        !           281: 
        !           282:                int x;
        !           283:                if (pal0x <= pt.x && pt.x < pal0x + font_height * 16) {
        !           284:                        x = (pt.x - pal0x) / font_height;
        !           285:                } else if (pal1x != 0) {
        !           286:                        // X68030 の右段
        !           287:                        if (pal1x <= pt.x && pt.x < pal1x + font_height * 16) {
        !           288:                                x = (pt.x - pal1x) / font_height;
        !           289:                                y += 16;
        !           290:                        } else {
        !           291:                                goto next;
        !           292:                        }
        !           293:                } else {
1.1       root      294:                        goto next;
                    295:                }
                    296: 
                    297:                new_cursor = y * 16 + x;
                    298:        }
                    299: 
                    300:  next:
                    301:        if (new_cursor != cursor) {
                    302:                cursor = new_cursor;
                    303:                Refresh();
                    304:        }
                    305: }
                    306: 
                    307: 
                    308: //
                    309: // パレットウィンドウ
                    310: //
                    311: 
                    312: // コンストラクタ
                    313: WXPaletteWindow::WXPaletteWindow(wxWindow *parent, const wxString& name)
                    314:        : inherited(parent, wxID_ANY, name)
                    315: {
                    316:        new WXPalettePanel(this);
1.1.1.4   root      317:        Fit();
1.1       root      318: }
                    319: 
                    320: // デストラクタ
                    321: WXPaletteWindow::~WXPaletteWindow()
                    322: {
                    323: }

unix.superglobalmegacorp.com

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