Merge pull request #1236 from reicast/clean-exit-light

Exit cleanly in desktop platforms
This commit is contained in:
Abandoned Cart 2018-08-02 12:20:03 -04:00 committed by GitHub
commit 9beb87ef64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 130 additions and 28 deletions

View File

@ -76,6 +76,7 @@ u32 VertexCount=0;
u32 FrameCount=1;
Renderer* renderer;
bool renderer_enabled = true; // Signals the renderer thread to exit
#if !defined(TARGET_NO_THREADS)
cResetEvent rs(false,true);
@ -217,6 +218,9 @@ bool rend_single_frame()
#if !defined(TARGET_NO_THREADS)
rs.Wait();
#endif
if (!renderer_enabled)
return false;
_pvrrc = DequeueRender();
}
while (!_pvrrc);
@ -269,11 +273,13 @@ void* rend_thread(void* p)
//we don't know if this is true, so let's not speculate here
//renderer->Resize(640, 480);
for(;;)
while (renderer_enabled)
{
if (rend_single_frame())
renderer->Present();
}
return NULL;
}
#if !defined(TARGET_NO_THREADS)
@ -490,11 +496,20 @@ bool rend_init()
void rend_term()
{
renderer_enabled = false;
#if !defined(TARGET_NO_THREADS)
rs.Set();
#endif
if (fCheckFrames)
fclose(fCheckFrames);
if (fLogFrames)
fclose(fLogFrames);
#if !defined(TARGET_NO_THREADS)
rthd.WaitToEnd();
#endif
}
void rend_vblank()

View File

@ -16,6 +16,8 @@
libevdev_func1_t libevdev_event_code_from_name;
libevdev_func2_t libevdev_event_code_get_name;
void dc_stop(void);
void load_libevdev()
{
if (libevdev_tried)
@ -353,7 +355,7 @@
} else if (ie.code == controller->mapping->Btn_Start) {
SET_FLAG(kcode[port], DC_BTN_START, ie.value);
} else if (ie.code == controller->mapping->Btn_Escape) {
die("death by escape key");
dc_stop();
} else if (ie.code == controller->mapping->Btn_DPad_Left) {
SET_FLAG(kcode[port], DC_DPAD_LEFT, ie.value);
} else if (ie.code == controller->mapping->Btn_DPad_Right) {

View File

@ -222,6 +222,7 @@ void os_DoEvents()
{
#if defined(SUPPORT_X11)
input_x11_handle();
event_x11_handle();
#endif
}
@ -252,6 +253,7 @@ void os_CreateWindow()
void common_linux_setup();
int dc_init(int argc,wchar* argv[]);
void dc_run();
void dc_term();
#ifdef TARGET_PANDORA
void gl_term();
@ -475,11 +477,26 @@ int main(int argc, wchar* argv[])
emscripten_set_main_loop(&dc_run, 100, false);
#endif
#ifdef TARGET_PANDORA
clean_exit(0);
#endif
dc_term();
#if defined(USE_EVDEV)
for (int port = 0; port < 4 ; port++)
{
if(evdev_controllers[port].fd >= 0)
{
close(evdev_controllers[port].fd);
}
}
#endif
#if defined(SUPPORT_X11)
x11_window_destroy();
#endif
return 0;
}
#endif

View File

@ -35,11 +35,14 @@ int x11_width;
int x11_height;
int ndcid = 0;
void* x11_glc;
void* x11_glc = NULL;
bool x11_fullscreen = false;
Atom wmDeleteMessage;
void* x11_vis;
void dc_stop(void);
enum
{
_NET_WM_STATE_REMOVE =0,
@ -64,6 +67,20 @@ void x11_window_set_fullscreen(bool fullscreen)
XSendEvent((Display*)x11_disp, DefaultRootWindow((Display*)x11_disp), False, SubstructureNotifyMask, &xev);
}
void event_x11_handle()
{
XEvent event;
while(XPending((Display *)x11_disp))
{
XNextEvent((Display *)x11_disp, &event);
if (event.type == ClientMessage &&
event.xclient.data.l[0] == wmDeleteMessage)
dc_stop();
}
}
void input_x11_handle()
{
if (x11_win && x11_keyboard_input)
@ -79,7 +96,7 @@ void input_x11_handle()
case KeyRelease:
if (e.type == KeyRelease && e.xkey.keycode == KEY_ESC)
{
die("X11: death by escape key");
dc_stop();
}
#if FEAT_HAS_NIXPROF
else if (e.type == KeyRelease && e.xkey.keycode == KEY_F10)
@ -244,7 +261,7 @@ void x11_window_create()
// Get a visual
XVisualInfo *vi = glXGetVisualFromFBConfig(x11Display, bestFbc);
printf("Chosen visual ID = 0x%x\n", vi->visualid);
printf("Chosen visual ID = 0x%lx\n", vi->visualid);
depth = vi->depth;
@ -283,6 +300,10 @@ void x11_window_create()
x11Window = XCreateWindow(x11Display, RootWindow(x11Display, x11Screen), (ndcid%3)*640, (ndcid/3)*480, x11_width, x11_height,
0, depth, InputOutput, x11Visual->visual, ui32Mask, &sWA);
// Capture the close window event
wmDeleteMessage = XInternAtom(x11Display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(x11Display, x11Window, &wmDeleteMessage, 1);
if(x11_fullscreen)
{
@ -354,12 +375,18 @@ void x11_window_destroy()
if (x11_win)
{
XDestroyWindow((Display*)x11_disp, (Window)x11_win);
x11_win = 0;
x11_win = NULL;
}
if (x11_disp)
{
if (x11_glc)
{
glXMakeCurrent((Display*)x11_disp, None, NULL);
glXDestroyContext((Display*)x11_disp, (GLXContext)x11_glc);
x11_glc = NULL;
}
XCloseDisplay((Display*)x11_disp);
x11_disp = 0;
x11_disp = NULL;
}
}
#endif

View File

@ -3,8 +3,10 @@
extern void* x11_glc;
extern void input_x11_init();
extern void input_x11_handle();
extern void event_x11_handle();
extern void x11_window_create();
extern void x11_window_set_text(const char* text);
extern void x11_window_destroy();
// numbers
const int KEY_1 = 10;

View File

@ -225,6 +225,13 @@ void dc_term()
SaveSettings();
#endif
SaveRomFiles(get_writable_data_path("/data/"));
TermAudio();
}
void dc_stop()
{
sh4_cpu.Stop();
}
void LoadSettings()

View File

@ -173,6 +173,10 @@ do_iter:
HIDDEN(no_update)
CSYM(no_update): @ next_pc _MUST_ be on r4 *R4 NOT R0 anymore*
ldr r0,[r8,#-156] @load CpuRunning
cmp r0,#0
beq CSYM(cleanup)
#if DC_PLATFORM == DC_PLATFORM_NAOMI
sub r2,r8,#0x4100000
ubfx r1,r4,#1,#24
@ -185,6 +189,8 @@ CSYM(no_update): @ next_pc _MUST_ be on r4 *R4 NOT R0 anymore*
@bic r1,r4,#0xFF000000
@ldr pc,[r2,r1,lsl #1]
HIDDEN(cleanup)
CSYM(cleanup):
pop {r4-r12,lr}
bx lr

View File

@ -53,7 +53,7 @@ void ngen_mainloop(void* v_cntx)
cycle_counter = 0;
#if !defined(TARGET_BOUNDED_EXECUTION)
for (;;) {
while (sh4_int_bCpuRun) {
#else
for (int i=0; i<10000; i++) {
#endif

View File

@ -44,7 +44,7 @@ void ngen_mainloop(void* v_cntx)
cycle_counter = 0;
for (;;) {
while (sh4_int_bCpuRun) {
cycle_counter = SH4_TIMESLICE;
do {
DynarecCodeEntryPtr rcb = bm_GetCode(ctx->cntx.pc);
@ -511,4 +511,4 @@ void ngen_CC_Finish(shil_opcode* op)
{
}
#endif
#endif

View File

@ -120,8 +120,10 @@ do_iter:
pop ecx
call rdv_DoInterrupts
mov ecx,eax
# cmp byte ptr [sh4_int_bCpuRun],0
# jz cleanup
mov edx,[p_sh4rcb];
add edx,[cpurun_offset];
cmp dword ptr [edx],0;
jz cleanup;
jmp no_update
cleanup:

View File

@ -59,6 +59,8 @@ naked void ngen_FailedToFindBlock_()
}
}
const u32 cpurun_offset=offsetof(Sh4RCB,cntx.CpuRunning);
void (*ngen_FailedToFindBlock)()=&ngen_FailedToFindBlock_;
naked void ngen_mainloop(void* cntx)
{
@ -93,8 +95,10 @@ do_iter:
pop ecx;
call rdv_DoInterrupts;
mov ecx,eax;
// cmp byte ptr [sh4_int_bCpuRun],0;
// jz cleanup;
mov edx,[p_sh4rcb];
add edx,[cpurun_offset];
cmp dword ptr [edx],0;
jz cleanup;
jmp no_update;
cleanup:
@ -128,6 +132,7 @@ naked void DYNACALL ngen_blockcheckfail2(u32 addr)
}
#else
u32 gas_offs=offsetof(Sh4RCB,cntx.jdyn);
u32 cpurun_offset=offsetof(Sh4RCB,cntx.CpuRunning);
void (*ngen_FailedToFindBlock)()=&ngen_FailedToFindBlock_;
#endif
#endif
#endif

View File

@ -21,7 +21,7 @@ static SDL_GLContext glcontext;
static SDL_Joystick* JoySDL = 0;
extern bool FrameSkipping;
extern void dc_term();
extern void dc_stop();
extern bool KillTex;
#ifdef TARGET_PANDORA
@ -374,10 +374,7 @@ void input_sdl_handle(u32 port)
if (keys[12]){ kcode[port] &= ~DC_BTN_START; }
if (keys[9])
{
dc_term();
// is there a proper way to exit? dc_term() doesn't end the dc_run() loop it seems
die("death by escape key");
dc_stop();
}
if (keys[10])
{

View File

@ -102,7 +102,7 @@ PCHAR*
return argv;
}
void dc_stop(void);
bool VramLockedWrite(u8* address);
bool ngen_Rewrite(unat& addr,unat retadr,unat acc);
@ -247,6 +247,8 @@ void UpdateInputState(u32 port)
if (GetAsyncKeyState(VK_F10))
DiscSwap();
if (GetAsyncKeyState(VK_ESCAPE))
dc_stop();
}
void UpdateController(u32 port)
@ -734,7 +736,7 @@ void os_DoEvents()
// If the message is WM_QUIT, exit the while loop
if (msg.message == WM_QUIT)
{
sh4_cpu.Stop();
dc_stop();
}
// Translate the message and dispatch it to WindowProc()

View File

@ -15,15 +15,15 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
emu_main();
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
emu_dc_stop()
}
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
}

View File

@ -8,7 +8,7 @@
import Cocoa
class EmuGLView: NSOpenGLView {
class EmuGLView: NSOpenGLView , NSWindowDelegate {
override var acceptsFirstResponder: Bool {
return true;
@ -71,4 +71,12 @@ class EmuGLView: NSOpenGLView {
emu_key_input(e.characters!, 0);
}
override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
self.window!.delegate = self
}
func windowWillClose(_ notification: Notification) {
emu_dc_stop()
}
}

View File

@ -10,6 +10,7 @@
#define emulator_osx_osx_main_Bridging_Header_h
void emu_main();
void emu_dc_stop();
int emu_single_frame(int w, int h);
void emu_gles_init();
void emu_key_input(const char* key, int state);

View File

@ -90,6 +90,8 @@ void gl_swap() {
int dc_init(int argc,wchar* argv[]);
void dc_run();
void dc_term();
void dc_stop();
bool has_init = false;
void* emuthread(void*) {
@ -115,9 +117,18 @@ void* emuthread(void*) {
dc_run();
has_init = false;
dc_term();
return 0;
}
extern "C" void emu_dc_stop()
{
dc_stop();
}
pthread_t emu_thread;
extern "C" void emu_main() {
pthread_create(&emu_thread, 0, &emuthread, 0);