@@ -173,7 +173,7 @@ add_executable( | |||||
src/packages/server/log/IZ_log.h | src/packages/server/log/IZ_log.h | ||||
src/packages/server/log/IZ_log.c | src/packages/server/log/IZ_log.c | ||||
src/packages/server/main.c | src/packages/server/main.c | ||||
src/packages/server/protocol_lws_minimal.c src/packages/server/IZ_app.c src/packages/server/IZ_app.h) | |||||
src/packages/server/protocol_lws_minimal.c src/packages/server/IZ_app.c src/packages/server/IZ_app.h src/packages/server/network/IZ_wsserver.c src/packages/server/network/IZ_wsserver.h) | |||||
target_link_libraries( | target_link_libraries( | ||||
server | server | ||||
@@ -1,6 +1,35 @@ | |||||
#include "IZ_app.h" | #include "IZ_app.h" | ||||
IZ_ProcedureResult IZ_AppWSClientCallback( | |||||
struct lws* wsi, | |||||
enum lws_callback_reasons reason, | |||||
void* userraw, | |||||
void* in, | |||||
size_t len | |||||
) { | |||||
IZ_App* user = userraw; | |||||
switch (reason) { | |||||
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: | |||||
printf("Client Connection Error %llu\n", len); | |||||
return 1; | |||||
case LWS_CALLBACK_CLIENT_CLOSED: | |||||
printf("Client Closed %llu\n", len); | |||||
return 0; | |||||
case LWS_CALLBACK_CLIENT_RECEIVE: | |||||
printf("Client Receive %llu\n", len); | |||||
break; | |||||
case LWS_CALLBACK_CLIENT_ESTABLISHED: | |||||
printf("Client Established %llu\n", len); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
return 0; | |||||
} | |||||
IZ_ProcedureResult IZ_AppInitialize(IZ_App* app) { | IZ_ProcedureResult IZ_AppInitialize(IZ_App* app) { | ||||
memset(app, 0, sizeof(IZ_App)); | |||||
u32 flags = ( | u32 flags = ( | ||||
SDL_INIT_VIDEO | SDL_INIT_VIDEO | ||||
| SDL_INIT_GAMECONTROLLER | | SDL_INIT_GAMECONTROLLER | ||||
@@ -40,12 +69,21 @@ void IZ_AppTeardown(IZ_App* app) { | |||||
} | } | ||||
IZ_ProcedureResult IZ_AppHandleSDLEvents(IZ_App* app) { | IZ_ProcedureResult IZ_AppHandleSDLEvents(IZ_App* app) { | ||||
while (SDL_PollEvent(&app->input_state.sdl_event) != 0) { | |||||
if (app->input_state.sdl_event.type == SDL_QUIT) { | |||||
SDL_Event e; | |||||
while (SDL_PollEvent(&e) != 0) { | |||||
if (e.type == SDL_QUIT) { | |||||
return 1; | return 1; | ||||
} | } | ||||
IZ_InputHandleSDLEvents(&app->input_state); | |||||
if (e.type == SDL_KEYDOWN) { | |||||
if (e.key.keysym.sym == SDLK_PAGEUP) { | |||||
// TODO connect | |||||
} else if (e.key.keysym.sym == SDLK_PAGEDOWN) { | |||||
// TODO disconnect | |||||
} | |||||
} | |||||
IZ_InputHandleSDLEvents(&app->input_state, e); | |||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
@@ -55,9 +93,14 @@ void IZ_AppHandlePortMIDIEvents(IZ_App* app) { | |||||
i32* midi_events_count; | i32* midi_events_count; | ||||
u32 midi_event_index; | u32 midi_event_index; | ||||
for (player_index = 0; player_index < PLAYERS; player_index += 1) { | for (player_index = 0; player_index < 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 = &app->input_state.midi_input_state[player_index].midi_events_count; | ||||
*midi_events_count = Pm_Read( | *midi_events_count = Pm_Read( | ||||
app->input_state.midi_input_state[player_index].stream, | 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, | app->input_state.midi_input_state[player_index].event_buffer, | ||||
1024 | 1024 | ||||
); | ); | ||||
@@ -83,11 +126,15 @@ IZ_ProcedureResult IZ_AppHandleEvents(IZ_App* app) { | |||||
return 0; | return 0; | ||||
} | } | ||||
IZ_ProcedureResult IZ_AppRun(IZ_App* app, u8 arg_count, char* arg_values[]) { | |||||
printf_s("Args (%u):\n", arg_count); | |||||
IZ_ProcedureResult IZ_AppRunNetworkingThread(void* ptr) { | |||||
return 0; | |||||
} | |||||
IZ_ProcedureResult IZ_AppRun(IZ_App* app, u8 argc, const char* argv[]) { | |||||
printf_s("Args (%u):\n", argc); | |||||
u8 arg_index; | u8 arg_index; | ||||
for (arg_index = 0; arg_index < arg_count; arg_index += 1) { | |||||
printf_s(" %s\n", arg_values[arg_index]); | |||||
for (arg_index = 0; arg_index < argc; arg_index += 1) { | |||||
printf_s(" %s\n", argv[arg_index]); | |||||
} | } | ||||
IZ_ProcedureResult init_result = IZ_AppInitialize(app); | IZ_ProcedureResult init_result = IZ_AppInitialize(app); | ||||
@@ -95,25 +142,29 @@ IZ_ProcedureResult IZ_AppRun(IZ_App* app, u8 arg_count, char* arg_values[]) { | |||||
return init_result; | return init_result; | ||||
} | } | ||||
if (IZ_WSClientConnect(&app->client, (IZ_WSClientConnectParams) { | |||||
.userdata = app, | |||||
.path = "/", | |||||
.protocol = "http", // TODO handle ws protocol correctly | |||||
.address = "localhost", | |||||
.port = 6969, | |||||
})) { | |||||
return IZ_APP_RUN_NETWORKING_ERROR; | |||||
} | |||||
// if (IZ_WSClientConnect(&app->client, (IZ_WSClientConnectParams) { | |||||
// .userdata = app, | |||||
// .path = "/", | |||||
// .protocol = NETWORK_PROTOCOL, // TODO handle ws protocol correctly | |||||
// .address = "localhost", | |||||
// .port = 42069, | |||||
// .callback = IZ_AppWSClientCallback, | |||||
// })) { | |||||
// return IZ_APP_RUN_NETWORKING_ERROR; | |||||
// } | |||||
//app->client_thread = SDL_CreateThread(IZ_AppRunNetworkingThread, "Networking", app); | |||||
//SDL_DetachThread(app->client_thread); | |||||
while (true) { | while (true) { | ||||
app->ticks = SDL_GetTicks64(); | app->ticks = SDL_GetTicks64(); | ||||
// TODO do audio processing | // TODO do audio processing | ||||
// TODO do networking | // TODO do networking | ||||
if (app->client.connection) { | |||||
//if (app->client.connection) { | |||||
// FIXME stuck in infinite loop | // FIXME stuck in infinite loop | ||||
IZ_WSClientHandle(&app->client); | |||||
} | |||||
//IZ_WSClientHandle(&app->client); | |||||
//} | |||||
if (IZ_AppHandleEvents(app)) { | if (IZ_AppHandleEvents(app)) { | ||||
// TODO refactor input handlers to have same function signature. | // TODO refactor input handlers to have same function signature. | ||||
@@ -27,9 +27,10 @@ typedef struct { | |||||
IZ_Pool pool; | IZ_Pool pool; | ||||
IZ_WSClient client; | IZ_WSClient client; | ||||
SDL_Thread* client_thread; | |||||
u64 ticks; | u64 ticks; | ||||
} IZ_App; | } IZ_App; | ||||
IZ_ProcedureResult IZ_AppRun(IZ_App*, u8, char**); | |||||
IZ_ProcedureResult IZ_AppRun(IZ_App*, u8, const char**); | |||||
#endif | #endif |
@@ -7,6 +7,8 @@ | |||||
#define PLAYERS (unsigned char) 1 | #define PLAYERS (unsigned char) 1 | ||||
#define APP_NAME "SDL2" | #define APP_NAME "SDL2" | ||||
#define NETWORK_PROTOCOL "izanagi-networking" | |||||
typedef uint8_t u8; | typedef uint8_t u8; | ||||
typedef uint16_t u16; | typedef uint16_t u16; | ||||
typedef uint32_t u32; | typedef uint32_t u32; | ||||
@@ -55,6 +55,7 @@ void _IZ_ListDeleteFirstNode(IZ_List* list, IZ_ListFindFilter filter) { | |||||
} | } | ||||
SDL_free(iterator); | SDL_free(iterator); | ||||
iterator = NULL; | |||||
list->length -= 1; | list->length -= 1; | ||||
return; | return; | ||||
} while (iterator); | } while (iterator); | ||||
@@ -1,8 +1,8 @@ | |||||
#include "IZ_input.h" | #include "IZ_input.h" | ||||
void IZ_InputHandleSDLEvents(IZ_InputState* state) { | |||||
IZ_JoystickHandleEvents(state->sdl_event, &state->joystick_state, &state->action); | |||||
IZ_KeyboardHandleEvents(state->sdl_event, &state->keyboard_state, &state->action); | |||||
void IZ_InputHandleSDLEvents(IZ_InputState* state, SDL_Event e) { | |||||
IZ_JoystickHandleEvents(e, &state->joystick_state, &state->action); | |||||
IZ_KeyboardHandleEvents(e, &state->keyboard_state, &state->action); | |||||
} | } | ||||
void IZ_InputHandlePortMIDIEvents(IZ_InputState* state, PmEvent e) { | void IZ_InputHandlePortMIDIEvents(IZ_InputState* state, PmEvent e) { | ||||
@@ -7,14 +7,13 @@ | |||||
#include "IZ_midi.h" | #include "IZ_midi.h" | ||||
typedef struct { | typedef struct { | ||||
SDL_Event sdl_event; | |||||
IZ_Action action[PLAYERS]; | IZ_Action action[PLAYERS]; | ||||
IZ_KeyboardState keyboard_state[PLAYERS]; | IZ_KeyboardState keyboard_state[PLAYERS]; | ||||
IZ_JoystickState joystick_state[PLAYERS]; | IZ_JoystickState joystick_state[PLAYERS]; | ||||
IZ_MIDIInputState midi_input_state[PLAYERS]; | IZ_MIDIInputState midi_input_state[PLAYERS]; | ||||
} IZ_InputState; | } IZ_InputState; | ||||
void IZ_InputHandleSDLEvents(IZ_InputState*); | |||||
void IZ_InputHandleSDLEvents(IZ_InputState*, SDL_Event); | |||||
void IZ_InputHandlePortMIDIEvents(IZ_InputState*, PmEvent); | void IZ_InputHandlePortMIDIEvents(IZ_InputState*, PmEvent); | ||||
@@ -1,6 +1,6 @@ | |||||
#include "IZ_app.h" | #include "IZ_app.h" | ||||
IZ_ProcedureResult main(i32 arg_count, char* arg_values[]) { | |||||
IZ_ProcedureResult main(i32 argc, char* argv[]) { | |||||
IZ_App app; | IZ_App app; | ||||
return IZ_AppRun(&app, arg_count, arg_values); | |||||
return IZ_AppRun(&app, argc, (const char**) argv); | |||||
} | } |
@@ -47,4 +47,5 @@ void IZ_PoolDeallocate(IZ_PoolItem* item) { | |||||
void IZ_PoolTeardown(IZ_Pool* pool) { | void IZ_PoolTeardown(IZ_Pool* pool) { | ||||
SDL_free(pool->memory); | SDL_free(pool->memory); | ||||
pool->memory = NULL; | |||||
} | } |
@@ -1,32 +1,5 @@ | |||||
#include "IZ_wsclient.h" | #include "IZ_wsclient.h" | ||||
IZ_ProcedureResult IZ_WSClientCallback( | |||||
struct lws* wsi, | |||||
enum lws_callback_reasons reason, | |||||
void* user, | |||||
void* in, | |||||
size_t len | |||||
) { | |||||
switch (reason) { | |||||
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: | |||||
printf("Client Connection Error %llu\n", len); | |||||
return 1; | |||||
case LWS_CALLBACK_CLIENT_CLOSED: | |||||
printf("Client Closed %llu\n", len); | |||||
return 0; | |||||
case LWS_CALLBACK_CLIENT_RECEIVE: | |||||
printf("Client Receive %llu\n", len); | |||||
break; | |||||
case LWS_CALLBACK_CLIENT_ESTABLISHED: | |||||
printf("Client Established %llu\n", len); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
return lws_callback_http_dummy(wsi, reason, user, in, len); | |||||
} | |||||
IZ_ProcedureResult IZ_WSClientCreateConnection(IZ_WSClient* client, IZ_WSClientConnectParams params) { | IZ_ProcedureResult IZ_WSClientCreateConnection(IZ_WSClient* client, IZ_WSClientConnectParams params) { | ||||
static struct lws_client_connect_info info; | static struct lws_client_connect_info info; | ||||
memset(&info, 0, sizeof info); | memset(&info, 0, sizeof info); | ||||
@@ -54,11 +27,11 @@ IZ_ProcedureResult IZ_WSClientCreateConnection(IZ_WSClient* client, IZ_WSClientC | |||||
return 0; | return 0; | ||||
} | } | ||||
IZ_ProcedureResult IZ_WSClientCreateContext(IZ_WSClient* client, void* userdata) { | |||||
IZ_ProcedureResult IZ_WSClientCreateContext(IZ_WSClient* client, lws_callback_function* callback, void* userdata) { | |||||
static struct lws_protocols protocols[] = { | static struct lws_protocols protocols[] = { | ||||
{ | { | ||||
.name = "http", | .name = "http", | ||||
.callback = IZ_WSClientCallback, | |||||
.callback = NULL, | |||||
.per_session_data_size = 0, | .per_session_data_size = 0, | ||||
.rx_buffer_size = 0, | .rx_buffer_size = 0, | ||||
.id = 0, | .id = 0, | ||||
@@ -67,6 +40,8 @@ IZ_ProcedureResult IZ_WSClientCreateContext(IZ_WSClient* client, void* userdata) | |||||
}, | }, | ||||
LWS_PROTOCOL_LIST_TERM, | LWS_PROTOCOL_LIST_TERM, | ||||
}; | }; | ||||
protocols[0].callback = callback; | |||||
protocols[0].user = userdata; | protocols[0].user = userdata; | ||||
static struct lws_context_creation_info info; | static struct lws_context_creation_info info; | ||||
memset(&info, 0, sizeof info); | memset(&info, 0, sizeof info); | ||||
@@ -90,7 +65,7 @@ void IZ_WSClientInitialize(IZ_WSClient* client) { | |||||
} | } | ||||
IZ_ProcedureResult IZ_WSClientConnect(IZ_WSClient* client, IZ_WSClientConnectParams params) { | IZ_ProcedureResult IZ_WSClientConnect(IZ_WSClient* client, IZ_WSClientConnectParams params) { | ||||
if (IZ_WSClientCreateContext(client, params.userdata)) { | |||||
if (IZ_WSClientCreateContext(client, params.callback, params.userdata)) { | |||||
return 1; | return 1; | ||||
} | } | ||||
@@ -15,6 +15,7 @@ typedef struct { | |||||
const char* path; | const char* path; | ||||
const char* protocol; | const char* protocol; | ||||
void* userdata; | void* userdata; | ||||
lws_callback_function* callback; | |||||
} IZ_WSClientConnectParams; | } IZ_WSClientConnectParams; | ||||
void IZ_WSClientInitialize(IZ_WSClient*); | void IZ_WSClientInitialize(IZ_WSClient*); | ||||
@@ -15,25 +15,25 @@ void IZ_AppCreateContext(IZ_App* app) { | |||||
); | ); | ||||
} | } | ||||
void IZ_AppLoadConfig(IZ_AppConfig* config, u8 argc, const char** argv) { | |||||
memcpy_s(config, sizeof(IZ_AppConfig), &IZ_APP_DEFAULT_CONFIG, sizeof(IZ_AppConfig)); | |||||
void IZ_AppLoadConfig(IZ_App* app, u8 argc, const char** argv) { | |||||
memcpy_s(app, sizeof(IZ_App), &IZ_APP_DEFAULT_STATE, sizeof(IZ_App)); | |||||
const char* cmdline_buffer; | const char* cmdline_buffer; | ||||
if ((cmdline_buffer = lws_cmdline_option(argc, argv, "-d"))) { | if ((cmdline_buffer = lws_cmdline_option(argc, argv, "-d"))) { | ||||
config->log_level = atoi(cmdline_buffer); | |||||
app->config.log_level = atoi(cmdline_buffer); | |||||
} | } | ||||
if ((cmdline_buffer = lws_cmdline_option(argc, argv, "-p"))) { | if ((cmdline_buffer = lws_cmdline_option(argc, argv, "-p"))) { | ||||
config->port = atoi(cmdline_buffer); | |||||
app->config.port = atoi(cmdline_buffer); | |||||
} | } | ||||
if (lws_cmdline_option(argc, argv, "-o")) { | if (lws_cmdline_option(argc, argv, "-o")) { | ||||
// connect once | // connect once | ||||
config->vhost_options |= 1; | |||||
app->config.vhost_options |= 1; | |||||
} | } | ||||
if (!lws_cmdline_option(argc, argv, "-n")) { | if (!lws_cmdline_option(argc, argv, "-n")) { | ||||
config->extensions_enabled = true; | |||||
app->config.extensions_enabled = true; | |||||
} | } | ||||
} | } | ||||
@@ -41,7 +41,7 @@ IZ_ProcedureResult IZ_AppInitialize(IZ_App* app, u8 argc, const char** argv) { | |||||
interrupted = false; | interrupted = false; | ||||
signal(SIGINT, IZ_AppHandleSignal); | signal(SIGINT, IZ_AppHandleSignal); | ||||
IZ_AppLoadConfig(&app->config, argc, argv); | |||||
IZ_AppLoadConfig(app, argc, argv); | |||||
IZ_LogInterceptWSMessages(app->config.log_level); | IZ_LogInterceptWSMessages(app->config.log_level); | ||||
IZ_AppCreateContext(app); | IZ_AppCreateContext(app); | ||||
@@ -21,11 +21,14 @@ typedef struct { | |||||
struct lws_context* context; | struct lws_context* context; | ||||
} IZ_App; | } IZ_App; | ||||
static const IZ_AppConfig IZ_APP_DEFAULT_CONFIG = { | |||||
.log_level = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE, | |||||
.port = 42069, | |||||
.vhost_options = 0, | |||||
.extensions_enabled = false, | |||||
static const IZ_App IZ_APP_DEFAULT_STATE = { | |||||
.config = { | |||||
.log_level = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE, | |||||
.port = 42069, | |||||
.vhost_options = 0, | |||||
.extensions_enabled = false, | |||||
}, | |||||
.context = NULL, | |||||
}; | }; | ||||
IZ_ProcedureResult IZ_AppRun(IZ_App*, u8, const char**); | IZ_ProcedureResult IZ_AppRun(IZ_App*, u8, const char**); | ||||
@@ -0,0 +1 @@ | |||||
#include "IZ_wsserver.h" |
@@ -0,0 +1,4 @@ | |||||
#ifndef IZ_WSSERVER_H | |||||
#define IZ_WSSERVER_H | |||||
#endif |
@@ -5,6 +5,7 @@ | |||||
#endif | #endif | ||||
#include <string.h> | #include <string.h> | ||||
#include "IZ_common.h" | |||||
#define RING_COUNT 32 | #define RING_COUNT 32 | ||||
/* one of these created for each message */ | /* one of these created for each message */ | ||||
@@ -259,7 +260,7 @@ callback_minimal(struct lws *wsi, enum lws_callback_reasons reason, | |||||
#define LWS_PLUGIN_PROTOCOL_MINIMAL \ | #define LWS_PLUGIN_PROTOCOL_MINIMAL \ | ||||
{ \ | { \ | ||||
"lws-minimal", \ | |||||
NETWORK_PROTOCOL, \ | |||||
callback_minimal, \ | callback_minimal, \ | ||||
sizeof(struct per_session_data__minimal), \ | sizeof(struct per_session_data__minimal), \ | ||||
0, \ | 0, \ | ||||