diff --git a/client/main.c b/client/main.c index 476295f..ed8d512 100644 --- a/client/main.c +++ b/client/main.c @@ -6,7 +6,8 @@ #include #include -MwWidget window, opengl; +static MwWidget window, opengl; +static GSEngine engine; static void gl_swapbuffer(void){ MwOpenGLSwapBuffer(opengl); @@ -36,8 +37,8 @@ static void tick(void){ static GSVector3 rot = {0, 0, 0}; static GSModel model = NULL; -static void render(GSEngine engine){ - GSGL gl = GSClientGetGL(GSEngineGetClient(engine)); +static void render(GSEngine self){ + GSGL gl = GSClientGetGL(GSEngineGetClient(self)); GSGLPushMatrix(gl); GSGLSetRotation(gl, rot); @@ -45,13 +46,16 @@ static void render(GSEngine engine){ GSGLPopMatrix(gl); } -static void after_render(GSEngine engine){ - rot[0] = rot[1] = rot[2] += (1.0 / GSEngineGetTPS(engine)) * 90; +static void after_render(GSEngine self){ + rot[0] = rot[1] = rot[2] += (1.0 / GSEngineGetTPS(self)) * 90; +} + +static void shutdown_engine(int sig){ + GSEngineShutdown(engine); } int main(int argc, char** argv){ GSEngineParam param; - GSEngine engine; GSEngineParamInit(¶m); param.ready = ready; @@ -65,6 +69,9 @@ int main(int argc, char** argv){ GSInit(); if((engine = GSEngineCreate(¶m)) != NULL){ + signal(SIGINT, shutdown_engine); + signal(SIGTERM, shutdown_engine); + model = GSModelOpen(engine, "game:/mdl/fish.gsm"); GSClientToggleSkybox(GSEngineGetClient(engine), GSTrue); diff --git a/engine/include/GearSrc/Core.h b/engine/include/GearSrc/Core.h index 81eec06..b755195 100644 --- a/engine/include/GearSrc/Core.h +++ b/engine/include/GearSrc/Core.h @@ -19,6 +19,7 @@ GSDECL GSServer GSEngineGetServer(GSEngine engine); GSDECL GSBool GSEngineRegisterResource(GSEngine engine, const char* name, const char* path); GSDECL void GSEngineUnregisterResource(GSEngine engine, const char* name); GSDECL GSNumber GSEngineGetTPS(GSEngine engine); +GSDECL void GSEngineShutdown(GSEngine engine); #ifdef __cplusplus } diff --git a/engine/include/GearSrc/Foundation.h b/engine/include/GearSrc/Foundation.h index 5b73b33..00cd459 100644 --- a/engine/include/GearSrc/Foundation.h +++ b/engine/include/GearSrc/Foundation.h @@ -17,5 +17,6 @@ #include #include #include +#include #endif diff --git a/engine/include/GearSrc/Sound.h b/engine/include/GearSrc/Sound.h new file mode 100644 index 0000000..cd61733 --- /dev/null +++ b/engine/include/GearSrc/Sound.h @@ -0,0 +1,20 @@ +#ifndef __GEARSRC_SOUND_H__ +#define __GEARSRC_SOUND_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSSoundRate 48000 + +GSDECL GSSound GSSoundOpen(GSClient client); +GSDECL void GSSoundClose(GSSound sound); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/engine/include/GearSrc/TypeDefs.h b/engine/include/GearSrc/TypeDefs.h index ef6e5a1..ee2de57 100644 --- a/engine/include/GearSrc/TypeDefs.h +++ b/engine/include/GearSrc/TypeDefs.h @@ -54,6 +54,7 @@ typedef struct _GSResource* GSResource; typedef struct _GSGL* GSGL; typedef struct _GSSkyBox* GSSkyBox; typedef struct _GSModel* GSModel; +typedef struct _GSSound* GSSound; typedef struct _GSModelFace GSModelFace; typedef struct _GSModelMaterial GSModelMaterial; @@ -68,6 +69,7 @@ typedef void* GSResource; typedef void* GSGL; typedef void* GSSkyBox; typedef void* GSModel; +typedef void* GSSound; #endif typedef float GSNumber; typedef GSNumber GSVector2[2]; @@ -95,6 +97,7 @@ struct _GSResourceKV { #ifdef _GEARSRC #include +#include struct _GSGL { GSEngine engine; @@ -110,30 +113,6 @@ struct _GSGL { GSBool bold; }; -struct _GSClient { - GSEngine engine; - - GSGL gl; - - GLuint font_normal; - int font_normal_width; - int font_normal_height; - int glyph_normal_width; - int glyph_normal_height; - - GLuint font_bold; - int font_bold_width; - int font_bold_height; - int glyph_bold_width; - int glyph_bold_height; - - GSVector3 look_at; - GSVector3 camera; - GSVector4 light0; - GSSkyBox skybox; - GSBool skybox_enabled; -}; - struct _GSSkyBox { GSEngine engine; @@ -180,6 +159,39 @@ struct _GSModel { GSModelFace* face; }; +struct _GSSound { + GSEngine engine; + + ma_device device; + ma_device_config config; +}; + +struct _GSClient { + GSEngine engine; + + GSGL gl; + + GLuint font_normal; + int font_normal_width; + int font_normal_height; + int glyph_normal_width; + int glyph_normal_height; + + GLuint font_bold; + int font_bold_width; + int font_bold_height; + int glyph_bold_width; + int glyph_bold_height; + + GSVector3 look_at; + GSVector3 camera; + GSVector4 light0; + GSSkyBox skybox; + GSBool skybox_enabled; + + GSSound sound; +}; + struct _GSServer { GSEngine engine; }; @@ -201,6 +213,7 @@ struct _GSEngine { GSNumber tps_sampled; GSEngineLog* log; + int shutdown; }; struct _GSFile { diff --git a/engine/src/audio.c b/engine/src/audio.c new file mode 100644 index 0000000..e69de29 diff --git a/engine/src/client.c b/engine/src/client.c index 19f681f..04910a9 100644 --- a/engine/src/client.c +++ b/engine/src/client.c @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -49,6 +50,13 @@ GSClient GSClientCreate(GSEngine engine) { client->skybox_enabled = GSFalse; + if((client->sound = GSSoundOpen(client)) == NULL) { + GSClientDestroy(client); + GSLog(engine, GSLogError, "Failed to create client"); + + return NULL; + } + client->gl = GSGLCreate(client); client->skybox = GSSkyBoxTry(client, "default"); @@ -81,6 +89,8 @@ void GSClientDestroy(GSClient client) { GSGLDestroy(client->gl); + if(client->sound != NULL) GSSoundClose(client->sound); + GSLog(client->engine, GSLogInfo, "Destroyed client"); free(client); @@ -101,7 +111,7 @@ void GSClientStep(GSClient client) { GSVector4 yellow = {1, 1, 0, 1}; GSVector4 half = {0, 0, 0, 0.5}; GSVector2 sq[4]; - int i, j, k, c; + int i, j, k, c, t; GSGLClear(client->gl); GSGLCameraSetup(client->gl); @@ -152,13 +162,13 @@ void GSClientStep(GSClient client) { for(k = 0; k < 2; k++) { c = 0; - for(i = arrlen(client->engine->log) - 1, j = 0; i >= 0 && j < 10; i--, j++) { + for(i = arrlen(client->engine->log) - 1, j = 0; i >= 0 && j < 5; i--, j++) { if(client->engine->param->get_tick != NULL) { if((client->engine->param->get_tick() - client->engine->log[i].tick) > 3000) continue; } if(k == 1) { - GSNumber y = c * GSGLTextHeight(client->gl, "M"); + GSNumber y = (t - c - 1) * GSGLTextHeight(client->gl, "M"); GSNumber w = 0; char str[6]; int level = client->engine->log[i].level; @@ -197,6 +207,8 @@ void GSClientStep(GSClient client) { c++; } + t = c; + if(k == 0) { sq[0][0] = 0, sq[0][1] = 0; sq[1][0] = 0, sq[1][1] = c * GSGLTextHeight(client->gl, "M"); diff --git a/engine/src/core.c b/engine/src/core.c index 7cc1718..0d2ab2a 100644 --- a/engine/src/core.c +++ b/engine/src/core.c @@ -50,8 +50,9 @@ GSEngine GSEngineCreate(GSEngineParam* param) { engine->param = malloc(sizeof(*engine->param)); memcpy(engine->param, param, sizeof(*param)); - engine->width = 800; - engine->height = 600; + engine->width = 800; + engine->height = 600; + engine->shutdown = 0; if(param->ready != NULL && param->client) { param->ready(engine->width, engine->height); @@ -80,6 +81,9 @@ GSEngine GSEngineCreate(GSEngineParam* param) { engine = NULL; } + if(param->client) engine->shutdown++; + if(param->server) engine->shutdown++; + if(engine == NULL) { GSLog(engine, GSLogError, "Failed to create engine"); } @@ -132,7 +136,7 @@ void GSEngineLoop(GSEngine engine) { engine->tps = tps; engine->tps_sampled = tps; - while(1) { + while(engine->shutdown > 0) { if(engine->client != NULL) GSClientStep(engine->client); if(engine->server != NULL) GSServerStep(engine->server); @@ -178,3 +182,10 @@ GSServer GSEngineGetServer(GSEngine engine) { GSNumber GSEngineGetTPS(GSEngine engine) { return engine->tps; } + +void GSEngineShutdown(GSEngine engine) { + GSLog(engine, GSLogInfo, "Engine shutdown started"); + + /* TODO: proper shutdown */ + engine->shutdown -= 2; +} diff --git a/engine/src/sound.c b/engine/src/sound.c new file mode 100644 index 0000000..5625549 --- /dev/null +++ b/engine/src/sound.c @@ -0,0 +1,48 @@ +#include + +#include + +#include + +static void data_callback(ma_device* device, void* output, const void* input, ma_uint32 frame) { +} + +GSSound GSSoundOpen(GSClient client) { + GSSound sound = malloc(sizeof(*sound)); + + memset(sound, 0, sizeof(*sound)); + + sound->engine = client->engine; + + sound->config = ma_device_config_init(ma_device_type_playback); + sound->config.playback.format = ma_format_s16; + sound->config.playback.channels = 2; + sound->config.sampleRate = GSSoundRate; + sound->config.dataCallback = data_callback; + sound->config.pUserData = sound; + + if(ma_device_init(NULL, &sound->config, &sound->device) != MA_SUCCESS) { + free(sound); + GSLog(client->engine, GSLogInfo, "Failed to open sound"); + return NULL; + } + + if(ma_device_start(&sound->device) != MA_SUCCESS) { + ma_device_uninit(&sound->device); + free(sound); + GSLog(client->engine, GSLogInfo, "Failed to open sound"); + return NULL; + } + + GSLog(client->engine, GSLogInfo, "Opened sound"); + + return sound; +} + +void GSSoundClose(GSSound sound) { + ma_device_uninit(&sound->device); + + GSLog(sound->engine, GSLogInfo, "Closed sound"); + + free(sound); +}