@@ -1,4 +1,4 @@ | |||
cmake_minimum_required(VERSION 3.20) | |||
cmake_minimum_required(VERSION 3.21) | |||
# Set your project name here | |||
project(izanagi C) | |||
@@ -9,6 +9,7 @@ include_directories( | |||
"${PROJECT_SOURCE_DIR}/dependencies/SDL2/include" | |||
"${PROJECT_SOURCE_DIR}/dependencies/minIni/dev" | |||
"${PROJECT_SOURCE_DIR}/dependencies/bdd-for-c" | |||
"${PROJECT_SOURCE_DIR}/dependencies/portmidi/pm_common" | |||
) | |||
if (WIN32) | |||
@@ -21,20 +22,21 @@ endif () | |||
link_directories( | |||
"${PROJECT_SOURCE_DIR}/dependencies/SDL2/lib/${PROJECT_ARCH}" | |||
"${PROJECT_SOURCE_DIR}/dependencies/portmidi/Release" | |||
) | |||
add_executable( | |||
game | |||
dependencies/minIni/dev/minIni.h | |||
dependencies/minIni/dev/minIni.c | |||
src/packages/game/config/IZ_config.h | |||
src/packages/game/config/IZ_config.c | |||
src/packages/game/output/IZ_video.h | |||
src/packages/game/output/IZ_video.c | |||
src/packages/game/IZ_common.h | |||
src/packages/game/IZ_action.h | |||
src/packages/game/IZ_app.h | |||
src/packages/game/IZ_app.c | |||
src/packages/game/main.c | |||
) | |||
src/packages/game/input/IZ_joystick.c src/packages/game/input/IZ_joystick.h src/packages/game/input/IZ_keyboard.c src/packages/game/input/IZ_keyboard.h src/packages/game/IZ_config.c src/packages/game/IZ_config.h) | |||
target_link_libraries( | |||
game | |||
SDL2main | |||
@@ -43,11 +45,11 @@ target_link_libraries( | |||
add_executable( | |||
game-test | |||
src/packages/game/config/IZ_config.h | |||
src/packages/game/config/IZ_config.c | |||
dependencies/bdd-for-c/bdd-for-c.h | |||
src/packages/game-test/config/IZ_config.c | |||
) | |||
src/packages/game/output/IZ_video.h | |||
src/packages/game/output/IZ_video.c | |||
src/packages/game/output/IZ_config.test.c | |||
src/packages/test/IZ_mock.h) | |||
if (WIN32) | |||
add_custom_command(TARGET game POST_BUILD | |||
@@ -1,2 +1,3 @@ | |||
https://github.com/compuphase/minIni | |||
https://github.com/grassator/bdd-for-c | |||
https://github.com/PortMidi/portmidi |
@@ -1,12 +1,12 @@ | |||
[Video] | |||
Width=640 | |||
Height=480 | |||
[Controls.0.Keyboard] | |||
MaxFps=30 | |||
[Keyboard.0.ControlMapping] | |||
Up=Up | |||
Right=Right | |||
Down=Down | |||
Left=Left | |||
Up=Up | |||
Affirm=Return | |||
Negate=Backspace | |||
Action0=A | |||
@@ -19,3 +19,18 @@ Action6=C | |||
Action7=V | |||
Action8=W | |||
Action9=E | |||
[Joystick.0.ControlMapping] | |||
Affirm=11 | |||
Negate=10 | |||
Action0=1 | |||
Action1=0 | |||
Action2=4 | |||
Action3=3 | |||
Action4=6 | |||
Action5=7 | |||
Action6=8 | |||
Action7=9 | |||
Action8=13 | |||
Action9=14 | |||
[Joystick.0] | |||
AxisThreshold=8000 |
@@ -1,15 +1,19 @@ | |||
#include "IZ_app.h" | |||
int IZ_InitializeApp(IZ_App* app) { | |||
IZ_LoadConfig(&app->config); | |||
IZ_SaveConfig(&app->config); | |||
IZ_LoadVideoConfig(&app->video_config); | |||
IZ_SaveVideoConfig(&app->video_config); | |||
app->video_update_at = 0u; | |||
for (uint8_t p = 0; p < PLAYERS; p += 1) { | |||
app->assigned_joysticks[p] = NULL; | |||
IZ_LoadKeyboardConfig(&app->keyboard_state->config, p); | |||
IZ_SaveKeyboardConfig(&app->keyboard_state->config, p); | |||
IZ_LoadJoystickConfig(&app->joystick_state->config, p); | |||
IZ_SaveJoystickConfig(&app->joystick_state->config, p); | |||
app->actions[p] = 0; | |||
} | |||
app->video_update_at = 0u; | |||
return 0; | |||
} |
@@ -1,17 +1,17 @@ | |||
#ifndef IZ_APP_H | |||
#define IZ_APP_H | |||
#include <SDL_joystick.h> | |||
#include "config/IZ_config.h" | |||
#include "input/IZ_keyboard.h" | |||
#include "input/IZ_joystick.h" | |||
#include "output/IZ_video.h" | |||
#include "IZ_action.h" | |||
typedef struct { | |||
IZ_Config config; | |||
IZ_VideoConfig video_config; | |||
IZ_Action actions[PLAYERS]; | |||
SDL_Joystick* assigned_joysticks[PLAYERS]; | |||
IZ_KeyboardState keyboard_state[PLAYERS]; | |||
IZ_JoystickState joystick_state[PLAYERS]; | |||
uint64_t video_update_at; | |||
} IZ_App; | |||
@@ -8,4 +8,6 @@ | |||
static const char* APP_NAME = "SDL2"; | |||
typedef uint8_t IZ_ProcedureResult; | |||
#endif |
@@ -0,0 +1,8 @@ | |||
#include "IZ_config.h" | |||
void IZ_GetConfigPath(char* config_path) { | |||
//const char* config_path_dir = SDL_GetPrefPath("Modal Studios", APP_NAME); | |||
const char* config_path_dir = SDL_GetBasePath(); | |||
memcpy_s(config_path, 128, config_path_dir, 128); | |||
strcat_s(config_path, 128, "config.ini"); | |||
} |
@@ -0,0 +1,9 @@ | |||
#ifndef IZ_CONFIG_H | |||
#define IZ_CONFIG_H | |||
#include <SDL_filesystem.h> | |||
#include <string.h> | |||
void IZ_GetConfigPath(char* config_path); | |||
#endif |
@@ -1,65 +0,0 @@ | |||
#include "IZ_config.h" | |||
void IZ_GetConfigPath(char* config_path) { | |||
//const char* config_path_dir = SDL_GetPrefPath("Modal Studios", APP_NAME); | |||
const char* config_path_dir = SDL_GetBasePath(); | |||
memcpy_s(config_path, 128, config_path_dir, 128); | |||
strcat_s(config_path, 128, "config.ini"); | |||
} | |||
void IZ_SaveConfig(IZ_Config* config) { | |||
char config_path[128]; | |||
IZ_GetConfigPath(config_path); | |||
FILE* fp; | |||
fopen_s(&fp, config_path, "w"); | |||
fprintf_s(fp, "[Video]\n"); | |||
fprintf_s(fp, "Width=%u\n", config->video.width); | |||
fprintf_s(fp, "Height=%u\n", config->video.height); | |||
fprintf_s(fp, "MaxFps=%u\n", config->video.max_fps); | |||
fprintf_s(fp, "\n"); | |||
fprintf_s(fp, "[Input]\n"); | |||
fprintf_s(fp, "GamepadAxisThreshold=%u\n", config->input.gamepad_axis_threshold); | |||
fprintf_s(fp, "\n"); | |||
for (uint8_t p = 0; p < PLAYERS; p += 1) { | |||
fprintf_s(fp, "[Controls.%u.Keyboard]\n", p); | |||
for (uint8_t i = 0; i < CONTROLS; i += 1) { | |||
fprintf_s(fp, "%s=%s\n", ACTION_NAMES[i], SDL_GetKeyName(config->controls[p].keyboard[i])); | |||
} | |||
fprintf_s(fp, "\n"); | |||
fprintf_s(fp, "[Controls.%u.Joystick]\n", p); | |||
for (uint8_t i = 4; i < CONTROLS; i += 1) { | |||
fprintf_s(fp, "%s=%d\n", ACTION_NAMES[i], config->controls[p].gamepad[i]); | |||
} | |||
} | |||
} | |||
void IZ_LoadConfig(IZ_Config* config) { | |||
char config_path[128]; | |||
IZ_GetConfigPath(config_path); | |||
config->video.width = ini_getl("Video", "Width", 640l, config_path); | |||
config->video.height = ini_getl("Video", "Height", 480l, config_path); | |||
config->video.max_fps = ini_getl("Video", "MaxFps", 30, config_path); | |||
config->input.gamepad_axis_threshold = ini_getl("Input", "GamepadAxisThreshold", 8000, config_path); | |||
char buffer[128]; | |||
char keyboard_section_name[20] = "Controls.0.Keyboard"; | |||
for (uint8_t p = 0; p < PLAYERS; p += 1) { | |||
keyboard_section_name[9] = (char) (48 + p); | |||
for (uint8_t i = 0; i < CONTROLS; i += 1) { | |||
ini_gets(keyboard_section_name, ACTION_NAMES[i], SDL_GetKeyName(IZ_DEFAULT_KEYBOARD_CONTROLS[p][i]), buffer, 128, | |||
config_path); | |||
config->controls[p].keyboard[i] = SDL_GetKeyFromName(buffer); | |||
} | |||
} | |||
char joystick_section_name[20] = "Controls.0.Joystick"; | |||
for (uint8_t p = 0; p < PLAYERS; p += 1) { | |||
joystick_section_name[9] = (char) (48 + p); | |||
for (uint8_t i = 4; i < CONTROLS; i += 1) { | |||
config->controls[p].gamepad[i] = ini_getl(joystick_section_name, ACTION_NAMES[i], IZ_DEFAULT_JOYSTICK_CONTROLS[p][i], config_path); | |||
} | |||
} | |||
} |
@@ -1,86 +0,0 @@ | |||
#ifndef IZ_CONFIG_H | |||
#define IZ_CONFIG_H | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include <SDL_filesystem.h> | |||
#include <SDL_keyboard.h> | |||
#include <minIni.h> | |||
#include "../IZ_common.h" | |||
#include "../IZ_action.h" | |||
typedef struct { | |||
uint16_t width; | |||
uint16_t height; | |||
uint8_t max_fps; | |||
} IZ_VideoConfig; | |||
typedef struct { | |||
uint16_t gamepad_axis_threshold; | |||
} IZ_InputConfig; | |||
typedef SDL_KeyCode IZ_KeyCode; | |||
typedef int IZ_PadButton; | |||
typedef struct { | |||
IZ_KeyCode keyboard[CONTROLS]; | |||
IZ_PadButton gamepad[CONTROLS]; | |||
} IZ_ControlsConfig; | |||
typedef struct { | |||
IZ_VideoConfig video; | |||
IZ_InputConfig input; | |||
IZ_ControlsConfig controls[PLAYERS]; | |||
} IZ_Config; | |||
static const IZ_KeyCode IZ_DEFAULT_KEYBOARD_CONTROLS[PLAYERS][CONTROLS] = { | |||
{ | |||
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 | |||
}, | |||
}; | |||
static const uint8_t IZ_DEFAULT_JOYSTICK_CONTROLS[PLAYERS][CONTROLS] = { | |||
{ | |||
255, | |||
255, | |||
255, | |||
255, | |||
11, | |||
10, | |||
1, | |||
0, | |||
4, | |||
3, | |||
6, | |||
7, | |||
8, | |||
9, | |||
13, | |||
14, | |||
}, | |||
}; | |||
void IZ_GetConfigPath(char* config_path); | |||
void IZ_SaveConfig(IZ_Config* config); | |||
void IZ_LoadConfig(IZ_Config* config); | |||
#endif |
@@ -0,0 +1,103 @@ | |||
#include "IZ_joystick.h" | |||
void IZ_HandleJoystickDeviceEvents(SDL_Event e, IZ_JoystickState* state) { | |||
if (e.type == SDL_JOYDEVICEADDED) { | |||
if (SDL_NumJoysticks() <= PLAYERS && !state->joystick_instance) { | |||
state->joystick_instance = SDL_JoystickOpen(e.jdevice.which); | |||
} | |||
} | |||
if (e.type == SDL_JOYDEVICEREMOVED) { | |||
if ( | |||
state->joystick_instance | |||
&& SDL_JoystickInstanceID(state->joystick_instance) == e.jdevice.which | |||
) { | |||
state->joystick_instance = NULL; | |||
} | |||
} | |||
} | |||
void IZ_HandleJoystickAxisEvents(SDL_Event e, IZ_JoystickState* state, IZ_Action* action) { | |||
if (e.type == SDL_JOYAXISMOTION) { | |||
if (e.jaxis.axis == 0 || e.jaxis.axis == 3) { | |||
*action &= ~(0x1 << IZ_ACTION_INDEX_RIGHT); | |||
*action &= ~(0x1 << IZ_ACTION_INDEX_LEFT); | |||
if (e.jaxis.value > state->config.axis_threshold) { | |||
*action |= (0x1 << IZ_ACTION_INDEX_RIGHT); | |||
} else if (e.jaxis.value <= -state->config.axis_threshold) { | |||
*action |= (0x1 << IZ_ACTION_INDEX_LEFT); | |||
} | |||
} | |||
if (e.jaxis.axis == 1 || e.jaxis.axis == 4) { | |||
*action &= ~(0x1 << IZ_ACTION_INDEX_UP); | |||
*action &= ~(0x1 << IZ_ACTION_INDEX_DOWN); | |||
if (e.jaxis.value > -state->config.axis_threshold) { | |||
*action |= (0x1 << IZ_ACTION_INDEX_DOWN); | |||
} else if (e.jaxis.value <= -state->config.axis_threshold) { | |||
*action |= (0x1 << IZ_ACTION_INDEX_UP); | |||
} | |||
} | |||
} | |||
} | |||
void IZ_HandleJoystickHatEvents(SDL_Event e, IZ_Action* action) { | |||
if (e.type == SDL_JOYHATMOTION) { | |||
*action &= ~(0x1 << IZ_ACTION_INDEX_UP); | |||
*action &= ~(0x1 << IZ_ACTION_INDEX_RIGHT); | |||
*action &= ~(0x1 << IZ_ACTION_INDEX_DOWN); | |||
*action &= ~(0x1 << IZ_ACTION_INDEX_LEFT); | |||
if (e.jhat.value != 0) { | |||
*action |= e.jhat.value; | |||
} | |||
} | |||
} | |||
void IZ_HandleJoystickButtonEvents(SDL_Event e, IZ_JoystickState* state, IZ_Action* action) { | |||
for (uint8_t i = 4; i < CONTROLS; i += 1) { | |||
if (e.jbutton.button == state->config.control_mapping[i]) { | |||
const uint16_t bitflag = (0x1 << i); | |||
if (e.type == SDL_JOYBUTTONDOWN) { | |||
*action |= bitflag; | |||
} else if (e.type == SDL_JOYBUTTONUP) { | |||
*action &= ~bitflag; | |||
} | |||
} | |||
} | |||
} | |||
void IZ_HandleJoystickEvents(SDL_Event e, IZ_JoystickState* state, IZ_Action* action) { | |||
IZ_HandleJoystickDeviceEvents(e, state); | |||
IZ_HandleJoystickAxisEvents(e, state, action); | |||
IZ_HandleJoystickHatEvents(e, action); | |||
IZ_HandleJoystickButtonEvents(e, state, action); | |||
} | |||
void IZ_LoadJoystickConfig(IZ_JoystickConfig* config, uint8_t p) { | |||
char config_path[128]; | |||
IZ_GetConfigPath(config_path); | |||
char joystick_control_mapping_section_name[] = "Joystick.0.ControlMapping"; | |||
joystick_control_mapping_section_name[9] = (char) (48 + p); | |||
for (uint8_t i = 4; i < CONTROLS; i += 1) { | |||
config->control_mapping[i] = ini_getl(joystick_control_mapping_section_name, ACTION_NAMES[i], IZ_DEFAULT_JOYSTICK_CONTROLS[p][i], config_path); | |||
} | |||
char joystick_section_name[] = "Joystick.0"; | |||
joystick_section_name[9] = (char) (48 + p); | |||
config->axis_threshold = ini_getl(joystick_section_name, "AxisThreshold", 8000, config_path); | |||
} | |||
void IZ_SaveJoystickConfig(IZ_JoystickConfig* config, uint8_t p) { | |||
char config_path[128]; | |||
IZ_GetConfigPath(config_path); | |||
char joystick_control_mapping_section_name[] = "Joystick.0.ControlMapping"; | |||
joystick_control_mapping_section_name[9] = (char) (48 + p); | |||
for (uint8_t i = 4; i < CONTROLS; i += 1) { | |||
ini_putl(joystick_control_mapping_section_name, ACTION_NAMES[i], config->control_mapping[i], config_path); | |||
} | |||
char joystick_section_name[] = "Joystick.0"; | |||
joystick_section_name[9] = (char) (48 + p); | |||
ini_putl(joystick_section_name, "AxisThreshold", config->axis_threshold, config_path); | |||
} |
@@ -0,0 +1,50 @@ | |||
#ifndef IZ_JOYSTICK_H | |||
#define IZ_JOYSTICK_H | |||
#include <SDL_joystick.h> | |||
#include <SDL_events.h> | |||
#include <minIni.h> | |||
#include "../IZ_action.h" | |||
#include "../IZ_config.h" | |||
typedef uint8_t IZ_PadButton; | |||
typedef struct { | |||
uint16_t axis_threshold; | |||
IZ_PadButton control_mapping[CONTROLS]; | |||
} IZ_JoystickConfig; | |||
typedef struct { | |||
SDL_Joystick* joystick_instance; | |||
IZ_JoystickConfig config; | |||
} IZ_JoystickState; | |||
static IZ_PadButton IZ_DEFAULT_JOYSTICK_CONTROLS[PLAYERS][CONTROLS] = { | |||
{ | |||
255, | |||
255, | |||
255, | |||
255, | |||
11, | |||
10, | |||
1, | |||
0, | |||
4, | |||
3, | |||
6, | |||
7, | |||
8, | |||
9, | |||
13, | |||
14, | |||
}, | |||
}; | |||
void IZ_LoadJoystickConfig(IZ_JoystickConfig*, uint8_t); | |||
void IZ_SaveJoystickConfig(IZ_JoystickConfig*, uint8_t); | |||
void IZ_HandleJoystickEvents(SDL_Event, IZ_JoystickState*, IZ_Action*); | |||
#endif |
@@ -0,0 +1,47 @@ | |||
#include "IZ_keyboard.h" | |||
void IZ_HandleKeyboardEvents(SDL_Event e, IZ_KeyboardState* state, IZ_Action* action) { | |||
for (uint8_t i = 0; i < CONTROLS; i += 1) { | |||
if (e.key.keysym.sym == state->config.control_mapping[i]) { | |||
const uint16_t bitflag = (0x1 << i); | |||
if (e.type == SDL_KEYDOWN) { | |||
*action |= bitflag; | |||
} else if (e.type == SDL_KEYUP) { | |||
*action &= ~bitflag; | |||
} | |||
} | |||
} | |||
} | |||
void IZ_SaveKeyboardConfig(IZ_KeyboardConfig* config, uint8_t p) { | |||
char config_path[128]; | |||
IZ_GetConfigPath(config_path); | |||
char keyboard_section_name[] = "Keyboard.0.ControlMapping"; | |||
keyboard_section_name[9] = (char) (48 + p); | |||
for (uint8_t i = 0; i < CONTROLS; i += 1) { | |||
ini_puts(keyboard_section_name, ACTION_NAMES[i], SDL_GetKeyName(config->control_mapping[i]), config_path); | |||
} | |||
} | |||
void IZ_LoadKeyboardConfig(IZ_KeyboardConfig* config, uint8_t p) { | |||
char config_path[128]; | |||
IZ_GetConfigPath(config_path); | |||
char buffer[128]; | |||
char keyboard_section_name[] = "Keyboard.0.ControlMapping"; | |||
keyboard_section_name[9] = (char) (48 + p); | |||
for (uint8_t i = 0; i < CONTROLS; i += 1) { | |||
ini_gets( | |||
keyboard_section_name, | |||
ACTION_NAMES[i], | |||
SDL_GetKeyName(IZ_DEFAULT_KEYBOARD_CONTROLS[p][i]), | |||
buffer, | |||
128, | |||
config_path | |||
); | |||
config->control_mapping[i] = SDL_GetKeyFromName(buffer); | |||
} | |||
} |
@@ -0,0 +1,45 @@ | |||
#ifndef IZ_KEYBOARD_H | |||
#define IZ_KEYBOARD_H | |||
#include <SDL_keyboard.h> | |||
#include <SDL_events.h> | |||
#include <minIni.h> | |||
#include "../IZ_action.h" | |||
#include "../IZ_config.h" | |||
typedef struct { | |||
SDL_KeyCode control_mapping[CONTROLS]; | |||
} IZ_KeyboardConfig; | |||
typedef struct { | |||
IZ_KeyboardConfig config; | |||
} IZ_KeyboardState; | |||
static const SDL_KeyCode IZ_DEFAULT_KEYBOARD_CONTROLS[PLAYERS][CONTROLS] = { | |||
{ | |||
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 | |||
}, | |||
}; | |||
void IZ_LoadKeyboardConfig(IZ_KeyboardConfig*, uint8_t); | |||
void IZ_SaveKeyboardConfig(IZ_KeyboardConfig*, uint8_t); | |||
void IZ_HandleKeyboardEvents(SDL_Event, IZ_KeyboardState*, IZ_Action*); | |||
#endif |
@@ -11,7 +11,6 @@ int main(int argc, char* args[]) { | |||
IZ_App app; | |||
IZ_InitializeApp(&app); | |||
if (SDL_Init( | |||
SDL_INIT_VIDEO | |||
| SDL_INIT_GAMECONTROLLER | |||
@@ -25,16 +24,14 @@ int main(int argc, char* args[]) { | |||
APP_NAME, | |||
SDL_WINDOWPOS_CENTERED, | |||
SDL_WINDOWPOS_CENTERED, | |||
app.config.video.width, | |||
app.config.video.height, | |||
app.video_config.width, | |||
app.video_config.height, | |||
SDL_WINDOW_SHOWN | |||
); | |||
if (window == NULL) { | |||
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError()); | |||
return -2; | |||
} | |||
screen_surface = SDL_GetWindowSurface(window); | |||
bool quit = false; | |||
@@ -43,84 +40,20 @@ int main(int argc, char* args[]) { | |||
while (true) { | |||
uint64_t ticks = SDL_GetTicks64(); | |||
// TODO do audio processing | |||
// TODO do networking? | |||
// process events | |||
while (SDL_PollEvent(&e) != 0) { | |||
if (e.type == SDL_QUIT) { | |||
quit = true; | |||
break; | |||
} | |||
// Handle joystick events | |||
for (uint8_t current_player = 0; current_player < PLAYERS; current_player += 1) { | |||
if (e.type == SDL_JOYDEVICEADDED) { | |||
if (SDL_NumJoysticks() <= PLAYERS && !app.assigned_joysticks[current_player]) { | |||
app.assigned_joysticks[current_player] = SDL_JoystickOpen(e.jdevice.which); | |||
} | |||
} | |||
if (e.type == SDL_JOYDEVICEREMOVED) { | |||
if ( | |||
app.assigned_joysticks[current_player] | |||
&& SDL_JoystickInstanceID(app.assigned_joysticks[current_player]) == e.jdevice.which | |||
) { | |||
app.assigned_joysticks[current_player] = NULL; | |||
} | |||
} | |||
if (e.type == SDL_JOYAXISMOTION) { | |||
if (e.jaxis.axis == 0 || e.jaxis.axis == 3) { | |||
app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_RIGHT); | |||
app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_LEFT); | |||
if (e.jaxis.value > app.config.input.gamepad_axis_threshold) { | |||
app.actions[current_player] |= (0x1 << IZ_ACTION_INDEX_RIGHT); | |||
} else if (e.jaxis.value <= -app.config.input.gamepad_axis_threshold) { | |||
app.actions[current_player] |= (0x1 << IZ_ACTION_INDEX_LEFT); | |||
} | |||
} | |||
if (e.jaxis.axis == 1 || e.jaxis.axis == 4) { | |||
app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_UP); | |||
app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_DOWN); | |||
if (e.jaxis.value > app.config.input.gamepad_axis_threshold) { | |||
app.actions[current_player] |= (0x1 << IZ_ACTION_INDEX_DOWN); | |||
} else if (e.jaxis.value <= -app.config.input.gamepad_axis_threshold) { | |||
app.actions[current_player] |= (0x1 << IZ_ACTION_INDEX_UP); | |||
} | |||
} | |||
} | |||
if (e.type == SDL_JOYHATMOTION) { | |||
app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_UP); | |||
app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_RIGHT); | |||
app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_DOWN); | |||
app.actions[current_player] &= ~(0x1 << IZ_ACTION_INDEX_LEFT); | |||
if (e.jhat.value != 0) { | |||
app.actions[current_player] |= e.jhat.value; | |||
} | |||
} | |||
} | |||
// Handle keyboard events | |||
for (uint8_t current_player = 0; current_player < PLAYERS; current_player += 1) { | |||
for (uint8_t i = 0; i < CONTROLS; i += 1) { | |||
if (e.key.keysym.sym == app.config.controls[current_player].keyboard[i]) { | |||
const uint16_t bitflag = (0x1 << i); | |||
if (e.type == SDL_KEYDOWN) { | |||
app.actions[current_player] |= bitflag; | |||
} else if (e.type == SDL_KEYUP) { | |||
app.actions[current_player] &= ~bitflag; | |||
} | |||
} | |||
if (i >= 4) { | |||
if (e.jbutton.button == app.config.controls[current_player].gamepad[i]) { | |||
const uint16_t bitflag = (0x1 << i); | |||
if (e.type == SDL_JOYBUTTONDOWN) { | |||
app.actions[current_player] |= bitflag; | |||
} else if (e.type == SDL_JOYBUTTONUP) { | |||
app.actions[current_player] &= ~bitflag; | |||
} | |||
} | |||
} | |||
} | |||
for (uint8_t p = 0; p < PLAYERS; p += 1) { | |||
IZ_HandleJoystickEvents(e, &(app.joystick_state[p]), &app.actions[p]); | |||
IZ_HandleKeyboardEvents(e, &(app.keyboard_state[p]), &app.actions[p]); | |||
} | |||
} | |||
@@ -128,10 +61,9 @@ int main(int argc, char* args[]) { | |||
break; | |||
} | |||
if (ticks - app.video_update_at > 1000 / app.config.video.max_fps) { | |||
if (ticks - app.video_update_at > 1000 / app.video_config.max_fps) { | |||
// Update window | |||
SDL_FillRect(screen_surface, NULL, SDL_MapRGB(screen_surface->format, 0x00, 0x00, 0x00)); | |||
for (uint8_t i = 0; i < 64; i += 1) { | |||
const uint8_t column = (64 - i) % 32; | |||
const uint8_t row = i / 32; | |||
@@ -140,20 +72,20 @@ int main(int argc, char* args[]) { | |||
if (ticks & bitflag) { | |||
SDL_FillRect(screen_surface, &(SDL_Rect) { | |||
column * size, | |||
app.config.video.height - ((row + 1) * size), | |||
app.video_config.height - ((row + 1) * size), | |||
size, | |||
size | |||
}, SDL_MapRGB(screen_surface->format, 0x00, 0xff, 0xff)); | |||
} | |||
} | |||
for (uint8_t current_player = 0; current_player < PLAYERS; current_player += 1) { | |||
for (uint8_t p = 0; p < PLAYERS; p += 1) { | |||
for (uint8_t i = 0; i < CONTROLS; i += 1) { | |||
const uint8_t column = i % 4; | |||
const uint8_t column = (i % 4) + (p * 4); | |||
const uint8_t row = i / 4; | |||
const IZ_Action bitflag = (0x1 << i); | |||
const uint8_t size = 4; | |||
if (app.actions[current_player] & bitflag) { | |||
if (app.actions[p] & bitflag) { | |||
SDL_FillRect(screen_surface, &(SDL_Rect) { | |||
column * size, | |||
row * size, | |||
@@ -164,7 +96,6 @@ int main(int argc, char* args[]) { | |||
} | |||
} | |||
SDL_UpdateWindowSurface(window); | |||
app.video_update_at = ticks; | |||
} | |||
} | |||
@@ -1,15 +1,6 @@ | |||
#include "bdd-for-c.h" | |||
#include "../../game/config/IZ_config.h" | |||
#define mock_call_count_t uint8_t | |||
#define mock(X) static mock_call_count_t calls_##X = 0; | |||
#define mock_return(X) calls_##X += 1; return | |||
#define mock_reset(X) calls_##X = 0 | |||
#define mock_calls(X) ((mock_call_count_t) (calls_##X)) | |||
#include <bdd-for-c.h> | |||
#include "../../test/IZ_mock.h" | |||
#include "IZ_video.h" | |||
mock(SDL_GetBasePath) char* SDL_GetBasePath() { | |||
mock_return(SDL_GetBasePath) ""; | |||
@@ -68,7 +59,7 @@ spec("config") { | |||
} | |||
it("should load default config values") { | |||
IZ_LoadConfig(&config); | |||
IZ_LoadVideoConfig(&config); | |||
check( | |||
mock_calls(SDL_GetBasePath) > 0, | |||
@@ -100,7 +91,7 @@ spec("config") { | |||
); | |||
check( | |||
config.input.gamepad_axis_threshold == 8000, | |||
config.input.axis_threshold == 8000, | |||
"Default value for Input.GamepadAxisThreshold is not loaded." | |||
); | |||
@@ -0,0 +1,19 @@ | |||
#include "IZ_video.h" | |||
void IZ_SaveVideoConfig(IZ_VideoConfig* config) { | |||
char config_path[128]; | |||
IZ_GetConfigPath(config_path); | |||
ini_putl("Video", "Width", config->width, config_path); | |||
ini_putl("Video", "Height", config->height, config_path); | |||
ini_putl("Video", "MaxFps", config->max_fps, config_path); | |||
} | |||
void IZ_LoadVideoConfig(IZ_VideoConfig* config) { | |||
char config_path[128]; | |||
IZ_GetConfigPath(config_path); | |||
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); | |||
} |
@@ -0,0 +1,18 @@ | |||
#ifndef IZ_VIDEO_H | |||
#define IZ_VIDEO_H | |||
#include <stdio.h> | |||
#include <minIni.h> | |||
#include "../IZ_config.h" | |||
typedef struct { | |||
uint16_t width; | |||
uint16_t height; | |||
uint8_t max_fps; | |||
} IZ_VideoConfig; | |||
void IZ_SaveVideoConfig(IZ_VideoConfig* config); | |||
void IZ_LoadVideoConfig(IZ_VideoConfig* config); | |||
#endif |
@@ -0,0 +1,14 @@ | |||
#ifndef IZ_MOCK_H | |||
#define IZ_MOCK_H | |||
#define mock_call_count_t uint8_t | |||
#define mock(X) static mock_call_count_t calls_##X = 0; | |||
#define mock_return(X) calls_##X += 1; return | |||
#define mock_reset(X) calls_##X = 0 | |||
#define mock_calls(X) ((mock_call_count_t) (calls_##X)) | |||
#endif |