[WIP-THREAD] Separate thread for emulation.
This commit is contained in:
parent
d5d01a8b68
commit
24cc810eb6
|
@ -22,6 +22,12 @@ include(VbamFunctions)
|
|||
|
||||
set(VBAM_LIBS ${VBAMCORE_LIBS})
|
||||
|
||||
option(ENABLE_THREAD_MAINLOOP "Enable separate thread for emulator main loop for WX port" OFF)
|
||||
|
||||
if(NOT ENABLE_THREAD_MAINLOOP)
|
||||
add_definitions(-DNO_THREAD_MAINLOOP)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# not yet implemented
|
||||
option(ENABLE_DIRECT3D "Enable Direct3D rendering for the wxWidgets port" OFF)
|
||||
|
|
|
@ -2297,6 +2297,10 @@ EVT_HANDLER(GeneralConfigure, "General options...")
|
|||
if (ShowModal(dlg) == wxID_OK)
|
||||
update_opts();
|
||||
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
|
||||
if (panel->game_type() != IMAGE_UNKNOWN)
|
||||
soundSetThrottle(throttle);
|
||||
|
||||
|
@ -2598,6 +2602,10 @@ EVT_HANDLER_MASK(DisplayConfigure, "Display options...", CMDEN_NREC_ANY)
|
|||
if (ShowModal(dlg) != wxID_OK)
|
||||
return;
|
||||
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
|
||||
if (frameSkip >= 0)
|
||||
systemFrameSkip = frameSkip;
|
||||
|
||||
|
@ -2609,16 +2617,16 @@ EVT_HANDLER_MASK(DisplayConfigure, "Display options...", CMDEN_NREC_ANY)
|
|||
panel->ShowFullScreen(true);
|
||||
}
|
||||
|
||||
if (panel->panel) {
|
||||
panel->panel->Destroy();
|
||||
panel->panel = NULL;
|
||||
}
|
||||
panel->DestroyDrawingPanel();
|
||||
|
||||
update_opts();
|
||||
}
|
||||
|
||||
EVT_HANDLER_MASK(ChangeFilter, "Change Pixel Filter", CMDEN_NREC_ANY)
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
int filt = gopts.filter;
|
||||
|
||||
if ((filt == FF_PLUGIN || ++gopts.filter == FF_PLUGIN) && gopts.filter_plugin.empty()) {
|
||||
|
@ -2627,10 +2635,7 @@ EVT_HANDLER_MASK(ChangeFilter, "Change Pixel Filter", CMDEN_NREC_ANY)
|
|||
|
||||
update_opts();
|
||||
|
||||
if (panel->panel) {
|
||||
panel->panel->Destroy();
|
||||
panel->panel = NULL;
|
||||
}
|
||||
panel->DestroyDrawingPanel();
|
||||
|
||||
wxString msg;
|
||||
msg.Printf(_("Using pixel filter #%d"), gopts.filter);
|
||||
|
@ -2639,13 +2644,13 @@ EVT_HANDLER_MASK(ChangeFilter, "Change Pixel Filter", CMDEN_NREC_ANY)
|
|||
|
||||
EVT_HANDLER_MASK(ChangeIFB, "Change Interframe Blending", CMDEN_NREC_ANY)
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
gopts.ifb = (gopts.ifb + 1) % 3;
|
||||
update_opts();
|
||||
|
||||
if (panel->panel) {
|
||||
panel->panel->Destroy();
|
||||
panel->panel = NULL;
|
||||
}
|
||||
panel->DestroyDrawingPanel();
|
||||
|
||||
wxString msg;
|
||||
msg.Printf(_("Using interframe blending #%d"), gopts.ifb);
|
||||
|
@ -2833,13 +2838,13 @@ EVT_HANDLER(Bilinear, "Use bilinear filter with 3d renderer")
|
|||
|
||||
EVT_HANDLER(RetainAspect, "Retain aspect ratio when resizing")
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
GetMenuOptionBool("RetainAspect", gopts.retain_aspect);
|
||||
|
||||
// Force new panel with new aspect ratio options.
|
||||
if (panel->panel) {
|
||||
panel->panel->Destroy();
|
||||
panel->panel = nullptr;
|
||||
}
|
||||
panel->DestroyDrawingPanel();
|
||||
|
||||
update_opts();
|
||||
}
|
||||
|
|
|
@ -4028,5 +4028,8 @@ bool MainFrame::BindControls()
|
|||
panel->SetFrameTitle();
|
||||
// All OK; activate idle loop
|
||||
panel->SetExtraStyle(panel->GetExtraStyle() | wxWS_EX_PROCESS_IDLE);
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
panel->StartEmulationThread();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
|
255
src/wx/panel.cpp
255
src/wx/panel.cpp
|
@ -53,10 +53,19 @@ GameArea::GameArea()
|
|||
systemColorDepth = 32;
|
||||
hq2x_init(32);
|
||||
Init_2xSaI(32);
|
||||
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
Bind(WX_THREAD_REQUEST_UPDATEDRAWPANEL, &GameArea::RequestUpdateDrawPanel, this);
|
||||
Bind(WX_THREAD_REQUEST_DRAWFRAME, &GameArea::RequestDrawFrame, this);
|
||||
Bind(WX_THREAD_REQUEST_UPDATESTATUSBAR, &GameArea::RequestUpdateStatusBar, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GameArea::LoadGame(const wxString& name)
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
rom_scene_rls = wxT("-");
|
||||
rom_scene_rls_name = wxT("-");
|
||||
rom_name = wxT("");
|
||||
|
@ -553,10 +562,7 @@ void GameArea::UnloadGame(bool destruct)
|
|||
|
||||
// in destructor, panel should be auto-deleted by wx since all panels
|
||||
// are derived from a window attached as child to GameArea
|
||||
if (panel)
|
||||
panel->Destroy();
|
||||
|
||||
panel = NULL;
|
||||
DestroyDrawingPanel();
|
||||
|
||||
// close any game-related viewer windows
|
||||
// in destructor, viewer windows are in process of being deleted anyway
|
||||
|
@ -595,6 +601,9 @@ bool GameArea::LoadState(int slot)
|
|||
|
||||
bool GameArea::LoadState(const wxFileName& fname)
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
// FIXME: first save to backup state if not backup state
|
||||
bool ret = emusys->emuReadState(UTF8(fname.GetFullPath()));
|
||||
|
||||
|
@ -642,6 +651,9 @@ bool GameArea::SaveState(int slot)
|
|||
|
||||
bool GameArea::SaveState(const wxFileName& fname)
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
// FIXME: first copy to backup state if not backup state
|
||||
bool ret = emusys->emuWriteState(UTF8(fname.GetFullPath()));
|
||||
wxGetApp().frame->update_state_ts(true);
|
||||
|
@ -681,6 +693,9 @@ void GameArea::SaveBattery()
|
|||
|
||||
void GameArea::AddBorder()
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
if (basic_width != GBWidth)
|
||||
return;
|
||||
|
||||
|
@ -693,14 +708,14 @@ void GameArea::AddBorder()
|
|||
wxGetApp().frame->Fit();
|
||||
GetSizer()->Detach(panel->GetWindow());
|
||||
|
||||
if (panel)
|
||||
panel->Destroy();
|
||||
|
||||
panel = NULL;
|
||||
DestroyDrawingPanel();
|
||||
}
|
||||
|
||||
void GameArea::DelBorder()
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
if (basic_width != SGBWidth)
|
||||
return;
|
||||
|
||||
|
@ -712,10 +727,7 @@ void GameArea::DelBorder()
|
|||
wxGetApp().frame->Fit();
|
||||
GetSizer()->Detach(panel->GetWindow());
|
||||
|
||||
if (panel)
|
||||
panel->Destroy();
|
||||
|
||||
panel = NULL;
|
||||
DestroyDrawingPanel();
|
||||
}
|
||||
|
||||
void GameArea::AdjustMinSize()
|
||||
|
@ -751,6 +763,9 @@ void GameArea::LowerMinSize()
|
|||
|
||||
void GameArea::AdjustSize(bool force)
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
AdjustMinSize();
|
||||
|
||||
if (fullscreen)
|
||||
|
@ -774,6 +789,9 @@ void GameArea::AdjustSize(bool force)
|
|||
|
||||
void GameArea::ShowFullScreen(bool full)
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
if (full == fullscreen) {
|
||||
// in case the tlw somehow lost its mind, force it to proper mode
|
||||
if (wxGetApp().frame->IsFullScreen() != fullscreen)
|
||||
|
@ -791,10 +809,7 @@ void GameArea::ShowFullScreen(bool full)
|
|||
|
||||
// just in case screen mode is going to change, go ahead and preemptively
|
||||
// delete panel to be recreated immediately after resize
|
||||
if (panel) {
|
||||
panel->Destroy();
|
||||
panel = NULL;
|
||||
}
|
||||
DestroyDrawingPanel();
|
||||
|
||||
// Windows does not restore old window size/pos
|
||||
// at least under Wine
|
||||
|
@ -939,6 +954,9 @@ void GameArea::OnKillFocus(wxFocusEvent& ev)
|
|||
|
||||
void GameArea::Pause()
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
if (paused)
|
||||
return;
|
||||
|
||||
|
@ -961,6 +979,9 @@ void GameArea::Pause()
|
|||
|
||||
void GameArea::Resume()
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
if (!paused)
|
||||
return;
|
||||
|
||||
|
@ -973,6 +994,206 @@ void GameArea::Resume()
|
|||
SetFocus();
|
||||
}
|
||||
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSection MainFrame::emulationCS;
|
||||
|
||||
wxThread::ExitCode GameArea::Entry()
|
||||
{
|
||||
MainFrame* mf = wxGetApp().frame;
|
||||
while (!GetThread()->TestDestroy()) {
|
||||
{
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
if (emusys) {
|
||||
if (!panel)
|
||||
wxQueueEvent(GetEventHandler(), new wxThreadEvent(WX_THREAD_REQUEST_UPDATEDRAWPANEL));
|
||||
mf->PollJoysticks();
|
||||
if (!paused) {
|
||||
emusys->emuMain(emusys->emuCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
wxMilliSleep(5);
|
||||
}
|
||||
return (wxThread::ExitCode)0;
|
||||
}
|
||||
|
||||
void GameArea::StopEmulationThread()
|
||||
{
|
||||
if (GetThread() && GetThread()->IsRunning())
|
||||
GetThread()->Delete(); // it will exit after next `TestDestroy()`
|
||||
}
|
||||
|
||||
void GameArea::StartEmulationThread()
|
||||
{
|
||||
if (CreateThread(wxTHREAD_JOINABLE) != wxTHREAD_NO_ERROR)
|
||||
{
|
||||
wxLogError(_("Could not create emulation thread!"));
|
||||
return;
|
||||
}
|
||||
if (GetThread()->Run() != wxTHREAD_NO_ERROR)
|
||||
{
|
||||
wxLogError(_("Could not run emulation thread!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void GameArea::RequestUpdateDrawPanel(wxThreadEvent& WXUNUSED(event))
|
||||
{
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
MainFrame* mf = wxGetApp().frame;
|
||||
if (!panel) {
|
||||
switch (gopts.render_method) {
|
||||
case RND_SIMPLE:
|
||||
panel = new BasicDrawingPanel(this, basic_width, basic_height);
|
||||
break;
|
||||
#ifdef __WXMAC__
|
||||
case RND_QUARTZ2D:
|
||||
panel = new Quartz2DDrawingPanel(this, basic_width, basic_height);
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_OGL
|
||||
case RND_OPENGL:
|
||||
panel = new GLDrawingPanel(this, basic_width, basic_height);
|
||||
break;
|
||||
#endif
|
||||
#if defined(__WXMSW__) && !defined(NO_D3D)
|
||||
case RND_DIRECT3D:
|
||||
panel = new DXDrawingPanel(this, basic_width, basic_height);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
wxWindow* w = panel->GetWindow();
|
||||
|
||||
// set up event handlers
|
||||
w->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(GameArea::OnKeyDown), NULL, this);
|
||||
w->Connect(wxEVT_KEY_UP, wxKeyEventHandler(GameArea::OnKeyUp), NULL, this);
|
||||
w->Connect(wxEVT_PAINT, wxPaintEventHandler(GameArea::PaintEv), NULL, this);
|
||||
w->Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(GameArea::EraseBackground), NULL, this);
|
||||
|
||||
// set userdata so we know it's the panel and not the frame being resized
|
||||
// the userdata is freed on disconnect/destruction
|
||||
this->Connect(wxEVT_SIZE, wxSizeEventHandler(GameArea::OnSize), NULL, this);
|
||||
|
||||
// We need to check if the buttons stayed pressed when focus the panel.
|
||||
w->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(GameArea::OnKillFocus), NULL, this);
|
||||
|
||||
// Update mouse last-used timers on mouse events etc..
|
||||
w->Connect(wxEVT_MOTION, wxMouseEventHandler(GameArea::MouseEvent), NULL, this);
|
||||
w->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(GameArea::MouseEvent), NULL, this);
|
||||
w->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(GameArea::MouseEvent), NULL, this);
|
||||
w->Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(GameArea::MouseEvent), NULL, this);
|
||||
w->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(GameArea::MouseEvent), NULL, this);
|
||||
|
||||
w->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
|
||||
w->SetSize(wxSize(basic_width, basic_height));
|
||||
|
||||
if (maxScale)
|
||||
w->SetMaxSize(wxSize(basic_width * maxScale,
|
||||
basic_height * maxScale));
|
||||
|
||||
// if user changed Display/Scale config, this needs to run
|
||||
AdjustMinSize();
|
||||
AdjustSize(false);
|
||||
|
||||
unsigned frame_priority = gopts.retain_aspect ? 0 : 1;
|
||||
|
||||
GetSizer()->Clear();
|
||||
|
||||
// add spacers on top and bottom to center panel vertically
|
||||
// but not on 2.8 which does not handle this correctly
|
||||
if (gopts.retain_aspect)
|
||||
#if wxCHECK_VERSION(2, 9, 0)
|
||||
GetSizer()->Add(0, 0, wxEXPAND);
|
||||
#else
|
||||
frame_priority = 1;
|
||||
#endif
|
||||
|
||||
// this triggers an assertion dialog in <= 3.1.2 in debug mode
|
||||
GetSizer()->Add(w, frame_priority, gopts.retain_aspect ? (wxSHAPED | wxALIGN_CENTER | wxEXPAND) : wxEXPAND);
|
||||
|
||||
#if wxCHECK_VERSION(2, 9, 0)
|
||||
if (gopts.retain_aspect)
|
||||
GetSizer()->Add(0, 0, wxEXPAND);
|
||||
#endif
|
||||
|
||||
Layout();
|
||||
|
||||
#if wxCHECK_VERSION(2, 9, 0)
|
||||
SendSizeEvent();
|
||||
#endif
|
||||
|
||||
if (pointer_blanked)
|
||||
w->SetCursor(wxCursor(wxCURSOR_BLANK));
|
||||
|
||||
// set focus to panel
|
||||
w->SetFocus();
|
||||
|
||||
// generate system color maps (after output module init)
|
||||
if (loaded == IMAGE_GBA) utilUpdateSystemColorMaps(gbaLcdFilter);
|
||||
else if (loaded == IMAGE_GB) utilUpdateSystemColorMaps(gbLcdFilter);
|
||||
else utilUpdateSystemColorMaps(false);
|
||||
}
|
||||
}
|
||||
|
||||
void GameArea::RequestDraw()
|
||||
{
|
||||
wxQueueEvent(this, new wxThreadEvent(WX_THREAD_REQUEST_DRAWFRAME));
|
||||
}
|
||||
|
||||
void GameArea::RequestStatusBar(int speed, int frames)
|
||||
{
|
||||
wxThreadEvent *event = new wxThreadEvent(WX_THREAD_REQUEST_UPDATESTATUSBAR);
|
||||
event->SetPayload(speed);
|
||||
event->SetExtraLong(frames); // should probably use payload too
|
||||
wxQueueEvent(this, event);
|
||||
}
|
||||
|
||||
void GameArea::RequestDrawFrame(wxThreadEvent& WXUNUSED(event))
|
||||
{
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
MainFrame* mf = wxGetApp().frame;
|
||||
mf->UpdateViewers();
|
||||
if (panel) {
|
||||
panel->DrawArea(&pix);
|
||||
}
|
||||
}
|
||||
|
||||
void GameArea::RequestUpdateStatusBar(wxThreadEvent& event)
|
||||
{
|
||||
//wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
MainFrame* f = wxGetApp().frame;
|
||||
int speed = event.GetPayload<int>();
|
||||
int frames = event.GetExtraLong(); // should probably use payload too
|
||||
wxString s;
|
||||
s.Printf(_("%d%%(%d, %d fps)"), speed, systemFrameSkip, frames * speed / 100);
|
||||
|
||||
switch (showSpeed) {
|
||||
case SS_NONE:
|
||||
f->GetPanel()->osdstat.clear();
|
||||
break;
|
||||
|
||||
case SS_PERCENT:
|
||||
f->GetPanel()->osdstat.Printf(_("%d%%"), speed);
|
||||
break;
|
||||
|
||||
case SS_DETAILED:
|
||||
f->GetPanel()->osdstat = s;
|
||||
break;
|
||||
}
|
||||
|
||||
wxGetApp().frame->SetStatusText(s, 1);
|
||||
}
|
||||
#endif // NO_THREAD_MAINLOOP
|
||||
|
||||
void GameArea::DestroyDrawingPanel()
|
||||
{
|
||||
if (panel) {
|
||||
panel->Destroy();
|
||||
panel = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GameArea::OnIdle(wxIdleEvent& event)
|
||||
{
|
||||
wxString pl = wxGetApp().pending_load;
|
||||
|
@ -1416,7 +1637,9 @@ void GameArea::OnSDLJoy(wxSDLJoyEvent& ev)
|
|||
}
|
||||
|
||||
BEGIN_EVENT_TABLE(GameArea, wxPanel)
|
||||
#ifdef NO_THREAD_MAINLOOP
|
||||
EVT_IDLE(GameArea::OnIdle)
|
||||
#endif
|
||||
EVT_SDLJOY(GameArea::OnSDLJoy)
|
||||
// FIXME: wxGTK does not generate motion events in MainFrame (not sure
|
||||
// what to do about it)
|
||||
|
|
|
@ -86,18 +86,20 @@ void systemDrawScreen()
|
|||
{
|
||||
frames++;
|
||||
MainFrame* mf = wxGetApp().frame;
|
||||
mf->UpdateViewers();
|
||||
// FIXME: Sm60FPS crap and sondBufferLow crap
|
||||
GameArea* ga = mf->GetPanel();
|
||||
#ifndef NO_FFMPEG
|
||||
|
||||
if (ga)
|
||||
ga->AddFrame(pix);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
ga->RequestDraw();
|
||||
#else
|
||||
mf->UpdateViewers();
|
||||
if (ga && ga->panel)
|
||||
ga->panel->DrawArea(&pix);
|
||||
#endif
|
||||
}
|
||||
|
||||
// record a game "movie"
|
||||
|
@ -337,6 +339,9 @@ uint32_t systemReadJoypad(int joy)
|
|||
void systemShowSpeed(int speed)
|
||||
{
|
||||
MainFrame* f = wxGetApp().frame;
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
f->GetPanel()->RequestStatusBar(speed, frames);
|
||||
#else
|
||||
wxString s;
|
||||
s.Printf(_("%d%%(%d, %d fps)"), speed, systemFrameSkip, frames * speed / 100);
|
||||
|
||||
|
@ -355,6 +360,7 @@ void systemShowSpeed(int speed)
|
|||
}
|
||||
|
||||
wxGetApp().frame->SetStatusText(s, 1);
|
||||
#endif // NO_THREAD_MAINLOOP
|
||||
frames = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -726,6 +726,9 @@ MainFrame::MainFrame()
|
|||
|
||||
MainFrame::~MainFrame()
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
GetPanel()->StopEmulationThread();
|
||||
#endif
|
||||
#ifndef NO_LINK
|
||||
CloseLink();
|
||||
#endif
|
||||
|
@ -772,6 +775,10 @@ void MainFrame::OnDropFile(wxDropFilesEvent& event)
|
|||
wxString* f = event.GetFiles();
|
||||
// ignore all but last
|
||||
wxGetApp().pending_load = f[event.GetNumberOfFiles() - 1];
|
||||
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
GetPanel()->LoadGame(wxGetApp().pending_load);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainFrame::OnMenu(wxContextMenuEvent& event)
|
||||
|
@ -845,6 +852,9 @@ void MainFrame::OnSize(wxSizeEvent& event)
|
|||
|
||||
int MainFrame::FilterEvent(wxEvent& event)
|
||||
{
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
wxCriticalSectionLocker lock(MainFrame::emulationCS);
|
||||
#endif
|
||||
if (event.GetEventType() == wxEVT_KEY_DOWN && !menus_opened && !dialog_opened)
|
||||
{
|
||||
wxKeyEvent& ke = (wxKeyEvent&)event;
|
||||
|
@ -1101,17 +1111,17 @@ void MainFrame::MenuPopped(wxMenuEvent& evt)
|
|||
void MainFrame::SetMenusOpened(bool state)
|
||||
{
|
||||
if ((menus_opened = state)) {
|
||||
#ifdef __WXMSW__
|
||||
paused = true;
|
||||
panel->Pause();
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#ifdef __WXMSW__
|
||||
paused = false;
|
||||
pause_next = false;
|
||||
panel->Resume();
|
||||
#endif
|
||||
//#ifdef __WXMSW__
|
||||
// paused = true;
|
||||
// panel->Pause();
|
||||
//#endif
|
||||
// }
|
||||
// else {
|
||||
//#ifdef __WXMSW__
|
||||
// paused = false;
|
||||
// pause_next = false;
|
||||
// panel->Resume();
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -214,6 +214,10 @@ public:
|
|||
MainFrame();
|
||||
~MainFrame();
|
||||
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
static wxCriticalSection emulationCS;
|
||||
#endif
|
||||
|
||||
bool BindControls();
|
||||
void MenuOptionIntMask(const char* menuName, int& field, int mask);
|
||||
void MenuOptionIntRadioValue(const char* menuName, int& field, int mask);
|
||||
|
@ -500,11 +504,36 @@ class DrawingPanelBase;
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
class GameArea : public wxPanel, public HiDPIAware {
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
#include <wx/thread.h>
|
||||
|
||||
wxDEFINE_EVENT(WX_THREAD_REQUEST_UPDATEDRAWPANEL, wxThreadEvent);
|
||||
wxDEFINE_EVENT(WX_THREAD_REQUEST_DRAWFRAME, wxThreadEvent);
|
||||
wxDEFINE_EVENT(WX_THREAD_REQUEST_UPDATESTATUSBAR, wxThreadEvent);
|
||||
#endif // NO_THREAD_MAINLOOP
|
||||
|
||||
class GameArea : public wxPanel, public HiDPIAware
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
, public wxThreadHelper
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
GameArea();
|
||||
virtual ~GameArea();
|
||||
|
||||
#ifndef NO_THREAD_MAINLOOP
|
||||
virtual wxThread::ExitCode Entry();
|
||||
void StartEmulationThread();
|
||||
void StopEmulationThread();
|
||||
void RequestUpdateDrawPanel(wxThreadEvent&);
|
||||
void RequestDrawFrame(wxThreadEvent&);
|
||||
void RequestUpdateStatusBar(wxThreadEvent&);
|
||||
void RequestDraw();
|
||||
void RequestStatusBar(int speed, int frames);
|
||||
#endif
|
||||
|
||||
void DestroyDrawingPanel();
|
||||
|
||||
virtual void SetMainFrame(MainFrame* parent) { main_frame = parent; }
|
||||
|
||||
// set to game title + link info
|
||||
|
|
Loading…
Reference in New Issue