diff --git a/CMakeLists.txt b/CMakeLists.txt index 13efa613..7a12b36d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -439,11 +439,11 @@ if(BACKEND_PLATFORM MATCHES "GLFW3") if (PKG_CONFIG_STATIC_LIBS) message(STATUS "Using system GLFW3 (pkg-config, static)") target_compile_options(CSE2 PRIVATE ${glfw3_STATIC_CFLAGS}) - target_link_libraries(CSE2 PRIVATE ${glfw3_STATIC_LINK_LIBRARIES}) + target_link_libraries(CSE2 PRIVATE ${glfw3_STATIC_LDFLAGS}) else() message(STATUS "Using system GLFW3 (pkg-config, dynamic)") target_compile_options(CSE2 PRIVATE ${glfw3_CFLAGS}) - target_link_libraries(CSE2 PRIVATE ${glfw3_LINK_LIBRARIES}) + target_link_libraries(CSE2 PRIVATE ${glfw3_LDFLAGS}) endif() elseif(TARGET glfw) # CMake @@ -475,11 +475,11 @@ if(BACKEND_PLATFORM MATCHES "SDL2" OR BACKEND_AUDIO MATCHES "SDL2") if (PKG_CONFIG_STATIC_LIBS) message(STATUS "Using system SDL2 (pkg-config, static)") target_compile_options(CSE2 PRIVATE ${sdl2_STATIC_CFLAGS}) - target_link_libraries(CSE2 PRIVATE ${sdl2_STATIC_LINK_LIBRARIES}) + target_link_libraries(CSE2 PRIVATE ${sdl2_STATIC_LDFLAGS}) else() message(STATUS "Using system SDL2 (pkg-config, dynamic)") target_compile_options(CSE2 PRIVATE ${sdl2_CFLAGS}) - target_link_libraries(CSE2 PRIVATE ${sdl2_LINK_LIBRARIES}) + target_link_libraries(CSE2 PRIVATE ${sdl2_LDFLAGS}) endif() elseif(TARGET SDL2::SDL2) # CMake-generated config (Arch, vcpkg, Raspbian) @@ -519,11 +519,11 @@ if(TARGET PkgConfig::freetype2) if (PKG_CONFIG_STATIC_LIBS) message(STATUS "Using system FreeType (pkg-config, static)") target_compile_options(CSE2 PRIVATE ${freetype2_STATIC_CFLAGS}) - target_link_libraries(CSE2 PRIVATE ${freetype2_STATIC_LINK_LIBRARIES}) + target_link_libraries(CSE2 PRIVATE ${freetype2_STATIC_LDFLAGS}) else() message(STATUS "Using system FreeType (pkg-config, dynamic)") target_compile_options(CSE2 PRIVATE ${freetype2_CFLAGS}) - target_link_libraries(CSE2 PRIVATE ${freetype2_LINK_LIBRARIES}) + target_link_libraries(CSE2 PRIVATE ${freetype2_LDFLAGS}) endif() elseif(FREETYPE_FOUND) message(STATUS "Using system FreeType (CMake)") diff --git a/DoConfig/CMakeLists.txt b/DoConfig/CMakeLists.txt index 1d23ce30..75bec4a5 100644 --- a/DoConfig/CMakeLists.txt +++ b/DoConfig/CMakeLists.txt @@ -95,11 +95,11 @@ if(TARGET PkgConfig::glfw3) if (PKG_CONFIG_STATIC_LIBS) message(STATUS "Using system GLFW3 (pkg-config, static)") target_compile_options(DoConfig PRIVATE ${glfw3_STATIC_CFLAGS}) - target_link_libraries(DoConfig PRIVATE ${glfw3_STATIC_LINK_LIBRARIES}) + target_link_libraries(DoConfig PRIVATE ${glfw3_STATIC_LDFLAGS}) else() message(STATUS "Using system GLFW3 (pkg-config, dynamic)") target_compile_options(DoConfig PRIVATE ${glfw3_CFLAGS}) - target_link_libraries(DoConfig PRIVATE ${glfw3_LINK_LIBRARIES}) + target_link_libraries(DoConfig PRIVATE ${glfw3_LDFLAGS}) endif() elseif(TARGET glfw) # CMake diff --git a/external/glad/CMakeLists.txt b/external/glad/CMakeLists.txt index e67a755f..c120bbb5 100644 --- a/external/glad/CMakeLists.txt +++ b/external/glad/CMakeLists.txt @@ -4,7 +4,7 @@ if(NOT TARGET glad) project(glad LANGUAGES C) -add_library(glad +add_library(glad STATIC "include/glad/glad.h" "include/KHR/khrplatform.h" "src/glad.c" diff --git a/src/Backends/Audio/SoftwareMixer.cpp b/src/Backends/Audio/SoftwareMixer.cpp index ade44cfa..a7088040 100644 --- a/src/Backends/Audio/SoftwareMixer.cpp +++ b/src/Backends/Audio/SoftwareMixer.cpp @@ -154,7 +154,7 @@ ATTRIBUTE_HOT void Mixer_MixSounds(float *stream, unsigned int frames_total) const float sample2 = (sound->samples[(size_t)sound->position + 1] - 128.0f) / 128.0f; // Perform linear interpolation - const float interpolated_sample = sample1 + ((sample2 - sample1) * fmod((float)sound->position, 1.0f)); + const float interpolated_sample = sample1 + ((sample2 - sample1) * fmod(sound->position, 1.0)); *steam_pointer++ += interpolated_sample * sound->volume_l; *steam_pointer++ += interpolated_sample * sound->volume_r; diff --git a/src/Backends/GLFW3/Controller.cpp b/src/Backends/GLFW3/Controller.cpp index bc378cdc..b5c55dc2 100644 --- a/src/Backends/GLFW3/Controller.cpp +++ b/src/Backends/GLFW3/Controller.cpp @@ -2,6 +2,7 @@ #include #include +#include #define GLFW_INCLUDE_NONE #include @@ -12,8 +13,8 @@ static BOOL joystick_connected; static int connected_joystick_id; -static int joystick_neutral_x; -static int joystick_neutral_y; + +static float *axis_neutrals; static void JoystickCallback(int joystick_id, int event) { @@ -24,10 +25,13 @@ static void JoystickCallback(int joystick_id, int event) if (!joystick_connected) { - int total_axis; - const float *axis = glfwGetJoystickAxes(joystick_id, &total_axis); + int total_axes; + const float *axes = glfwGetJoystickAxes(joystick_id, &total_axes); - if (total_axis >= 2) + int total_buttons; + const unsigned char *buttons = glfwGetJoystickButtons(joystick_id, &total_buttons); + + if (total_axes >= 2 && total_buttons >= 6) { #if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3) if (glfwJoystickIsGamepad(joystick_id) == GLFW_TRUE) // Avoid selecting things like laptop touchpads @@ -37,9 +41,11 @@ static void JoystickCallback(int joystick_id, int event) joystick_connected = TRUE; connected_joystick_id = joystick_id; - // Reset default stick positions (this is performed in ResetJoystickStatus in vanilla Cave Story - joystick_neutral_x = axis[0]; - joystick_neutral_y = axis[1]; + // Set up neutral axes + axis_neutrals = (float*)malloc(sizeof(float) * total_axes); + + for (int i = 0; i < total_axes; ++i) + axis_neutrals[i] = axes[i]; } } } @@ -51,6 +57,8 @@ static void JoystickCallback(int joystick_id, int event) { printf("Joystick #%d disconnected\n", connected_joystick_id); joystick_connected = FALSE; + + free(axis_neutrals); } break; @@ -76,8 +84,9 @@ void ControllerBackend_Deinit(void) joystick_connected = FALSE; connected_joystick_id = 0; - joystick_neutral_x = 0; - joystick_neutral_y = 0; + + free(axis_neutrals); + axis_neutrals = NULL; } BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status) @@ -85,29 +94,79 @@ BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status) if (!joystick_connected) return FALSE; - // Read axis - int total_axis; - const float *axis = glfwGetJoystickAxes(connected_joystick_id, &total_axis); + const size_t button_limit = sizeof(status->bButton) / sizeof(status->bButton[0]); - status->bLeft = axis[0] < joystick_neutral_x - DEADZONE; - status->bRight = axis[0] > joystick_neutral_x + DEADZONE; - status->bUp = axis[1] < joystick_neutral_y - DEADZONE; - status->bDown = axis[1] > joystick_neutral_y + DEADZONE; - - // Read buttons int total_buttons; const unsigned char *buttons = glfwGetJoystickButtons(connected_joystick_id, &total_buttons); - // The original `Input.cpp` assumed there were 32 buttons (because of DirectInput's `DIJOYSTATE` struct) - if (total_buttons > 32) - total_buttons = 32; + int total_axes; + const float *axes = glfwGetJoystickAxes(connected_joystick_id, &total_axes); - // Read whatever buttons actually exist +#if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3) + int total_hats; + const unsigned char *hats = glfwGetJoystickHats(connected_joystick_id, &total_hats); +#endif + + // Handle directional inputs + status->bLeft = axes[0] < axis_neutrals[0] - DEADZONE; + status->bRight = axes[0] > axis_neutrals[0] + DEADZONE; + status->bUp = axes[1] < axis_neutrals[1] - DEADZONE; + status->bDown = axes[1] > axis_neutrals[1] + DEADZONE; + + // Handle button inputs + unsigned int buttons_done = 0; + + // Start with the joystick buttons for (int i = 0; i < total_buttons; ++i) - status->bButton[i] = buttons[i] == GLFW_PRESS; + { + status->bButton[buttons_done] = buttons[i] == GLFW_PRESS; - // Blank the buttons that do not - for (int i = total_buttons; i < 32; ++i) + if (++buttons_done >= button_limit) + break; + } + + // Then the joystick axes + for (int i = 0; i < total_axes; ++i) + { + status->bButton[buttons_done] = axes[i] < axis_neutrals[i] - DEADZONE; + + if (++buttons_done >= button_limit) + break; + + status->bButton[buttons_done] = axes[i] > axis_neutrals[i] + DEADZONE; + + if (++buttons_done >= button_limit) + break; + } + +#if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3) + // Then the joystick hats + for (int i = 0; i < total_axes; ++i) + { + status->bButton[buttons_done] = hats[i] & GLFW_HAT_UP; + + if (++buttons_done >= button_limit) + break; + + status->bButton[buttons_done] = hats[i] & GLFW_HAT_RIGHT; + + if (++buttons_done >= button_limit) + break; + + status->bButton[buttons_done] = hats[i] & GLFW_HAT_DOWN; + + if (++buttons_done >= button_limit) + break; + + status->bButton[buttons_done] = hats[i] & GLFW_HAT_LEFT; + + if (++buttons_done >= button_limit) + break; + } +#endif + + // Blank any remaining buttons + for (size_t i = buttons_done; i < button_limit; ++i) status->bButton[i] = FALSE; return TRUE; @@ -118,7 +177,5 @@ BOOL ControllerBackend_ResetJoystickStatus(void) if (!joystick_connected) return FALSE; - // The code that would normally run here has been moved to JoystickCallback, to better-support hotplugging - return TRUE; } diff --git a/src/Backends/GLFW3/Misc.cpp b/src/Backends/GLFW3/Misc.cpp index 0a45eff3..50945b37 100644 --- a/src/Backends/GLFW3/Misc.cpp +++ b/src/Backends/GLFW3/Misc.cpp @@ -20,12 +20,12 @@ #define DO_KEY(GLFW_KEY, BACKEND_KEY) \ case GLFW_KEY: \ - backend_keyboard_state[BACKEND_KEY] = action == GLFW_PRESS; \ + keyboard_state[BACKEND_KEY] = action == GLFW_PRESS; \ break; BOOL bActive = TRUE; -BOOL backend_keyboard_state[BACKEND_KEYBOARD_TOTAL]; -BOOL backend_previous_keyboard_state[BACKEND_KEYBOARD_TOTAL]; + +static BOOL keyboard_state[BACKEND_KEYBOARD_TOTAL]; static GLFWcursor* cursor; @@ -264,8 +264,6 @@ BOOL Backend_SystemTask(void) return FALSE; } - memcpy(backend_previous_keyboard_state, backend_keyboard_state, sizeof(backend_keyboard_state)); - glfwPollEvents(); while (!bActive) @@ -274,6 +272,11 @@ BOOL Backend_SystemTask(void) return TRUE; } +void Backend_GetKeyboardState(BOOL *out_keyboard_state) +{ + memcpy(out_keyboard_state, keyboard_state, sizeof(keyboard_state)); +} + void Backend_ShowMessageBox(const char *title, const char *message) { // GLFW3 doesn't have a message box diff --git a/src/Backends/Misc.h b/src/Backends/Misc.h index e6d11124..7cdf3d2f 100644 --- a/src/Backends/Misc.h +++ b/src/Backends/Misc.h @@ -84,8 +84,6 @@ enum }; extern BOOL bActive; -extern BOOL backend_keyboard_state[BACKEND_KEYBOARD_TOTAL]; -extern BOOL backend_previous_keyboard_state[BACKEND_KEYBOARD_TOTAL]; void Backend_Init(void); void Backend_Deinit(void); @@ -96,6 +94,7 @@ void Backend_SetWindowIcon(const unsigned char *rgb_pixels, unsigned int width, void Backend_SetCursor(const unsigned char *rgb_pixels, unsigned int width, unsigned int height); void PlaybackBackend_EnableDragAndDrop(void); BOOL Backend_SystemTask(void); +void Backend_GetKeyboardState(BOOL *keyboard_state); void Backend_ShowMessageBox(const char *title, const char *message); unsigned long Backend_GetTicks(void); void Backend_Delay(unsigned int ticks); diff --git a/src/Backends/SDL2/Controller.cpp b/src/Backends/SDL2/Controller.cpp index bedc56d5..7b2eae08 100644 --- a/src/Backends/SDL2/Controller.cpp +++ b/src/Backends/SDL2/Controller.cpp @@ -11,8 +11,8 @@ #define DEADZONE 10000; static SDL_Joystick *joystick; -static int joystick_neutral_x; -static int joystick_neutral_y; + +static Sint16 *axis_neutrals; BOOL ControllerBackend_Init(void) { @@ -37,26 +37,77 @@ BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status) if (joystick == NULL) return FALSE; - // Read axis + const size_t button_limit = sizeof(status->bButton) / sizeof(status->bButton[0]); + + // Handle directional inputs const Sint16 joystick_x = SDL_JoystickGetAxis(joystick, 0); const Sint16 joystick_y = SDL_JoystickGetAxis(joystick, 1); - status->bLeft = joystick_x < joystick_neutral_x - DEADZONE; - status->bRight = joystick_x > joystick_neutral_x + DEADZONE; - status->bUp = joystick_y < joystick_neutral_y - DEADZONE; - status->bDown = joystick_y > joystick_neutral_y + DEADZONE; + status->bLeft = joystick_x < axis_neutrals[0] - DEADZONE; + status->bRight = joystick_x > axis_neutrals[0] + DEADZONE; + status->bUp = joystick_y < axis_neutrals[1] - DEADZONE; + status->bDown = joystick_y > axis_neutrals[1] + DEADZONE; - // The original `Input.cpp` assumed there were 32 buttons (because of DirectInput's `DIJOYSTATE` struct) - int numButtons = SDL_JoystickNumButtons(joystick); - if (numButtons > 32) - numButtons = 32; + // Handle button inputs + int total_buttons = SDL_JoystickNumButtons(joystick); + int total_axes = SDL_JoystickNumAxes(joystick); + int total_hats = SDL_JoystickNumHats(joystick); - // Read whatever buttons actually exist - for (int i = 0; i < numButtons; ++i) - status->bButton[i] = SDL_JoystickGetButton(joystick, i); + unsigned int buttons_done = 0; - // Blank the buttons that do not - for (int i = numButtons; i < 32; ++i) + // Start with the joystick buttons + for (int i = 0; i < total_buttons; ++i) + { + status->bButton[buttons_done] = SDL_JoystickGetButton(joystick, i); + + if (++buttons_done >= button_limit) + break; + } + + // Then the joystick axes + for (int i = 0; i < total_axes; ++i) + { + Sint16 axis = SDL_JoystickGetAxis(joystick, i); + + status->bButton[buttons_done] = axis < axis_neutrals[i] - DEADZONE; + + if (++buttons_done >= button_limit) + break; + + status->bButton[buttons_done] = axis > axis_neutrals[i] + DEADZONE; + + if (++buttons_done >= button_limit) + break; + } + + // Then the joystick hats + for (int i = 0; i < total_axes; ++i) + { + Uint8 hat = SDL_JoystickGetHat(joystick, i); + + status->bButton[buttons_done] = hat == SDL_HAT_UP || hat == SDL_HAT_LEFTUP || hat == SDL_HAT_RIGHTUP; + + if (++buttons_done >= button_limit) + break; + + status->bButton[buttons_done] = hat == SDL_HAT_RIGHT || hat == SDL_HAT_RIGHTUP || hat == SDL_HAT_RIGHTDOWN; + + if (++buttons_done >= button_limit) + break; + + status->bButton[buttons_done] = hat == SDL_HAT_DOWN || hat == SDL_HAT_LEFTDOWN || hat == SDL_HAT_RIGHTDOWN; + + if (++buttons_done >= button_limit) + break; + + status->bButton[buttons_done] = hat == SDL_HAT_LEFT || hat == SDL_HAT_LEFTUP || hat == SDL_HAT_LEFTDOWN; + + if (++buttons_done >= button_limit) + break; + } + + // Blank any remaining buttons + for (size_t i = buttons_done; i < button_limit; ++i) status->bButton[i] = FALSE; return TRUE; @@ -67,8 +118,6 @@ BOOL ControllerBackend_ResetJoystickStatus(void) if (joystick == NULL) return FALSE; - // The code that would normally run here has been moved to JoystickCallback, to better-support hotplugging - return TRUE; } @@ -82,11 +131,24 @@ void ControllerBackend_JoystickConnect(Sint32 joystick_id) if (joystick != NULL) { - printf("Joystick #%d selected\n", joystick_id); + int total_axes = SDL_JoystickNumAxes(joystick); + int total_buttons = SDL_JoystickNumButtons(joystick); - // Reset default stick positions (this is performed in ResetJoystickStatus in vanilla Cave Story - joystick_neutral_x = SDL_JoystickGetAxis(joystick, 0); - joystick_neutral_y = SDL_JoystickGetAxis(joystick, 1); + if (total_axes >= 2 && total_buttons >= 6) + { + printf("Joystick #%d selected\n", joystick_id); + + // Set up neutral axes + axis_neutrals = (Sint16*)malloc(sizeof(Sint16) * total_axes); + + for (int i = 0; i < total_axes; ++i) + axis_neutrals[i] = SDL_JoystickGetAxis(joystick, i); + } + else + { + SDL_JoystickClose(joystick); + joystick = NULL; + } } } } @@ -96,6 +158,9 @@ void ControllerBackend_JoystickDisconnect(Sint32 joystick_id) if (joystick_id == SDL_JoystickInstanceID(joystick)) { printf("Joystick #%d disconnected\n", joystick_id); + SDL_JoystickClose(joystick); joystick = NULL; + + free(axis_neutrals); } } diff --git a/src/Backends/SDL2/Misc.cpp b/src/Backends/SDL2/Misc.cpp index bb858d90..0beec4b9 100644 --- a/src/Backends/SDL2/Misc.cpp +++ b/src/Backends/SDL2/Misc.cpp @@ -18,12 +18,12 @@ #define DO_KEY(SDL_KEY, BACKEND_KEY) \ case SDL_KEY: \ - backend_keyboard_state[BACKEND_KEY] = event.key.type == SDL_KEYDOWN; \ + keyboard_state[BACKEND_KEY] = event.key.type == SDL_KEYDOWN; \ break; BOOL bActive = TRUE; -BOOL backend_keyboard_state[BACKEND_KEYBOARD_TOTAL]; -BOOL backend_previous_keyboard_state[BACKEND_KEYBOARD_TOTAL]; + +static BOOL keyboard_state[BACKEND_KEYBOARD_TOTAL]; static SDL_Surface *cursor_surface; static SDL_Cursor *cursor; @@ -97,8 +97,6 @@ void PlaybackBackend_EnableDragAndDrop(void) BOOL Backend_SystemTask(void) { - memcpy(backend_previous_keyboard_state, backend_keyboard_state, sizeof(backend_keyboard_state)); - while (SDL_PollEvent(NULL) || !bActive) { SDL_Event event; @@ -240,6 +238,11 @@ BOOL Backend_SystemTask(void) return TRUE; } +void Backend_GetKeyboardState(BOOL *out_keyboard_state) +{ + memcpy(out_keyboard_state, keyboard_state, sizeof(keyboard_state)); +} + void Backend_ShowMessageBox(const char *title, const char *message) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, message, window); diff --git a/src/Input.h b/src/Input.h index 4ad8aa7a..84008430 100644 --- a/src/Input.h +++ b/src/Input.h @@ -8,7 +8,7 @@ struct JOYSTICK_STATUS BOOL bRight; BOOL bUp; BOOL bDown; - BOOL bButton[32]; + BOOL bButton[32]; // The original `Input.cpp` assumed there were 32 buttons (because of DirectInput's `DIJOYSTATE` struct) }; void ReleaseDirectInput(void); diff --git a/src/Main.cpp b/src/Main.cpp index 0980528f..4979237e 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -277,13 +277,16 @@ int main(int argc, char *argv[]) size_t window_icon_resource_size; const unsigned char *window_icon_resource_data = FindResource("ICON_MINI", "ICON", &window_icon_resource_size); - unsigned int window_icon_width, window_icon_height; - unsigned char *window_icon_rgb_pixels = DecodeBitmap(window_icon_resource_data, window_icon_resource_size, &window_icon_width, &window_icon_height); - - if (window_icon_rgb_pixels != NULL) + if (window_icon_resource_data != NULL) { - Backend_SetWindowIcon(window_icon_rgb_pixels, window_icon_width, window_icon_height); - FreeBitmap(window_icon_rgb_pixels); + unsigned int window_icon_width, window_icon_height; + unsigned char *window_icon_rgb_pixels = DecodeBitmap(window_icon_resource_data, window_icon_resource_size, &window_icon_width, &window_icon_height); + + if (window_icon_rgb_pixels != NULL) + { + Backend_SetWindowIcon(window_icon_rgb_pixels, window_icon_width, window_icon_height); + FreeBitmap(window_icon_rgb_pixels); + } } #endif @@ -291,13 +294,16 @@ int main(int argc, char *argv[]) size_t cursor_resource_size; const unsigned char *cursor_resource_data = FindResource("CURSOR_NORMAL", "CURSOR", &cursor_resource_size); - unsigned int cursor_width, cursor_height; - unsigned char *cursor_rgb_pixels = DecodeBitmap(cursor_resource_data, cursor_resource_size, &cursor_width, &cursor_height); - - if (cursor_rgb_pixels != NULL) + if (cursor_resource_data != NULL) { - Backend_SetCursor(cursor_rgb_pixels, cursor_width, cursor_height); - FreeBitmap(cursor_rgb_pixels); + unsigned int cursor_width, cursor_height; + unsigned char *cursor_rgb_pixels = DecodeBitmap(cursor_resource_data, cursor_resource_size, &cursor_width, &cursor_height); + + if (cursor_rgb_pixels != NULL) + { + Backend_SetCursor(cursor_rgb_pixels, cursor_width, cursor_height); + FreeBitmap(cursor_rgb_pixels); + } } if (IsKeyFile("fps")) @@ -379,12 +385,17 @@ void JoystickProc(void); BOOL SystemTask(void) { + static BOOL previous_keyboard_state[BACKEND_KEYBOARD_TOTAL]; + if (!Backend_SystemTask()) return FALSE; + BOOL keyboard_state[BACKEND_KEYBOARD_TOTAL]; + Backend_GetKeyboardState(keyboard_state); + for (unsigned int i = 0; i < BACKEND_KEYBOARD_TOTAL; ++i) { - if ((backend_keyboard_state[i] ^ backend_previous_keyboard_state[i]) & backend_keyboard_state[i]) + if (keyboard_state[i] && !previous_keyboard_state[i]) { switch (i) { @@ -470,7 +481,7 @@ BOOL SystemTask(void) break; } } - else if ((backend_keyboard_state[i] ^ backend_previous_keyboard_state[i]) & backend_previous_keyboard_state[i]) + else if (!keyboard_state[i] && previous_keyboard_state[i]) { switch (i) { @@ -554,6 +565,8 @@ BOOL SystemTask(void) } } + memcpy(previous_keyboard_state, keyboard_state, sizeof(keyboard_state)); + // Run joystick code if (gbUseJoystick) JoystickProc(); @@ -569,7 +582,7 @@ void JoystickProc(void) if (!GetJoystickStatus(&status)) return; - gKey &= (KEY_ESCAPE | KEY_F2 | KEY_F1); + gKey &= (KEY_ESCAPE | KEY_F1 | KEY_F2); // Set movement buttons if (status.bLeft)