Merge branch 'portable' into improvePerformance2

This commit is contained in:
Gabriel Ravier 2020-04-05 19:33:13 +02:00
commit 1cf4200051
11 changed files with 228 additions and 88 deletions

View file

@ -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)")

View file

@ -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

View file

@ -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"

View file

@ -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;

View file

@ -2,6 +2,7 @@
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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)