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