From 9417a20d9a5bd9819eb9b92f8e37ee43e49afd4a Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Mon, 30 May 2022 17:56:36 +0800 Subject: [PATCH] Improve initialization logic Provide default states for input and output. --- docs/reference/files/config.ini | 4 +-- src/packages/game/input/IZ_joystick.c | 4 ++- src/packages/game/input/IZ_joystick.h | 40 +++++++++++++---------- src/packages/game/input/IZ_keyboard.c | 3 +- src/packages/game/input/IZ_keyboard.h | 38 ++++++++++++---------- src/packages/game/input/IZ_midi.c | 3 +- src/packages/game/input/IZ_midi.h | 46 ++++++++++++++++----------- src/packages/game/input/input.test.c | 20 ++++++------ src/packages/game/output/IZ_video.c | 37 ++++++++++++--------- src/packages/game/output/IZ_video.h | 16 ++++++++-- 10 files changed, 127 insertions(+), 84 deletions(-) diff --git a/docs/reference/files/config.ini b/docs/reference/files/config.ini index c583719..0337383 100644 --- a/docs/reference/files/config.ini +++ b/docs/reference/files/config.ini @@ -1,6 +1,6 @@ [Video] -Width=640 -Height=480 +Width=320 +Height=240 MaxFps=30 [Joystick.0.ControlMapping] Affirm=11 diff --git a/src/packages/game/input/IZ_joystick.c b/src/packages/game/input/IZ_joystick.c index ea07515..2c56e20 100644 --- a/src/packages/game/input/IZ_joystick.c +++ b/src/packages/game/input/IZ_joystick.c @@ -101,7 +101,7 @@ void IZ_LoadJoystickConfig(const char* config_path, IZ_JoystickState(* state)[PL state[player_index]->config.control_mapping[i] = ini_getl( control_mapping_section_name, ACTION_NAMES[i], - IZ_DEFAULT_JOYSTICK_CONTROLS[player_index][i], + IZ_DEFAULT_JOYSTICK_STATE[player_index].config.control_mapping[i], config_path ); } @@ -155,6 +155,8 @@ IZ_ProcedureResult IZ_SaveJoystickConfig(const char* config_path, IZ_JoystickSta } IZ_ProcedureResult IZ_InitializeJoystickState(const char* config_path, IZ_JoystickState(* state)[PLAYERS]) { + SDL_memcpy(state, &IZ_DEFAULT_JOYSTICK_STATE, sizeof(IZ_JoystickState)); + IZ_LoadJoystickConfig(config_path, state); if (IZ_SaveJoystickConfig(config_path, state)) { return 1; diff --git a/src/packages/game/input/IZ_joystick.h b/src/packages/game/input/IZ_joystick.h index a257958..597570c 100644 --- a/src/packages/game/input/IZ_joystick.h +++ b/src/packages/game/input/IZ_joystick.h @@ -28,24 +28,30 @@ typedef struct { IZ_JoystickConfig config; } IZ_JoystickState; -static IZ_PadButton IZ_DEFAULT_JOYSTICK_CONTROLS[PLAYERS][CONTROLS] = { +static const IZ_JoystickState IZ_DEFAULT_JOYSTICK_STATE[PLAYERS] = { { - 255, - 255, - 255, - 255, - 11, - 10, - 1, - 0, - 4, - 3, - 6, - 7, - 8, - 9, - 13, - 14, + .config = { + .control_mapping = { + 255, + 255, + 255, + 255, + 11, + 10, + 1, + 0, + 4, + 3, + 6, + 7, + 8, + 9, + 13, + 14, + }, + .axis_threshold = 8000u, + .device_id = 0, + }, }, }; diff --git a/src/packages/game/input/IZ_keyboard.c b/src/packages/game/input/IZ_keyboard.c index e39bd99..c1a7b1a 100644 --- a/src/packages/game/input/IZ_keyboard.c +++ b/src/packages/game/input/IZ_keyboard.c @@ -51,7 +51,7 @@ void IZ_LoadKeyboardConfig(const char* config_path, IZ_KeyboardState(* state)[PL ini_gets( keyboard_section_name, ACTION_NAMES[i], - SDL_GetKeyName(IZ_DEFAULT_KEYBOARD_CONTROLS[player_index][i]), + SDL_GetKeyName(IZ_DEFAULT_KEYBOARD_STATE[player_index].config.control_mapping[i]), buffer, 128, config_path @@ -63,6 +63,7 @@ void IZ_LoadKeyboardConfig(const char* config_path, IZ_KeyboardState(* state)[PL } IZ_ProcedureResult IZ_InitializeKeyboardState(const char* config_path, IZ_KeyboardState(* state)[PLAYERS]) { + SDL_memcpy(state, &IZ_DEFAULT_KEYBOARD_STATE, sizeof(IZ_KeyboardState)); IZ_LoadKeyboardConfig(config_path, state); return IZ_SaveKeyboardConfig(config_path, state); } diff --git a/src/packages/game/input/IZ_keyboard.h b/src/packages/game/input/IZ_keyboard.h index 16228ec..175dc82 100644 --- a/src/packages/game/input/IZ_keyboard.h +++ b/src/packages/game/input/IZ_keyboard.h @@ -14,24 +14,28 @@ typedef struct { IZ_KeyboardConfig config; } IZ_KeyboardState; -static const SDL_KeyCode IZ_DEFAULT_KEYBOARD_CONTROLS[PLAYERS][CONTROLS] = { +static const IZ_KeyboardState IZ_DEFAULT_KEYBOARD_STATE[PLAYERS] = { { - SDLK_UP, - SDLK_RIGHT, - SDLK_DOWN, - SDLK_LEFT, - SDLK_RETURN, // yes - SDLK_BACKSPACE, // no - SDLK_a, // action0 - SDLK_s, // action1 - SDLK_d, // action2 - SDLK_f, // action3 - SDLK_z, // action4 - SDLK_x, // action5 - SDLK_c, // action6 - SDLK_v, // action7 - SDLK_w, // action8 - SDLK_e, // action9 + .config = { + .control_mapping = { + SDLK_UP, + SDLK_RIGHT, + SDLK_DOWN, + SDLK_LEFT, + SDLK_RETURN, // yes + SDLK_BACKSPACE, // no + SDLK_a, // action0 + SDLK_s, // action1 + SDLK_d, // action2 + SDLK_f, // action3 + SDLK_z, // action4 + SDLK_x, // action5 + SDLK_c, // action6 + SDLK_v, // action7 + SDLK_w, // action8 + SDLK_e, // action9 + }, + }, }, }; diff --git a/src/packages/game/input/IZ_midi.c b/src/packages/game/input/IZ_midi.c index e4f712a..9559f6c 100644 --- a/src/packages/game/input/IZ_midi.c +++ b/src/packages/game/input/IZ_midi.c @@ -147,7 +147,7 @@ void IZ_LoadMIDIInputConfig(const char* config_path, IZ_MIDIInputState(* state)[ ini_gets( control_mapping_section_name, ACTION_NAMES[i], - IZ_GetMIDINoteName(IZ_DEFAULT_MIDI_INPUT_CONTROLS[player_index][i]), + IZ_GetMIDINoteName(IZ_DEFAULT_MIDI_INPUT_STATE[player_index].config.control_mapping[i]), buffer, 128, config_path @@ -167,6 +167,7 @@ IZ_ProcedureResult IZ_InitializeMIDIInput(const char* config_path, IZ_MIDIInputS return 1; } + SDL_memcpy(state, &IZ_DEFAULT_MIDI_INPUT_STATE, sizeof(IZ_MIDIInputState)); IZ_LoadMIDIInputConfig(config_path, state); if (IZ_SaveMIDIInputConfig(config_path, state)) { return 2; diff --git a/src/packages/game/input/IZ_midi.h b/src/packages/game/input/IZ_midi.h index 63d1f3f..7baaf53 100644 --- a/src/packages/game/input/IZ_midi.h +++ b/src/packages/game/input/IZ_midi.h @@ -1,6 +1,7 @@ #ifndef IZ_MIDI_H #define IZ_MIDI_H +#include #include #include #include @@ -27,25 +28,34 @@ typedef struct { PmEvent event_buffer[MIDI_EVENT_BUFFER_SIZE]; } IZ_MIDIInputState; -static const IZ_MIDINote IZ_DEFAULT_MIDI_INPUT_CONTROLS[PLAYERS][CONTROLS] = { +static const IZ_MIDIInputState IZ_DEFAULT_MIDI_INPUT_STATE[PLAYERS] = { { - 70, - 72, - 71, - 69, - 65, - 64, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - } + .config = { + .control_mapping = { + 70, + 72, + 71, + 69, + 65, + 64, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + }, + .device_id = 0, + .channel = 0, + }, + .event_buffer = {}, + .stream = NULL, + .device_info = NULL, + }, }; IZ_ProcedureResult IZ_SaveMIDIInputConfig(const char*, IZ_MIDIInputState(*)[PLAYERS]); diff --git a/src/packages/game/input/input.test.c b/src/packages/game/input/input.test.c index b65b9a9..7af9f77 100644 --- a/src/packages/game/input/input.test.c +++ b/src/packages/game/input/input.test.c @@ -228,8 +228,8 @@ spec("input") { for (uint8_t i = 4; i < CONTROLS; i += 1) { it("handles %s action activation", ACTION_NAMES[i]) { e.type = SDL_JOYBUTTONDOWN; - e.jbutton.button = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i]; - state.config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i]; + e.jbutton.button = IZ_DEFAULT_JOYSTICK_STATE[0][i]; + state.config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_STATE[0][i]; action = 0; IZ_HandleJoystickEvents(e, &state, &action); @@ -241,8 +241,8 @@ spec("input") { it("handles %s action deactivation", ACTION_NAMES[i]) { e.type = SDL_JOYBUTTONUP; - e.jbutton.button = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i]; - state.config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i]; + e.jbutton.button = IZ_DEFAULT_JOYSTICK_STATE[0][i]; + state.config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_STATE[0][i]; action = ~0; IZ_HandleJoystickEvents(e, &state, &action); @@ -285,7 +285,7 @@ spec("input") { before_each() { for (uint8_t i = 0; i < CONTROLS; i += 1) { - config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_CONTROLS[0][i]; + config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_STATE[0][i]; } } @@ -313,8 +313,8 @@ spec("input") { for (uint8_t i = 0; i < CONTROLS; i += 1) { it("handles %s action activation", ACTION_NAMES[i]) { e.type = SDL_KEYDOWN; - e.key.keysym.sym = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i]; - state.config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i]; + e.key.keysym.sym = IZ_DEFAULT_KEYBOARD_STATE[0][i]; + state.config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_STATE[0][i]; action = 0; IZ_HandleKeyboardEvents(e, &state, &action); @@ -326,8 +326,8 @@ spec("input") { it("handles %s action deactivation", ACTION_NAMES[i]) { e.type = SDL_KEYUP; - e.key.keysym.sym = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i]; - state.config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i]; + e.key.keysym.sym = IZ_DEFAULT_KEYBOARD_STATE[0][i]; + state.config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_STATE[0][i]; action = ~0; IZ_HandleKeyboardEvents(e, &state, &action); @@ -369,7 +369,7 @@ spec("input") { before_each() { for (uint8_t i = 0; i < CONTROLS; i += 1) { - config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_CONTROLS[0][i]; + config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_STATE[0][i]; } } diff --git a/src/packages/game/output/IZ_video.c b/src/packages/game/output/IZ_video.c index 27fb142..9aa3f29 100644 --- a/src/packages/game/output/IZ_video.c +++ b/src/packages/game/output/IZ_video.c @@ -15,13 +15,13 @@ IZ_ProcedureResult IZ_SaveVideoConfig(const char* config_path, IZ_VideoConfig* c } void IZ_LoadVideoConfig(const char* config_path, IZ_VideoConfig* config) { - config->width = ini_getl("Video", "Width", 640l, config_path); - config->height = ini_getl("Video", "Height", 480l, config_path); - config->max_fps = ini_getl("Video", "MaxFps", 30, config_path); + config->width = ini_getl("Video", "Width", IZ_DEFAULT_VIDEO_STATE.config.width, config_path); + config->height = ini_getl("Video", "Height", IZ_DEFAULT_VIDEO_STATE.config.height, config_path); + config->max_fps = ini_getl("Video", "MaxFps", IZ_DEFAULT_VIDEO_STATE.config.max_fps, config_path); } IZ_ProcedureResult IZ_InitializeVideo(const char* config_path, IZ_VideoState* state) { - *state = (IZ_VideoState) {}; + SDL_memcpy(state, &IZ_DEFAULT_VIDEO_STATE, sizeof(IZ_VideoState)); IZ_LoadVideoConfig(config_path, &state->config); if (IZ_SaveVideoConfig(config_path, &state->config)) { @@ -42,7 +42,7 @@ IZ_ProcedureResult IZ_InitializeVideo(const char* config_path, IZ_VideoState* st return 1; } state->window = window; - state->surface = SDL_GetWindowSurface(window); + state->renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); return 0; } @@ -50,22 +50,28 @@ IZ_ProcedureResult IZ_InitializeVideo(const char* config_path, IZ_VideoState* st void IZ_UpdateVideo(IZ_VideoState* video_state, IZ_InputState* input_states, uint64_t ticks) { if (ticks - video_state->last_update_at > 1000 / video_state->config.max_fps) { // Update window - SDL_FillRect(video_state->surface, NULL, SDL_MapRGB(video_state->surface->format, 0x00, 0x00, 0x00)); + SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0x00, 0x00, 0xff); + SDL_RenderClear(video_state->renderer); + + SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0xff, 0xff, 0xff); + uint64_t the_ticks = ticks; for (uint8_t i = 0; i < 64; i += 1) { - const uint8_t column = (64 - i) % 32; + const uint8_t column = i % 32; const uint8_t row = i / 32; - const uint64_t bitflag = (0x1lu << i); const uint8_t size = 4; - if (ticks & bitflag) { - SDL_FillRect(video_state->surface, &(SDL_Rect) { - column * size, + + if (the_ticks & 0x1) { + SDL_RenderFillRectF(video_state->renderer, &(SDL_FRect) { + video_state->config.width - ((column + 1) * size), video_state->config.height - ((row + 1) * size), size, size - }, SDL_MapRGB(video_state->surface->format, 0x00, 0xff, 0xff)); + }); } + the_ticks >>= 1; } + SDL_SetRenderDrawColor(video_state->renderer, 0xff, 0xff, 0x00, 0xff); // TODO refer to app's state for (uint8_t p = 0; p < PLAYERS; p += 1) { for (uint8_t i = 0; i < CONTROLS; i += 1) { @@ -74,16 +80,17 @@ void IZ_UpdateVideo(IZ_VideoState* video_state, IZ_InputState* input_states, uin const IZ_Action bitflag = (0x1 << i); const uint8_t size = 4; if (input_states->action[p] & bitflag) { - SDL_FillRect(video_state->surface, &(SDL_Rect) { + SDL_RenderFillRectF(video_state->renderer, &(SDL_FRect) { column * size, row * size, size, size - }, SDL_MapRGB(video_state->surface->format, 0xff, 0xff, 0x00)); + }); } } } - SDL_UpdateWindowSurface(video_state->window); + + SDL_RenderPresent(video_state->renderer); video_state->last_update_at = ticks; } } diff --git a/src/packages/game/output/IZ_video.h b/src/packages/game/output/IZ_video.h index 01c7e82..2430669 100644 --- a/src/packages/game/output/IZ_video.h +++ b/src/packages/game/output/IZ_video.h @@ -4,6 +4,7 @@ #include #include #include +#include // TODO move this out from video, refer to app's state instead #include "../input/IZ_input.h" @@ -12,7 +13,7 @@ typedef struct { uint16_t width; - uint16_t height; + uint16_t height; uint8_t max_fps; } IZ_VideoConfig; @@ -20,9 +21,20 @@ typedef struct { IZ_VideoConfig config; uint64_t last_update_at; SDL_Window* window; - SDL_Surface* surface; + SDL_Renderer* renderer; } IZ_VideoState; +static const IZ_VideoState IZ_DEFAULT_VIDEO_STATE = { + .config = { + .width = 320u, + .height = 240u, + .max_fps = 30u, + }, + .last_update_at = 0, + .renderer = NULL, + .window = NULL, +}; + IZ_ProcedureResult IZ_InitializeVideo(const char*, IZ_VideoState*); IZ_ProcedureResult IZ_SaveVideoConfig(const char*, IZ_VideoConfig*);