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