Browse Source

Fix multi player support

Correctly dereference pointers.
feature/data-structs
TheoryOfNekomata 2 years ago
parent
commit
259780cdb2
25 changed files with 287 additions and 196 deletions
  1. +12
    -0
      docs/characters.md
  2. +5
    -0
      docs/mechanics.md
  3. +15
    -0
      docs/weapons.md
  4. +20
    -20
      src/packages/game/IZ_app.c
  5. +1
    -1
      src/packages/game/IZ_app.h
  6. +1
    -1
      src/packages/game/IZ_config.c
  7. +1
    -1
      src/packages/game/IZ_config.h
  8. +2
    -2
      src/packages/game/geometry/IZ_rect.c
  9. +2
    -2
      src/packages/game/geometry/IZ_rect.h
  10. +10
    -10
      src/packages/game/geometry/geometry.test.c
  11. +18
    -13
      src/packages/game/input/IZ_input.c
  12. +4
    -4
      src/packages/game/input/IZ_input.h
  13. +24
    -24
      src/packages/game/input/IZ_joystick.c
  14. +30
    -4
      src/packages/game/input/IZ_joystick.h
  15. +10
    -10
      src/packages/game/input/IZ_keyboard.c
  16. +25
    -3
      src/packages/game/input/IZ_keyboard.h
  17. +24
    -24
      src/packages/game/input/IZ_midi.c
  18. +31
    -4
      src/packages/game/input/IZ_midi.h
  19. +30
    -30
      src/packages/game/input/input.test.c
  20. +1
    -1
      src/packages/game/main.c
  21. +1
    -1
      src/packages/game/memory/IZ_pool.c
  22. +1
    -1
      src/packages/game/memory/IZ_pool.h
  23. +14
    -14
      src/packages/game/output/IZ_video.c
  24. +4
    -4
      src/packages/game/output/IZ_video.h
  25. +1
    -22
      src/packages/game/output/output.test.c

+ 12
- 0
docs/characters.md View File

@@ -0,0 +1,12 @@
* Player 1
* Dark gray gothic/punk
* Player 2
* White punk
* Enemies
* OL (secretary pencil skirt)
* assassin (leather shorts)
* agent (suit and tie)
* mercenary (bandana mask)
* boss (mafia boss)
* boss bodyguards
* Hostage ?

+ 5
- 0
docs/mechanics.md View File

@@ -0,0 +1,5 @@
* Starts in a random section in a map
* Player/s must retrieve package/s from random sections in the map
* Each section has different mechanics (outdoors open area - survival, machine gunning, sometimes no enemies spawn here; warehouse - platforming, machine gunning, boss battle; electrical/computer room - puzzle, library with vault - puzzle, boss room - boss battle, lobby - no enemies spawn here, unless the packages are retrieved, etc)
* Player/s must go to the extraction point (helicopter or runaway vehicle)
* Sometimes, crate boxes paradrop on open areas, rooftop, in warehouse areas crates are delivered by trucks

+ 15
- 0
docs/weapons.md View File

@@ -0,0 +1,15 @@
# Combat knife
# Oriental sword (Katana)
# Twin pistols (Beretta M9)
- Ammo: 9x19mm Parabellum (15x x 2pcs)
- Muzzle velocity: 381 m/s
# Shotgun (Ithaca)
- Ammo: 12 gauge 2.75" shells (8x)
# Submachine gun (MP5A3)
- Ammo: 9x19mm Parabellum (30x)
- Rate of fire: 800 round/min cyclic
- Muzzle velocity: 400 m/s
# Assault rifle (M4A1)
- Rate of fire: 700–950 round/min cyclic
- Ammo: 5.56x45mm NATO
- Muzzle velocity: 910 m/s

+ 20
- 20
src/packages/game/IZ_app.c View File

@@ -1,6 +1,6 @@
#include "IZ_app.h" #include "IZ_app.h"


IZ_ProcedureResult IZ_InitializeApp(IZ_App* app) {
IZ_ProcedureResult IZ_AppInitialize(IZ_App* app) {
if (SDL_Init( if (SDL_Init(
SDL_INIT_VIDEO SDL_INIT_VIDEO
| SDL_INIT_GAMECONTROLLER | SDL_INIT_GAMECONTROLLER
@@ -11,14 +11,14 @@ IZ_ProcedureResult IZ_InitializeApp(IZ_App* app) {
} }


char config_path[128]; char config_path[128];
IZ_GetConfigPath(config_path, 128);
IZ_ConfigGetPath(config_path, 128);


if (IZ_InitializeVideo(config_path, &app->video_state)) {
if (IZ_VideoInitialize(config_path, &app->video_state)) {
return 2; return 2;
} }


IZ_InitializeInput(config_path, &app->input_state);
IZ_InitializePool(&app->memory_pool);
IZ_InputInitialize(config_path, &app->input_state);
IZ_PoolInitialize(&app->memory_pool);
// void* p1 = IZ_PoolAllocate(&app->memory_pool, sizeof(u16), 0)->pointer; // void* p1 = IZ_PoolAllocate(&app->memory_pool, sizeof(u16), 0)->pointer;
// void* p2 = IZ_PoolAllocate(&app->memory_pool, sizeof(u8), 0)->pointer; // void* p2 = IZ_PoolAllocate(&app->memory_pool, sizeof(u8), 0)->pointer;
// void* p3 = IZ_PoolAllocate(&app->memory_pool, sizeof(u64), 0)->pointer; // void* p3 = IZ_PoolAllocate(&app->memory_pool, sizeof(u64), 0)->pointer;
@@ -32,24 +32,24 @@ IZ_ProcedureResult IZ_InitializeApp(IZ_App* app) {
return 0; return 0;
} }


void IZ_TeardownApp(IZ_App* app) {
IZ_TeardownInput(&app->input_state);
IZ_TeardownVideo(&app->video_state);
void IZ_AppTeardown(IZ_App* app) {
IZ_InputTeardown(&app->input_state);
IZ_VideoTeardown(&app->video_state);
SDL_Quit(); SDL_Quit();
} }


void IZ_HandleSDLEvents(IZ_App* app) {
void IZ_AppHandleSDLEvents(IZ_App* app) {
while (SDL_PollEvent(&app->sdl_event) != 0) { while (SDL_PollEvent(&app->sdl_event) != 0) {
if (app->sdl_event.type == SDL_QUIT) { if (app->sdl_event.type == SDL_QUIT) {
app->quit = true; app->quit = true;
break; break;
} }


IZ_HandleSDLInputEvents(app->sdl_event, &app->input_state);
IZ_InputHandleSDLEvents(app->sdl_event, &app->input_state);
} }
} }


void IZ_HandlePortMIDIEvents(IZ_App* app) {
void IZ_AppHandlePortMIDIEvents(IZ_App* app) {
u8 player_index; u8 player_index;
i32* midi_events_count; i32* midi_events_count;
u32 midi_event_index; u32 midi_event_index;
@@ -66,7 +66,7 @@ void IZ_HandlePortMIDIEvents(IZ_App* app) {
} }


for (midi_event_index = 0; midi_event_index < *midi_events_count; midi_event_index += 1) { for (midi_event_index = 0; midi_event_index < *midi_events_count; midi_event_index += 1) {
IZ_HandlePortMIDIInputEvents(
IZ_InputHandlePortMIDIEvents(
app->input_state.midi_input_state[player_index].event_buffer[midi_event_index], app->input_state.midi_input_state[player_index].event_buffer[midi_event_index],
&app->input_state &app->input_state
); );
@@ -74,12 +74,12 @@ void IZ_HandlePortMIDIEvents(IZ_App* app) {
} }
} }


void IZ_HandleEvents(IZ_App* app) {
IZ_HandleSDLEvents(app);
IZ_HandlePortMIDIEvents(app);
void IZ_AppHandleEvents(IZ_App* app) {
IZ_AppHandleSDLEvents(app);
IZ_AppHandlePortMIDIEvents(app);
} }


IZ_ProcedureResult IZ_RunApp(IZ_App* app, u8 arg_count, char* arg_values[]) {
IZ_ProcedureResult IZ_AppRun(IZ_App* app, u8 arg_count, char* arg_values[]) {
printf_s("Args (%u):\n", arg_count); printf_s("Args (%u):\n", arg_count);
u8 arg_index; u8 arg_index;
for (arg_index = 0; arg_index < arg_count; arg_index += 1) { for (arg_index = 0; arg_index < arg_count; arg_index += 1) {
@@ -87,7 +87,7 @@ IZ_ProcedureResult IZ_RunApp(IZ_App* app, u8 arg_count, char* arg_values[]) {
} }




IZ_ProcedureResult init_result = IZ_InitializeApp(app);
IZ_ProcedureResult init_result = IZ_AppInitialize(app);
if (init_result) { if (init_result) {
return init_result; return init_result;
} }
@@ -98,14 +98,14 @@ IZ_ProcedureResult IZ_RunApp(IZ_App* app, u8 arg_count, char* arg_values[]) {
// TODO do audio processing // TODO do audio processing
// TODO do networking? // TODO do networking?


IZ_HandleEvents(app);
IZ_AppHandleEvents(app);
if (app->quit) { if (app->quit) {
break; break;
} }


IZ_UpdateVideo(&app->video_state, &app->input_state, app->ticks);
IZ_VideoUpdate(&app->video_state, &app->input_state, app->ticks);
} }


IZ_TeardownApp(app);
IZ_AppTeardown(app);
return 0; return 0;
} }

+ 1
- 1
src/packages/game/IZ_app.h View File

@@ -23,6 +23,6 @@ typedef struct {
bool quit; bool quit;
} IZ_App; } IZ_App;


IZ_ProcedureResult IZ_RunApp(IZ_App*, u8, char**);
IZ_ProcedureResult IZ_AppRun(IZ_App*, u8, char**);


#endif #endif

+ 1
- 1
src/packages/game/IZ_config.c View File

@@ -1,6 +1,6 @@
#include "IZ_config.h" #include "IZ_config.h"


void IZ_GetConfigPath(char* config_path, size_t string_size) {
void IZ_ConfigGetPath(char* config_path, size_t string_size) {
//const char* config_path_dir = SDL_GetPrefPath("Modal Studios", APP_NAME); //const char* config_path_dir = SDL_GetPrefPath("Modal Studios", APP_NAME);
const char* config_path_dir = SDL_GetBasePath(); const char* config_path_dir = SDL_GetBasePath();
memcpy_s(config_path, string_size, config_path_dir, 128); memcpy_s(config_path, string_size, config_path_dir, 128);


+ 1
- 1
src/packages/game/IZ_config.h View File

@@ -4,6 +4,6 @@
#include <SDL_filesystem.h> #include <SDL_filesystem.h>
#include <string.h> #include <string.h>


void IZ_GetConfigPath(char*, size_t);
void IZ_ConfigGetPath(char*, size_t);


#endif #endif

+ 2
- 2
src/packages/game/geometry/IZ_rect.c View File

@@ -9,7 +9,7 @@ IZ_Bounds IZ_RectGetBounds(IZ_Rect rect) {
}; };
} }


bool IZ_BoundsContainPoint(IZ_Bounds bounds, IZ_Point2D point) {
bool IZ_RectBoundsContainPoint(IZ_Bounds bounds, IZ_Point2D point) {
return ( return (
bounds.left <= point.x bounds.left <= point.x
&& bounds.top <= point.y && bounds.top <= point.y
@@ -18,7 +18,7 @@ bool IZ_BoundsContainPoint(IZ_Bounds bounds, IZ_Point2D point) {
); );
} }


bool IZ_BoundsCollide(IZ_Bounds a, IZ_Bounds b) {
bool IZ_RectBoundsCollide(IZ_Bounds a, IZ_Bounds b) {
return ( return (
b.left < a.right b.left < a.right
&& b.top < a.bottom && b.top < a.bottom


+ 2
- 2
src/packages/game/geometry/IZ_rect.h View File

@@ -20,8 +20,8 @@ typedef struct {


IZ_Bounds IZ_RectGetBounds(IZ_Rect); IZ_Bounds IZ_RectGetBounds(IZ_Rect);


bool IZ_BoundsContainPoint(IZ_Bounds, IZ_Point2D);
bool IZ_RectBoundsContainPoint(IZ_Bounds, IZ_Point2D);


bool IZ_BoundsCollide(IZ_Bounds, IZ_Bounds);
bool IZ_RectBoundsCollide(IZ_Bounds, IZ_Bounds);


#endif #endif

+ 10
- 10
src/packages/game/geometry/geometry.test.c View File

@@ -76,7 +76,7 @@ spec("geometry") {
check(expected_product.up == actual_product.up, "Up values do not match."); check(expected_product.up == actual_product.up, "Up values do not match.");
} }
} }
describe("VectorScale") { describe("VectorScale") {
it("scales a vector") { it("scales a vector") {
static IZ_Vector2D v = { static IZ_Vector2D v = {
@@ -129,7 +129,7 @@ spec("geometry") {
} }
} }


describe("BoundsContainPoint") {
describe("RectBoundsContainPoint") {
it("returns true for points inside bounds") { it("returns true for points inside bounds") {
static IZ_Bounds b = { static IZ_Bounds b = {
.left = 50, .left = 50,
@@ -143,7 +143,7 @@ spec("geometry") {
.y = 150, .y = 150,
}; };


check(IZ_BoundsContainPoint(b, p), "Point not found inside bounds.");
check(IZ_RectBoundsContainPoint(b, p), "Point not found inside bounds.");
} }


it("returns true for points along bounds edge") { it("returns true for points along bounds edge") {
@@ -164,8 +164,8 @@ spec("geometry") {
.y = 300, .y = 300,
}; };


check(IZ_BoundsContainPoint(b, p1), "Point p1 not found inside bounds.");
check(IZ_BoundsContainPoint(b, p2), "Point p2 not found inside bounds.");
check(IZ_RectBoundsContainPoint(b, p1), "Point p1 not found inside bounds.");
check(IZ_RectBoundsContainPoint(b, p2), "Point p2 not found inside bounds.");
} }


it("returns false for points outside bounds") { it("returns false for points outside bounds") {
@@ -181,11 +181,11 @@ spec("geometry") {
.y = 0, .y = 0,
}; };


check(!IZ_BoundsContainPoint(b, p), "Point found inside bounds.");
check(!IZ_RectBoundsContainPoint(b, p), "Point found inside bounds.");
} }
} }


describe("BoundsCollide") {
describe("RectBoundsCollide") {
it("returns true for bounds A inside bounds B") { it("returns true for bounds A inside bounds B") {
static IZ_Bounds a = { static IZ_Bounds a = {
.left = 100, .left = 100,
@@ -201,7 +201,7 @@ spec("geometry") {
.bottom = 250, .bottom = 250,
}; };


check(IZ_BoundsCollide(a, b), "Bounds not colliding.");
check(IZ_RectBoundsCollide(a, b), "Bounds not colliding.");
} }


it("returns true for bounds A intersecting bounds B") { it("returns true for bounds A intersecting bounds B") {
@@ -219,7 +219,7 @@ spec("geometry") {
.bottom = 250, .bottom = 250,
}; };


check(IZ_BoundsCollide(a, b), "Bounds not colliding.");
check(IZ_RectBoundsCollide(a, b), "Bounds not colliding.");
} }


it("returns true for bounds A outside bounds B") { it("returns true for bounds A outside bounds B") {
@@ -237,7 +237,7 @@ spec("geometry") {
.bottom = 850, .bottom = 850,
}; };


check(!IZ_BoundsCollide(a, b), "Bounds colliding.");
check(!IZ_RectBoundsCollide(a, b), "Bounds colliding.");
} }
} }
} }


+ 18
- 13
src/packages/game/input/IZ_input.c View File

@@ -1,28 +1,33 @@
#include "IZ_input.h" #include "IZ_input.h"


void IZ_HandleSDLInputEvents(SDL_Event e, IZ_InputState* state) {
IZ_HandleJoystickEvents(e, &state->joystick_state, &state->action);
IZ_HandleKeyboardEvents(e, &state->keyboard_state, &state->action);
void IZ_InputHandleSDLEvents(SDL_Event e, IZ_InputState* state) {
IZ_JoystickHandleEvents(e, &state->joystick_state, &state->action);
IZ_KeyboardHandleEvents(e, &state->keyboard_state, &state->action);
} }


void IZ_HandlePortMIDIInputEvents(PmEvent e, IZ_InputState* state) {
IZ_HandleMIDIInputEvents(e, &state->midi_input_state, &state->action);
void IZ_InputHandlePortMIDIEvents(PmEvent e, IZ_InputState* state) {
IZ_MIDIInputHandleEvents(e, &state->midi_input_state, &state->action);
} }


void IZ_InitializeInput(const char* config_path, IZ_InputState* state) {
*state = (IZ_InputState) {};
void IZ_InputInitialize(const char* config_path, IZ_InputState* state) {
*state = (IZ_InputState) {
.action = {},
.joystick_state = {},
.midi_input_state = {},
.keyboard_state = {},
};


IZ_ProcedureResult joystick_result = IZ_InitializeJoystickState(config_path, &state->joystick_state);
IZ_ProcedureResult joystick_result = IZ_JoystickInitialize(config_path, &state->joystick_state);
if (joystick_result) { if (joystick_result) {
fprintf_s(stderr, "Error committing joystick config. Code: %u.\n", joystick_result); fprintf_s(stderr, "Error committing joystick config. Code: %u.\n", joystick_result);
} }


IZ_ProcedureResult keyboard_result = IZ_InitializeKeyboardState(config_path, &state->keyboard_state);
IZ_ProcedureResult keyboard_result = IZ_KeyboardInitialize(config_path, &state->keyboard_state);
if (keyboard_result) { if (keyboard_result) {
fprintf_s(stderr, "Error committing keyboard config. Code: %u.\n", keyboard_result); fprintf_s(stderr, "Error committing keyboard config. Code: %u.\n", keyboard_result);
} }


IZ_ProcedureResult midi_input_result = IZ_InitializeMIDIInput(config_path, &state->midi_input_state);
IZ_ProcedureResult midi_input_result = IZ_MIDIInputInitialize(config_path, &state->midi_input_state);
if (midi_input_result) { if (midi_input_result) {
fprintf_s(stderr, "Error committing MIDI input config. Code: %u.\n", midi_input_result); fprintf_s(stderr, "Error committing MIDI input config. Code: %u.\n", midi_input_result);
} }
@@ -33,7 +38,7 @@ void IZ_InitializeInput(const char* config_path, IZ_InputState* state) {
} }
} }


void IZ_TeardownInput(IZ_InputState* state) {
IZ_TeardownJoystickState(&state->joystick_state);
IZ_TeardownMIDIInput(&state->midi_input_state);
void IZ_InputTeardown(IZ_InputState* state) {
IZ_JoystickTeardown(&state->joystick_state);
IZ_MIDIInputTeardown(&state->midi_input_state);
} }

+ 4
- 4
src/packages/game/input/IZ_input.h View File

@@ -13,12 +13,12 @@ typedef struct {
IZ_MIDIInputState midi_input_state[PLAYERS]; IZ_MIDIInputState midi_input_state[PLAYERS];
} IZ_InputState; } IZ_InputState;


void IZ_HandleSDLInputEvents(SDL_Event, IZ_InputState*);
void IZ_InputHandleSDLEvents(SDL_Event, IZ_InputState*);


void IZ_HandlePortMIDIInputEvents(PmEvent, IZ_InputState*);
void IZ_InputHandlePortMIDIEvents(PmEvent, IZ_InputState*);


void IZ_InitializeInput(const char*, IZ_InputState*);
void IZ_InputInitialize(const char*, IZ_InputState*);


void IZ_TeardownInput(IZ_InputState*);
void IZ_InputTeardown(IZ_InputState*);


#endif #endif

+ 24
- 24
src/packages/game/input/IZ_joystick.c View File

@@ -1,6 +1,6 @@
#include "IZ_joystick.h" #include "IZ_joystick.h"


void IZ_HandleJoystickDeviceEvents(SDL_Event e, IZ_JoystickState* state) {
void IZ_JoystickHandleDeviceEvents(SDL_Event e, IZ_JoystickState* state) {
if (e.type == SDL_JOYDEVICEADDED) { if (e.type == SDL_JOYDEVICEADDED) {
if (SDL_NumJoysticks() <= PLAYERS && !state->device) { if (SDL_NumJoysticks() <= PLAYERS && !state->device) {
state->device = SDL_JoystickOpen(e.jdevice.which); state->device = SDL_JoystickOpen(e.jdevice.which);
@@ -18,7 +18,7 @@ void IZ_HandleJoystickDeviceEvents(SDL_Event e, IZ_JoystickState* state) {
} }
} }


void IZ_HandleJoystickAxisEvents(SDL_Event e, IZ_JoystickState* state, IZ_Action* action) {
void IZ_JoystickHandleAxisEvents(SDL_Event e, IZ_JoystickState* state, IZ_Action* action) {
if (e.type == SDL_JOYAXISMOTION) { if (e.type == SDL_JOYAXISMOTION) {
if ( if (
e.jaxis.axis == IZ_JOY_AXIS_DIRECTION_HORIZONTAL1 e.jaxis.axis == IZ_JOY_AXIS_DIRECTION_HORIZONTAL1
@@ -52,7 +52,7 @@ void IZ_HandleJoystickAxisEvents(SDL_Event e, IZ_JoystickState* state, IZ_Action
} }
} }


void IZ_HandleJoystickHatEvents(SDL_Event e, IZ_Action* action) {
void IZ_JoystickHandleHatEvents(SDL_Event e, IZ_Action* action) {
if (e.type == SDL_JOYHATMOTION) { if (e.type == SDL_JOYHATMOTION) {
*action &= ~(0x1 << IZ_ACTION_INDEX_UP); *action &= ~(0x1 << IZ_ACTION_INDEX_UP);
*action &= ~(0x1 << IZ_ACTION_INDEX_RIGHT); *action &= ~(0x1 << IZ_ACTION_INDEX_RIGHT);
@@ -64,7 +64,7 @@ void IZ_HandleJoystickHatEvents(SDL_Event e, IZ_Action* action) {
} }
} }


void IZ_HandleJoystickButtonEvents(SDL_Event e, IZ_JoystickState* state, IZ_Action* action) {
void IZ_JoystickHandleButtonEvents(SDL_Event e, IZ_JoystickState* state, IZ_Action* action) {
u8 control_index; u8 control_index;
for (control_index = 4; control_index < CONTROLS; control_index += 1) { for (control_index = 4; control_index < CONTROLS; control_index += 1) {
if (e.jbutton.button == state->config.control_mapping[control_index]) { if (e.jbutton.button == state->config.control_mapping[control_index]) {
@@ -83,17 +83,17 @@ void IZ_HandleJoystickButtonEvents(SDL_Event e, IZ_JoystickState* state, IZ_Acti
} }
} }


void IZ_HandleJoystickEvents(SDL_Event e, IZ_JoystickState(* state)[PLAYERS], IZ_Action(* action)[PLAYERS]) {
void IZ_JoystickHandleEvents(SDL_Event e, IZ_JoystickState(* state)[PLAYERS], IZ_Action(* action)[PLAYERS]) {
u8 player_index; u8 player_index;
for (player_index = 0; player_index < PLAYERS; player_index += 1) { for (player_index = 0; player_index < PLAYERS; player_index += 1) {
IZ_HandleJoystickDeviceEvents(e, state[player_index]);
IZ_HandleJoystickAxisEvents(e, state[player_index], action[player_index]);
IZ_HandleJoystickHatEvents(e, action[player_index]);
IZ_HandleJoystickButtonEvents(e, state[player_index], action[player_index]);
IZ_JoystickHandleDeviceEvents(e, &(*state)[player_index]);
IZ_JoystickHandleAxisEvents(e, &(*state)[player_index], &(*action)[player_index]);
IZ_JoystickHandleHatEvents(e, &(*action)[player_index]);
IZ_JoystickHandleButtonEvents(e, &(*state)[player_index], &(*action)[player_index]);
} }
} }


void IZ_LoadJoystickConfig(const char* config_path, IZ_JoystickState(* state)[PLAYERS]) {
void IZ_JoystickLoadConfig(const char* config_path, IZ_JoystickState(* state)[PLAYERS]) {
char control_mapping_section_name[26]; char control_mapping_section_name[26];
char main_section_name[11]; char main_section_name[11];


@@ -103,7 +103,7 @@ void IZ_LoadJoystickConfig(const char* config_path, IZ_JoystickState(* state)[PL
sprintf_s(control_mapping_section_name, 26, "Joystick.%d.ControlMapping", player_index); sprintf_s(control_mapping_section_name, 26, "Joystick.%d.ControlMapping", player_index);


for (control_index = 4; control_index < CONTROLS; control_index += 1) { for (control_index = 4; control_index < CONTROLS; control_index += 1) {
state[player_index]->config.control_mapping[control_index] = ini_getl(
(*state)[player_index].config.control_mapping[control_index] = ini_getl(
control_mapping_section_name, control_mapping_section_name,
ACTION_NAMES[control_index], ACTION_NAMES[control_index],
IZ_DEFAULT_JOYSTICK_STATE[player_index].config.control_mapping[control_index], IZ_DEFAULT_JOYSTICK_STATE[player_index].config.control_mapping[control_index],
@@ -112,12 +112,12 @@ void IZ_LoadJoystickConfig(const char* config_path, IZ_JoystickState(* state)[PL
} }


sprintf_s(main_section_name, 11, "Joystick.%d", player_index); sprintf_s(main_section_name, 11, "Joystick.%d", player_index);
state[player_index]->config.axis_threshold = ini_getl(main_section_name, "AxisThreshold", IZ_DEFAULT_AXIS_THRESHOLD, config_path);
state[player_index]->config.device_id = ini_getl(main_section_name, "DeviceID", player_index, config_path);
(*state)[player_index].config.axis_threshold = ini_getl(main_section_name, "AxisThreshold", IZ_DEFAULT_AXIS_THRESHOLD, config_path);
(*state)[player_index].config.device_id = ini_getl(main_section_name, "DeviceID", player_index, config_path);
} }
} }


IZ_ProcedureResult IZ_SaveJoystickConfig(const char* config_path, IZ_JoystickState(* state)[PLAYERS]) {
IZ_ProcedureResult IZ_JoystickSaveConfig(const char* config_path, IZ_JoystickState(* state)[PLAYERS]) {
u8 problem = 0; u8 problem = 0;


char control_mapping_section_name[26]; char control_mapping_section_name[26];
@@ -131,7 +131,7 @@ IZ_ProcedureResult IZ_SaveJoystickConfig(const char* config_path, IZ_JoystickSta
if (!ini_putl( if (!ini_putl(
control_mapping_section_name, control_mapping_section_name,
ACTION_NAMES[control_index], ACTION_NAMES[control_index],
state[player_index]->config.control_mapping[control_index],
(*state)[player_index].config.control_mapping[control_index],
config_path config_path
)) { )) {
return 1; return 1;
@@ -142,7 +142,7 @@ IZ_ProcedureResult IZ_SaveJoystickConfig(const char* config_path, IZ_JoystickSta
if (!ini_putl( if (!ini_putl(
main_section_name, main_section_name,
"DeviceID", "DeviceID",
state[player_index]->config.device_id,
(*state)[player_index].config.device_id,
config_path config_path
)) { )) {
problem |= (1 << player_index); problem |= (1 << player_index);
@@ -151,7 +151,7 @@ IZ_ProcedureResult IZ_SaveJoystickConfig(const char* config_path, IZ_JoystickSta
if (!ini_putl( if (!ini_putl(
main_section_name, main_section_name,
"AxisThreshold", "AxisThreshold",
state[player_index]->config.axis_threshold,
(*state)[player_index].config.axis_threshold,
config_path config_path
)) { )) {
problem |= (1 << player_index); problem |= (1 << player_index);
@@ -161,29 +161,29 @@ IZ_ProcedureResult IZ_SaveJoystickConfig(const char* config_path, IZ_JoystickSta
return problem; return problem;
} }


IZ_ProcedureResult IZ_InitializeJoystickState(const char* config_path, IZ_JoystickState(* state)[PLAYERS]) {
IZ_ProcedureResult IZ_JoystickInitialize(const char* config_path, IZ_JoystickState(* state)[PLAYERS]) {
SDL_memcpy(state, &IZ_DEFAULT_JOYSTICK_STATE, sizeof(IZ_JoystickState)); SDL_memcpy(state, &IZ_DEFAULT_JOYSTICK_STATE, sizeof(IZ_JoystickState));


IZ_LoadJoystickConfig(config_path, state);
if (IZ_SaveJoystickConfig(config_path, state)) {
IZ_JoystickLoadConfig(config_path, state);
if (IZ_JoystickSaveConfig(config_path, state)) {
return 1; return 1;
} }


u8 joysticks_count = SDL_NumJoysticks(); u8 joysticks_count = SDL_NumJoysticks();
u8 player_index; u8 player_index;
for (player_index = 0; player_index < joysticks_count; player_index += 1) { for (player_index = 0; player_index < joysticks_count; player_index += 1) {
state[player_index]->device = SDL_JoystickOpen(state[player_index]->config.device_id);
(*state)[player_index].device = SDL_JoystickOpen(state[player_index]->config.device_id);
} }


return 0; return 0;
} }


void IZ_TeardownJoystickState(IZ_JoystickState(* state)[PLAYERS]) {
void IZ_JoystickTeardown(IZ_JoystickState(* state)[PLAYERS]) {
u8 player_index; u8 player_index;
for (player_index = 0; player_index < PLAYERS; player_index += 1) { for (player_index = 0; player_index < PLAYERS; player_index += 1) {
if (!state[player_index]->device) {
if (!(*state)[player_index].device) {
continue; continue;
} }
SDL_JoystickClose(state[player_index]->device);
SDL_JoystickClose((*state)[player_index].device);
} }
} }

+ 30
- 4
src/packages/game/input/IZ_joystick.h View File

@@ -53,15 +53,41 @@ static const IZ_JoystickState IZ_DEFAULT_JOYSTICK_STATE[PLAYERS] = {
.axis_threshold = 8000u, .axis_threshold = 8000u,
.device_id = 0, .device_id = 0,
}, },
.device = NULL,
},
{
.config = {
.control_mapping = {
255,
255,
255,
255,
11,
10,
1,
0,
4,
3,
6,
7,
8,
9,
13,
14,
},
.axis_threshold = 8000u,
.device_id = 1,
},
.device = NULL,
}, },
}; };


IZ_ProcedureResult IZ_SaveJoystickConfig(const char*, IZ_JoystickState(*)[PLAYERS]);
IZ_ProcedureResult IZ_JoystickSaveConfig(const char*, IZ_JoystickState(*)[PLAYERS]);


void IZ_HandleJoystickEvents(SDL_Event, IZ_JoystickState(*)[PLAYERS], IZ_Action(*)[PLAYERS]);
void IZ_JoystickHandleEvents(SDL_Event, IZ_JoystickState(*)[PLAYERS], IZ_Action(*)[PLAYERS]);


IZ_ProcedureResult IZ_InitializeJoystickState(const char*, IZ_JoystickState(*)[PLAYERS]);
IZ_ProcedureResult IZ_JoystickInitialize(const char*, IZ_JoystickState(*)[PLAYERS]);


void IZ_TeardownJoystickState(IZ_JoystickState(*)[PLAYERS]);
void IZ_JoystickTeardown(IZ_JoystickState(*)[PLAYERS]);


#endif #endif

+ 10
- 10
src/packages/game/input/IZ_keyboard.c View File

@@ -1,6 +1,6 @@
#include "IZ_keyboard.h" #include "IZ_keyboard.h"


void IZ_HandleKewyboardKeyUpDownEvents(SDL_Event e, IZ_KeyboardState* state, IZ_Action* action) {
void IZ_KeyboardHandleKeyUpDownEvents(SDL_Event e, IZ_KeyboardState* state, IZ_Action* action) {
u8 control_index; u8 control_index;
for (control_index = 0; control_index < CONTROLS; control_index += 1) { for (control_index = 0; control_index < CONTROLS; control_index += 1) {
if (e.key.keysym.sym == state->config.control_mapping[control_index]) { if (e.key.keysym.sym == state->config.control_mapping[control_index]) {
@@ -17,13 +17,13 @@ void IZ_HandleKewyboardKeyUpDownEvents(SDL_Event e, IZ_KeyboardState* state, IZ_
} }
} }


void IZ_HandleKeyboardEvents(SDL_Event e, IZ_KeyboardState(* state)[PLAYERS], IZ_Action(* action)[PLAYERS]) {
void IZ_KeyboardHandleEvents(SDL_Event e, IZ_KeyboardState(* state)[PLAYERS], IZ_Action(* action)[PLAYERS]) {
for (u8 player_index = 0; player_index < PLAYERS; player_index += 1) { for (u8 player_index = 0; player_index < PLAYERS; player_index += 1) {
IZ_HandleKewyboardKeyUpDownEvents(e, state[player_index], action[player_index]);
IZ_KeyboardHandleKeyUpDownEvents(e, &(*state)[player_index], &(*action)[player_index]);
} }
} }


IZ_ProcedureResult IZ_SaveKeyboardConfig(const char* config_path, IZ_KeyboardState(* state)[PLAYERS]) {
IZ_ProcedureResult IZ_KeyboardSaveConfig(const char* config_path, IZ_KeyboardState(* state)[PLAYERS]) {
u8 problem = 0; u8 problem = 0;
char control_mapping_section_name[26]; char control_mapping_section_name[26];


@@ -35,7 +35,7 @@ IZ_ProcedureResult IZ_SaveKeyboardConfig(const char* config_path, IZ_KeyboardSta
if (!ini_puts( if (!ini_puts(
control_mapping_section_name, control_mapping_section_name,
ACTION_NAMES[control_index], ACTION_NAMES[control_index],
SDL_GetKeyName(state[player_index]->config.control_mapping[control_index]),
SDL_GetKeyName((*state)[player_index].config.control_mapping[control_index]),
config_path config_path
)) { )) {
problem |= (1 << player_index); problem |= (1 << player_index);
@@ -46,7 +46,7 @@ IZ_ProcedureResult IZ_SaveKeyboardConfig(const char* config_path, IZ_KeyboardSta
return problem; return problem;
} }


void IZ_LoadKeyboardConfig(const char* config_path, IZ_KeyboardState(* state)[PLAYERS]) {
void IZ_KeyboardLoadConfig(const char* config_path, IZ_KeyboardState(* state)[PLAYERS]) {
char buffer[128]; char buffer[128];
char keyboard_section_name[26]; char keyboard_section_name[26];


@@ -64,13 +64,13 @@ void IZ_LoadKeyboardConfig(const char* config_path, IZ_KeyboardState(* state)[PL
config_path config_path
); );


state[player_index]->config.control_mapping[control_index] = SDL_GetKeyFromName(buffer);
(*state)[player_index].config.control_mapping[control_index] = SDL_GetKeyFromName(buffer);
} }
} }
} }


IZ_ProcedureResult IZ_InitializeKeyboardState(const char* config_path, IZ_KeyboardState(* state)[PLAYERS]) {
IZ_ProcedureResult IZ_KeyboardInitialize(const char* config_path, IZ_KeyboardState(* state)[PLAYERS]) {
SDL_memcpy(state, &IZ_DEFAULT_KEYBOARD_STATE, sizeof(IZ_KeyboardState)); SDL_memcpy(state, &IZ_DEFAULT_KEYBOARD_STATE, sizeof(IZ_KeyboardState));
IZ_LoadKeyboardConfig(config_path, state);
return IZ_SaveKeyboardConfig(config_path, state);
IZ_KeyboardLoadConfig(config_path, state);
return IZ_KeyboardSaveConfig(config_path, state);
} }

+ 25
- 3
src/packages/game/input/IZ_keyboard.h View File

@@ -38,12 +38,34 @@ static const IZ_KeyboardState IZ_DEFAULT_KEYBOARD_STATE[PLAYERS] = {
}, },
}, },
}, },
{
.config = {
.control_mapping = {
SDLK_KP_8,
SDLK_KP_6,
SDLK_KP_5,
SDLK_KP_4,
SDLK_KP_ENTER, // yes
SDLK_KP_MINUS, // no
SDLK_j, // action0
SDLK_k, // action1
SDLK_l, // action2
SDLK_SEMICOLON, // action3
SDLK_m, // action4
SDLK_COMMA, // action5
SDLK_PERIOD, // action6
SDLK_SLASH, // action7
SDLK_i, // action8
SDLK_o, // action9
},
},
},
}; };


IZ_ProcedureResult IZ_SaveKeyboardConfig(const char*, IZ_KeyboardState(*)[PLAYERS]);
IZ_ProcedureResult IZ_KeyboardSaveConfig(const char*, IZ_KeyboardState(*)[PLAYERS]);


void IZ_HandleKeyboardEvents(SDL_Event, IZ_KeyboardState(*)[PLAYERS], IZ_Action(*)[PLAYERS]);
void IZ_KeyboardHandleEvents(SDL_Event, IZ_KeyboardState(*)[PLAYERS], IZ_Action(*)[PLAYERS]);


IZ_ProcedureResult IZ_InitializeKeyboardState(const char*, IZ_KeyboardState(*)[PLAYERS]);
IZ_ProcedureResult IZ_KeyboardInitialize(const char*, IZ_KeyboardState(*)[PLAYERS]);


#endif #endif

+ 24
- 24
src/packages/game/input/IZ_midi.c View File

@@ -1,6 +1,6 @@
#include "IZ_midi.h" #include "IZ_midi.h"


char* IZ_GetMIDINoteName(u8 midi_note) {
char* IZ_MIDIGetNoteName(u8 midi_note) {
static const char* pitch_names[] = { static const char* pitch_names[] = {
"C", "C",
"C#", "C#",
@@ -23,7 +23,7 @@ char* IZ_GetMIDINoteName(u8 midi_note) {
return note_name; return note_name;
} }


u8 IZ_GetMIDINoteFromName(char* name) {
u8 IZ_MIDIGetNoteFromName(char* name) {
char name_copy[4]; char name_copy[4];
memcpy_s(name_copy, 4, name, 4); memcpy_s(name_copy, 4, name, 4);
_strlwr_s(name_copy, 4); _strlwr_s(name_copy, 4);
@@ -61,7 +61,7 @@ u8 IZ_GetMIDINoteFromName(char* name) {
return (octave * 12) + pitch_class; return (octave * 12) + pitch_class;
} }


void IZ_HandleMIDINoteOnOffEvents(PmEvent e, IZ_MIDIInputState* state, IZ_Action* action) {
void IZ_MIDIInputHandleNoteOnOffEvents(PmEvent e, IZ_MIDIInputState* state, IZ_Action* action) {
u32 message = e.message; u32 message = e.message;
u8 status = message & 0xF0u; u8 status = message & 0xF0u;
u8 channel = message & 0x0Fu; u8 channel = message & 0x0Fu;
@@ -90,14 +90,14 @@ void IZ_HandleMIDINoteOnOffEvents(PmEvent e, IZ_MIDIInputState* state, IZ_Action
} }
} }


void IZ_HandleMIDIInputEvents(PmEvent e, IZ_MIDIInputState(* state)[PLAYERS], IZ_Action(* action)[PLAYERS]) {
void IZ_MIDIInputHandleEvents(PmEvent e, IZ_MIDIInputState(* state)[PLAYERS], IZ_Action(* action)[PLAYERS]) {
u8 player_index; u8 player_index;
for (player_index = 0; player_index < PLAYERS; player_index += 1) { for (player_index = 0; player_index < PLAYERS; player_index += 1) {
IZ_HandleMIDINoteOnOffEvents(e, state[player_index], action[player_index]);
IZ_MIDIInputHandleNoteOnOffEvents(e, &(*state)[player_index], &(*action)[player_index]);
} }
} }


IZ_ProcedureResult IZ_SaveMIDIInputConfig(const char* config_path, IZ_MIDIInputState(* state)[PLAYERS]) {
IZ_ProcedureResult IZ_MIDIInputSaveConfig(const char* config_path, IZ_MIDIInputState(* state)[PLAYERS]) {
u8 problem = 0; u8 problem = 0;


char control_mapping_section_name[27]; char control_mapping_section_name[27];
@@ -111,7 +111,7 @@ IZ_ProcedureResult IZ_SaveMIDIInputConfig(const char* config_path, IZ_MIDIInputS
if (!ini_puts( if (!ini_puts(
control_mapping_section_name, control_mapping_section_name,
ACTION_NAMES[control_index], ACTION_NAMES[control_index],
IZ_GetMIDINoteName(state[player_index]->config.control_mapping[control_index]),
IZ_MIDIGetNoteName((*state)[player_index].config.control_mapping[control_index]),
config_path config_path
)) { )) {
problem |= (1 << player_index); problem |= (1 << player_index);
@@ -122,7 +122,7 @@ IZ_ProcedureResult IZ_SaveMIDIInputConfig(const char* config_path, IZ_MIDIInputS
if (!ini_putl( if (!ini_putl(
main_section_name, main_section_name,
"Channel", "Channel",
state[player_index]->config.channel,
(*state)[player_index].config.channel,
config_path config_path
)) { )) {
problem |= (1 << player_index); problem |= (1 << player_index);
@@ -131,7 +131,7 @@ IZ_ProcedureResult IZ_SaveMIDIInputConfig(const char* config_path, IZ_MIDIInputS
if (!ini_putl( if (!ini_putl(
main_section_name, main_section_name,
"DeviceID", "DeviceID",
state[player_index]->config.device_id,
(*state)[player_index].config.device_id,
config_path config_path
)) { )) {
problem |= (1 << player_index); problem |= (1 << player_index);
@@ -141,7 +141,7 @@ IZ_ProcedureResult IZ_SaveMIDIInputConfig(const char* config_path, IZ_MIDIInputS
return problem; return problem;
} }


void IZ_LoadMIDIInputConfig(const char* config_path, IZ_MIDIInputState(* state)[PLAYERS]) {
void IZ_MIDIInputLoadConfig(const char* config_path, IZ_MIDIInputState(* state)[PLAYERS]) {
char buffer[128]; char buffer[128];
char control_mapping_section_name[27]; char control_mapping_section_name[27];
char main_section_name[12]; char main_section_name[12];
@@ -154,39 +154,39 @@ void IZ_LoadMIDIInputConfig(const char* config_path, IZ_MIDIInputState(* state)[
ini_gets( ini_gets(
control_mapping_section_name, control_mapping_section_name,
ACTION_NAMES[control_index], ACTION_NAMES[control_index],
IZ_GetMIDINoteName(IZ_DEFAULT_MIDI_INPUT_STATE[player_index].config.control_mapping[control_index]),
IZ_MIDIGetNoteName(IZ_DEFAULT_MIDI_INPUT_STATE[player_index].config.control_mapping[control_index]),
buffer, buffer,
128, 128,
config_path config_path
); );


state[player_index]->config.control_mapping[control_index] = IZ_GetMIDINoteFromName(buffer);
(*state)[player_index].config.control_mapping[control_index] = IZ_MIDIGetNoteFromName(buffer);
} }


sprintf_s(main_section_name, 12, "MIDIInput.%d", player_index); sprintf_s(main_section_name, 12, "MIDIInput.%d", player_index);
state[player_index]->config.channel = ini_getl(main_section_name, "Channel", player_index, config_path);
state[player_index]->config.device_id = ini_getl(main_section_name, "DeviceID", player_index, config_path);
(*state)[player_index].config.channel = ini_getl(main_section_name, "Channel", player_index, config_path);
(*state)[player_index].config.device_id = ini_getl(main_section_name, "DeviceID", player_index, config_path);
} }
} }


IZ_ProcedureResult IZ_InitializeMIDIInput(const char* config_path, IZ_MIDIInputState(* state)[PLAYERS]) {
IZ_ProcedureResult IZ_MIDIInputInitialize(const char* config_path, IZ_MIDIInputState(* state)[PLAYERS]) {
if (Pm_Initialize()) { if (Pm_Initialize()) {
return 1; return 1;
} }


SDL_memcpy(state, &IZ_DEFAULT_MIDI_INPUT_STATE, sizeof(IZ_MIDIInputState)); SDL_memcpy(state, &IZ_DEFAULT_MIDI_INPUT_STATE, sizeof(IZ_MIDIInputState));
IZ_LoadMIDIInputConfig(config_path, state);
if (IZ_SaveMIDIInputConfig(config_path, state)) {
IZ_MIDIInputLoadConfig(config_path, state);
if (IZ_MIDIInputSaveConfig(config_path, state)) {
return 2; return 2;
} }


u8 player_index; u8 player_index;
for (player_index = 0; player_index < PLAYERS; player_index += 1) { for (player_index = 0; player_index < PLAYERS; player_index += 1) {
state[player_index]->device_info = Pm_GetDeviceInfo(state[player_index]->config.device_id);
state[player_index]->stream = NULL;
(*state)[player_index].device_info = Pm_GetDeviceInfo((*state)[player_index].config.device_id);
(*state)[player_index].stream = NULL;
Pm_OpenInput( Pm_OpenInput(
&state[player_index]->stream,
state[player_index]->config.device_id,
&(*state)[player_index].stream,
(*state)[player_index].config.device_id,
NULL, NULL,
MIDI_EVENT_BUFFER_SIZE, MIDI_EVENT_BUFFER_SIZE,
NULL, NULL,
@@ -197,12 +197,12 @@ IZ_ProcedureResult IZ_InitializeMIDIInput(const char* config_path, IZ_MIDIInputS
return 0; return 0;
} }


void IZ_TeardownMIDIInput(IZ_MIDIInputState(* state)[PLAYERS]) {
void IZ_MIDIInputTeardown(IZ_MIDIInputState(* state)[PLAYERS]) {
u8 player_index; u8 player_index;
for (player_index = 0; player_index < PLAYERS; player_index += 1) { for (player_index = 0; player_index < PLAYERS; player_index += 1) {
if (!state[player_index]->stream) {
if (!(*state)[player_index].stream) {
continue; continue;
} }
Pm_Close(state[player_index]->stream);
Pm_Close((*state)[player_index].stream);
} }
} }

+ 31
- 4
src/packages/game/input/IZ_midi.h View File

@@ -57,14 +57,41 @@ static const IZ_MIDIInputState IZ_DEFAULT_MIDI_INPUT_STATE[PLAYERS] = {
.stream = NULL, .stream = NULL,
.device_info = NULL, .device_info = NULL,
}, },
{
.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]);
IZ_ProcedureResult IZ_MIDIInputSaveConfig(const char *config_path, IZ_MIDIInputState(*)[PLAYERS]);


void IZ_HandleMIDIInputEvents(PmEvent, IZ_MIDIInputState(*)[PLAYERS], IZ_Action(*)[PLAYERS]);
void IZ_MIDIInputHandleEvents(PmEvent e, IZ_MIDIInputState(*)[PLAYERS], IZ_Action(*)[PLAYERS]);


IZ_ProcedureResult IZ_InitializeMIDIInput(const char*, IZ_MIDIInputState(*)[PLAYERS]);
IZ_ProcedureResult IZ_MIDIInputInitialize(const char *config_path, IZ_MIDIInputState(*)[PLAYERS]);


void IZ_TeardownMIDIInput(IZ_MIDIInputState(*)[PLAYERS]);
void IZ_MIDIInputTeardown(IZ_MIDIInputState(*)[PLAYERS]);


#endif #endif

+ 30
- 30
src/packages/game/input/input.test.c View File

@@ -15,17 +15,17 @@ i16 GenerateAxisValueOutsideThreshold(u16 threshold) {


spec("input") { spec("input") {
describe("joystick") { describe("joystick") {
describe("HandleJoystickEvents") {
describe("JoystickHandleEvents") {
static SDL_Event e; static SDL_Event e;
static IZ_JoystickState state[PLAYERS];
static IZ_Action action[PLAYERS];
static IZ_JoystickState state[PLAYERS] = {};
static IZ_Action action[PLAYERS] = {};


u8 p; u8 p;
for (p = 0; p < PLAYERS; p += 1) { for (p = 0; p < PLAYERS; p += 1) {
describe("on axis motion events") { describe("on axis motion events") {
before_each() { before_each() {
e.type = SDL_JOYAXISMOTION; e.type = SDL_JOYAXISMOTION;
state[0].config.axis_threshold = 8000u;
state[p].config.axis_threshold = 8000u;
} }


describe("on primary horizontal direction") { describe("on primary horizontal direction") {
@@ -38,7 +38,7 @@ spec("input") {
action[p] = 0; action[p] = 0;


printf("(axis value: %d) ", e.jaxis.value); printf("(axis value: %d) ", e.jaxis.value);
IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == (0x1 << IZ_ACTION_INDEX_RIGHT), action[p] == (0x1 << IZ_ACTION_INDEX_RIGHT),
"Action not set." "Action not set."
@@ -50,7 +50,7 @@ spec("input") {
action[p] = 0; action[p] = 0;


printf("(axis value: %d) ", e.jaxis.value); printf("(axis value: %d) ", e.jaxis.value);
IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == (0x1 << IZ_ACTION_INDEX_LEFT), action[p] == (0x1 << IZ_ACTION_INDEX_LEFT),
"Action not set." "Action not set."
@@ -62,7 +62,7 @@ spec("input") {
action[p] = 0; action[p] = 0;


printf("(axis value: %d) ", e.jaxis.value); printf("(axis value: %d) ", e.jaxis.value);
IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == 0, action[p] == 0,
"Action not set." "Action not set."
@@ -80,7 +80,7 @@ spec("input") {
action[p] = 0; action[p] = 0;


printf("(axis value: %d) ", e.jaxis.value); printf("(axis value: %d) ", e.jaxis.value);
IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == (0x1 << IZ_ACTION_INDEX_RIGHT), action[p] == (0x1 << IZ_ACTION_INDEX_RIGHT),
"Action not set." "Action not set."
@@ -92,7 +92,7 @@ spec("input") {
action[p] = 0; action[p] = 0;


printf("(axis value: %d) ", e.jaxis.value); printf("(axis value: %d) ", e.jaxis.value);
IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == (0x1 << IZ_ACTION_INDEX_LEFT), action[p] == (0x1 << IZ_ACTION_INDEX_LEFT),
"Action not set." "Action not set."
@@ -104,7 +104,7 @@ spec("input") {
action[p] = 0; action[p] = 0;


printf("(axis value: %d) ", e.jaxis.value); printf("(axis value: %d) ", e.jaxis.value);
IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == 0, action[p] == 0,
"Action not set." "Action not set."
@@ -122,7 +122,7 @@ spec("input") {
action[p] = 0; action[p] = 0;


printf("(axis value: %d) ", e.jaxis.value); printf("(axis value: %d) ", e.jaxis.value);
IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == (0x1 << IZ_ACTION_INDEX_DOWN), action[p] == (0x1 << IZ_ACTION_INDEX_DOWN),
"Action not set." "Action not set."
@@ -134,7 +134,7 @@ spec("input") {
action[p] = 0; action[p] = 0;


printf("(axis value: %d) ", e.jaxis.value); printf("(axis value: %d) ", e.jaxis.value);
IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == (0x1 << IZ_ACTION_INDEX_UP), action[p] == (0x1 << IZ_ACTION_INDEX_UP),
"Action not set." "Action not set."
@@ -146,7 +146,7 @@ spec("input") {
action[p] = 0; action[p] = 0;


printf("(axis value: %d) ", e.jaxis.value); printf("(axis value: %d) ", e.jaxis.value);
IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == 0, action[p] == 0,
"Action not set." "Action not set."
@@ -164,7 +164,7 @@ spec("input") {
action[p] = 0; action[p] = 0;


printf("(axis value: %d) ", e.jaxis.value); printf("(axis value: %d) ", e.jaxis.value);
IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == (0x1 << IZ_ACTION_INDEX_DOWN), action[p] == (0x1 << IZ_ACTION_INDEX_DOWN),
"Action not set." "Action not set."
@@ -176,7 +176,7 @@ spec("input") {
action[p] = 0; action[p] = 0;


printf("(axis value: %d) ", e.jaxis.value); printf("(axis value: %d) ", e.jaxis.value);
IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == (0x1 << IZ_ACTION_INDEX_UP), action[p] == (0x1 << IZ_ACTION_INDEX_UP),
"Action not set." "Action not set."
@@ -188,7 +188,7 @@ spec("input") {
action[p] = 0; action[p] = 0;


printf("(axis value: %d) ", e.jaxis.value); printf("(axis value: %d) ", e.jaxis.value);
IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == 0, action[p] == 0,
"Action not set." "Action not set."
@@ -207,7 +207,7 @@ spec("input") {
e.jhat.value = (0x1u << i); e.jhat.value = (0x1u << i);
action[p] = 0; action[p] = 0;


IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == (0x1u << i), action[p] == (0x1u << i),
"Action not set." "Action not set."
@@ -218,7 +218,7 @@ spec("input") {
e.jhat.value = 0; e.jhat.value = 0;
action[p] = ~0; action[p] = ~0;


IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
!(action[p] & (0x1 << i)), !(action[p] & (0x1 << i)),
"Action not unset." "Action not unset."
@@ -235,7 +235,7 @@ spec("input") {
state[p].config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_STATE[p].config.control_mapping[i]; state[p].config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_STATE[p].config.control_mapping[i];
action[p] = 0; action[p] = 0;


IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
action[p] == (0x1u << i), action[p] == (0x1u << i),
"Action not set." "Action not set."
@@ -248,7 +248,7 @@ spec("input") {
state[p].config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_STATE[p].config.control_mapping[i]; state[p].config.control_mapping[i] = IZ_DEFAULT_JOYSTICK_STATE[p].config.control_mapping[i];
action[p] = ~0; action[p] = ~0;


IZ_HandleJoystickEvents(e, &state, &action);
IZ_JoystickHandleEvents(e, &state, &action);
check( check(
!(action[p] & (0x1 << i)), !(action[p] & (0x1 << i)),
"Action not unset." "Action not unset."
@@ -259,7 +259,7 @@ spec("input") {
} }
} }


describe("SaveJoystickConfig") {
describe("JoystickSaveConfig") {
static IZ_JoystickState state[PLAYERS]; static IZ_JoystickState state[PLAYERS];


after_each() { after_each() {
@@ -277,7 +277,7 @@ spec("input") {
it("calls save method") { it("calls save method") {
mock_set_expected_calls(ini_putl, ((CONTROLS - 4) + 2) * PLAYERS); mock_set_expected_calls(ini_putl, ((CONTROLS - 4) + 2) * PLAYERS);


IZ_SaveJoystickConfig("config.ini", &state);
IZ_JoystickSaveConfig("config.ini", &state);


check( check(
mock_get_expected_calls(ini_putl) == mock_get_actual_calls(ini_putl), mock_get_expected_calls(ini_putl) == mock_get_actual_calls(ini_putl),
@@ -290,10 +290,10 @@ spec("input") {
} }


describe("keyboard") { describe("keyboard") {
describe("HandleKeyboardEvents") {
describe("KeyboardHandleEvents") {
static SDL_Event e; static SDL_Event e;
static IZ_KeyboardState state[PLAYERS];
static IZ_Action action[PLAYERS];
static IZ_KeyboardState state[PLAYERS] = {};
static IZ_Action action[PLAYERS] = {};


for (u8 p = 0; p < PLAYERS; p += 1) { for (u8 p = 0; p < PLAYERS; p += 1) {
for (u8 i = 0; i < CONTROLS; i += 1) { for (u8 i = 0; i < CONTROLS; i += 1) {
@@ -303,7 +303,7 @@ spec("input") {
state[p].config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_STATE[p].config.control_mapping[i]; state[p].config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_STATE[p].config.control_mapping[i];
action[p] = 0; action[p] = 0;


IZ_HandleKeyboardEvents(e, &state, &action);
IZ_KeyboardHandleEvents(e, &state, &action);
check( check(
action[p] == (0x1 << i), action[p] == (0x1 << i),
"Action not set." "Action not set."
@@ -316,7 +316,7 @@ spec("input") {
state[p].config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_STATE[p].config.control_mapping[i]; state[p].config.control_mapping[i] = IZ_DEFAULT_KEYBOARD_STATE[p].config.control_mapping[i];
action[p] = ~0; action[p] = ~0;


IZ_HandleKeyboardEvents(e, &state, &action);
IZ_KeyboardHandleEvents(e, &state, &action);
check( check(
!(action[p] & (0x1 << i)), !(action[p] & (0x1 << i)),
"Action not unset." "Action not unset."
@@ -326,8 +326,8 @@ spec("input") {
} }
} }


describe("SaveKeyboardConfig") {
static IZ_KeyboardState state[PLAYERS];
describe("KeyboardSaveConfig") {
static IZ_KeyboardState state[PLAYERS] = {};


after_each() { after_each() {
mock_reset(ini_puts); mock_reset(ini_puts);
@@ -344,7 +344,7 @@ spec("input") {
it("calls save method") { it("calls save method") {
mock_set_expected_calls(ini_puts, CONTROLS * PLAYERS); mock_set_expected_calls(ini_puts, CONTROLS * PLAYERS);


IZ_SaveKeyboardConfig("config.ini", &state);
IZ_KeyboardSaveConfig("config.ini", &state);


check( check(
mock_get_expected_calls(ini_puts) == mock_get_actual_calls(ini_puts), mock_get_expected_calls(ini_puts) == mock_get_actual_calls(ini_puts),


+ 1
- 1
src/packages/game/main.c View File

@@ -3,5 +3,5 @@


int main(int arg_count, char* arg_values[]) { int main(int arg_count, char* arg_values[]) {
IZ_App app; IZ_App app;
return IZ_RunApp(&app, arg_count, arg_values);
return IZ_AppRun(&app, arg_count, arg_values);
} }

+ 1
- 1
src/packages/game/memory/IZ_pool.c View File

@@ -1,6 +1,6 @@
#include "IZ_pool.h" #include "IZ_pool.h"


void IZ_InitializePool(IZ_Pool* pool) {
void IZ_PoolInitialize(IZ_Pool* pool) {
SDL_memset(pool->items, 0, POOL_MAX_ITEMS * sizeof(IZ_PoolItem)); SDL_memset(pool->items, 0, POOL_MAX_ITEMS * sizeof(IZ_PoolItem));
pool->top = 0; pool->top = 0;
pool->memory = SDL_malloc(POOL_MAX_SIZE); pool->memory = SDL_malloc(POOL_MAX_SIZE);


+ 1
- 1
src/packages/game/memory/IZ_pool.h View File

@@ -23,7 +23,7 @@ typedef struct IZ_Pool {
void* memory; void* memory;
} IZ_Pool; } IZ_Pool;


void IZ_InitializePool(IZ_Pool*);
void IZ_PoolInitialize(IZ_Pool*);


IZ_PoolItem* IZ_PoolAllocate(IZ_Pool*, size_t, u64); IZ_PoolItem* IZ_PoolAllocate(IZ_Pool*, size_t, u64);




+ 14
- 14
src/packages/game/output/IZ_video.c View File

@@ -1,6 +1,6 @@
#include "IZ_video.h" #include "IZ_video.h"


IZ_ProcedureResult IZ_SaveVideoConfig(const char* config_path, IZ_VideoConfig* config) {
IZ_ProcedureResult IZ_VideoSaveConfig(const char* config_path, IZ_VideoConfig* config) {
if (!ini_putl("Video", "Width", config->width, config_path)) { if (!ini_putl("Video", "Width", config->width, config_path)) {
return 1; return 1;
} }
@@ -14,17 +14,17 @@ IZ_ProcedureResult IZ_SaveVideoConfig(const char* config_path, IZ_VideoConfig* c
return 0; return 0;
} }


void IZ_LoadVideoConfig(const char* config_path, IZ_VideoConfig* config) {
void IZ_VideoLoadConfig(const char* config_path, IZ_VideoConfig* config) {
config->width = ini_getl("Video", "Width", IZ_DEFAULT_VIDEO_STATE.config.width, 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->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); 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) {
IZ_ProcedureResult IZ_VideoInitialize(const char* config_path, IZ_VideoState* state) {
SDL_memcpy(state, &IZ_DEFAULT_VIDEO_STATE, sizeof(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)) {
IZ_VideoLoadConfig(config_path, &state->config);
if (IZ_VideoSaveConfig(config_path, &state->config)) {
fprintf_s(stderr, "Error committing video config.\n"); fprintf_s(stderr, "Error committing video config.\n");
} }
state->last_update_at = 0u; state->last_update_at = 0u;
@@ -47,7 +47,7 @@ IZ_ProcedureResult IZ_InitializeVideo(const char* config_path, IZ_VideoState* st
return 0; return 0;
} }


void IZ_UpdateVideoForDebugTicks(IZ_VideoState* video_state, uint64_t ticks) {
void IZ_VideoUpdateForDebugTicks(IZ_VideoState* video_state, uint64_t ticks) {
SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0xff, 0xff, 0xff); SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0xff, 0xff, 0xff);
u64 the_ticks = ticks; u64 the_ticks = ticks;
u8 column; u8 column;
@@ -71,7 +71,7 @@ void IZ_UpdateVideoForDebugTicks(IZ_VideoState* video_state, uint64_t ticks) {
} }
} }


void IZ_UpdateVideoForDebugInput(IZ_VideoState* video_state, IZ_InputState* input_states) {
void IZ_VideoUpdateForDebugInput(IZ_VideoState* video_state, IZ_InputState* input_state) {
SDL_SetRenderDrawColor(video_state->renderer, 0xff, 0xff, 0x00, 0xff); SDL_SetRenderDrawColor(video_state->renderer, 0xff, 0xff, 0x00, 0xff);
u8 column; u8 column;
u8 row; u8 row;
@@ -80,7 +80,7 @@ void IZ_UpdateVideoForDebugInput(IZ_VideoState* video_state, IZ_InputState* inpu
u8 p; u8 p;
u8 i; u8 i;
for (p = 0; p < PLAYERS; p += 1) { for (p = 0; p < PLAYERS; p += 1) {
IZ_Action the_action = input_states->action[p];
IZ_Action the_action = input_state->action[p];
for (i = 0; i < CONTROLS; i += 1) { for (i = 0; i < CONTROLS; i += 1) {
column = (i % 4) + (p * 4); column = (i % 4) + (p * 4);
row = i / 4; row = i / 4;
@@ -98,22 +98,22 @@ void IZ_UpdateVideoForDebugInput(IZ_VideoState* video_state, IZ_InputState* inpu
} }
} }


void IZ_UpdateVideoForDebug(IZ_VideoState* video_state, IZ_InputState* input_states, uint64_t ticks) {
IZ_UpdateVideoForDebugTicks(video_state, ticks);
IZ_UpdateVideoForDebugInput(video_state, input_states);
void IZ_VideoUpdateForDebug(IZ_VideoState* video_state, IZ_InputState* input_state, u64 ticks) {
IZ_VideoUpdateForDebugTicks(video_state, ticks);
IZ_VideoUpdateForDebugInput(video_state, input_state);
} }


void IZ_UpdateVideo(IZ_VideoState* video_state, IZ_InputState* input_states, uint64_t ticks) {
void IZ_VideoUpdate(IZ_VideoState* video_state, IZ_InputState* input_state, u64 ticks) {
if (ticks - video_state->last_update_at > 1000 / video_state->config.max_fps) { if (ticks - video_state->last_update_at > 1000 / video_state->config.max_fps) {
// Update window // Update window
SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0x00, 0x00, 0xff); SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0x00, 0x00, 0xff);
SDL_RenderClear(video_state->renderer); SDL_RenderClear(video_state->renderer);
IZ_UpdateVideoForDebug(video_state, input_states, ticks);
IZ_VideoUpdateForDebug(video_state, input_state, ticks);
SDL_RenderPresent(video_state->renderer); SDL_RenderPresent(video_state->renderer);
video_state->last_update_at = ticks; video_state->last_update_at = ticks;
} }
} }


void IZ_TeardownVideo(IZ_VideoState* state) {
void IZ_VideoTeardown(IZ_VideoState* state) {
SDL_DestroyWindow(state->window); SDL_DestroyWindow(state->window);
} }

+ 4
- 4
src/packages/game/output/IZ_video.h View File

@@ -35,12 +35,12 @@ static const IZ_VideoState IZ_DEFAULT_VIDEO_STATE = {
.window = NULL, .window = NULL,
}; };


IZ_ProcedureResult IZ_InitializeVideo(const char*, IZ_VideoState*);
IZ_ProcedureResult IZ_VideoInitialize(const char*, IZ_VideoState*);


IZ_ProcedureResult IZ_SaveVideoConfig(const char*, IZ_VideoConfig*);
IZ_ProcedureResult IZ_VideoSaveConfig(const char*, IZ_VideoConfig*);


void IZ_UpdateVideo(IZ_VideoState*, IZ_InputState*, uint64_t);
void IZ_VideoUpdate(IZ_VideoState*, IZ_InputState*, u64);


void IZ_TeardownVideo(IZ_VideoState*);
void IZ_VideoTeardown(IZ_VideoState*);


#endif #endif

+ 1
- 22
src/packages/game/output/output.test.c View File

@@ -3,27 +3,6 @@


spec("output") { spec("output") {
describe("video") { describe("video") {
describe("LoadVideoConfig") {
static IZ_VideoConfig config;

after_each() {
mock_reset(ini_getl);
}

it("calls load method") {
mock_set_expected_calls(ini_getl, 3);

IZ_LoadVideoConfig("config.ini", &config);

check(
mock_get_expected_calls(ini_getl) == mock_get_actual_calls(ini_getl),
"Call count mismatch for ini_getl() (expected %u, received %u).",
mock_get_expected_calls(ini_getl),
mock_get_actual_calls(ini_getl)
);
}
}

describe("SaveVideoConfig") { describe("SaveVideoConfig") {
static IZ_VideoConfig config; static IZ_VideoConfig config;


@@ -40,7 +19,7 @@ spec("output") {
it("calls save method") { it("calls save method") {
mock_set_expected_calls(ini_putl, 3); mock_set_expected_calls(ini_putl, 3);


IZ_SaveVideoConfig("config.ini", &config);
IZ_VideoSaveConfig("config.ini", &config);


check( check(
mock_get_expected_calls(ini_putl) == mock_get_actual_calls(ini_putl), mock_get_expected_calls(ini_putl) == mock_get_actual_calls(ini_putl),


Loading…
Cancel
Save