* clean up code

* working-ish run/pause/reset
* proper closing/cleanup
* ability to run BIOS alone
This commit is contained in:
StapleButter
2017-03-29 18:59:20 +02:00
parent c0734352ab
commit 4e7dc60d37
6 changed files with 212 additions and 391 deletions

View File

@ -328,6 +328,14 @@ void LoadROM(const char* path, bool direct)
if (NDSCart::LoadROM(path, direct)) if (NDSCart::LoadROM(path, direct))
Running = true; Running = true;
else
printf("Failed to load ROM %s\n", path);
}
void LoadBIOS()
{
Reset();
Running = true;
} }

View File

@ -117,6 +117,7 @@ void DeInit();
void Reset(); void Reset();
void LoadROM(const char* path, bool direct); void LoadROM(const char* path, bool direct);
void LoadBIOS();
void SetupDirectBoot(); void SetupDirectBoot();
void RunFrame(); void RunFrame();

View File

@ -68,6 +68,10 @@ void DeInit()
void Reset() void Reset()
{ {
if (SRAM) delete[] SRAM;
if (Discover_Buffer) delete[] Discover_Buffer;
SRAM = NULL;
Discover_Buffer = NULL;
} }
void LoadSave(char* path) void LoadSave(char* path)
@ -625,6 +629,7 @@ void Reset()
DataOutLen = 0; DataOutLen = 0;
CartInserted = false; CartInserted = false;
if (CartROM) delete[] CartROM;
CartROM = NULL; CartROM = NULL;
CartROMSize = 0; CartROMSize = 0;
CartID = 0; CartID = 0;
@ -735,6 +740,8 @@ void ReadROM(u32 addr, u32 len, u32 offset)
void ReadROM_B7(u32 addr, u32 len, u32 offset) void ReadROM_B7(u32 addr, u32 len, u32 offset)
{ {
if (!CartInserted) return;
addr &= (CartROMSize-1); addr &= (CartROMSize-1);
if (!CartIsHomebrew) if (!CartIsHomebrew)
{ {
@ -858,7 +865,7 @@ void WriteROMCnt(u32 val)
break; break;
case 0x3C: case 0x3C:
CmdEncMode = 1; if (CartInserted) CmdEncMode = 1;
break; break;
case 0xB7: case 0xB7:

View File

@ -116,7 +116,7 @@ InputConfigDialog::InputConfigDialog(wxWindow* parent)
p->SetSizer(grid); p->SetSizer(grid);
sizer->Add(p, 0, wxALL, 15); sizer->Add(p, 0, wxALL, 15);
wxComboBox* joycombo = new wxComboBox(joyside, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN | wxCB_READONLY); /*wxComboBox* joycombo = new wxComboBox(joyside, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN | wxCB_READONLY);
int numjoys = SDL_NumJoysticks(); int numjoys = SDL_NumJoysticks();
if (numjoys > 0) if (numjoys > 0)
@ -133,7 +133,7 @@ InputConfigDialog::InputConfigDialog(wxWindow* parent)
joycombo->Enable(false); joycombo->Enable(false);
} }
sizer->Add(joycombo, 0, wxALL&(~wxTOP), 15); sizer->Add(joycombo, 0, wxALL&(~wxTOP), 15);*/
joyside->SetSizer(sizer); joyside->SetSizer(sizer);
} }
@ -241,7 +241,6 @@ void InputConfigDialog::OnConfigureKey(wxMouseEvent& event)
parent->pollbtn = btn; parent->pollbtn = btn;
parent->pollbtntext = btn->GetLabel(); parent->pollbtntext = btn->GetLabel();
parent->pollid = event.GetId(); parent->pollid = event.GetId();
//parent->polltimer->Start(50);
btn->SetLabel("[press key]"); btn->SetLabel("[press key]");
btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT)); btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT));
@ -270,77 +269,32 @@ void InputConfigDialog::OnPoll(wxTimerEvent& event)
{ {
if (pollid < 200) return; if (pollid < 200) return;
//keycatcher->SetFocus(); int id = pollid - 200;
//SDL_SetWindowInputFocus(sdlwin); if (id >= 12) return;
//SDL_RaiseWindow(sdlwin);
//SDL_PumpEvents();
//keycatcher->SetFocus();
//SDL_RaiseWindow(sdlwin);
/*if (keystate[SDL_SCANCODE_ESCAPE]) if (keystate[SDL_SCANCODE_BACKSPACE])
{ {
joymapping[id] = -1;
char keyname[16];
JoyMappingName(joymapping[id], keyname);
pollbtn->SetLabel(keyname);
polltimer->Stop(); polltimer->Stop();
pollbtn->SetLabel(pollbtntext);
pollid = 0; pollid = 0;
pollbtn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); pollbtn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
pollbtn->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT)); pollbtn->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT));
pollbtn->Refresh(); pollbtn->Refresh();
return; return;
}*/ }
if (pollid >= 200) int nbuttons = SDL_JoystickNumButtons(joy);
for (int i = 0; i < nbuttons; i++)
{ {
int id = pollid - 200; if (SDL_JoystickGetButton(joy, i))
if (id >= 12) return;
if (keystate[SDL_SCANCODE_BACKSPACE])
{ {
joymapping[id] = -1; joymapping[id] = i;
char keyname[16];
JoyMappingName(joymapping[id], keyname);
pollbtn->SetLabel(keyname);
polltimer->Stop();
pollid = 0;
pollbtn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
pollbtn->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT));
pollbtn->Refresh();
return;
}
int nbuttons = SDL_JoystickNumButtons(joy);
for (int i = 0; i < nbuttons; i++)
{
if (SDL_JoystickGetButton(joy, i))
{
joymapping[id] = i;
char keyname[16];
JoyMappingName(joymapping[id], keyname);
pollbtn->SetLabel(keyname);
polltimer->Stop();
pollid = 0;
pollbtn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
pollbtn->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT));
pollbtn->Refresh();
return;
}
}
u8 blackhat = SDL_JoystickGetHat(joy, 0);
if (blackhat)
{
if (blackhat & 0x1) blackhat = 0x1;
else if (blackhat & 0x2) blackhat = 0x2;
else if (blackhat & 0x4) blackhat = 0x4;
else blackhat = 0x8;
joymapping[id] = 0x100 | blackhat;
char keyname[16]; char keyname[16];
JoyMappingName(joymapping[id], keyname); JoyMappingName(joymapping[id], keyname);
@ -355,32 +309,29 @@ void InputConfigDialog::OnPoll(wxTimerEvent& event)
return; return;
} }
} }
/*else
u8 blackhat = SDL_JoystickGetHat(joy, 0);
if (blackhat)
{ {
int id = pollid - 100; if (blackhat & 0x1) blackhat = 0x1;
if (id >= 12) return; else if (blackhat & 0x2) blackhat = 0x2;
else if (blackhat & 0x4) blackhat = 0x4;
else blackhat = 0x8;
for (int i = 0; i < nkeys; i++) joymapping[id] = 0x100 | blackhat;
{
if (keystate[i])
{
keymapping[id] = i;
pollbtn->Enable(true); char keyname[16];
JoyMappingName(joymapping[id], keyname);
pollbtn->SetLabel(keyname);
const char* keyname = SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)i)); polltimer->Stop();
pollbtn->SetLabel(keyname); pollid = 0;
polltimer->Stop(); pollbtn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
pollid = 0; pollbtn->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT));
pollbtn->Refresh();
pollbtn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); return;
pollbtn->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT)); }
pollbtn->Refresh();
return;
}
}
}*/
} }
void InputConfigDialog::OnFancybuttonHover(wxMouseEvent& event) void InputConfigDialog::OnFancybuttonHover(wxMouseEvent& event)

View File

@ -105,10 +105,11 @@ wxBEGIN_EVENT_TABLE(MainFrame, wxFrame)
EVT_MENU(ID_OPENROM, MainFrame::OnOpenROM) EVT_MENU(ID_OPENROM, MainFrame::OnOpenROM)
EVT_MENU(ID_EXIT, MainFrame::OnCloseFromMenu) EVT_MENU(ID_EXIT, MainFrame::OnCloseFromMenu)
EVT_MENU(ID_INPUTCONFIG, MainFrame::OnInputConfig) EVT_MENU(ID_RUN, MainFrame::OnRun)
EVT_MENU(ID_PAUSE, MainFrame::OnPause)
EVT_MENU(ID_RESET, MainFrame::OnReset)
EVT_PAINT(MainFrame::OnPaint) EVT_MENU(ID_INPUTCONFIG, MainFrame::OnInputConfig)
EVT_IDLE(MainFrame::OnIdle)
wxEND_EVENT_TABLE() wxEND_EVENT_TABLE()
@ -122,7 +123,7 @@ MainFrame::MainFrame()
wxMenu* systemmenu = new wxMenu(); wxMenu* systemmenu = new wxMenu();
systemmenu->Append(ID_RUN, "Run"); systemmenu->Append(ID_RUN, "Run");
systemmenu->Append(ID_PAUSE, "Pause"); systemmenu->AppendCheckItem(ID_PAUSE, "Pause");
systemmenu->AppendSeparator(); systemmenu->AppendSeparator();
systemmenu->Append(ID_RESET, "Reset"); systemmenu->Append(ID_RESET, "Reset");
@ -136,18 +137,9 @@ MainFrame::MainFrame()
SetMenuBar(melonbar); SetMenuBar(melonbar);
SetClientSize(256, 384); SetClientSize(256, 256);
SetMinSize(GetSize()); SetMinSize(GetSize());
emustatus = 2;
/*emustatuschangemutex = new wxMutex();
emustatuschange = new wxCondition(*emustatuschangemutex);
emustopmutex = new wxMutex();
emustop = new wxCondition(*emustopmutex);
emustopmutex->Lock();*/
emuthread = new EmuThread(this); emuthread = new EmuThread(this);
if (emuthread->Run() != wxTHREAD_NO_ERROR) if (emuthread->Run() != wxTHREAD_NO_ERROR)
{ {
@ -156,48 +148,33 @@ MainFrame::MainFrame()
return; return;
} }
/*sdlwin = SDL_CreateWindowFrom(GetHandle());
sdlrend = SDL_CreateRenderer(sdlwin, -1, SDL_RENDERER_ACCELERATED);// | SDL_RENDERER_PRESENTVSYNC);
sdltex = SDL_CreateTexture(sdlrend, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, 256, 384);
texmutex = new wxMutex();
SDL_LockTexture(sdltex, NULL, &texpixels, &texstride);
texmutex->Unlock();*/
NDS::Init(); NDS::Init();
rompath = wxEmptyString;
GetMenuBar()->Enable(ID_PAUSE, false);
GetMenuBar()->Enable(ID_RESET, false);
Touching = false; Touching = false;
/*SDL_GetWindowPosition(sdlwin, &WindowX, &WindowY);
SDL_GetWindowSize(sdlwin, &WindowW, &WindowH);*/
joy = NULL; joy = NULL;
joyid = -1; joyid = -1;
axismask = 0; }
void MainFrame::CloseFromOutside()
{
emuthread = NULL;
Close();
} }
void MainFrame::OnClose(wxCloseEvent& event) void MainFrame::OnClose(wxCloseEvent& event)
{ {
if (emustatus == 1) if (emuthread)
{ {
emustatus = 0; emuthread->EmuExit();
//emustop->Wait();
}
else
{
emustatus = 0;
/*emustatuschangemutex->Lock();
emustatuschange->Signal();
emustatuschangemutex->Unlock();*/
}
emuthread->Wait(); emuthread->Wait();
delete emuthread; delete emuthread;
/*delete emustatuschange; emuthread = NULL;
delete emustatuschangemutex; }
delete emustop;
delete emustopmutex;*/
NDS::DeInit(); NDS::DeInit();
@ -208,14 +185,6 @@ void MainFrame::OnClose(wxCloseEvent& event)
joyid = -1; joyid = -1;
} }
/*SDL_UnlockTexture(sdltex);
delete texmutex;
SDL_DestroyTexture(sdltex);
SDL_DestroyRenderer(sdlrend);
SDL_DestroyWindow(sdlwin);*/
SDL_Quit(); SDL_Quit();
Destroy(); Destroy();
@ -232,20 +201,77 @@ void MainFrame::OnOpenROM(wxCommandEvent& event)
if (opener.ShowModal() == wxID_CANCEL) if (opener.ShowModal() == wxID_CANCEL)
return; return;
if (emustatus == 1) emuthread->EmuPause();
rompath = opener.GetPath();
NDS::LoadROM(rompath.mb_str(), true);
emuthread->EmuRun();
GetMenuBar()->Enable(ID_PAUSE, true);
GetMenuBar()->Check(ID_PAUSE, false);
GetMenuBar()->Enable(ID_RESET, true);
if (!joy)
{ {
emustatus = 2; if (SDL_NumJoysticks() > 0)
emustop->Wait(); {
joy = SDL_JoystickOpen(0);
joyid = SDL_JoystickInstanceID(joy);
}
}
}
void MainFrame::OnRun(wxCommandEvent& event)
{
// TODO: reduce duplicate code
if (!emuthread->EmuIsRunning())
{
NDS::LoadBIOS();
} }
wxString filename = opener.GetPath();
NDS::LoadROM(filename.mb_str(), true);
emustatus = 1;
/*emustatuschangemutex->Lock();
emustatuschange->Signal();
emustatuschangemutex->Unlock();*/
emuthread->EmuRun(); emuthread->EmuRun();
GetMenuBar()->Enable(ID_PAUSE, true);
GetMenuBar()->Check(ID_PAUSE, false);
GetMenuBar()->Enable(ID_RESET, true);
if (!joy)
{
if (SDL_NumJoysticks() > 0)
{
joy = SDL_JoystickOpen(0);
joyid = SDL_JoystickInstanceID(joy);
}
}
}
void MainFrame::OnPause(wxCommandEvent& event)
{
if (!emuthread->EmuIsPaused())
{
emuthread->EmuPause();
GetMenuBar()->Check(ID_PAUSE, true);
}
else
{
emuthread->EmuRun();
GetMenuBar()->Check(ID_PAUSE, false);
}
}
void MainFrame::OnReset(wxCommandEvent& event)
{
emuthread->EmuPause();
if (!rompath.IsEmpty())
NDS::LoadROM(rompath.mb_str(), true);
else
NDS::LoadBIOS();
emuthread->EmuRun();
GetMenuBar()->Enable(ID_PAUSE, true);
GetMenuBar()->Check(ID_PAUSE, false);
GetMenuBar()->Enable(ID_RESET, true);
if (!joy) if (!joy)
{ {
@ -276,153 +302,6 @@ void MainFrame::OnInputConfig(wxCommandEvent& event)
} }
} }
/*void MainFrame::ProcessSDLEvents()
{
bool running = (emustatus == 1);
SDL_Event evt;
while (SDL_PollEvent(&evt))
{
switch (evt.type)
{
case SDL_WINDOWEVENT:
if (evt.window.event != SDL_WINDOWEVENT_EXPOSED)
{
SDL_GetWindowPosition(sdlwin, &WindowX, &WindowY);
SDL_GetWindowSize(sdlwin, &WindowW, &WindowH);
}
break;
case SDL_MOUSEBUTTONDOWN:
if (!running) return;
if (evt.button.y >= 192 && evt.button.button == SDL_BUTTON_LEFT)
{
Touching = true;
NDS::PressKey(16+6);
}
break;
case SDL_KEYDOWN:
if (!running) return;
for (int i = 0; i < 10; i++)
if (evt.key.keysym.scancode == Config::KeyMapping[i]) NDS::PressKey(i);
if (evt.key.keysym.scancode == Config::KeyMapping[10]) NDS::PressKey(16);
if (evt.key.keysym.scancode == Config::KeyMapping[11]) NDS::PressKey(17);
break;
case SDL_KEYUP:
if (!running) return;
for (int i = 0; i < 10; i++)
if (evt.key.keysym.scancode == Config::KeyMapping[i]) NDS::ReleaseKey(i);
if (evt.key.keysym.scancode == Config::KeyMapping[10]) NDS::ReleaseKey(16);
if (evt.key.keysym.scancode == Config::KeyMapping[11]) NDS::ReleaseKey(17);
break;
case SDL_JOYBUTTONDOWN:
if (!running) return;
if (evt.jbutton.which != joyid) return;
for (int i = 0; i < 10; i++)
if (evt.jbutton.button == Config::JoyMapping[i]) NDS::PressKey(i);
if (evt.jbutton.button == Config::JoyMapping[10]) NDS::PressKey(16);
if (evt.jbutton.button == Config::JoyMapping[11]) NDS::PressKey(17);
break;
case SDL_JOYBUTTONUP:
if (!running) return;
if (evt.jbutton.which != joyid) return;
for (int i = 0; i < 10; i++)
if (evt.jbutton.button == Config::JoyMapping[i]) NDS::ReleaseKey(i);
if (evt.jbutton.button == Config::JoyMapping[10]) NDS::ReleaseKey(16);
if (evt.jbutton.button == Config::JoyMapping[11]) NDS::ReleaseKey(17);
break;
case SDL_JOYHATMOTION:
if (!running) return;
if (evt.jhat.which != joyid) return;
if (evt.jhat.hat != 0) return;
for (int i = 0; i < 12; i++)
{
int j = (i >= 10) ? (i+6) : i;
if (Config::JoyMapping[i] == 0x101)
(evt.jhat.value & SDL_HAT_UP) ? NDS::PressKey(j) : NDS::ReleaseKey(j);
else if (Config::JoyMapping[i] == 0x102)
(evt.jhat.value & SDL_HAT_RIGHT) ? NDS::PressKey(j) : NDS::ReleaseKey(j);
else if (Config::JoyMapping[i] == 0x104)
(evt.jhat.value & SDL_HAT_DOWN) ? NDS::PressKey(j) : NDS::ReleaseKey(j);
else if (Config::JoyMapping[i] == 0x108)
(evt.jhat.value & SDL_HAT_LEFT) ? NDS::PressKey(j) : NDS::ReleaseKey(j);
}
break;
case SDL_JOYAXISMOTION:
if (!running) return;
if (evt.jaxis.which != joyid) return;
if (evt.jaxis.axis == 0)
{
if (evt.jaxis.value >= 16384) { NDS::PressKey(4); axismask |= 0x1; }
else if (axismask & 0x1) { NDS::ReleaseKey(4); axismask &= ~0x1; }
if (evt.jaxis.value <= -16384) { NDS::PressKey(5); axismask |= 0x2; }
else if (axismask & 0x2) { NDS::ReleaseKey(5); axismask &= ~0x2; }
}
else if (evt.jaxis.axis == 1)
{
if (evt.jaxis.value >= 16384) { NDS::PressKey(7); axismask |= 0x4; }
else if (axismask & 0x4) { NDS::ReleaseKey(7); axismask &= ~0x4; }
if (evt.jaxis.value <= -16384) { NDS::PressKey(6); axismask |= 0x8; }
else if (axismask & 0x8) { NDS::ReleaseKey(6); axismask &= ~0x8; }
}
break;
}
}
if (Touching)
{
int mx, my;
u32 btn = SDL_GetGlobalMouseState(&mx, &my);
if (!(btn & SDL_BUTTON(SDL_BUTTON_LEFT)))
{
Touching = false;
NDS::ReleaseKey(16+6);
NDS::ReleaseScreen();
}
else
{
mx -= WindowX;
my -= (WindowY + 192);
if (mx < 0) mx = 0;
else if (mx > 255) mx = 255;
if (my < 0) my = 0;
else if (my > 191) my = 191;
NDS::TouchScreen(mx, my);
}
}
}*/
void MainFrame::OnPaint(wxPaintEvent& event)
{
wxPaintDC dc(this);
/*texmutex->Lock();
SDL_UnlockTexture(sdltex);
//SDL_RenderClear(sdlrend);
SDL_RenderCopy(sdlrend, sdltex, NULL, NULL);
SDL_RenderPresent(sdlrend);
SDL_LockTexture(sdltex, NULL, &texpixels, &texstride);
texmutex->Unlock();
ProcessSDLEvents();*/
}
void MainFrame::OnIdle(wxIdleEvent& event)
{
//ProcessSDLEvents();
}
EmuThread::EmuThread(MainFrame* parent) EmuThread::EmuThread(MainFrame* parent)
: wxThread(wxTHREAD_JOINABLE) : wxThread(wxTHREAD_JOINABLE)
@ -436,8 +315,8 @@ EmuThread::~EmuThread()
wxThread::ExitCode EmuThread::Entry() wxThread::ExitCode EmuThread::Entry()
{ {
//parent->emustatuschangemutex->Lock(); emustatus = 3;
emustatus = 2; emupaused = false;
sdlwin = SDL_CreateWindow("melonDS " MELONDS_VERSION, sdlwin = SDL_CreateWindow("melonDS " MELONDS_VERSION,
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
@ -447,9 +326,12 @@ wxThread::ExitCode EmuThread::Entry()
sdlrend = SDL_CreateRenderer(sdlwin, -1, SDL_RENDERER_ACCELERATED);// | SDL_RENDERER_PRESENTVSYNC); sdlrend = SDL_CreateRenderer(sdlwin, -1, SDL_RENDERER_ACCELERATED);// | SDL_RENDERER_PRESENTVSYNC);
sdltex = SDL_CreateTexture(sdlrend, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, 256, 384); sdltex = SDL_CreateTexture(sdlrend, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, 256, 384);
joyid = -1;
axismask = 0; axismask = 0;
u32 nframes = 0;
u32 lasttick = SDL_GetTicks();
u32 fpslimitcount = 0;
for (;;) for (;;)
{ {
if (emustatus == 0) break; if (emustatus == 0) break;
@ -458,7 +340,7 @@ wxThread::ExitCode EmuThread::Entry()
if (emustatus == 1) if (emustatus == 1)
{ {
// u32 starttick = SDL_GetTicks();
NDS::RunFrame(); NDS::RunFrame();
@ -481,81 +363,51 @@ wxThread::ExitCode EmuThread::Entry()
//SDL_RenderClear(sdlrend); //SDL_RenderClear(sdlrend);
SDL_RenderCopy(sdlrend, sdltex, NULL, NULL); SDL_RenderCopy(sdlrend, sdltex, NULL, NULL);
SDL_RenderPresent(sdlrend); SDL_RenderPresent(sdlrend);
fpslimitcount++;
if (fpslimitcount >= 3) fpslimitcount = 0;
u32 frametime = (fpslimitcount == 0) ? 16 : 17;
u32 endtick = SDL_GetTicks();
u32 diff = endtick - starttick;
if (diff < frametime)
Sleep(frametime - diff);
nframes++;
if (nframes >= 30)
{
u32 tick = SDL_GetTicks();
u32 diff = tick - lasttick;
lasttick = tick;
u32 fps = (nframes * 1000) / diff;
nframes = 0;
char melontitle[100];
sprintf(melontitle, "%d FPS - melonDS " MELONDS_VERSION, fps);
SDL_SetWindowTitle(sdlwin, melontitle);
}
} }
else else
{ {
Sleep(17); nframes = 0;
lasttick = SDL_GetTicks();
fpslimitcount = 0;
emupaused = true;
Sleep(50);
if (emustatus == 2)
{
char* melontitle = "Paused - melonDS " MELONDS_VERSION;
SDL_SetWindowTitle(sdlwin, melontitle);
}
} }
} }
/*for (;;) SDL_DestroyTexture(sdltex);
{ SDL_DestroyRenderer(sdlrend);
parent->emustatuschange->Wait(); SDL_DestroyWindow(sdlwin);
if (parent->emustatus == 1)
{
u32 nframes = 0;
u32 lasttick = SDL_GetTicks();
u32 fpslimitcount = 0;
while (parent->emustatus == 1)
{
u32 starttick = SDL_GetTicks();
NDS::RunFrame();
parent->texmutex->Lock();
if (parent->texstride == 256*4)
{
memcpy(parent->texpixels, GPU::Framebuffer, 256*384*4);
}
else
{
int dsty = 0;
for (int y = 0; y < 256*384; y+=256)
{
memcpy(&((u8*)parent->texpixels)[dsty], &GPU::Framebuffer[y], 256*4);
dsty += parent->texstride;
}
}
parent->texmutex->Unlock();
parent->Refresh();
fpslimitcount++;
if (fpslimitcount >= 3) fpslimitcount = 0;
u32 frametime = (fpslimitcount == 0) ? 16 : 17;
u32 endtick = SDL_GetTicks();
u32 diff = endtick - starttick;
if (diff < frametime)
Sleep(frametime - diff);
nframes++;
if (nframes >= 30)
{
u32 tick = SDL_GetTicks();
u32 diff = tick - lasttick;
lasttick = tick;
u32 fps = (nframes * 1000) / diff;
nframes = 0;
char melontitle[100];
sprintf(melontitle, "%d FPS - melonDS " MELONDS_VERSION, fps);
parent->SetTitle(melontitle);
}
}
parent->emustopmutex->Lock();
parent->emustop->Signal();
parent->emustopmutex->Unlock();
}
if (parent->emustatus == 0)
break;
}*/
return (wxThread::ExitCode)0; return (wxThread::ExitCode)0;
} }
@ -570,6 +422,14 @@ void EmuThread::ProcessEvents()
switch (evt.type) switch (evt.type)
{ {
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
if (evt.window.event == SDL_WINDOWEVENT_CLOSE)
{
wxThread* thread = parent->emuthread;
parent->CloseFromOutside();
EmuExit();
delete thread;
return;
}
if (evt.window.event != SDL_WINDOWEVENT_EXPOSED) if (evt.window.event != SDL_WINDOWEVENT_EXPOSED)
{ {
SDL_GetWindowPosition(sdlwin, &WindowX, &WindowY); SDL_GetWindowPosition(sdlwin, &WindowX, &WindowY);
@ -604,7 +464,7 @@ void EmuThread::ProcessEvents()
case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONDOWN:
if (!running) return; if (!running) return;
if (evt.jbutton.which != joyid) return; if (evt.jbutton.which != parent->joyid) return;
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
if (evt.jbutton.button == Config::JoyMapping[i]) NDS::PressKey(i); if (evt.jbutton.button == Config::JoyMapping[i]) NDS::PressKey(i);
if (evt.jbutton.button == Config::JoyMapping[10]) NDS::PressKey(16); if (evt.jbutton.button == Config::JoyMapping[10]) NDS::PressKey(16);
@ -613,7 +473,7 @@ void EmuThread::ProcessEvents()
case SDL_JOYBUTTONUP: case SDL_JOYBUTTONUP:
if (!running) return; if (!running) return;
if (evt.jbutton.which != joyid) return; if (evt.jbutton.which != parent->joyid) return;
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
if (evt.jbutton.button == Config::JoyMapping[i]) NDS::ReleaseKey(i); if (evt.jbutton.button == Config::JoyMapping[i]) NDS::ReleaseKey(i);
if (evt.jbutton.button == Config::JoyMapping[10]) NDS::ReleaseKey(16); if (evt.jbutton.button == Config::JoyMapping[10]) NDS::ReleaseKey(16);
@ -622,7 +482,7 @@ void EmuThread::ProcessEvents()
case SDL_JOYHATMOTION: case SDL_JOYHATMOTION:
if (!running) return; if (!running) return;
if (evt.jhat.which != joyid) return; if (evt.jhat.which != parent->joyid) return;
if (evt.jhat.hat != 0) return; if (evt.jhat.hat != 0) return;
for (int i = 0; i < 12; i++) for (int i = 0; i < 12; i++)
{ {
@ -640,7 +500,7 @@ void EmuThread::ProcessEvents()
case SDL_JOYAXISMOTION: case SDL_JOYAXISMOTION:
if (!running) return; if (!running) return;
if (evt.jaxis.which != joyid) return; if (evt.jaxis.which != parent->joyid) return;
if (evt.jaxis.axis == 0) if (evt.jaxis.axis == 0)
{ {
if (evt.jaxis.value >= 16384) { NDS::PressKey(4); axismask |= 0x1; } if (evt.jaxis.value >= 16384) { NDS::PressKey(4); axismask |= 0x1; }
@ -659,7 +519,7 @@ void EmuThread::ProcessEvents()
} }
} }
if (Touching) if (Touching && running)
{ {
int mx, my; int mx, my;
u32 btn = SDL_GetGlobalMouseState(&mx, &my); u32 btn = SDL_GetGlobalMouseState(&mx, &my);

View File

@ -51,24 +51,14 @@ class MainFrame : public wxFrame
public: public:
MainFrame(); MainFrame();
SDL_Window* sdlwin;
SDL_Renderer* sdlrend;
SDL_Texture* sdltex;
SDL_Joystick* joy; SDL_Joystick* joy;
SDL_JoystickID joyid; SDL_JoystickID joyid;
u8 axismask;
wxMutex* texmutex;
void* texpixels;
int texstride;
int emustatus;
EmuThread* emuthread; EmuThread* emuthread;
wxMutex* emustatuschangemutex;
wxCondition* emustatuschange; wxString rompath;
wxMutex* emustopmutex;
wxCondition* emustop; void CloseFromOutside();
private: private:
wxDECLARE_EVENT_TABLE(); wxDECLARE_EVENT_TABLE();
@ -77,12 +67,13 @@ private:
void OnCloseFromMenu(wxCommandEvent& event); void OnCloseFromMenu(wxCommandEvent& event);
void OnOpenROM(wxCommandEvent& event); void OnOpenROM(wxCommandEvent& event);
void OnRun(wxCommandEvent& event);
void OnPause(wxCommandEvent& event);
void OnReset(wxCommandEvent& event);
void OnInputConfig(wxCommandEvent& event); void OnInputConfig(wxCommandEvent& event);
void ProcessSDLEvents(); void ProcessSDLEvents();
void OnPaint(wxPaintEvent& event);
void OnIdle(wxIdleEvent& event);
}; };
class EmuThread : public wxThread class EmuThread : public wxThread
@ -91,10 +82,13 @@ public:
EmuThread(MainFrame* parent); EmuThread(MainFrame* parent);
~EmuThread(); ~EmuThread();
void EmuRun() { emustatus = 1; } void EmuRun() { emustatus = 1; emupaused = false; SDL_RaiseWindow(sdlwin); }
void EmuPause() { emustatus = 2; } void EmuPause() { emustatus = 2; while (!emupaused); }
void EmuExit() { emustatus = 0; } void EmuExit() { emustatus = 0; }
bool EmuIsRunning() { return (emustatus == 1) || (emustatus == 2); }
bool EmuIsPaused() { return (emustatus == 2) && emupaused; }
protected: protected:
virtual ExitCode Entry(); virtual ExitCode Entry();
void ProcessEvents(); void ProcessEvents();
@ -108,10 +102,10 @@ protected:
void* texpixels; void* texpixels;
int texstride; int texstride;
int joyid;
u32 axismask; u32 axismask;
int emustatus; int emustatus;
volatile bool emupaused;
}; };
#endif // WX_MAIN_H #endif // WX_MAIN_H