--- nono/wx/wxpalettemonitor.cpp 2026/04/29 17:05:27 1.1.1.2 +++ nono/wx/wxpalettemonitor.cpp 2026/04/29 17:05:58 1.1.1.6 @@ -9,10 +9,10 @@ // #include "wxpalettemonitor.h" -#include "wxcolor.h" #include "wxtextscreen.h" #include "wxuimessage.h" #include "bt45x.h" +#include "mainapp.h" #include "videoctlr.h" // @@ -41,6 +41,10 @@ // パレット欄は1マスが横 font_height (= font_width * 2)、縦 font_height [px] // で、マスの右端と左端の1ピクセルを BGPANEL 色にして罫線にする。 +// Bt454 は 16 色なので 16色 x 1行。 +// Bt458 は 256 色なので 16色 x 16行。 +// X68030 は 512 色なので 16色 x 16行 x 2列組。 + // イベントテーブル wxBEGIN_EVENT_TABLE(WXPalettePanel, inherited) EVT_MOUSE_EVENTS(WXPalettePanel::OnMouse) @@ -50,6 +54,8 @@ wxEND_EVENT_TABLE() WXPalettePanel::WXPalettePanel(wxWindow *parent) : inherited(parent) { + SetName("PalettePanel"); + // デバイスを取得 bt45x = gMainApp.FindObject(OBJ_BT45x); videoctlr = gMainApp.FindObject(OBJ_VIDEOCTLR); @@ -61,10 +67,13 @@ WXPalettePanel::WXPalettePanel(wxWindow const std::vector *hpal; if (videoctlr) { hpal = &videoctlr->GetHostPalette(); + rows = 16; + idxlen = 3; } else { hpal = &bt45x->GetHostPalette(); + rows = hpal->size() / 16; + idxlen = (rows == 1) ? 1 : 2; } - rows = hpal->size() / 16; FontChanged(); PaletteChanged(); @@ -94,17 +103,28 @@ WXPalettePanel::FontChanged() pal0y += WXTextScreen::DefaultPadding; // テキストとパレットの境界余白 pal0y += font_height; // ヘッダ("+0+1"…) + if (videoctlr) { + pal1x = pal0x + 17 * font_height; + pal0y += font_height; // Text/Graphic の表示 + } + wxSize size; size.x = pal0x; // パレットより左全部 size.x += 16 * font_height; // パレット部 + if (videoctlr) { + size.x += 17 * font_height; // X68030 なら2列組。 + } size.x += WXTextScreen::DefaultPadding; // 右余白 size.y = pal0y; // パレットより上全部 size.y += rows * font_height; // パレット部 size.y += WXTextScreen::DefaultPadding; // 下余白 - SetClientSize(size); - SetMinClientSize(size); + // バックバッファのサイズを固定。 + SetMinBitmapSize(size); + + SetSize(size); + SetMinSize(size); } // VM からのパレット変更通知 @@ -117,13 +137,13 @@ WXPalettePanel::OnPaletteChanged(wxComma void WXPalettePanel::PaletteChanged() { - // ホストパレットをここでコピー。 + // ホスト/ゲストパレットをここでコピー。 if (videoctlr) { pal = videoctlr->GetHostPalette(); - ipal = videoctlr->GetIntPalette(); + vcpal = videoctlr->GetGuestPalette(); } else { pal = bt45x->GetHostPalette(); - ipal = bt45x->GetIntPalette(); + btpal = bt45x->GetGuestPalette(); } Refresh(); } @@ -133,41 +153,62 @@ WXPalettePanel::Draw() { bitmap.Fill(BGPANEL); + // Bt454 (2 or 16色) + // 01234567 + // [$0] Guest + // Host + // + // Bt458 (256色) + // 01234567 + // [$00] Guest + // Host + // + // X68030 (512色) + // 01234567 + // [$000] Guest + // Host + // テキスト (2行) // XXX snprintf が色々うるさくてアレ… char text1[36 + 1 + 40]; char text2[36 + 1]; if (cursor < 0) { - strlcpy(text1, "[ ]", sizeof(text1)); + strlcpy(text1, "[ Guest", sizeof(text1)); + text1[idxlen + 2] = ']'; strlcpy(text2, "Host R: G: B:", sizeof(text2)); } else { // この位置のパレット情報を取得 - __assume(cursor <= 0xff); - snprintf(text1, sizeof(text1), "[$%02x]", cursor); if (videoctlr) { - uint r = (ipal[cursor] >> 6) & 0x1f; - uint g = (ipal[cursor] >> 11) & 0x1f; - uint b = (ipal[cursor] >> 1) & 0x1f; - uint i = ipal[cursor] & 1; - snprintf(text1 + 5, sizeof(text1) - 5, - " $%04x R:%02x G:%02x B:%02x I:%d", - ipal[cursor], r, g, b, i); - text1[36] = '\0'; + // X68030 のパレットは %GGGGG'RRRRR'BBBBB'I の16ビット。 + assert(cursor <= 0x1ff); + uint c = vcpal[cursor]; + uint r = (c >> 6) & 0x1f; + uint g = (c >> 11) & 0x1f; + uint b = (c >> 1) & 0x1f; + uint i = c & 1; + snprintf(text1, sizeof(text1), + "[$%03x] Guest $%04x R:%02x G:%02x B:%02x I:%u", + cursor, c, r, g, b, i); } else { if (rows == 1) { - // Bt454 - uint r = ipal[cursor] >> 8; - uint g = (ipal[cursor] >> 4) & 0xf; - uint b = ipal[cursor] & 0xf; - snprintf(text1 + 5, sizeof(text1) - 5, - " Guest R:%x G:%x B:%x", r, g, b); + // Bt454 のパレットは $RR, $GG, $BB の3バイト。 + // ただし上位4ビットと下位4ビットは同じにしてある。 + assert(cursor <= 0xf); + const uint8 *c = &btpal[cursor * 3]; + uint r = c[0] >> 4; + uint g = c[1] >> 4; + uint b = c[2] >> 4; + snprintf(text1, sizeof(text1), + "[$%x] Guest R:%x G:%x B:%x", cursor, r, g, b); } else { - // Bt458 - uint r = ipal[cursor] >> 16; - uint g = (ipal[cursor] >> 8) & 0xff; - uint b = ipal[cursor] & 0xff; - snprintf(text1 + 5, sizeof(text1) - 5, - " Guest R:%02x G:%02x B:%02x", r, g, b); + // Bt458 のパレットは $RR, $GG, $BB の3バイトで各8ビット。 + assert(cursor <= 0xff); + const uint8 *c = &btpal[cursor * 3]; + uint r = c[0]; + uint g = c[1]; + uint b = c[2]; + snprintf(text1, sizeof(text1), + "[$%02x] Guest R:%02x G:%02x B:%02x", cursor, r, g, b); } } snprintf(text2, sizeof(text2), "Host R:%02x G:%02x B:%02x", @@ -177,11 +218,11 @@ WXPalettePanel::Draw() } const int padding = WXTextScreen::DefaultPadding; DrawStringSJIS(padding, padding, text1); - DrawStringSJIS(padding + font_width * 6, padding + font_height, text2); + DrawStringSJIS(padding + font_width * 7, padding + font_height, text2); // ヘッダ - DrawStringSJIS(pal0x, pal0y - font_height, - "+0+1+2+3+4+5+6+7+8+9+a+b+c+d+e+f"); + static const char xlabel[] = "+0+1+2+3+4+5+6+7+8+9+a+b+c+d+e+f"; + DrawStringSJIS(pal0x, pal0y - font_height, xlabel); for (int y = 0; y < rows; y++) { char buf[8]; __assume(y < 16); // XXX snprintf 対策。うーん @@ -199,6 +240,22 @@ WXPalettePanel::Draw() bitmap.FillRect(pal[cc], rect); } } + if (videoctlr) { + DrawStringSJIS(pal0x, pal0y - font_height * 2, "Graphic Palette"); + DrawStringSJIS(pal1x, pal0y - font_height * 2, + "Text/Sprite/BG Palette"); + DrawStringSJIS(pal1x, pal0y - font_height, xlabel); + uint cc = 256; + rect.y = pal0y; + for (uint y = 0; y < rows; y++) { + rect.x = pal1x; + for (uint x = 0; x < 16; x++) { + bitmap.FillRect(pal[cc++], rect); + rect.x += font_height; + } + rect.y += font_height; + } + } } void @@ -212,16 +269,27 @@ WXPalettePanel::OnMouse(wxMouseEvent& ev if (event.Leaving() == false && GetClientRect().Contains(pt)) { // マウスカーソルがパネル上にある - int x = pt.x - pal0x; int y = pt.y - pal0y; - if (x < 0 || y < 0) { - // パレット外 + if (y < 0) { goto next; } - x /= font_height; y /= font_height; - if (x >= 16 || y >= rows) { - // パレット外 + if (y >= rows) { + goto next; + } + + int x; + if (pal0x <= pt.x && pt.x < pal0x + font_height * 16) { + x = (pt.x - pal0x) / font_height; + } else if (pal1x != 0) { + // X68030 の右段 + if (pal1x <= pt.x && pt.x < pal1x + font_height * 16) { + x = (pt.x - pal1x) / font_height; + y += 16; + } else { + goto next; + } + } else { goto next; } @@ -245,7 +313,7 @@ WXPaletteWindow::WXPaletteWindow(wxWindo : inherited(parent, wxID_ANY, name) { new WXPalettePanel(this); - DoSize(); + Fit(); } // デストラクタ