Browse Source

Refactor input and video logic

Put input and video subsystems into their own directories.
feature/data-structs
TheoryOfNekomata 2 years ago
parent
commit
5283548bb3
14 changed files with 243 additions and 208 deletions
  1. +5
    -5
      CMakeLists.txt
  2. +3
    -0
      TODO.md
  3. +0
    -183
      src/packages/game/IZ_app.c
  4. +2
    -2
      src/packages/game/IZ_app.h
  5. +1
    -0
      src/packages/game/IZ_subsystem.c
  6. +16
    -0
      src/packages/game/IZ_subsystem.h
  7. +74
    -0
      src/packages/game/input/IZ_app.c
  8. +8
    -0
      src/packages/game/input/IZ_app.h
  9. +2
    -9
      src/packages/game/net/IZ_app.h
  10. +1
    -1
      src/packages/game/output/output.test.c
  11. +116
    -0
      src/packages/game/output/video/IZ_app.c
  12. +9
    -0
      src/packages/game/output/video/IZ_app.h
  13. +0
    -0
      src/packages/game/output/video/IZ_video.c
  14. +6
    -8
      src/packages/game/output/video/IZ_video.h

+ 5
- 5
CMakeLists.txt View File

@@ -43,8 +43,8 @@ add_executable(
dependencies/minIni/dev/minIni.c dependencies/minIni/dev/minIni.c
dependencies/getopt-for-windows/getopt.h dependencies/getopt-for-windows/getopt.h
dependencies/getopt-for-windows/getopt.c dependencies/getopt-for-windows/getopt.c
src/packages/game/output/IZ_video.h
src/packages/game/output/IZ_video.c
src/packages/game/output/video/IZ_video.h
src/packages/game/output/video/IZ_video.c
src/packages/game/IZ_common.h src/packages/game/IZ_common.h
src/packages/game/input/IZ_action.h src/packages/game/input/IZ_action.h
src/packages/game/IZ_app.h src/packages/game/IZ_app.h
@@ -84,7 +84,7 @@ add_executable(
src/packages/game/util/IZ_midi.h src/packages/game/util/IZ_midi.h
src/packages/game/net/core/IZ_websocket.h src/packages/game/net/core/IZ_websocket.h
src/packages/game/net/core/IZ_websocket.c src/packages/game/net/core/IZ_websocket.c
src/packages/game/net/IZ_net.c src/packages/game/net/IZ_net.h src/packages/game/net/IZ_app.c src/packages/game/net/IZ_app.h)
src/packages/game/net/IZ_net.c src/packages/game/net/IZ_net.h src/packages/game/net/IZ_app.c src/packages/game/net/IZ_app.h src/packages/game/output/video/IZ_app.c src/packages/game/output/video/IZ_app.h src/packages/game/IZ_subsystem.c src/packages/game/IZ_subsystem.h src/packages/game/input/IZ_app.c src/packages/game/input/IZ_app.h)


target_link_libraries( target_link_libraries(
game game
@@ -153,8 +153,8 @@ add_executable(


src/packages/game/IZ_config.h src/packages/game/IZ_config.h


src/packages/game/output/IZ_video.h
src/packages/game/output/IZ_video.c
src/packages/game/output/video/IZ_video.h
src/packages/game/output/video/IZ_video.c
src/packages/game/output/output.test.c src/packages/game/output/output.test.c
) )




+ 3
- 0
TODO.md View File

@@ -0,0 +1,3 @@
- [ ] Authentication server, using HTTP dynamic content
- [ ] server
- [ ] client (frontend)

+ 0
- 183
src/packages/game/IZ_app.c View File

@@ -65,189 +65,6 @@ void IZ_AppTeardown(struct IZ_App* app) {
SDL_Quit(); SDL_Quit();
} }


IZ_ProcedureResult IZ_AppHandleSDLEvents(struct IZ_App* app) {
SDL_Event e;
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) {
return 1;
}

if (e.type == SDL_KEYDOWN) {
if (e.key.keysym.sym == SDLK_PAGEUP) {
IZ_NetConnect(
&app->net_state,
(IZ_WSClientInitializeParams) {
.host = "127.0.0.1",
.path = "/",
.port = 42069,
}
);
} else if (e.key.keysym.sym == SDLK_PAGEDOWN) {
IZ_NetDisconnect(&app->net_state);
} else if (e.key.keysym.sym == SDLK_INSERT) {
IZ_NetSendTextMessage(&app->net_state, "hello", 5);
}
}

IZ_InputHandleSDLEvents(&app->input_state, e);
}
return 0;
}

void IZ_AppHandlePortMIDIEvents(struct IZ_App* app) {
u8 player_index;
i32* midi_events_count;
u32 midi_event_index;
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) {
if (!app->input_state.midi_input_state[player_index].device_info) {
continue;
}

midi_events_count = &app->input_state.midi_input_state[player_index].midi_events_count;
*midi_events_count = Pm_Read(
app->input_state.midi_input_state[player_index].stream,
// TODO bind buffers and streams to device instead of player input state
app->input_state.midi_input_state[player_index].event_buffer,
1024
);

if (*midi_events_count < 1) {
continue;
}

for (midi_event_index = 0; midi_event_index < *midi_events_count; midi_event_index += 1) {
IZ_InputHandlePortMIDIEvents(
&app->input_state,
app->input_state.midi_input_state[player_index].event_buffer[midi_event_index]
);
}
}
}

IZ_ProcedureResult IZ_AppHandleInputEvents(struct IZ_App* app) {
i32 sdl_events_result = IZ_AppHandleSDLEvents(app);
if (sdl_events_result) {
return sdl_events_result;
}

IZ_AppHandlePortMIDIEvents(app);
return 0;
}

void IZ_VideoUpdateForDebugTicks(IZ_VideoState* video_state, uint64_t ticks) {
SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0xff, 0xff, 0xff);
u64 the_ticks = ticks;
u8 column;
u8 row;
const u8 size = 4;

u8 i;
for (i = 0; i < 64; i += 1) {
column = i % 32;
row = i / 32;

if (the_ticks & 0x1) {
SDL_RenderFillRectF(video_state->renderer, &(SDL_FRect) {
(f32) (video_state->config.width - ((column + 1) * size)),
(f32) (video_state->config.height - ((row + 1) * size)),
size,
size
});
}
the_ticks >>= 1;
}
}

void IZ_VideoUpdateForDebugInput(IZ_VideoState* video_state, IZ_InputState* input_state) {
SDL_SetRenderDrawColor(video_state->renderer, 0xff, 0xff, 0x00, 0xff);
const u8 size = 4;

u8 column;
u8 row;

u8 p;
u8 i;
for (p = 0; p < IZ_PLAYERS; p += 1) {
IZ_Action the_action = input_state->action[p];
for (i = 0; i < CONTROLS; i += 1) {
column = (i % 4) + (p * 4);
row = i / 4;

if (the_action & 0x1) {
SDL_RenderFillRectF(video_state->renderer, &(SDL_FRect) {
(f32) (column * size),
(f32) (row * size),
size,
size
});
}
the_action >>= 1;
}
}
}

void IZ_VideoUpdateForDebugNet(IZ_VideoState* video_state, IZ_NetState* net_state) {
if (!net_state->ws.connection) {
return;
}
const u8 size = 4;

SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0xff, 0x00, 0xff);
SDL_RenderFillRectF(video_state->renderer, &(SDL_FRect) {
0,
(f32) (video_state->config.height - size),
size,
size,
});

u8 column;
u8 row;

u8 p;
u8 i;
for (p = 0; p < IZ_PLAYERS; p += 1) {
IZ_Action the_action = net_state->action[p];
for (i = 0; i < CONTROLS; i += 1) {
column = (i % 4) + (p * 4);
row = i / 4;

if (the_action & 0x1) {
SDL_RenderFillRectF(video_state->renderer, &(SDL_FRect) {
(f32) (column * size),
(f32) ((row * size) + (video_state->config.height - (size * 5))),
size,
size
});
}
the_action >>= 1;
}
}
}

void IZ_VideoUpdateForDebug(IZ_VideoState* video_state, u64 ticks, IZ_InputState* input_state, IZ_NetState* net_state) {
IZ_VideoUpdateForDebugTicks(video_state, ticks);
IZ_VideoUpdateForDebugInput(video_state, input_state);
IZ_VideoUpdateForDebugNet(video_state, net_state);
}

void IZ_VideoUpdate(IZ_VideoState* video_state) {
struct IZ_App* app = video_state->user_data;
if (app->ticks - video_state->last_update_at > 1000 / video_state->config.max_fps) {
// Update window
SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0x00, 0x00, 0xff);
SDL_RenderClear(video_state->renderer);
for (u8 i = 0; i < MAX_ACTIVE_SPRITES; i += 1) {
if (!video_state->active_sprites[i]) {
continue;
}
// TODO draw sprites
}
IZ_VideoUpdateForDebug(video_state, app->ticks, &app->input_state, &app->net_state);
SDL_RenderPresent(video_state->renderer);
video_state->last_update_at = app->ticks;
}
}

IZ_ProcedureResult IZ_AppRun(struct IZ_App* app, u8 argc, const char* argv[]) { IZ_ProcedureResult IZ_AppRun(struct IZ_App* app, u8 argc, const char* argv[]) {
IZ_ProcedureResult init_result = IZ_AppInitialize(app, argc, argv); IZ_ProcedureResult init_result = IZ_AppInitialize(app, argc, argv);
if (init_result) { if (init_result) {


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

@@ -3,10 +3,10 @@


#include <SDL.h> #include <SDL.h>
#include <libwebsockets.h> #include <libwebsockets.h>
#include "input/IZ_input.h"
#include "output/IZ_video.h"
#include "memory/IZ_pool.h" #include "memory/IZ_pool.h"
#include "input/IZ_app.h"
#include "net/IZ_app.h" #include "net/IZ_app.h"
#include "output/video/IZ_app.h"


typedef enum { typedef enum {
IZ_APP_RUN_RESULT_OK, IZ_APP_RUN_RESULT_OK,


+ 1
- 0
src/packages/game/IZ_subsystem.c View File

@@ -0,0 +1 @@
#include "IZ_subsystem.h"

+ 16
- 0
src/packages/game/IZ_subsystem.h View File

@@ -0,0 +1,16 @@
#ifndef IZ_SUBSYSTEM_H
#define IZ_SUBSYSTEM_H

#include "IZ_common.h"
#include "net/IZ_net.h"
#include "input/IZ_input.h"

struct IZ_App;

u64 IZ_AppGetTicks(struct IZ_App*);

IZ_NetState* IZ_AppGetNetState(struct IZ_App*);

IZ_InputState* IZ_AppGetInputState(struct IZ_App*);

#endif

+ 74
- 0
src/packages/game/input/IZ_app.c View File

@@ -0,0 +1,74 @@
#include "IZ_app.h"

IZ_ProcedureResult IZ_AppHandleSDLEvents(struct IZ_App* app) {
SDL_Event e;
IZ_InputState* input_state = IZ_AppGetInputState(app);
IZ_NetState* net_state = IZ_AppGetNetState(app);

while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) {
return 1;
}

if (e.type == SDL_KEYDOWN) {
if (e.key.keysym.sym == SDLK_PAGEUP) {
IZ_NetConnect(
net_state,
(IZ_WSClientInitializeParams) {
.host = "127.0.0.1",
.path = "/",
.port = 42069,
}
);
} else if (e.key.keysym.sym == SDLK_PAGEDOWN) {
IZ_NetDisconnect(net_state);
} else if (e.key.keysym.sym == SDLK_INSERT) {
IZ_NetSendTextMessage(net_state, "hello", 5);
}
}

IZ_InputHandleSDLEvents(input_state, e);
}
return 0;
}

void IZ_AppHandlePortMIDIEvents(struct IZ_App* app) {
IZ_InputState* input_state = IZ_AppGetInputState(app);
u8 player_index;
i32* midi_events_count;
u32 midi_event_index;
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) {
if (!input_state->midi_input_state[player_index].device_info) {
continue;
}

midi_events_count = &input_state->midi_input_state[player_index].midi_events_count;
*midi_events_count = Pm_Read(
input_state->midi_input_state[player_index].stream,
// TODO bind buffers and streams to device instead of player input state
input_state->midi_input_state[player_index].event_buffer,
1024
);

if (*midi_events_count < 1) {
continue;
}

for (midi_event_index = 0; midi_event_index < *midi_events_count; midi_event_index += 1) {
IZ_InputHandlePortMIDIEvents(
input_state,
input_state->midi_input_state[player_index].event_buffer[midi_event_index]
);
}
}
}

IZ_ProcedureResult IZ_AppHandleInputEvents(struct IZ_App* app) {
i32 sdl_events_result = IZ_AppHandleSDLEvents(app);
if (sdl_events_result) {
return sdl_events_result;
}

IZ_AppHandlePortMIDIEvents(app);
return 0;
}

+ 8
- 0
src/packages/game/input/IZ_app.h View File

@@ -0,0 +1,8 @@
#ifndef IZ_INPUT_APP_H
#define IZ_INPUT_APP_H

#include "../IZ_subsystem.h"

IZ_ProcedureResult IZ_AppHandleInputEvents(struct IZ_App*);

#endif

+ 2
- 9
src/packages/game/net/IZ_app.h View File

@@ -1,14 +1,13 @@
#ifndef IZ_NET_APP_H #ifndef IZ_NET_APP_H
#define IZ_NET_APP_H #define IZ_NET_APP_H


#include "../IZ_common.h"
#include "../input/IZ_input.h"
#include "IZ_net.h" #include "IZ_net.h"
#include "../IZ_subsystem.h"


typedef enum { typedef enum {
IZ_MESSAGE_KIND_ACTION_SYNC = 0, IZ_MESSAGE_KIND_ACTION_SYNC = 0,
IZ_MESSAGE_KIND_STATE_SYNC = 1, IZ_MESSAGE_KIND_STATE_SYNC = 1,
} IZ_MessageKind;
} IZ_AppMessageKind;


typedef struct { typedef struct {
u8 index: 3; u8 index: 3;
@@ -47,14 +46,8 @@ typedef struct {


struct IZ_App; struct IZ_App;


u64 IZ_AppGetTicks(struct IZ_App*);

void IZ_AppBindConnection(struct IZ_App*, struct lws*); void IZ_AppBindConnection(struct IZ_App*, struct lws*);


IZ_NetState* IZ_AppGetNetState(struct IZ_App*);

IZ_InputState* IZ_AppGetInputState(struct IZ_App*);

void IZ_AppHandleOutboundNetworking(struct IZ_App*); void IZ_AppHandleOutboundNetworking(struct IZ_App*);


#endif #endif

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

@@ -1,7 +1,7 @@
#include "../../../__mocks__/minIni.mock.h" #include "../../../__mocks__/minIni.mock.h"
#include "../../../__mocks__/SDL_stdinc.mock.h" #include "../../../__mocks__/SDL_stdinc.mock.h"
#include "../../../__mocks__/SDL_render.mock.h" #include "../../../__mocks__/SDL_render.mock.h"
#include "IZ_video.h"
#include "video/IZ_video.h"


const char* IZ_ConfigGetCommandlineOption(u8 argc, const char* argv[], const char* val) { const char* IZ_ConfigGetCommandlineOption(u8 argc, const char* argv[], const char* val) {
size_t n = strlen(val); size_t n = strlen(val);


+ 116
- 0
src/packages/game/output/video/IZ_app.c View File

@@ -0,0 +1,116 @@
#include "IZ_app.h"

void IZ_VideoUpdateForDebugTicks(IZ_VideoState* video_state, uint64_t ticks) {
SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0xff, 0xff, 0xff);
u64 the_ticks = ticks;
u8 column;
u8 row;
const u8 size = 4;

u8 bit_index;
for (bit_index = 0; bit_index < 64; bit_index += 1) {
column = bit_index % 32;
row = bit_index / 32;

if (the_ticks & 0x1) {
SDL_RenderFillRectF(video_state->renderer, &(SDL_FRect) {
(f32) (video_state->config.width - ((column + 1) * size)),
(f32) (video_state->config.height - ((row + 1) * size)),
size,
size
});
}
the_ticks >>= 1;
}
}

void IZ_VideoUpdateForDebugInput(IZ_VideoState* video_state, IZ_InputState* input_state) {
SDL_SetRenderDrawColor(video_state->renderer, 0xff, 0xff, 0x00, 0xff);
const u8 size = 4;

u8 column;
u8 row;

u8 player_index;
u8 control_index;
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) {
IZ_Action the_action = input_state->action[player_index];
for (control_index = 0; control_index < CONTROLS; control_index += 1) {
column = (control_index % 4) + (player_index * 4);
row = control_index / 4;

if (the_action & 0x1) {
SDL_RenderFillRectF(video_state->renderer, &(SDL_FRect) {
(f32) (column * size),
(f32) (row * size),
size,
size
});
}
the_action >>= 1;
}
}
}

void IZ_VideoUpdateForDebugNet(IZ_VideoState* video_state, IZ_NetState* net_state) {
if (!net_state->ws.connection) {
return;
}
const u8 size = 4;

SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0xff, 0x00, 0xff);
SDL_RenderFillRectF(video_state->renderer, &(SDL_FRect) {
0,
(f32) (video_state->config.height - size),
size,
size,
});

u8 column;
u8 row;

u8 player_index;
u8 control_index;
for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) {
IZ_Action the_action = net_state->action[player_index];
for (control_index = 0; control_index < CONTROLS; control_index += 1) {
column = (control_index % 4) + (player_index * 4);
row = control_index / 4;

if (the_action & 0x1) {
SDL_RenderFillRectF(video_state->renderer, &(SDL_FRect) {
(f32) (column * size),
(f32) ((row * size) + (video_state->config.height - (size * 5))),
size,
size
});
}
the_action >>= 1;
}
}
}

void IZ_VideoUpdate(IZ_VideoState* video_state) {
struct IZ_App* app = video_state->user_data;
u64 ticks = IZ_AppGetTicks(app);
IZ_InputState* input_state = IZ_AppGetInputState(app);
IZ_NetState* net_state = IZ_AppGetNetState(app);

if (ticks - video_state->last_update_at > 1000 / video_state->config.max_fps) {
// Update window
SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0x00, 0x00, 0xff);
SDL_RenderClear(video_state->renderer);
u8 sprite_index;
for (sprite_index = 0; sprite_index < MAX_ACTIVE_SPRITES; sprite_index += 1) {
if (!video_state->active_sprites[sprite_index]) {
continue;
}
// TODO draw sprites
}
IZ_VideoUpdateForDebugTicks(video_state, ticks);
IZ_VideoUpdateForDebugInput(video_state, input_state);
IZ_VideoUpdateForDebugNet(video_state, net_state);
SDL_RenderPresent(video_state->renderer);
video_state->last_update_at = ticks;
}
}

+ 9
- 0
src/packages/game/output/video/IZ_app.h View File

@@ -0,0 +1,9 @@
#ifndef IZ_VIDEO_APP_H
#define IZ_VIDEO_APP_H

#include "IZ_video.h"
#include "../../IZ_subsystem.h"

void IZ_VideoUpdate(IZ_VideoState*);

#endif

src/packages/game/output/IZ_video.c → src/packages/game/output/video/IZ_video.c View File


src/packages/game/output/IZ_video.h → src/packages/game/output/video/IZ_video.h View File

@@ -2,13 +2,13 @@
#define IZ_VIDEO_H #define IZ_VIDEO_H


#include <stdio.h> #include <stdio.h>
#include <minIni.h>
#include <SDL_render.h>
#include "minIni.h"
#include "SDL_render.h"


#include "../input/IZ_input.h"
#include "../net/IZ_net.h"
#include "../IZ_common.h"
#include "../IZ_config.h"
#include "../../input/IZ_input.h"
#include "../../net/IZ_net.h"
#include "../../IZ_common.h"
#include "../../IZ_config.h"


#define MAX_ACTIVE_SPRITES 32 #define MAX_ACTIVE_SPRITES 32


@@ -47,8 +47,6 @@ IZ_ProcedureResult IZ_VideoInitialize(IZ_VideoState*, void*, const char*, u8, co


IZ_ProcedureResult IZ_VideoSaveConfig(IZ_VideoState*, const char*); IZ_ProcedureResult IZ_VideoSaveConfig(IZ_VideoState*, const char*);


void IZ_VideoUpdate(IZ_VideoState*);

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


#endif #endif

Loading…
Cancel
Save