|
|
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.