|
|
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"
1.1.1.2 ! root 9: #include "keyboard.h"
1.1 root 10: #include "lance.h"
11: #include "lcd.h"
12: #include "mfp.h"
13: #include "mpu.h"
14: #include "netdriver.h"
15: #include "rtc.h"
16: #include "scheduler.h"
17: #include "sio.h"
18: #include "spc.h"
19: #include "wxheader.h"
20: #include "wxdumpmonitor.h"
21: #include "wxlogmonitor.h"
22: #include "wxmainframe.h"
23: #include "wxmainview.h"
24: #include "wxmonitor.h"
25: #include "wxsoftkey.h"
26: #include "wxtextpanel.h"
27: #include "wxvideomonitor.h"
28:
29: static void wxmainframe_poweroff_callback();
30:
31: WXMainFrame *gMainFrame;
32:
33: wxBEGIN_EVENT_TABLE(WXMainFrame, inherited)
34: EVT_CREATE(WXMainFrame::OnCreate)
35: EVT_MENU(wxID_EXIT, WXMainFrame::OnExit)
36:
37: EVT_MENU(ID_FULL_SPEED, WXMainFrame::OnFullSpeed)
38: EVT_UPDATE_UI(ID_FULL_SPEED, WXMainFrame::OnFullSpeedUI)
39: EVT_MENU_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1,
40: WXMainFrame::OnMenuScale)
41: EVT_UPDATE_UI_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1,
42: WXMainFrame::OnMenuScaleUI)
43: EVT_MENU_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
44: WXMainFrame::OnMenuFontSize)
45: EVT_UPDATE_UI_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
46: WXMainFrame::OnMenuFontSizeUI)
1.1.1.2 ! root 47: EVT_MENU(ID_MOUSEMODE, WXMainFrame::OnMouseMode)
! 48: EVT_UPDATE_UI(ID_MOUSEMODE, WXMainFrame::OnMouseModeUI)
1.1 root 49: EVT_MENU_RANGE(WinID_Start, WinID_MAX - 1, WXMainFrame::OnWindow)
50: EVT_UPDATE_UI_RANGE(WinID_Start, WinID_MAX - 1, WXMainFrame::OnWindowUI)
51: wxEND_EVENT_TABLE()
52:
53: WXMainFrame::WXMainFrame(wxWindow *parent)
1.1.1.2 ! root 54: : wxFrame(parent, wxID_ANY, wxT("nono"))
1.1 root 55: {
56: int vmtype;
57:
58: vmtype = gVM->GetType();
59:
60: // とりあえずメニュー
61: // XXX すぐにメニューファクトリーになる
62: wxMenuBar *menubar = new wxMenuBar();
63: wxMenu *menuFile = new wxMenu();
64: // XXX とりあえず適当なところにおいとく
1.1.1.2 ! root 65: menuFile->Append(ID_FULL_SPEED, wxT("高速モード(&S)"), "", wxITEM_CHECK);
! 66: menuFile->Append(wxID_EXIT, wxT("終了(&X)"));
! 67: menubar->Append(menuFile, wxT("ファイル(&F)"));
1.1 root 68:
69: wxMenu *menuDisplay = new wxMenu();
70: wxMenu *menuViewScale = new wxMenu();
1.1.1.2 ! root 71: menuViewScale->Append(ID_SCALE_1_00, wxT("x1.&0"), "", wxITEM_CHECK);
! 72: menuViewScale->Append(ID_SCALE_0_75, wxT("x0.&75"), "", wxITEM_CHECK);
! 73: menuViewScale->Append(ID_SCALE_0_50, wxT("x0.&5"), "", wxITEM_CHECK);
! 74: menuDisplay->AppendSubMenu(menuViewScale, wxT("スケール(&S)"));
1.1 root 75: wxMenu *menuFontSize = new wxMenu();
1.1.1.2 ! root 76: menuFontSize->AppendRadioItem(ID_FONTSIZE_12, wxT("1&2"));
! 77: menuFontSize->AppendRadioItem(ID_FONTSIZE_16, wxT("1&6"));
! 78: menuFontSize->AppendRadioItem(ID_FONTSIZE_24, wxT("2&4"));
! 79: menuDisplay->AppendSubMenu(menuFontSize, wxT("フォントサイズ(&F)"));
! 80: menubar->Append(menuDisplay, wxT("表示(&V)"));
1.1 root 81:
82: wxMenu *menuDevice = new wxMenu();
1.1.1.2 ! root 83: menuDevice->Append(WinID_SOFTKEY, wxT("ソフトウェアキーボード(&K)"),
! 84: "", wxITEM_CHECK);
! 85: menuDevice->Append(ID_MOUSEMODE, wxT("マウスモード(&M)\tCTRL+F12"),
! 86: "", wxITEM_CHECK);
! 87: menubar->Append(menuDevice, wxT("デバイス(&D)"));
1.1 root 88:
89: wxMenu *menuMonitor = new wxMenu();
1.1.1.2 ! root 90: menuMonitor->Append(WinID_MONITOR_SCHEDULER, wxT("スケジューラ(&S)"),
! 91: "", wxITEM_CHECK);
! 92: menuMonitor->Append(WinID_MONITOR_LOG, wxT("ログ(&L)"), "", wxITEM_CHECK);
! 93: menuMonitor->Append(WinID_MONITOR_MPUREG, wxT("MPU レジスタ(&R)"),
! 94: "", wxITEM_CHECK);
! 95: menuMonitor->Append(WinID_MONITOR_MPUATC, wxT("MPU(&ATC)"),
! 96: "", wxITEM_CHECK);
! 97: menuMonitor->Append(WinID_MONITOR_MPUBRHIST, wxT("MPU(ブランチ履歴)(&H)"),
! 98: "", wxITEM_CHECK);
! 99: menuMonitor->Append(WinID_MONITOR_MEMDUMP, wxT("メモリダンプ(&D)"),
! 100: "", wxITEM_CHECK);
1.1 root 101: if (vmtype == VM::TYPE_X68030) {
1.1.1.2 ! root 102: menuMonitor->Append(WinID_MONITOR_MFP, wxT("&MFP"), "", wxITEM_CHECK);
1.1 root 103: }
1.1.1.2 ! root 104: menuMonitor->Append(WinID_MONITOR_SPC, wxT("S&PC"), "", wxITEM_CHECK);
! 105: menuMonitor->Append(WinID_MONITOR_RTC, wxT("&RTC"), "", wxITEM_CHECK);
1.1 root 106: if (vmtype == VM::TYPE_LUNA) {
1.1.1.2 ! root 107: menuMonitor->Append(WinID_MONITOR_SIO, wxT("S&IO"), "", wxITEM_CHECK);
! 108: menuMonitor->Append(WinID_MONITOR_LUNAKEYBOARD,
! 109: wxT("キーボード/マウス(&K)"), "", wxITEM_CHECK);
! 110: menuMonitor->Append(WinID_MONITOR_LCD, wxT("LCD(&J)"),
! 111: "", wxITEM_CHECK);
! 112: menuMonitor->Append(WinID_MONITOR_LANCE, wxT("Lance(&E)"),
! 113: "", wxITEM_CHECK);
! 114: menuMonitor->Append(WinID_MONITOR_BITMAP, wxT("ビットマップ制御(&B)"),
! 115: "", wxITEM_CHECK);
! 116: menuMonitor->Append(WinID_MONITOR_BITMAP0, wxT("ビットマップ#&0"),
! 117: "", wxITEM_CHECK);
! 118: }
! 119: menuMonitor->Append(WinID_MONITOR_NETDRIVER, wxT("ホストネットワーク(&N)"),
! 120: "", wxITEM_CHECK);
! 121: menubar->Append(menuMonitor, wxT("モニター(&M)"));
1.1 root 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:
1.1.1.2 ! root 242: if (current_scale == 1.0) {
! 243: event.Check(event.GetId() == ID_SCALE_1_00);
! 244: } else if (current_scale == 0.75) {
! 245: event.Check(event.GetId() == ID_SCALE_0_75);
! 246: } else if (current_scale == 0.5) {
! 247: event.Check(event.GetId() == ID_SCALE_0_50);
1.1 root 248: }
249: }
250:
251: // メニューの「表示 > フォントサイズ > *」の共通イベント
252: void
253: WXMainFrame::OnMenuFontSize(wxCommandEvent& event)
254: {
255: fontsize_t fontsize;
256:
257: assert(ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_24);
258: switch (event.GetId()) {
259: case ID_FONTSIZE_12:
260: fontsize = FONT_6x12;
261: break;
262: case ID_FONTSIZE_16:
263: fontsize = FONT_8x16;
264: break;
265: case ID_FONTSIZE_24:
266: fontsize = FONT_12x24;
267: break;
268: default:
269: __unreachable();
270: break;
271: }
272:
273: if (fontsize != WXTextPanel::global_fontsize) {
274: WXTextPanel::global_fontsize = fontsize;
275:
276: // アクティブなサブウィンドウ全員に通知
277: for (int i = 0; i < WinID_MAX; i++) {
278: if (windows[i] != NULL) {
279: WXSubWindow *subwin = dynamic_cast<WXSubWindow *>(windows[i]);
280: subwin->SetFontSize(fontsize);
281: }
282: }
283: }
284: }
285:
286: // メニューの「表示 > フォントサイズ > *」共通 UI
287: void
288: WXMainFrame::OnMenuFontSizeUI(wxUpdateUIEvent& event)
289: {
290: fontsize_t current_size = WXTextPanel::global_fontsize;
291: fontsize_t event_size = (fontsize_t)(event.GetId() - (ID_FONTSIZE_START+1));
292:
293: event.Check(current_size == event_size);
294: }
295:
1.1.1.2 ! root 296: // メニューの「デバイス > マウスモード」
! 297: void
! 298: WXMainFrame::OnMouseMode(wxCommandEvent& event)
! 299: {
! 300: // enable ならチェックを付けようとして呼ばれた
! 301: bool enable = event.IsChecked();
! 302:
! 303: if (enable) {
! 304: // メッセージを表示したい
! 305: } else {
! 306: // メッセージを表示したい
! 307: }
! 308:
! 309: // マウスモードを設定
! 310: gMainView->SetMouseMode(enable);
! 311: }
! 312:
! 313: // メニューの「デバイス > マウスモード」UI
! 314: void
! 315: WXMainFrame::OnMouseModeUI(wxUpdateUIEvent& event)
! 316: {
! 317: event.Check(gMainView->GetMouseMode());
! 318: }
! 319:
1.1 root 320: // メニューのウィンドウ ID 共通イベント
321: // チェックが入る方なら、ウィンドウを作成して表示。
322: // チェックが消える方なら、ウィンドウを削除。
323: void
324: WXMainFrame::OnWindow(wxCommandEvent& event)
325: {
326: int id = event.GetId();
327:
328: DoWindow(id, event.IsChecked());
329: }
330:
331: void
332: WXMainFrame::DoWindow(int id, bool enable)
333: {
334: if (enable) {
335: // チェックが入ったのでウィンドウを作成
336: switch (id) {
337: case WinID_MONITOR_LOG:
338: windows[id] = new WXLogMonitor(this, id);
339: break;
340: case WinID_MONITOR_SCHEDULER:
1.1.1.2 ! root 341: windows[id] = new WXMonitorWindow(this, id, wxT("スケジューラ"),
1.1 root 342: gScheduler);
343: break;
344: case WinID_MONITOR_MPUREG:
1.1.1.2 ! root 345: windows[id] = new WXMonitorWindow(this, id, wxT("MPU レジスタ"),
! 346: gMPU);
1.1 root 347: break;
348: case WinID_MONITOR_MPUATC:
1.1.1.2 ! root 349: windows[id] = new WXMonitorWindow(this, id, wxT("MPU (ATC)"),
! 350: gMPUATC);
1.1 root 351: break;
352: case WinID_MONITOR_MPUBRHIST:
1.1.1.2 ! root 353: windows[id] = new WXMonitorWindow(this, id,
! 354: wxT("MPU (ブランチ履歴)"), gMPUBrHist);
1.1 root 355: break;
356: case WinID_MONITOR_MEMDUMP:
357: windows[id] = new WXMemdumpWindow(this, id);
358: break;
359: case WinID_MONITOR_MFP:
1.1.1.2 ! root 360: windows[id] = new WXMonitorWindow(this, id, wxT("MFP"), gMFP);
1.1 root 361: break;
362: case WinID_MONITOR_SPC:
1.1.1.2 ! root 363: windows[id] = new WXMonitorWindow(this, id, wxT("SPC"), gSPC);
1.1 root 364: break;
365: case WinID_MONITOR_RTC:
1.1.1.2 ! root 366: windows[id] = new WXMonitorWindow(this, id, wxT("RTC"), gRTC);
1.1 root 367: break;
368: case WinID_MONITOR_SIO:
1.1.1.2 ! root 369: windows[id] = new WXMonitorWindow(this, id, wxT("SIO"), gSIO);
! 370: break;
! 371: case WinID_MONITOR_LUNAKEYBOARD:
! 372: windows[id] = new WXMonitorWindow(this, id,
! 373: wxT("キーボード/マウス"), gKeyboard);
1.1 root 374: break;
375: case WinID_MONITOR_LCD:
1.1.1.2 ! root 376: windows[id] = new WXMonitorWindow(this, id, wxT("LCD"), gLCD);
1.1 root 377: break;
378: case WinID_MONITOR_LANCE:
1.1.1.2 ! root 379: windows[id] = new WXMonitorWindow(this, id, wxT("Lance"),
! 380: dynamic_cast<LanceDevice*>(gEthernet));
1.1 root 381: break;
382: case WinID_MONITOR_NETDRIVER:
1.1.1.2 ! root 383: windows[id] = new WXMonitorWindow(this, id,
! 384: wxT("ホストネットワーク"), gNetDriver);
1.1 root 385: break;
386: case WinID_MONITOR_BITMAP:
1.1.1.2 ! root 387: windows[id] = new WXMonitorWindow(this, id, wxT("ビットマップ制御"),
1.1 root 388: gBitmap);
389: break;
390: case WinID_MONITOR_BITMAP0:
1.1.1.2 ! root 391: windows[id] = new WXLunaBitmapWindow(this, id,
! 392: wxT("ビットマップ#0"));
1.1 root 393: break;
394: case WinID_SOFTKEY:
395: windows[id] = new WXLunaSoftKeyWindow(this, id);
396: break;
397: }
398: windows[id]->Show();
399: } else {
400: // チェックが消えたのでウィンドウを終了
401: windows[id]->Close();
402: // (削除自体はこの少し下の DeleteWindow() で行なっている)
403: }
404: }
405:
406: // Update UI イベント
407: void
408: WXMainFrame::OnWindowUI(wxUpdateUIEvent& event)
409: {
410: int id = event.GetId();
411:
412: // ウィンドウが存在していればチェックを表示
413: event.Check((windows[id] != NULL));
414: }
415:
416: // ウィンドウをリストから削除する
417: // (ウィンドウの Close() から呼ばれる)
418: void
419: WXMainFrame::DeleteWindow(wxWindowID id)
420: {
421: delete windows[id];
422: windows[id] = NULL;
423: }
424:
425: // VM 電源オフ時に呼ばれるコールバック。
426: // (VM スレッドからアプリケーションを終了するため)
427: void
428: wxmainframe_poweroff_callback()
429: {
430: gMainFrame->PowerOffCallback();
431: }
432:
433: // VM からの電源オフ処理
434: void
435: WXMainFrame::PowerOffCallback()
436: {
437: wxCommandEvent *ev = new wxCommandEvent(wxEVT_MENU, wxID_EXIT);
438: QueueEvent(ev);
439: }
440:
441: // モニタウィンドウ識別名一覧
442: /*static*/ const char *
443: WXMainFrame::monitor_names[WinID_MAX] = {
444: "log", // LOG
445: "scheduler", // SCHEDULER
446: "mpureg", // MPUREG
447: "mpuatc", // MPUATC
448: "mpuhist", // MPUBRHIST
449: "memdump", // MEMDUMP
450: "mfp", // MFP
451: "spc", // SPC
452: "rtc", // RTC
453: "sio", // SIO
1.1.1.2 ! root 454: "keyboard", // LunaKeyboard
1.1 root 455: "lcd", // LCD
456: "lance", // LANCE
457: "bitmap", // BITMAP
458: "bitmap0", // BITMAP0
459: "netdriver", // NETDRIVER
460: "softkey", // SOFTKEY
461: };
462:
463: // 起動時にオープンするモニタウィンドウ (-M オプション)
464: /*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.