|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2018 [email protected]
4: //
5:
6: #include "vm.h"
7: #include "bitmap.h"
8: #include "bt454.h"
9: #include "lance.h"
10: #include "lcd.h"
11: #include "mfp.h"
12: #include "mpu.h"
13: #include "netdriver.h"
14: #include "rtc.h"
15: #include "scheduler.h"
16: #include "sio.h"
17: #include "spc.h"
18: #include "wxheader.h"
19: #include "wxdumpmonitor.h"
20: #include "wxlogmonitor.h"
21: #include "wxmainframe.h"
22: #include "wxmainview.h"
23: #include "wxmonitor.h"
24: #include "wxsoftkey.h"
25: #include "wxtextpanel.h"
26: #include "wxvideomonitor.h"
27:
28: static void wxmainframe_poweroff_callback();
29:
30: WXMainFrame *gMainFrame;
31:
32: wxBEGIN_EVENT_TABLE(WXMainFrame, inherited)
33: EVT_CREATE(WXMainFrame::OnCreate)
34: EVT_MENU(wxID_EXIT, WXMainFrame::OnExit)
35:
36: EVT_MENU(ID_FULL_SPEED, WXMainFrame::OnFullSpeed)
37: EVT_UPDATE_UI(ID_FULL_SPEED, WXMainFrame::OnFullSpeedUI)
38: EVT_MENU_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1,
39: WXMainFrame::OnMenuScale)
40: EVT_UPDATE_UI_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1,
41: WXMainFrame::OnMenuScaleUI)
42: EVT_MENU_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
43: WXMainFrame::OnMenuFontSize)
44: EVT_UPDATE_UI_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
45: WXMainFrame::OnMenuFontSizeUI)
46: EVT_MENU_RANGE(WinID_Start, WinID_MAX - 1, WXMainFrame::OnWindow)
47: EVT_UPDATE_UI_RANGE(WinID_Start, WinID_MAX - 1, WXMainFrame::OnWindowUI)
48: wxEND_EVENT_TABLE()
49:
50: WXMainFrame::WXMainFrame(wxWindow *parent)
51: : wxFrame(parent, wxID_ANY, "mm")
52: {
53: int vmtype;
54:
55: vmtype = gVM->GetType();
56:
57: // とりあえずメニュー
58: // XXX すぐにメニューファクトリーになる
59: wxMenuBar *menubar = new wxMenuBar();
60: wxMenu *menuFile = new wxMenu();
61: // XXX とりあえず適当なところにおいとく
62: menuFile->Append(ID_FULL_SPEED, wxT("高速モード"), wxT("高速モード"),
63: wxITEM_CHECK);
64: menuFile->Append(wxID_EXIT, wxT("終了"));
65: menubar->Append(menuFile, wxT("ファイル"));
66:
67: wxMenu *menuDisplay = new wxMenu();
68: wxMenu *menuViewScale = new wxMenu();
69: menuViewScale->AppendRadioItem(ID_SCALE_1_00, wxT("x1.0"), wxT("x1.0"));
70: menuViewScale->AppendRadioItem(ID_SCALE_0_75, wxT("x0.75"), wxT("x0.75"));
71: menuViewScale->AppendRadioItem(ID_SCALE_0_50, wxT("x0.5"), wxT("x0.5"));
72: menuDisplay->AppendSubMenu(menuViewScale, wxT("スケール"), wxT("スケール"));
73: wxMenu *menuFontSize = new wxMenu();
74: menuFontSize->AppendRadioItem(ID_FONTSIZE_12, wxT("12"), wxT("12"));
75: menuFontSize->AppendRadioItem(ID_FONTSIZE_16, wxT("16"), wxT("16"));
76: menuFontSize->AppendRadioItem(ID_FONTSIZE_24, wxT("24"), wxT("24"));
77: menuDisplay->AppendSubMenu(menuFontSize, wxT("フォントサイズ"),
78: wxT("フォントサイズ"));
79: menubar->Append(menuDisplay, wxT("表示"));
80:
81: wxMenu *menuDevice = new wxMenu();
82: menuDevice->Append(WinID_SOFTKEY, wxT("ソフトウェアキーボード"),
83: wxT("ソフトウェアキーボード"), wxITEM_CHECK);
84: menubar->Append(menuDevice, wxT("デバイス"));
85:
86: wxMenu *menuMonitor = new wxMenu();
87: menuMonitor->Append(WinID_MONITOR_SCHEDULER, wxT("スケジューラ"),
88: wxT("スケジューラ"), wxITEM_CHECK);
89: menuMonitor->Append(WinID_MONITOR_LOG, wxT("ログ"), wxT("ログ"),
90: wxITEM_CHECK);
91: menuMonitor->Append(WinID_MONITOR_MPUREG, wxT("MPU レジスタ"),
92: wxT("MPU レジスタ"), wxITEM_CHECK);
93: menuMonitor->Append(WinID_MONITOR_MPUATC, wxT("MPU(ATC)"), wxT("MPU(ATC)"),
94: wxITEM_CHECK);
95: menuMonitor->Append(WinID_MONITOR_MPUBRHIST, wxT("MPU(ブランチ履歴)"),
96: wxT("MPU(ブランチ履歴)"), wxITEM_CHECK);
97: menuMonitor->Append(WinID_MONITOR_MEMDUMP, wxT("メモリダンプ"),
98: wxT("メモリダンプ"), wxITEM_CHECK);
99: if (vmtype == VM::TYPE_X68030) {
100: menuMonitor->Append(WinID_MONITOR_MFP, wxT("MFP"), wxT("MFP"),
101: wxITEM_CHECK);
102: }
103: menuMonitor->Append(WinID_MONITOR_SPC, wxT("SPC"), wxT("SPC"),
104: wxITEM_CHECK);
105: menuMonitor->Append(WinID_MONITOR_RTC, wxT("RTC"), wxT("RTC"),
106: wxITEM_CHECK);
107: if (vmtype == VM::TYPE_LUNA) {
108: menuMonitor->Append(WinID_MONITOR_SIO, wxT("SIO"), wxT("SIO"),
109: wxITEM_CHECK);
110: menuMonitor->Append(WinID_MONITOR_LCD, wxT("LCD"), wxT("LCD"),
111: wxITEM_CHECK);
112: menuMonitor->Append(WinID_MONITOR_LANCE, wxT("Lance"), wxT("Lance"),
113: wxITEM_CHECK);
114: menuMonitor->Append(WinID_MONITOR_BITMAP, wxT("ビットマップ制御"),
115: wxT("ビットマップ制御"), wxITEM_CHECK);
116: menuMonitor->Append(WinID_MONITOR_BITMAP0, wxT("ビットマップ#0"),
117: wxT("ビットマップ#0"), wxITEM_CHECK);
118: }
119: menuMonitor->Append(WinID_MONITOR_NETDRIVER, wxT("ホストネットワーク"),
120: wxT("ホストネットワーク"), wxITEM_CHECK);
121: menubar->Append(menuMonitor, wxT("モニター"));
122: SetMenuBar(menubar);
123:
124: wxString title("nono");
125: switch (vmtype) {
126: case VM::TYPE_LUNA:
127: title += "(LUNA-I)";
128: break;
129: case VM::TYPE_X68030:
130: title += "(X68030)";
131: break;
132: }
133: SetTitle(title);
134:
135: // UpdateUI イベントは Idle 時に時折チェックされるらしいが、
136: // (メインビューとサブウィンドウを合わせた) タイマーイベントの粒度が
137: // 小さいためか、秒間120回とかいうレベルで UpdateUIEvent が飛んでくる
138: // っぽい (全タイマーをとめたら治る模様)。
139: // さすがにそんなに来られても気持ち悪いのと、どうせメニュー開いた瞬間
140: // 表示しようとする前には一度飛んでくるのだから、アイドル時のチェックは
141: // いらない気がする。間隔広げておいても、ぱっと見副作用はなさそうだけど
142: // 念のため事象が分かりやすいように 10秒くらいにしておく。
143: wxUpdateUIEvent::SetUpdateInterval(10000);
144:
145: wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
146:
147: gMainView = new WXMainView(this);
148: vbox->Add(gMainView, 1, wxEXPAND | wxFIXED_MINSIZE);
149:
150: SetSizer(vbox);
151:
152: Layout();
153: Fit();
154:
155: POST_CREATE();
156: }
157:
158: WXMainFrame::~WXMainFrame()
159: {
160: }
161:
162: // ウィンドウ作成イベント
163: void
164: WXMainFrame::OnCreate(wxCommandEvent& event)
165: {
166: // ウィンドウを表示
167: for (int i = 0; i < monitor_start.size(); i++) {
168: if (monitor_start[i]) {
169: DoWindow(i, true);
170: }
171: }
172:
173: // 時刻開始?
174: // なるべく VM が開始する直前にしたい。
175: gRTC->InitRTC();
176:
177: // VM 実行開始
178: gVM->SetPowerOffCallback(wxmainframe_poweroff_callback);
179: gVM->PowerButton();
180: }
181:
182: // メニューの「高速モード」イベント
183: void
184: WXMainFrame::OnFullSpeed(wxCommandEvent& event)
185: {
186: if (event.IsChecked()) {
187: // チェックが入ったので、高速モードにする
188: gScheduler->SetFullSpeed(true);
189: } else {
190: // チェックが消えたので、通常モードにする
191: gScheduler->SetFullSpeed(false);
192: }
193: }
194:
195: // メニューの「高速モード」UI
196: void
197: WXMainFrame::OnFullSpeedUI(wxUpdateUIEvent& event)
198: {
199: bool is_fullspeed = gScheduler->GetFullSpeed();
200: event.Check(is_fullspeed);
201: }
202:
203: // メニューの「終了」イベント
204: void
205: WXMainFrame::OnExit(wxCommandEvent& event)
206: {
207: // ウィンドウを閉じる
208: Close();
209: }
210:
211: // メニューの「表示 > スケール > *」の共通イベント
212: void
213: WXMainFrame::OnMenuScale(wxCommandEvent& event)
214: {
215: double scale;
216:
217: switch (event.GetId()) {
218: default:
219: case ID_SCALE_1_00:
220: scale = 1.0;
221: break;
222: case ID_SCALE_0_75:
223: scale = 0.75;
224: break;
225: case ID_SCALE_0_50:
226: scale = 0.5;
227: break;
228: }
229: gMainView->DoResize(scale);
230:
231: // 再レイアウト
232: Layout();
233: Fit();
234: }
235:
236: // メニューの「表示 > スケール > *」の共通 UI
237: void
238: WXMainFrame::OnMenuScaleUI(wxUpdateUIEvent& event)
239: {
240: double current_scale = gMainView->GetScale();
241: double event_scale;
242:
243: switch (event.GetId()) {
244: case ID_SCALE_1_00:
245: event_scale = 1.0;
246: break;
247: case ID_SCALE_0_75:
248: event_scale = 0.75;
249: break;
250: case ID_SCALE_0_50:
251: event_scale = 0.50;
252: break;
253: default:
254: event_scale = 0;
255: break;
256: }
257: event.Check(current_scale == event_scale);
258: }
259:
260: // メニューの「表示 > フォントサイズ > *」の共通イベント
261: void
262: WXMainFrame::OnMenuFontSize(wxCommandEvent& event)
263: {
264: fontsize_t fontsize;
265:
266: assert(ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_24);
267: switch (event.GetId()) {
268: case ID_FONTSIZE_12:
269: fontsize = FONT_6x12;
270: break;
271: case ID_FONTSIZE_16:
272: fontsize = FONT_8x16;
273: break;
274: case ID_FONTSIZE_24:
275: fontsize = FONT_12x24;
276: break;
277: default:
278: __unreachable();
279: break;
280: }
281:
282: if (fontsize != WXTextPanel::global_fontsize) {
283: WXTextPanel::global_fontsize = fontsize;
284:
285: // アクティブなサブウィンドウ全員に通知
286: for (int i = 0; i < WinID_MAX; i++) {
287: if (windows[i] != NULL) {
288: WXSubWindow *subwin = dynamic_cast<WXSubWindow *>(windows[i]);
289: subwin->SetFontSize(fontsize);
290: }
291: }
292: }
293: }
294:
295: // メニューの「表示 > フォントサイズ > *」共通 UI
296: void
297: WXMainFrame::OnMenuFontSizeUI(wxUpdateUIEvent& event)
298: {
299: fontsize_t current_size = WXTextPanel::global_fontsize;
300: fontsize_t event_size = (fontsize_t)(event.GetId() - (ID_FONTSIZE_START+1));
301:
302: event.Check(current_size == event_size);
303: }
304:
305: // メニューのウィンドウ ID 共通イベント
306: // チェックが入る方なら、ウィンドウを作成して表示。
307: // チェックが消える方なら、ウィンドウを削除。
308: void
309: WXMainFrame::OnWindow(wxCommandEvent& event)
310: {
311: int id = event.GetId();
312:
313: DoWindow(id, event.IsChecked());
314: }
315:
316: void
317: WXMainFrame::DoWindow(int id, bool enable)
318: {
319: if (enable) {
320: // チェックが入ったのでウィンドウを作成
321: switch (id) {
322: case WinID_MONITOR_LOG:
323: windows[id] = new WXLogMonitor(this, id);
324: break;
325: case WinID_MONITOR_SCHEDULER:
326: windows[id] = new WXMonitorWindow(this, id, "スケジューラ",
327: gScheduler);
328: break;
329: case WinID_MONITOR_MPUREG:
330: windows[id] = new WXMonitorWindow(this, id, "MPU レジスタ", gMPU);
331: break;
332: case WinID_MONITOR_MPUATC:
333: windows[id] = new WXMonitorWindow(this, id, "MPU (ATC)", gMPUATC);
334: break;
335: case WinID_MONITOR_MPUBRHIST:
336: windows[id] = new WXMonitorWindow(this, id, "MPU (ブランチ履歴)",
337: gMPUBrHist);
338: break;
339: case WinID_MONITOR_MEMDUMP:
340: windows[id] = new WXMemdumpWindow(this, id);
341: break;
342: case WinID_MONITOR_MFP:
343: windows[id] = new WXMonitorWindow(this, id, "MFP", gMFP);
344: break;
345: case WinID_MONITOR_SPC:
346: windows[id] = new WXMonitorWindow(this, id, "SPC", gSPC);
347: break;
348: case WinID_MONITOR_RTC:
349: windows[id] = new WXMonitorWindow(this, id, "RTC", gRTC);
350: break;
351: case WinID_MONITOR_SIO:
352: windows[id] = new WXMonitorWindow(this, id, "SIO", gSIO);
353: break;
354: case WinID_MONITOR_LCD:
355: windows[id] = new WXMonitorWindow(this, id, "LCD", gLCD);
356: break;
357: case WinID_MONITOR_LANCE:
358: windows[id] = new WXMonitorWindow(this, id, "Lance", gLance);
359: break;
360: case WinID_MONITOR_NETDRIVER:
361: windows[id] = new WXMonitorWindow(this, id, "ホストネットワーク",
362: gNetDriver);
363: break;
364: case WinID_MONITOR_BITMAP:
365: windows[id] = new WXMonitorWindow(this, id, "ビットマップ制御",
366: gBitmap);
367: break;
368: case WinID_MONITOR_BITMAP0:
369: windows[id] = new WXLunaBitmapWindow(this, id, "ビットマップ#0");
370: break;
371: case WinID_SOFTKEY:
372: windows[id] = new WXLunaSoftKeyWindow(this, id);
373: break;
374: }
375: windows[id]->Show();
376: } else {
377: // チェックが消えたのでウィンドウを終了
378: windows[id]->Close();
379: // (削除自体はこの少し下の DeleteWindow() で行なっている)
380: }
381: }
382:
383: // Update UI イベント
384: void
385: WXMainFrame::OnWindowUI(wxUpdateUIEvent& event)
386: {
387: int id = event.GetId();
388:
389: // ウィンドウが存在していればチェックを表示
390: event.Check((windows[id] != NULL));
391: }
392:
393: // ウィンドウをリストから削除する
394: // (ウィンドウの Close() から呼ばれる)
395: void
396: WXMainFrame::DeleteWindow(wxWindowID id)
397: {
398: delete windows[id];
399: windows[id] = NULL;
400: }
401:
402: // VM 電源オフ時に呼ばれるコールバック。
403: // (VM スレッドからアプリケーションを終了するため)
404: void
405: wxmainframe_poweroff_callback()
406: {
407: gMainFrame->PowerOffCallback();
408: }
409:
410: // VM からの電源オフ処理
411: void
412: WXMainFrame::PowerOffCallback()
413: {
414: wxCommandEvent *ev = new wxCommandEvent(wxEVT_MENU, wxID_EXIT);
415: QueueEvent(ev);
416: }
417:
418: // モニタウィンドウ識別名一覧
419: /*static*/ const char *
420: WXMainFrame::monitor_names[WinID_MAX] = {
421: "log", // LOG
422: "scheduler", // SCHEDULER
423: "mpureg", // MPUREG
424: "mpuatc", // MPUATC
425: "mpuhist", // MPUBRHIST
426: "memdump", // MEMDUMP
427: "mfp", // MFP
428: "spc", // SPC
429: "rtc", // RTC
430: "sio", // SIO
431: "lcd", // LCD
432: "lance", // LANCE
433: "bitmap", // BITMAP
434: "bitmap0", // BITMAP0
435: "netdriver", // NETDRIVER
436: "softkey", // SOFTKEY
437: };
438:
439: // 起動時にオープンするモニタウィンドウ (-M オプション)
440: /*static*/ std::array<bool, WinID_MAX> WXMainFrame::monitor_start;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.