--- nono/wx/wxmainframe.cpp 2026/04/29 17:05:48 1.1.1.23 +++ nono/wx/wxmainframe.cpp 2026/04/29 17:05:53 1.1.1.24 @@ -24,6 +24,7 @@ #include "wxromwindow.h" #include "wxsoftkey.h" #include "wxstatuspanel.h" +#include "wxthreadmonitor.h" #include "wxtvrammonitor.h" #include "wxuimessage.h" #include "wxversion.h" @@ -32,6 +33,7 @@ #include "fdd.h" #include "hostcom.h" #include "hostnet.h" +#include "hostsound.h" #include "mainapp.h" #include "mpu.h" #include "netdriver_slirp.h" @@ -124,6 +126,13 @@ enum { ID_HOSTCOM_DBG_CONSOLE, // 存在しないけど HOSTCOMn と揃える必要がある。 ID_HOSTCOM_DBG_NONE, // 最後に置くこと。 + ID_HOSTSOUND_START, + ID_HOSTSOUND_NETBSD, + ID_HOSTSOUND_SNDIO, + ID_HOSTSOUND_ALSA, + ID_HOSTSOUND_WAV, + ID_HOSTSOUND_NONE, // 最後に置くこと + ID_SCALE_START, ID_SCALE_END = ID_SCALE_START + 6, @@ -225,6 +234,10 @@ wxBEGIN_EVENT_TABLE(WXMainFrame, inherit WXMainFrame::OnMenuHostCom) EVT_UPDATE_UI_RANGE(ID_HOSTCOM0_START + 1, ID_HOSTCOM2_NONE, WXMainFrame::OnMenuHostComUI) + EVT_MENU_RANGE(ID_HOSTSOUND_START + 1, ID_HOSTSOUND_NONE, + WXMainFrame::OnMenuHostSound) + EVT_UPDATE_UI_RANGE(ID_HOSTSOUND_START + 1, ID_HOSTSOUND_NONE, + WXMainFrame::OnMenuHostSoundUI) EVT_MENU_RANGE(ID_SCALE_START, ID_SCALE_END, WXMainFrame::OnMenuScale) @@ -295,6 +308,7 @@ WXMainFrame::WXMainFrame(wxWindow *paren hostcom[i] = gMainApp.FindObject(OBJ_HOSTCOM(i)); } hostcom_dbg = gMainApp.FindObject(OBJ_HOSTCOM_DBG); + hostsound = gMainApp.FindObject(OBJ_HOSTSOUND); // メイン MPU 名を取得。メニューとタイトルによく出てくるので。 // "88xx0" とか "88200" は別処理。 @@ -342,6 +356,7 @@ WXMainFrame::WXMainFrame(wxWindow *paren for (uint i = 0; i < hostcom.size(); i++) { CreateHostComMenu(menuSet, i); } + CreateHostSoundMenu(menuSet); menubar->Append(menuSet, _("&Setting")); // メニュー > 表示 @@ -526,7 +541,9 @@ WXMainFrame::WXMainFrame(wxWindow *paren AppendIf(menuDev, ID_SUBWIN_LUNAFB, _("Bitmap Plane")); AppendIf(menuDev, ID_SUBWIN_TVRAM, _("Text Screen")); AppendIf(menuDev, ID_SUBWIN_GVRAM, _("Graphic Screen")); + AppendIf(menuDev, ID_MONITOR_SOUND, _("Sound")); AppendIf(menuDev, ID_MONITOR_SSG, "SSG"); + AppendIf(menuDev, ID_MONITOR_ADPCM, "ADPCM"); AppendIf(menuDev, ID_MONITOR_ROMCONS, _("ROM Console (provisional)")); AppendIf(menuDev, ID_SUBWIN_ROM, "ROM"); // LUNA はバスが複数あるので Mainbus Device とする。 @@ -539,6 +556,7 @@ WXMainFrame::WXMainFrame(wxWindow *paren wxMenu *menuHost = new wxMenu(); AppendIf(menuHost, ID_MONITOR_WXHOSTINFO, _("Host &Information")); + AppendIf(menuHost, ID_SUBWIN_THREADS, _("Thread Status")); for (uint i = 0; i < hostnet.size(); i++) { uint id = ID_MONITOR_HOSTNET(i); if (gMonitorManager->Find(id)) { @@ -552,6 +570,7 @@ WXMainFrame::WXMainFrame(wxWindow *paren menuHost->AppendCheckItem(id, GetHostComLabel(i)); } } + AppendIf(menuHost, ID_MONITOR_HOSTSOUND, _("Host Sound")); menuMonitor->AppendSubMenu(menuHost, _("&Host")); wxMenu *menuDebug = new wxMenu(); @@ -645,6 +664,8 @@ WXMainFrame::WXMainFrame(wxWindow *paren wxCommandEventHandler(WXMainFrame::OnHostNetFailed)); WXUIMessage::Connect(UIMessage::HOSTCOM_FAILED, this, wxCommandEventHandler(WXMainFrame::OnHostComFailed)); + WXUIMessage::Connect(UIMessage::HOSTSOUND_FAILED, this, + wxCommandEventHandler(WXMainFrame::OnHostSoundFailed)); if (gMainApp.Has(VMCap::M68K)) { WXUIMessage::Connect(UIMessage::HALT, this, wxCommandEventHandler(WXMainFrame::OnHaltNotify)); @@ -663,6 +684,8 @@ WXMainFrame::~WXMainFrame() wxCommandEventHandler(WXMainFrame::OnHostNetFailed)); WXUIMessage::Disconnect(UIMessage::HOSTCOM_FAILED, this, wxCommandEventHandler(WXMainFrame::OnHostComFailed)); + WXUIMessage::Disconnect(UIMessage::HOSTSOUND_FAILED, this, + wxCommandEventHandler(WXMainFrame::OnHostSoundFailed)); if (gMainApp.Has(VMCap::M68K)) { WXUIMessage::Disconnect(UIMessage::HALT, this, wxCommandEventHandler(WXMainFrame::OnHaltNotify)); @@ -768,6 +791,29 @@ WXMainFrame::CreateHostComMenu(wxMenu *m menuSet->AppendSubMenu(menu, name); } +// HostSound 用のメニューを作成して menuSet に追加する。 +void +WXMainFrame::CreateHostSoundMenu(wxMenu *menuSet) +{ + if (hostsound == NULL) { + return; + } + + wxMenu *menu = new wxMenu(); +#if defined(HAVE_HOSTSOUND_NETBSD) + menu->AppendRadioItem(ID_HOSTSOUND_NETBSD, "&netbsd"); +#endif +#if defined(HAVE_HOSTSOUND_SNDIO) + menu->AppendRadioItem(ID_HOSTSOUND_SNDIO, "&sndio"); +#endif +#if defined(HAVE_HOSTSOUND_ALSA) + menu->AppendRadioItem(ID_HOSTSOUND_ALSA, "&alsa"); +#endif + menu->AppendRadioItem(ID_HOSTSOUND_WAV, "&wav"); + menu->AppendRadioItem(ID_HOSTSOUND_NONE, "&none"); + menuSet->AppendSubMenu(menu, "HostSound"); +} + // リムーバブルデバイス用のメニューを作成して menuDevice に追加する void WXMainFrame::CreateRemovableMenu(wxMenu *menuDevice) @@ -1043,10 +1089,10 @@ WXMainFrame::OnFullSpeed(wxCommandEvent& { if (event.IsChecked()) { // チェックが入ったので、高速モードにする - syncer->RequestFullSpeed(true); + syncer->NotifyFullSpeed(true); } else { // チェックが消えたので、通常モードにする - syncer->RequestFullSpeed(false); + syncer->NotifyFullSpeed(false); } } @@ -1222,6 +1268,49 @@ WXMainFrame::OnMenuHostComUI(wxUpdateUIE event.Check((id == selected)); } +// メニューの「設定 > HostSound > *」の選択肢イベント +void +WXMainFrame::OnMenuHostSound(wxCommandEvent& event) +{ + // 設定を更新。 + std::string line = "hostsound-driver="; + switch (event.GetId()) { + case ID_HOSTSOUND_NETBSD: line += "netbsd"; break; + case ID_HOSTSOUND_SNDIO: line += "sndio"; break; + case ID_HOSTSOUND_ALSA: line += "alsa"; break; + case ID_HOSTSOUND_WAV: line += "wav"; break; + case ID_HOSTSOUND_NONE: line += "none"; break; + default: + assert(false); + } + gConfig->UpdateRunning(line); + + // ホストスレッドに通知。 + hostsound->NotifyReselectDriver(); +} + +// メニューの「設定 > HostSound > *」の UI +void +WXMainFrame::OnMenuHostSoundUI(wxUpdateUIEvent& event) +{ + int id = event.GetId(); + const std::string driver = hostsound->GetDriverName(); + int selected; + if (driver == "netbsd") { + selected = ID_HOSTSOUND_NETBSD; + } else if (driver == "sndio") { + selected = ID_HOSTSOUND_SNDIO; + } else if (driver == "alsa") { + selected = ID_HOSTSOUND_ALSA; + } else if (driver == "wav") { + selected = ID_HOSTSOUND_WAV; + } else { + selected = ID_HOSTSOUND_NONE; + } + + event.Check((id == selected)); +} + // hostnet ドライバ起動失敗のメッセージ。 void WXMainFrame::OnHostNetFailed(wxCommandEvent& event) @@ -1235,6 +1324,7 @@ WXMainFrame::OnHostNetFailed(wxCommandEv HostDriverFailed(hostdev, errmsg); } +// hostcom ドライバ起動失敗のメッセージ。 void WXMainFrame::OnHostComFailed(wxCommandEvent& event) { @@ -1252,6 +1342,16 @@ WXMainFrame::OnHostComFailed(wxCommandEv HostDriverFailed(hostdev, errmsg); } +// hostsound ドライバ起動失敗のメッセージ +void +WXMainFrame::OnHostSoundFailed(wxCommandEvent& event) +{ + wxString errmsg; + + errmsg = hostsound->GetErrmsg(); + HostDriverFailed("hostsound", errmsg); +} + // ホストドライバ起動失敗のメッセージ。 void WXMainFrame::HostDriverFailed(const wxString& hostdev, const wxString& errmsg) @@ -1717,6 +1817,10 @@ WXMainFrame::DoWindow(int id, bool enabl } catch (...) { } break; + case ID_MONITOR_ADPCM: + SetMonitor(id, "ADPCM"); + break; + case ID_MONITOR_AREASET: SetMonitor(id, _("Areaset")); break; @@ -1800,6 +1904,10 @@ WXMainFrame::DoWindow(int id, bool enabl break; } + case ID_MONITOR_HOSTSOUND: + SetMonitor(id, _("Host Sound")); + break; + case ID_MONITOR_INTERRUPT: { wxString name; @@ -1941,6 +2049,10 @@ WXMainFrame::DoWindow(int id, bool enabl SetMonitor(id, _("SLIRP Internal States")); break; + case ID_MONITOR_SOUND: + SetMonitor(id, _("Sound")); + break; + case ID_MONITOR_SPC: SetMonitor(id, "SPC (MB89352)"); break; @@ -2110,6 +2222,12 @@ WXMainFrame::DoWindow(int id, bool enabl } catch (...) { } break; + case ID_SUBWIN_THREADS: + try { + windows[id].reset(new WXThreadMonitorWindow(this)); + } catch (...) { } + break; + case ID_SUBWIN_VECTOR: { wxString name = MPUName() + " " + _("Vector Table");