diff --git a/src/debugger.h b/src/debugger.h index 4e2e61e..aa39308 100644 --- a/src/debugger.h +++ b/src/debugger.h @@ -47,6 +47,7 @@ void dbg_main(int bp_no); void dbg_onsleep(void); uint8_t dbg_handle_breakpoint(int page, int addr); boolean dbg_console_vprintf(int lv, const char *format, va_list ap); +void dbg_post_command(void *data); #else // ENABLE_DEBUGGER @@ -57,6 +58,7 @@ boolean dbg_console_vprintf(int lv, const char *format, va_list ap); #define dbg_onsleep() #define dbg_handle_breakpoint(page, addr) BREAKPOINT #define dbg_console_vprintf(lv, format, ap) false +#define dbg_post_command(data) #endif // ENABLE_DEBUGGER diff --git a/src/debugger_dap.c b/src/debugger_dap.c index ebc917e..5683bff 100644 --- a/src/debugger_dap.c +++ b/src/debugger_dap.c @@ -567,13 +567,13 @@ static int read_command_thread(void *data) { } char *buf = malloc(content_length); fread(buf, content_length, 1, stdin); - msgq_enqueue(queue, buf); + sdl_post_debugger_command(buf); content_length = -1; } else { fprintf(stderr, "Unknown Debug Adapter Protocol header: %s", header); } } - msgq_enqueue(queue, NULL); // EOF + sdl_post_debugger_command(NULL); // end of messages return 0; } @@ -588,11 +588,16 @@ static void dbg_dap_init(const char *path) { SDL_CreateThread(read_command_thread, "Debugger", NULL); - while (!initialized) { - char *msg = msgq_dequeue(queue); - if (!msg) - break; - handle_message(msg); + while (!initialized && !nact->is_quit) { + SDL_Event e; + SDL_WaitEvent(&e); + sdl_handle_event(&e); + while (!msgq_isempty(queue)) { + char *msg = msgq_dequeue(queue); + if (!msg) + return; + handle_message(msg); + } } } @@ -605,11 +610,16 @@ static void dbg_dap_repl(int bp_no) { dbg_state = DBG_RUNNING; boolean continue_repl = true; - while (continue_repl) { - char *msg = msgq_dequeue(queue); - if (!msg) - break; - continue_repl = handle_message(msg); + while (continue_repl && !nact->is_quit) { + SDL_Event e; + SDL_WaitEvent(&e); + sdl_handle_event(&e); + while (!msgq_isempty(queue)) { + char *msg = msgq_dequeue(queue); + if (!msg) + return; + continue_repl = handle_message(msg); + } } } @@ -624,6 +634,10 @@ static void dbg_dap_onsleep(void) { dbg_main(0); } +void dbg_post_command(void *data) { + msgq_enqueue(queue, data); +} + DebuggerImpl dbg_dap_impl = { .init = dbg_dap_init, .quit = dbg_dap_quit, diff --git a/src/sdl_core.h b/src/sdl_core.h index 98e29e5..d6f93bd 100644 --- a/src/sdl_core.h +++ b/src/sdl_core.h @@ -25,6 +25,7 @@ #include "config.h" #include +#include #include #include "portab.h" #include "ags.h" @@ -110,5 +111,7 @@ extern uint32_t sdl_getTicks(void); extern void sdl_sleep(int msec); extern void sdl_wait_vsync(); extern boolean sdl_inputString(struct inputstring_param *); +extern void sdl_post_debugger_command(void *data); +extern void sdl_handle_event(SDL_Event *e); #endif /* !__SDL_CORE__ */ diff --git a/src/sdl_event.c b/src/sdl_event.c index eae1075..279020e 100644 --- a/src/sdl_event.c +++ b/src/sdl_event.c @@ -33,6 +33,7 @@ #include "portab.h" #include "system.h" +#include "debugger.h" #include "nact.h" #include "sdl_core.h" #include "sdl_private.h" @@ -47,6 +48,7 @@ static uint32_t custom_event_type = (uint32_t)-1; enum CustomEventCode { SIMULATE_RIGHT_BUTTON, + DEBUGGER_COMMAND, }; /* pointer の状態 */ @@ -233,190 +235,195 @@ static void rance4v2_hack(void) { nact->wait_vsync = FALSE; } +void sdl_handle_event(SDL_Event *e) { + if (sdl_custom_event_handler && sdl_custom_event_handler(e)) + return; + + switch (e->type) { + case SDL_QUIT: + menu_quitmenu_open(); + break; + + case SDL_WINDOWEVENT: + switch (e->window.event) { + case SDL_WINDOWEVENT_EXPOSED: + sdl_dirty = TRUE; + break; + } + break; +#ifdef _WIN32 + case SDL_SYSWMEVENT: + win_menu_onsyswmevent(e->syswm.msg); + break; +#endif + case SDL_APP_DIDENTERFOREGROUND: + sdl_dirty = TRUE; + break; + case SDL_KEYDOWN: + keyEventProsess(&e->key, TRUE); + break; + case SDL_KEYUP: + keyEventProsess(&e->key, FALSE); + switch (e->key.keysym.sym) { + case SDLK_F1: + msgskip_activate(!msgskip_isActivated()); + break; + case SDLK_F4: + sdl_setFullscreen(!sdl_fs_on); + break; + } + break; + case SDL_MOUSEMOTION: + mousex = e->motion.x; + mousey = e->motion.y; + send_agsevent(AGSEVENT_MOUSE_MOTION, 0); + break; + + case SDL_MOUSEWHEEL: + { + int y = e->wheel.y * (e->wheel.direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1); + if (y > 0) + mouse_wheel_up += y; + else if (y < 0) + mouse_wheel_down -= y; + send_agsevent(AGSEVENT_MOUSE_WHEEL, y); + break; + } + + case SDL_MOUSEBUTTONDOWN: + mouseb |= (1 << e->button.button); + RawKeyInfo[mouse_to_rawkey(e->button.button)] = TRUE; + send_agsevent(AGSEVENT_BUTTON_PRESS, mouse_to_agsevent(e->button.button)); + break; + + case SDL_MOUSEBUTTONUP: + mouseb &= (0xffffffff ^ (1 << e->button.button)); + RawKeyInfo[mouse_to_rawkey(e->button.button)] = FALSE; + send_agsevent(AGSEVENT_BUTTON_RELEASE, mouse_to_agsevent(e->button.button)); + if (e->button.button == 2) { + menu_open(); + } + break; + + case SDL_FINGERDOWN: + if (SDL_GetNumTouchFingers(e->tfinger.touchId) >= 2) { + mouseb &= ~(1 << SDL_BUTTON_LEFT); + mouseb |= 1 << SDL_BUTTON_RIGHT; + RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_LEFT)] = FALSE; + RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_RIGHT)] = TRUE; + send_agsevent(AGSEVENT_BUTTON_PRESS, AGSEVENT_BUTTON_RIGHT); + } else { + // SDL_RendererEventWatch clamps touch locations outside of the + // viewport to 0.0-1.0. Treat such events as right-clicks. + int button; + if (e->tfinger.x == 0.0f || e->tfinger.x == 1.0f || e->tfinger.y == 0.0f || e->tfinger.y == 1.0f) { + button = SDL_BUTTON_RIGHT; + } else { + button = SDL_BUTTON_LEFT; + mousex = e->tfinger.x * view_w; + mousey = e->tfinger.y * view_h; + send_agsevent(AGSEVENT_MOUSE_MOTION, 0); + } + mouseb |= 1 << button; + RawKeyInfo[mouse_to_rawkey(button)] = TRUE; + send_agsevent(AGSEVENT_BUTTON_PRESS, mouse_to_agsevent(button)); + } + break; + + case SDL_FINGERUP: + if (SDL_GetNumTouchFingers(e->tfinger.touchId) == 0) { + int ags_button = (mouseb & 1 << SDL_BUTTON_LEFT) ? AGSEVENT_BUTTON_LEFT : AGSEVENT_BUTTON_RIGHT; + mouseb &= ~(1 << SDL_BUTTON_LEFT | 1 << SDL_BUTTON_RIGHT); + RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_LEFT)] = FALSE; + RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_RIGHT)] = FALSE; + mousex = e->tfinger.x * view_w; + mousey = e->tfinger.y * view_h; + send_agsevent(AGSEVENT_BUTTON_RELEASE, ags_button); + } + break; + + case SDL_FINGERMOTION: + mousex = e->tfinger.x * view_w; + mousey = e->tfinger.y * view_h; + send_agsevent(AGSEVENT_MOUSE_MOTION, 0); + break; + + case SDL_JOYDEVICEADDED: + sdl_joy_open(e->jdevice.which); + break; + + case SDL_JOYAXISMOTION: + if (abs(e->jaxis.value) < 0x4000) { + joyinfo &= e->jaxis.axis == 0 ? ~0xc : ~3; + } else { + int i = (e->jaxis.axis == 0 ? 2 : 0) + + (e->jaxis.value > 0 ? 1 : 0); + joyinfo |= 1 << i; + } + break; + + case SDL_JOYBALLMOTION: + break; + + case SDL_JOYHATMOTION: + joyinfo &= ~(SYS35KEY_UP | SYS35KEY_DOWN | SYS35KEY_LEFT | SYS35KEY_RIGHT); + switch (e->jhat.value) { + case SDL_HAT_UP: joyinfo |= SYS35KEY_UP; break; + case SDL_HAT_DOWN: joyinfo |= SYS35KEY_DOWN; break; + case SDL_HAT_LEFT: joyinfo |= SYS35KEY_LEFT; break; + case SDL_HAT_RIGHT: joyinfo |= SYS35KEY_RIGHT; break; + case SDL_HAT_LEFTUP: joyinfo |= SYS35KEY_LEFT | SYS35KEY_UP; break; + case SDL_HAT_RIGHTUP: joyinfo |= SYS35KEY_RIGHT | SYS35KEY_UP; break; + case SDL_HAT_LEFTDOWN: joyinfo |= SYS35KEY_LEFT | SYS35KEY_DOWN; break; + case SDL_HAT_RIGHTDOWN: joyinfo |= SYS35KEY_RIGHT | SYS35KEY_DOWN; break; + } + break; + + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + if (e->jbutton.button < 4) { + int i = 1 << (e->jbutton.button+4); + if (e->jbutton.state == SDL_PRESSED) + joyinfo |= i; + else + joyinfo &= ~i; + } else { + if (e->jbutton.state == SDL_RELEASED) { + } + } + break; + default: + if (e->type == custom_event_type) { + switch (e->user.code) { + case SIMULATE_RIGHT_BUTTON: + if ((intptr_t)e->user.data1) { + mouseb |= 1 << SDL_BUTTON_RIGHT; + RawKeyInfo[KEY_MOUSE_RIGHT] = TRUE; + send_agsevent(AGSEVENT_BUTTON_PRESS, AGSEVENT_BUTTON_RIGHT); + } else { + mouseb &= ~(1 << SDL_BUTTON_RIGHT); + RawKeyInfo[KEY_MOUSE_RIGHT] = FALSE; + send_agsevent(AGSEVENT_BUTTON_RELEASE, AGSEVENT_BUTTON_RIGHT); + } + break; + case DEBUGGER_COMMAND: + dbg_post_command(e->user.data1); + break; + } + } + break; + } +} + /* Event処理 */ static void sdl_getEvent(void) { static int cmd_count_of_prev_input = -1; - SDL_Event e; - boolean m2b = FALSE, msg_skip = FALSE; boolean had_input = false; + SDL_Event e; while (SDL_PollEvent(&e)) { had_input = true; - - if (sdl_custom_event_handler && sdl_custom_event_handler(&e)) - continue; - - switch (e.type) { - case SDL_QUIT: - menu_quitmenu_open(); - break; - - case SDL_WINDOWEVENT: - switch (e.window.event) { - case SDL_WINDOWEVENT_EXPOSED: - sdl_dirty = TRUE; - break; - } - break; -#ifdef _WIN32 - case SDL_SYSWMEVENT: - win_menu_onsyswmevent(e.syswm.msg); - break; -#endif - case SDL_APP_DIDENTERFOREGROUND: - sdl_dirty = TRUE; - break; - case SDL_KEYDOWN: - keyEventProsess(&e.key, TRUE); - break; - case SDL_KEYUP: - keyEventProsess(&e.key, FALSE); - switch (e.key.keysym.sym) { - case SDLK_F1: - msg_skip = TRUE; - break; - case SDLK_F4: - sdl_setFullscreen(!sdl_fs_on); - break; - } - break; - case SDL_MOUSEMOTION: - mousex = e.motion.x; - mousey = e.motion.y; - send_agsevent(AGSEVENT_MOUSE_MOTION, 0); - break; - - case SDL_MOUSEWHEEL: - { - int y = e.wheel.y * (e.wheel.direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1); - if (y > 0) - mouse_wheel_up += y; - else if (y < 0) - mouse_wheel_down -= y; - send_agsevent(AGSEVENT_MOUSE_WHEEL, y); - break; - } - - case SDL_MOUSEBUTTONDOWN: - mouseb |= (1 << e.button.button); - RawKeyInfo[mouse_to_rawkey(e.button.button)] = TRUE; - send_agsevent(AGSEVENT_BUTTON_PRESS, mouse_to_agsevent(e.button.button)); - break; - - case SDL_MOUSEBUTTONUP: - mouseb &= (0xffffffff ^ (1 << e.button.button)); - RawKeyInfo[mouse_to_rawkey(e.button.button)] = FALSE; - send_agsevent(AGSEVENT_BUTTON_RELEASE, mouse_to_agsevent(e.button.button)); - if (e.button.button == 2) { - m2b = TRUE; - } - break; - - case SDL_FINGERDOWN: - if (SDL_GetNumTouchFingers(e.tfinger.touchId) >= 2) { - mouseb &= ~(1 << SDL_BUTTON_LEFT); - mouseb |= 1 << SDL_BUTTON_RIGHT; - RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_LEFT)] = FALSE; - RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_RIGHT)] = TRUE; - send_agsevent(AGSEVENT_BUTTON_PRESS, AGSEVENT_BUTTON_RIGHT); - } else { - // SDL_RendererEventWatch clamps touch locations outside of the - // viewport to 0.0-1.0. Treat such events as right-clicks. - int button; - if (e.tfinger.x == 0.0f || e.tfinger.x == 1.0f || e.tfinger.y == 0.0f || e.tfinger.y == 1.0f) { - button = SDL_BUTTON_RIGHT; - } else { - button = SDL_BUTTON_LEFT; - mousex = e.tfinger.x * view_w; - mousey = e.tfinger.y * view_h; - send_agsevent(AGSEVENT_MOUSE_MOTION, 0); - } - mouseb |= 1 << button; - RawKeyInfo[mouse_to_rawkey(button)] = TRUE; - send_agsevent(AGSEVENT_BUTTON_PRESS, mouse_to_agsevent(button)); - } - break; - - case SDL_FINGERUP: - if (SDL_GetNumTouchFingers(e.tfinger.touchId) == 0) { - int ags_button = (mouseb & 1 << SDL_BUTTON_LEFT) ? AGSEVENT_BUTTON_LEFT : AGSEVENT_BUTTON_RIGHT; - mouseb &= ~(1 << SDL_BUTTON_LEFT | 1 << SDL_BUTTON_RIGHT); - RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_LEFT)] = FALSE; - RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_RIGHT)] = FALSE; - mousex = e.tfinger.x * view_w; - mousey = e.tfinger.y * view_h; - send_agsevent(AGSEVENT_BUTTON_RELEASE, ags_button); - } - break; - - case SDL_FINGERMOTION: - mousex = e.tfinger.x * view_w; - mousey = e.tfinger.y * view_h; - send_agsevent(AGSEVENT_MOUSE_MOTION, 0); - break; - - case SDL_JOYDEVICEADDED: - sdl_joy_open(e.jdevice.which); - break; - - case SDL_JOYAXISMOTION: - if (abs(e.jaxis.value) < 0x4000) { - joyinfo &= e.jaxis.axis == 0 ? ~0xc : ~3; - } else { - int i = (e.jaxis.axis == 0 ? 2 : 0) + - (e.jaxis.value > 0 ? 1 : 0); - joyinfo |= 1 << i; - } - break; - - case SDL_JOYBALLMOTION: - break; - - case SDL_JOYHATMOTION: - joyinfo &= ~(SYS35KEY_UP | SYS35KEY_DOWN | SYS35KEY_LEFT | SYS35KEY_RIGHT); - switch (e.jhat.value) { - case SDL_HAT_UP: joyinfo |= SYS35KEY_UP; break; - case SDL_HAT_DOWN: joyinfo |= SYS35KEY_DOWN; break; - case SDL_HAT_LEFT: joyinfo |= SYS35KEY_LEFT; break; - case SDL_HAT_RIGHT: joyinfo |= SYS35KEY_RIGHT; break; - case SDL_HAT_LEFTUP: joyinfo |= SYS35KEY_LEFT | SYS35KEY_UP; break; - case SDL_HAT_RIGHTUP: joyinfo |= SYS35KEY_RIGHT | SYS35KEY_UP; break; - case SDL_HAT_LEFTDOWN: joyinfo |= SYS35KEY_LEFT | SYS35KEY_DOWN; break; - case SDL_HAT_RIGHTDOWN: joyinfo |= SYS35KEY_RIGHT | SYS35KEY_DOWN; break; - } - break; - - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - if (e.jbutton.button < 4) { - int i = 1 << (e.jbutton.button+4); - if (e.jbutton.state == SDL_PRESSED) - joyinfo |= i; - else - joyinfo &= ~i; - } else { - if (e.jbutton.state == SDL_RELEASED) { - } - } - break; - default: - if (e.type == custom_event_type) { - switch (e.user.code) { - case SIMULATE_RIGHT_BUTTON: - if ((intptr_t)e.user.data1) { - mouseb |= 1 << SDL_BUTTON_RIGHT; - RawKeyInfo[KEY_MOUSE_RIGHT] = TRUE; - send_agsevent(AGSEVENT_BUTTON_PRESS, AGSEVENT_BUTTON_RIGHT); - } else { - mouseb &= ~(1 << SDL_BUTTON_RIGHT); - RawKeyInfo[KEY_MOUSE_RIGHT] = FALSE; - send_agsevent(AGSEVENT_BUTTON_RELEASE, AGSEVENT_BUTTON_RIGHT); - } - break; - } - } - break; - } + sdl_handle_event(&e); } if (had_input) { cmd_count_of_prev_input = nact->cmd_count; @@ -425,12 +432,6 @@ static void sdl_getEvent(void) { if (nact->game == GAME_RANCE4_V2) rance4v2_hack(); } - - if (m2b) { - menu_open(); - } - - if (msg_skip) msgskip_activate(!msgskip_isActivated()); } /* キー情報の取得 */ @@ -488,6 +489,17 @@ int sdl_getJoyInfo(void) { return joyinfo; } +void sdl_post_debugger_command(void *data) { + SDL_Event event = { + .user = { + .type = custom_event_type, + .code = DEBUGGER_COMMAND, + .data1 = data + } + }; + SDL_PushEvent(&event); +} + #ifdef __EMSCRIPTEN__ EMSCRIPTEN_KEEPALIVE void simulate_right_button(int pressed) {