|
|
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" ! 16: #include "videoctlr.h" ! 17: ! 18: // ! 19: // パレットビットマップ ! 20: // ! 21: // ! 22: // 情報欄は WXTextScreen 同様に上下と左に DefaultPadding を手動で入れてある。 ! 23: // ! 24: // ! 25: // +------------ DefaultPadding (情報欄の左側) ! 26: // | ! 27: // +-|------ ! 28: // | v <- DefaultPadding (情報欄の上側) ! 29: // | "Text" ! 30: // | <- DefaultPadding (情報欄の下側、パレット欄の区切り) ! 31: // | "+0 +1 …" ! 32: // |-------- <- pal_y0 (ここから以下がパレット領域) ! 33: // | □‥ ! 34: // : : ! 35: // | □‥ ! 36: // | <- DefaultPadding (パレットの下側) ! 37: // +-^-------^ ! 38: // | | ! 39: // +-------+---- DefaultPadding (パレットの左右) ! 40: // ! 41: // パレット欄は1マスが横 font_height (= font_width * 2)、縦 font_height [px] ! 42: // で、マスの右端と左端の1ピクセルを BGPANEL 色にして罫線にする。 ! 43: ! 44: // イベントテーブル ! 45: wxBEGIN_EVENT_TABLE(WXPalettePanel, inherited) ! 46: EVT_MOUSE_EVENTS(WXPalettePanel::OnMouse) ! 47: wxEND_EVENT_TABLE() ! 48: ! 49: // コンストラクタ ! 50: WXPalettePanel::WXPalettePanel(wxWindow *parent) ! 51: : inherited(parent) ! 52: { ! 53: // デバイスを取得 ! 54: bt45x = gMainApp.FindObject<BT45xDevice>(OBJ_BT45x); ! 55: videoctlr = gMainApp.FindObject<VideoCtlrDevice>(OBJ_VIDEOCTLR); ! 56: ! 57: cursor = -1; ! 58: ! 59: // パレットは1行に16個で、行数 (1 or 16) が可変。 ! 60: // ここではサイズだけ確定させる。 ! 61: const std::vector<ColorXBGR> *hpal; ! 62: if (videoctlr) { ! 63: hpal = &videoctlr->GetHostPalette(); ! 64: } else { ! 65: hpal = &bt45x->GetHostPalette(); ! 66: } ! 67: rows = hpal->size() / 16; ! 68: ! 69: FontChanged(); ! 70: PaletteChanged(); ! 71: ! 72: // VM からの通知を受け取る ! 73: WXUIMessage::Connect(UIMessage::PALETTE, this, ! 74: wxCommandEventHandler(WXPalettePanel::OnPaletteChanged)); ! 75: } ! 76: ! 77: // デストラクタ ! 78: WXPalettePanel::~WXPalettePanel() ! 79: { ! 80: WXUIMessage::Disconnect(UIMessage::PALETTE, this, ! 81: wxCommandEventHandler(WXPalettePanel::OnPaletteChanged)); ! 82: } ! 83: ! 84: void ! 85: WXPalettePanel::FontChanged() ! 86: { ! 87: inherited::FontChanged(); ! 88: ! 89: pal0x = WXTextScreen::DefaultPadding; // 左余白 ! 90: pal0x += font_width * 4; // "$00:" ! 91: ! 92: pal0y = WXTextScreen::DefaultPadding; // 上余白 ! 93: pal0y += font_height * 2; // テキスト ! 94: pal0y += WXTextScreen::DefaultPadding; // テキストとパレットの境界余白 ! 95: pal0y += font_height; // ヘッダ("+0+1"…) ! 96: ! 97: wxSize size; ! 98: size.x = pal0x; // パレットより左全部 ! 99: size.x += 16 * font_height; // パレット部 ! 100: size.x += WXTextScreen::DefaultPadding; // 右余白 ! 101: ! 102: size.y = pal0y; // パレットより上全部 ! 103: size.y += rows * font_height; // パレット部 ! 104: size.y += WXTextScreen::DefaultPadding; // 下余白 ! 105: ! 106: SetClientSize(size); ! 107: SetMinClientSize(size); ! 108: } ! 109: ! 110: // VM からのパレット変更通知 ! 111: void ! 112: WXPalettePanel::OnPaletteChanged(wxCommandEvent& event) ! 113: { ! 114: PaletteChanged(); ! 115: } ! 116: ! 117: void ! 118: WXPalettePanel::PaletteChanged() ! 119: { ! 120: // ホストパレットをここでコピー。 ! 121: if (videoctlr) { ! 122: pal = videoctlr->GetHostPalette(); ! 123: ipal = videoctlr->GetIntPalette(); ! 124: } else { ! 125: pal = bt45x->GetHostPalette(); ! 126: ipal = bt45x->GetIntPalette(); ! 127: } ! 128: Refresh(); ! 129: } ! 130: ! 131: void ! 132: WXPalettePanel::Draw() ! 133: { ! 134: bitmap.Fill(BGPANEL); ! 135: ! 136: // テキスト (2行) ! 137: // XXX snprintf が色々うるさくてアレ… ! 138: char text1[36 + 1 + 40]; ! 139: char text2[36 + 1]; ! 140: if (cursor < 0) { ! 141: strlcpy(text1, "[ ]", sizeof(text1)); ! 142: strlcpy(text2, "Host R: G: B:", sizeof(text2)); ! 143: } else { ! 144: // この位置のパレット情報を取得 ! 145: __assume(cursor <= 0xff); ! 146: snprintf(text1, sizeof(text1), "[$%02x]", cursor); ! 147: if (videoctlr) { ! 148: uint r = (ipal[cursor] >> 6) & 0x1f; ! 149: uint g = (ipal[cursor] >> 11) & 0x1f; ! 150: uint b = (ipal[cursor] >> 1) & 0x1f; ! 151: uint i = ipal[cursor] & 1; ! 152: snprintf(text1 + 5, sizeof(text1) - 5, ! 153: " $%04x R:%02x G:%02x B:%02x I:%d", ! 154: ipal[cursor], r, g, b, i); ! 155: text1[36] = '\0'; ! 156: } else { ! 157: if (rows == 1) { ! 158: // Bt454 ! 159: uint r = ipal[cursor] >> 8; ! 160: uint g = (ipal[cursor] >> 4) & 0xf; ! 161: uint b = ipal[cursor] & 0xf; ! 162: snprintf(text1 + 5, sizeof(text1) - 5, ! 163: " Guest R:%x G:%x B:%x", r, g, b); ! 164: } else { ! 165: // Bt458 ! 166: uint r = ipal[cursor] >> 16; ! 167: uint g = (ipal[cursor] >> 8) & 0xff; ! 168: uint b = ipal[cursor] & 0xff; ! 169: snprintf(text1 + 5, sizeof(text1) - 5, ! 170: " Guest R:%02x G:%02x B:%02x", r, g, b); ! 171: } ! 172: } ! 173: snprintf(text2, sizeof(text2), "Host R:%02x G:%02x B:%02x", ! 174: pal[cursor].r, ! 175: pal[cursor].g, ! 176: pal[cursor].b); ! 177: } ! 178: const int padding = WXTextScreen::DefaultPadding; ! 179: DrawStringSJIS(padding, padding, text1); ! 180: DrawStringSJIS(padding + font_width * 6, padding + font_height, text2); ! 181: ! 182: // ヘッダ ! 183: DrawStringSJIS(pal0x, pal0y - font_height, ! 184: "+0+1+2+3+4+5+6+7+8+9+a+b+c+d+e+f"); ! 185: for (int y = 0; y < rows; y++) { ! 186: char buf[8]; ! 187: __assume(y < 16); // XXX snprintf 対策。うーん ! 188: snprintf(buf, sizeof(buf), "$%02x:", y * 16); ! 189: DrawStringSJIS(padding, pal0y + y * font_height, buf); ! 190: } ! 191: ! 192: // パレット ! 193: Rect rect(0, 0, font_height - 1, font_height - 1); ! 194: for (int y = 0; y < rows; y++) { ! 195: for (int x = 0; x < 16; x++) { ! 196: int cc = y * 16 + x; ! 197: rect.x = pal0x + x * font_height; ! 198: rect.y = pal0y + y * font_height; ! 199: bitmap.FillRect(pal[cc].ToColor(), rect); ! 200: } ! 201: } ! 202: } ! 203: ! 204: void ! 205: WXPalettePanel::OnMouse(wxMouseEvent& event) ! 206: { ! 207: wxPoint pt = event.GetPosition(); ! 208: int new_cursor = -1; ! 209: ! 210: // pt がパネル内の座標なのに Leaving() になることがある。 ! 211: // pt がパネル外の座標なのに Leaving() にならないことがある。 ! 212: if (event.Leaving() == false && GetClientRect().Contains(pt)) { ! 213: // マウスカーソルがパネル上にある ! 214: ! 215: int x = pt.x - pal0x; ! 216: int y = pt.y - pal0y; ! 217: if (x < 0 || y < 0) { ! 218: // パレット外 ! 219: goto next; ! 220: } ! 221: x /= font_height; ! 222: y /= font_height; ! 223: if (x >= 16 || y >= rows) { ! 224: // パレット外 ! 225: goto next; ! 226: } ! 227: ! 228: new_cursor = y * 16 + x; ! 229: } ! 230: ! 231: next: ! 232: if (new_cursor != cursor) { ! 233: cursor = new_cursor; ! 234: Refresh(); ! 235: } ! 236: } ! 237: ! 238: ! 239: // ! 240: // パレットウィンドウ ! 241: // ! 242: ! 243: // コンストラクタ ! 244: WXPaletteWindow::WXPaletteWindow(wxWindow *parent, const wxString& name) ! 245: : inherited(parent, wxID_ANY, name) ! 246: { ! 247: new WXPalettePanel(this); ! 248: DoSize(); ! 249: } ! 250: ! 251: // デストラクタ ! 252: WXPaletteWindow::~WXPaletteWindow() ! 253: { ! 254: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.