Переглянути джерело

Integrate libwebsockets connection

Add libwebsockets client to game executable.
feature/data-structs
TheoryOfNekomata 2 роки тому
джерело
коміт
c3248953e2
10 змінених файлів з 183 додано та 37 видалено
  1. +19
    -1
      CMakeLists.txt
  2. +7
    -5
      src/packages/game/IZ_app.c
  3. +3
    -1
      src/packages/game/IZ_app.h
  4. +2
    -2
      src/packages/game/input/IZ_input.c
  5. +2
    -2
      src/packages/game/input/IZ_input.h
  6. +90
    -0
      src/packages/game/network/IZ_wsclient.c
  7. +29
    -0
      src/packages/game/network/IZ_wsclient.h
  8. +6
    -6
      src/packages/game/output/IZ_video.c
  9. +3
    -3
      src/packages/game/output/IZ_video.h
  10. +22
    -17
      src/packages/server/main.c

+ 19
- 1
CMakeLists.txt Переглянути файл

@@ -70,13 +70,16 @@ add_executable(
src/packages/game/input/IZ_midi.h
src/packages/game/data/IZ_list.c
src/packages/game/data/IZ_list.h
)
src/packages/game/network/IZ_wsclient.c src/packages/game/network/IZ_wsclient.h)

target_link_libraries(
game
SDL2main
SDL2
portmidi
libcrypto
libssl
websockets
)

add_executable(
@@ -188,6 +191,21 @@ if (WIN32)
"${PROJECT_SOURCE_DIR}/dependencies/portmidi/Release/portmidi.dll" # <--this is in-file
$<TARGET_FILE_DIR:game>) # <--this is out-file path

add_custom_command(TARGET game POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake - E copy_if_different..."
"${PROJECT_SOURCE_DIR}/dependencies/libwebsockets/build/bin/Release/websockets.dll" # <--this is in-file
$<TARGET_FILE_DIR:game>) # <--this is out-file path

add_custom_command(TARGET game POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake - E copy_if_different..."
"${PROJECT_SOURCE_DIR}/dependencies/openssl/${PROJECT_ARCH}/bin/libssl-1_1-x64.dll" # <--this is in-file
$<TARGET_FILE_DIR:game>) # <--this is out-file path

add_custom_command(TARGET game POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake - E copy_if_different..."
"${PROJECT_SOURCE_DIR}/dependencies/openssl/${PROJECT_ARCH}/bin/libcrypto-1_1-x64.dll" # <--this is in-file
$<TARGET_FILE_DIR:game>) # <--this is out-file path

add_custom_command(TARGET server POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake - E copy_if_different..."
"${PROJECT_SOURCE_DIR}/dependencies/libwebsockets/build/bin/Release/websockets.dll" # <--this is in-file


+ 7
- 5
src/packages/game/IZ_app.c Переглянути файл

@@ -15,15 +15,16 @@ IZ_ProcedureResult IZ_AppInitialize(IZ_App* app) {

char config_path[128];
IZ_ConfigGetPath(config_path, 128);
if (IZ_VideoInitialize(config_path, &app->video_state)) {
if (IZ_VideoInitialize(&app->video_state, config_path)) {
return 2;
}

if (IZ_InputInitialize(config_path, &app->input_state)) {
if (IZ_InputInitialize(&app->input_state, config_path)) {
return 3;
}

IZ_PoolInitialize(&app->pool, POOL_MAX_SIZE);
IZ_WSClientInitialize(&app->client, app);

// TODO put into its timer module
app->ticks = 0;
@@ -31,6 +32,7 @@ IZ_ProcedureResult IZ_AppInitialize(IZ_App* app) {
}

void IZ_AppTeardown(IZ_App* app) {
IZ_WSClientTeardown(&app->client);
IZ_PoolTeardown(&app->pool);
IZ_InputTeardown(&app->input_state);
IZ_VideoTeardown(&app->video_state);
@@ -66,8 +68,8 @@ void IZ_AppHandlePortMIDIEvents(IZ_App* app) {

for (midi_event_index = 0; midi_event_index < *midi_events_count; midi_event_index += 1) {
IZ_InputHandlePortMIDIEvents(
app->input_state.midi_input_state[player_index].event_buffer[midi_event_index],
&app->input_state
&app->input_state,
app->input_state.midi_input_state[player_index].event_buffer[midi_event_index]
);
}
}
@@ -104,7 +106,7 @@ IZ_ProcedureResult IZ_AppRun(IZ_App* app, u8 arg_count, char* arg_values[]) {
break;
}

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

IZ_AppTeardown(app);


+ 3
- 1
src/packages/game/IZ_app.h Переглянути файл

@@ -10,12 +10,14 @@
#include "input/IZ_input.h"
#include "output/IZ_video.h"
#include "memory/IZ_pool.h"
#include "network/IZ_wsclient.h"

typedef struct {
IZ_InputState input_state;
IZ_VideoState video_state;

IZ_Pool pool;

IZ_WSClient client;
u64 ticks;
} IZ_App;



+ 2
- 2
src/packages/game/input/IZ_input.c Переглянути файл

@@ -5,11 +5,11 @@ void IZ_InputHandleSDLEvents(IZ_InputState* state) {
IZ_KeyboardHandleEvents(state->sdl_event, &state->keyboard_state, &state->action);
}

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

IZ_ProcedureResult IZ_InputInitialize(const char* config_path, IZ_InputState* state) {
IZ_ProcedureResult IZ_InputInitialize(IZ_InputState* state, const char* config_path) {
*state = (IZ_InputState) {
.action = {},
.joystick_state = {},


+ 2
- 2
src/packages/game/input/IZ_input.h Переглянути файл

@@ -16,9 +16,9 @@ typedef struct {

void IZ_InputHandleSDLEvents(IZ_InputState*);

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

IZ_ProcedureResult IZ_InputInitialize(const char*, IZ_InputState*);
IZ_ProcedureResult IZ_InputInitialize(IZ_InputState*, const char*);

void IZ_InputTeardown(IZ_InputState*);



+ 90
- 0
src/packages/game/network/IZ_wsclient.c Переглянути файл

@@ -0,0 +1,90 @@
#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:
return 1;
case LWS_CALLBACK_CLIENT_CLOSED:
return 0;
case LWS_CALLBACK_CLIENT_RECEIVE:
case LWS_CALLBACK_CLIENT_ESTABLISHED:
default:
break;
}

return lws_callback_http_dummy(wsi, reason, user, in, len);
}

IZ_ProcedureResult IZ_WSClientConnect(IZ_WSClient* client, IZ_WSClientConnectParams params) {
static struct lws_client_connect_info info;
memset(&info, 0, sizeof info);

info.context = client->context;
info.port = params.port;
info.address = params.address;
info.host = params.address;
info.origin = params.address;
info.protocol = params.protocol;
info.path = params.path;
info.userdata = params.userdata;
// info.ssl_connection = (
// LCCSCF_ALLOW_SELFSIGNED
// | LCCSCF_ALLOW_INSECURE
// | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK
// | LCCSCF_ALLOW_EXPIRED
// );

client->connection = lws_client_connect_via_info(&info);
if (!client->connection) {
return 1;
}

return 0;
}

IZ_ProcedureResult IZ_WSClientInitialize(IZ_WSClient* client, void* app) {
static struct lws_protocols protocols[] = {
{
.name = "lws-minimal-client",
.callback = IZ_WSClientCallback,
.per_session_data_size = 0,
.rx_buffer_size = 0,
.id = 0,
.user = NULL,
.tx_packet_size = 0,
},
LWS_PROTOCOL_LIST_TERM,
};
protocols[0].user = app;
static struct lws_context_creation_info info;
memset(&info, 0, sizeof info);
info.port = CONTEXT_PORT_NO_LISTEN,
info.protocols = protocols,
info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT,

client->context = lws_create_context(&info);
if (!client->context) {
return 1;
}

return 0;
}

IZ_ProcedureResult IZ_WSClientHandle(IZ_WSClient* client) {
i32 response = lws_service(client->context, 0);
if (response < 0) {
return 1;
}

return 0;
}

void IZ_WSClientTeardown(IZ_WSClient* client) {
lws_context_destroy(client->context);
}

+ 29
- 0
src/packages/game/network/IZ_wsclient.h Переглянути файл

@@ -0,0 +1,29 @@
#ifndef IZ_WSCLIENT_H
#define IZ_WSCLIENT_H

#include <libwebsockets.h>
#include "../IZ_common.h"

typedef struct {
struct lws_context* context;
struct lws* connection;
i32 n;
} IZ_WSClient;

typedef struct {
u16 port;
const char* address;
const char* path;
const char* protocol;
void* userdata;
} IZ_WSClientConnectParams;

IZ_ProcedureResult IZ_WSClientInitialize(IZ_WSClient*, void*);

IZ_ProcedureResult IZ_WSClientConnect(IZ_WSClient*, IZ_WSClientConnectParams);

IZ_ProcedureResult IZ_WSClientHandle(IZ_WSClient*);

void IZ_WSClientTeardown(IZ_WSClient*);

#endif

+ 6
- 6
src/packages/game/output/IZ_video.c Переглянути файл

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

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

void IZ_VideoLoadConfig(const char* config_path, IZ_VideoConfig* config) {
void IZ_VideoLoadConfig(IZ_VideoConfig* config, const char* 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_VideoInitialize(const char* config_path, IZ_VideoState* state) {
IZ_ProcedureResult IZ_VideoInitialize(IZ_VideoState* state, const char* config_path) {
SDL_memcpy(state, &IZ_DEFAULT_VIDEO_STATE, sizeof(IZ_VideoState));

IZ_VideoLoadConfig(config_path, &state->config);
if (IZ_VideoSaveConfig(config_path, &state->config)) {
IZ_VideoLoadConfig(&state->config, config_path);
if (IZ_VideoSaveConfig(&state->config, config_path)) {
// fprintf_s(stderr, "Error committing video config.\n");
}
state->last_update_at = 0u;
@@ -103,7 +103,7 @@ void IZ_VideoUpdateForDebug(IZ_VideoState* video_state, IZ_InputState* input_sta
IZ_VideoUpdateForDebugInput(video_state, input_state);
}

void IZ_VideoUpdate(IZ_VideoState* video_state, IZ_InputState* input_state, u64 ticks) {
void IZ_VideoUpdate(IZ_VideoState* video_state, u64 ticks, IZ_InputState* input_state) {
if (ticks - video_state->last_update_at > 1000 / video_state->config.max_fps) {
// Update window
SDL_SetRenderDrawColor(video_state->renderer, 0x00, 0x00, 0x00, 0xff);


+ 3
- 3
src/packages/game/output/IZ_video.h Переглянути файл

@@ -34,11 +34,11 @@ static const IZ_VideoState IZ_DEFAULT_VIDEO_STATE = {
.window = NULL,
};

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

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

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

void IZ_VideoTeardown(IZ_VideoState*);



+ 22
- 17
src/packages/server/main.c Переглянути файл

@@ -19,25 +19,30 @@ static const lws_retry_bo_t retry = {
static i32 interrupted;

static const struct lws_http_mount mount = {
/* .mount_next */ NULL, /* linked-list "next" */
/* .mountpoint */ "/", /* mountpoint URL */
/* .origin */ "./mount-origin", /* serve from dir */
/* .def */ "index.html", /* default filename */
/* .protocol */ NULL,
/* .cgienv */ NULL,
/* .extra_mimetypes */ NULL,
/* .interpret */ NULL,
/* .cgi_timeout */ 0,
/* .cache_max_age */ 0,
/* .auth_mask */ 0,
/* .cache_reusable */ 0,
/* .cache_revalidate */ 0,
/* .cache_intermediaries */ 0,
/* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */
/* .mountpoint_len */ 1, /* char count */
/* .basic_auth_login_file */ NULL,
.mount_next = NULL, /* linked-list "next" */
.mountpoint = "/", /* mountpoint URL */
.origin = "./mount-origin", /* serve from dir */
.def = "index.html", /* default filename */
.protocol = NULL,
.cgienv = NULL,
.extra_mimetypes = NULL,
.interpret = NULL,
.cgi_timeout = 0,
.cache_max_age = 0,
.auth_mask = 0,
.cache_reusable = 0,
.cache_revalidate = 0,
.cache_intermediaries = 0,
.origin_protocol = LWSMPRO_FILE, /* files in a dir */
.mountpoint_len = 1, /* char count */
.basic_auth_login_file = NULL,
};

#if defined(LWS_WITH_PLUGINS)
/* if plugins enabled, only protocols explicitly named in pvo bind to vhost */
static struct lws_protocol_vhost_options pvo = { NULL, NULL, "lws-minimal", "" };
#endif

void sigint_handler(i32 sig) {
interrupted = 1;
}


Завантаження…
Відмінити
Зберегти