Provide default states for input and output.feature/data-structs
@@ -1,6 +1,6 @@ | |||||
[Video] | [Video] | ||||
Width=640 | |||||
Height=480 | |||||
Width=320 | |||||
Height=240 | |||||
MaxFps=30 | MaxFps=30 | ||||
[Joystick.0.ControlMapping] | [Joystick.0.ControlMapping] | ||||
Affirm=11 | Affirm=11 | ||||
@@ -101,7 +101,7 @@ void IZ_LoadJoystickConfig(const char* config_path, IZ_JoystickState(* state)[PL | |||||
state[player_index]->config.control_mapping[i] = ini_getl( | state[player_index]->config.control_mapping[i] = ini_getl( | ||||
control_mapping_section_name, | control_mapping_section_name, | ||||
ACTION_NAMES[i], | ACTION_NAMES[i], | ||||
IZ_DEFAULT_JOYSTICK_CONTROLS[player_index][i], | |||||
IZ_DEFAULT_JOYSTICK_STATE[player_index].config.control_mapping[i], | |||||
config_path | 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]) { | 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); | IZ_LoadJoystickConfig(config_path, state); | ||||
if (IZ_SaveJoystickConfig(config_path, state)) { | if (IZ_SaveJoystickConfig(config_path, state)) { | ||||
return 1; | return 1; | ||||
@@ -28,24 +28,30 @@ typedef struct { | |||||
IZ_JoystickConfig config; | IZ_JoystickConfig config; | ||||
} IZ_JoystickState; | } 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, | |||||
}, | |||||
}, | }, | ||||
}; | }; | ||||
@@ -51,7 +51,7 @@ void IZ_LoadKeyboardConfig(const char* config_path, IZ_KeyboardState(* state)[PL | |||||
ini_gets( | ini_gets( | ||||
keyboard_section_name, | keyboard_section_name, | ||||
ACTION_NAMES[i], | 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, | buffer, | ||||
128, | 128, | ||||
config_path | 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]) { | 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); | IZ_LoadKeyboardConfig(config_path, state); | ||||
return IZ_SaveKeyboardConfig(config_path, state); | return IZ_SaveKeyboardConfig(config_path, state); | ||||
} | } |
@@ -14,24 +14,28 @@ typedef struct { | |||||
IZ_KeyboardConfig config; | IZ_KeyboardConfig config; | ||||
} IZ_KeyboardState; | } 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 | |||||
}, | |||||
}, | |||||
}, | }, | ||||
}; | }; | ||||
@@ -147,7 +147,7 @@ void IZ_LoadMIDIInputConfig(const char* config_path, IZ_MIDIInputState(* state)[ | |||||
ini_gets( | ini_gets( | ||||
control_mapping_section_name, | control_mapping_section_name, | ||||
ACTION_NAMES[i], | 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, | buffer, | ||||
128, | 128, | ||||
config_path | config_path | ||||
@@ -167,6 +167,7 @@ IZ_ProcedureResult IZ_InitializeMIDIInput(const char* config_path, IZ_MIDIInputS | |||||
return 1; | return 1; | ||||
} | } | ||||
SDL_memcpy(state, &IZ_DEFAULT_MIDI_INPUT_STATE, sizeof(IZ_MIDIInputState)); | |||||
IZ_LoadMIDIInputConfig(config_path, state); | IZ_LoadMIDIInputConfig(config_path, state); | ||||
if (IZ_SaveMIDIInputConfig(config_path, state)) { | if (IZ_SaveMIDIInputConfig(config_path, state)) { | ||||
return 2; | return 2; | ||||
@@ -1,6 +1,7 @@ | |||||
#ifndef IZ_MIDI_H | #ifndef IZ_MIDI_H | ||||
#define IZ_MIDI_H | #define IZ_MIDI_H | ||||
#include <SDL_stdinc.h> | |||||
#include <string.h> | #include <string.h> | ||||
#include <portmidi.h> | #include <portmidi.h> | ||||
#include <minIni.h> | #include <minIni.h> | ||||
@@ -27,25 +28,34 @@ typedef struct { | |||||
PmEvent event_buffer[MIDI_EVENT_BUFFER_SIZE]; | PmEvent event_buffer[MIDI_EVENT_BUFFER_SIZE]; | ||||
} IZ_MIDIInputState; | } 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]); | IZ_ProcedureResult IZ_SaveMIDIInputConfig(const char*, IZ_MIDIInputState(*)[PLAYERS]); | ||||
@@ -228,8 +228,8 @@ spec("input") { | |||||
for (uint8_t i = 4; i < CONTROLS; i += 1) { | for (uint8_t i = 4; i < CONTROLS; i += 1) { | ||||
it("handles %s action activation", ACTION_NAMES[i]) { | it("handles %s action activation", ACTION_NAMES[i]) { | ||||
e.type = SDL_JOYBUTTONDOWN; | 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; | action = 0; | ||||
IZ_HandleJoystickEvents(e, &state, &action); | IZ_HandleJoystickEvents(e, &state, &action); | ||||
@@ -241,8 +241,8 @@ spec("input") { | |||||
it("handles %s action deactivation", ACTION_NAMES[i]) { | it("handles %s action deactivation", ACTION_NAMES[i]) { | ||||
e.type = SDL_JOYBUTTONUP; | 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; | action = ~0; | ||||
IZ_HandleJoystickEvents(e, &state, &action); | IZ_HandleJoystickEvents(e, &state, &action); | ||||
@@ -285,7 +285,7 @@ spec("input") { | |||||
before_each() { | before_each() { | ||||
for (uint8_t i = 0; i < CONTROLS; i += 1) { | 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) { | for (uint8_t i = 0; i < CONTROLS; i += 1) { | ||||
it("handles %s action activation", ACTION_NAMES[i]) { | it("handles %s action activation", ACTION_NAMES[i]) { | ||||
e.type = SDL_KEYDOWN; | 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; | action = 0; | ||||
IZ_HandleKeyboardEvents(e, &state, &action); | IZ_HandleKeyboardEvents(e, &state, &action); | ||||
@@ -326,8 +326,8 @@ spec("input") { | |||||
it("handles %s action deactivation", ACTION_NAMES[i]) { | it("handles %s action deactivation", ACTION_NAMES[i]) { | ||||
e.type = SDL_KEYUP; | 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; | action = ~0; | ||||
IZ_HandleKeyboardEvents(e, &state, &action); | IZ_HandleKeyboardEvents(e, &state, &action); | ||||
@@ -369,7 +369,7 @@ spec("input") { | |||||
before_each() { | before_each() { | ||||
for (uint8_t i = 0; i < CONTROLS; i += 1) { | 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]; | |||||
} | } | ||||
} | } | ||||
@@ -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) { | 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) { | 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); | IZ_LoadVideoConfig(config_path, &state->config); | ||||
if (IZ_SaveVideoConfig(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; | return 1; | ||||
} | } | ||||
state->window = window; | state->window = window; | ||||
state->surface = SDL_GetWindowSurface(window); | |||||
state->renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); | |||||
return 0; | 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) { | 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) { | if (ticks - video_state->last_update_at > 1000 / video_state->config.max_fps) { | ||||
// Update window | // 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) { | 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 uint8_t row = i / 32; | ||||
const uint64_t bitflag = (0x1lu << i); | |||||
const uint8_t size = 4; | 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), | video_state->config.height - ((row + 1) * size), | ||||
size, | 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 | // TODO refer to app's state | ||||
for (uint8_t p = 0; p < PLAYERS; p += 1) { | for (uint8_t p = 0; p < PLAYERS; p += 1) { | ||||
for (uint8_t i = 0; i < CONTROLS; i += 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 IZ_Action bitflag = (0x1 << i); | ||||
const uint8_t size = 4; | const uint8_t size = 4; | ||||
if (input_states->action[p] & bitflag) { | if (input_states->action[p] & bitflag) { | ||||
SDL_FillRect(video_state->surface, &(SDL_Rect) { | |||||
SDL_RenderFillRectF(video_state->renderer, &(SDL_FRect) { | |||||
column * size, | column * size, | ||||
row * size, | row * size, | ||||
size, | 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; | video_state->last_update_at = ticks; | ||||
} | } | ||||
} | } | ||||
@@ -4,6 +4,7 @@ | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <minIni.h> | #include <minIni.h> | ||||
#include <SDL_video.h> | #include <SDL_video.h> | ||||
#include <SDL_render.h> | |||||
// TODO move this out from video, refer to app's state instead | // TODO move this out from video, refer to app's state instead | ||||
#include "../input/IZ_input.h" | #include "../input/IZ_input.h" | ||||
@@ -12,7 +13,7 @@ | |||||
typedef struct { | typedef struct { | ||||
uint16_t width; | uint16_t width; | ||||
uint16_t height; | |||||
uint16_t height; | |||||
uint8_t max_fps; | uint8_t max_fps; | ||||
} IZ_VideoConfig; | } IZ_VideoConfig; | ||||
@@ -20,9 +21,20 @@ typedef struct { | |||||
IZ_VideoConfig config; | IZ_VideoConfig config; | ||||
uint64_t last_update_at; | uint64_t last_update_at; | ||||
SDL_Window* window; | SDL_Window* window; | ||||
SDL_Surface* surface; | |||||
SDL_Renderer* renderer; | |||||
} IZ_VideoState; | } 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_InitializeVideo(const char*, IZ_VideoState*); | ||||
IZ_ProcedureResult IZ_SaveVideoConfig(const char*, IZ_VideoConfig*); | IZ_ProcedureResult IZ_SaveVideoConfig(const char*, IZ_VideoConfig*); | ||||