Compare commits

...

6 Commits

Author SHA1 Message Date
En Yi 7dc66945da Add in engine configuration
All engine constants now sits in a single header file for easy tweaking
Also, SFX list fields is now an array rather than a pointer instead.
2023-10-13 21:55:30 +08:00
En Yi b9b0c11524 Separate out engine from scenes
This creates stronger separation the engine stuff from game
implementations.

way overdue tbh
2023-10-13 21:26:42 +08:00
En Yi b3de60b4bc Merge EC into engine directly
There is not much gained separating EC from engine. Merge it.
sc is still separated though.
2023-10-13 21:21:22 +08:00
En Yi 92555708d7 Put more boilerplate inits into engine init 2023-10-13 21:08:48 +08:00
En Yi e318c65135 Add some more sfx 2023-10-10 21:57:45 +08:00
En Yi 2b79b5e6bc implement simple sfx playback for jumping 2023-10-09 21:28:30 +08:00
47 changed files with 179 additions and 83 deletions

View File

@ -23,7 +23,7 @@ set(GAME_LIBS
lib_scenes lib_scenes
) )
add_subdirectory(engine)
add_subdirectory(scenes) add_subdirectory(scenes)
add_subdirectory(res) add_subdirectory(res)

View File

@ -1,4 +1,4 @@
add_subdirectory(EC) add_subdirectory(sc)
add_library(lib_engine STATIC add_library(lib_engine STATIC
assets.c assets.c
AABB.c AABB.c
@ -6,6 +6,8 @@ add_library(lib_engine STATIC
engine.c engine.c
collisions.c collisions.c
rres.c rres.c
mempool.c
entManager.c
${LIBZSTD_DIR}/lib/libzstd.a ${LIBZSTD_DIR}/lib/libzstd.a
) )
target_include_directories(lib_engine target_include_directories(lib_engine
@ -13,9 +15,18 @@ target_include_directories(lib_engine
${LIBZSTD_DIR}/include ${LIBZSTD_DIR}/include
PUBLIC PUBLIC
${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}
${RAYLIB_DIR}/include
)
target_link_directories(lib_engine
PUBLIC
${RAYLIB_DIR}/lib
) )
target_link_libraries(lib_engine target_link_libraries(lib_engine
PUBLIC PUBLIC
lib_EC
zstd zstd
raylib
sc_queue
sc_map
sc_array
m
) )

View File

@ -6,9 +6,8 @@
#include "sc/map/sc_map.h" #include "sc/map/sc_map.h"
#include "sc/queue/sc_queue.h" #include "sc/queue/sc_queue.h"
#define N_TAGS 10 #include "engine_conf.h"
#define N_COMPONENTS 14
#define MAX_COMP_POOL_SIZE 1024
typedef struct EntityManager EntityManager_t; typedef struct EntityManager EntityManager_t;
typedef struct Entity Entity_t; typedef struct Entity Entity_t;

View File

@ -1,5 +1,6 @@
#include "assets.h" #include "assets.h"
#include "assert.h" #include "assert.h"
#include "engine_conf.h"
#define RRES_RAYLIB_IMPLEMENTATION #define RRES_RAYLIB_IMPLEMENTATION
#include "rres.h" #include "rres.h"
@ -7,13 +8,6 @@
#include "zstd.h" #include "zstd.h"
#include <stdio.h> #include <stdio.h>
#define MAX_TEXTURES 16
#define MAX_SPRITES 64
#define MAX_SOUNDS 16
#define MAX_FONTS 4
#define MAX_N_TILES 4096
#define MAX_NAME_LEN 32
#define MAX_LEVEL_PACK 4
uint8_t n_loaded[5] = {0}; uint8_t n_loaded[5] = {0};
// Hard limit number of // Hard limit number of

View File

@ -65,4 +65,12 @@ Font* get_font(Assets_t* assets, const char* name);
LevelPack_t* get_level_pack(Assets_t* assets, const char* name); LevelPack_t* get_level_pack(Assets_t* assets, const char* name);
void draw_sprite(Sprite_t* spr, Vector2 pos, bool flip_x); void draw_sprite(Sprite_t* spr, Vector2 pos, bool flip_x);
typedef struct SFX
{
Sound* snd;
uint8_t plays;
uint8_t cooldown;
} SFX_t;
#endif // __ASSETS_H #endif // __ASSETS_H

View File

@ -1,7 +1,6 @@
#ifndef __COLLISION_FUNCS_H #ifndef __COLLISION_FUNCS_H
#define __COLLISION_FUNCS_H #define __COLLISION_FUNCS_H
#include "EC.h" #include "EC.h"
#define MAX_TILE_TYPES 16
typedef enum SolidType typedef enum SolidType
{ {

View File

@ -1,12 +1,19 @@
#include "engine.h" #include "engine.h"
#include "mempool.h"
void init_engine(GameEngine_t* engine) void init_engine(GameEngine_t* engine)
{ {
sc_queue_init(&engine->key_buffer); sc_queue_init(&engine->key_buffer);
engine->sfx_list.n_sfx = N_SFX;
memset(engine->sfx_list.sfx, 0, engine->sfx_list.n_sfx * sizeof(SFX_t));
init_memory_pools();
init_assets(&engine->assets);
} }
void deinit_engine(GameEngine_t* engine) void deinit_engine(GameEngine_t* engine)
{ {
term_assets(&engine->assets);
free_memory_pools();
sc_queue_term(&engine->key_buffer); sc_queue_term(&engine->key_buffer);
} }
@ -48,6 +55,39 @@ void change_scene(GameEngine_t* engine, unsigned int idx)
engine->scenes[engine->curr_scene]->state = SCENE_PLAYING; engine->scenes[engine->curr_scene]->state = SCENE_PLAYING;
} }
bool load_sfx(GameEngine_t* engine, const char* snd_name, uint32_t tag_idx)
{
if (tag_idx >= engine->sfx_list.n_sfx) return false;
Sound* snd = get_sound(&engine->assets, snd_name);
if (snd == NULL) return false;
engine->sfx_list.sfx[tag_idx].snd = snd;
engine->sfx_list.sfx[tag_idx].cooldown = 0;
engine->sfx_list.sfx[tag_idx].plays = 0;
return true;
}
void play_sfx(GameEngine_t* engine, unsigned int tag_idx)
{
if (tag_idx >= engine->sfx_list.n_sfx) return;
SFX_t* sfx = engine->sfx_list.sfx + tag_idx;
if (sfx->plays == 0 && sfx->snd != NULL)
{
PlaySound(*sfx->snd);
sfx->plays++;
engine->sfx_list.sfx_queue[engine->sfx_list.played_sfx++] = tag_idx;
}
}
void update_sfx_list(GameEngine_t* engine)
{
for (uint32_t i = 0; i< engine->sfx_list.played_sfx; ++i)
{
uint32_t tag_idx = engine->sfx_list.sfx_queue[i];
engine->sfx_list.sfx[tag_idx].plays = 0;
}
engine->sfx_list.played_sfx = 0;
}
//void init_scene(Scene_t* scene, SceneType_t scene_type, system_func_t render_func, action_func_t action_func) //void init_scene(Scene_t* scene, SceneType_t scene_type, system_func_t render_func, action_func_t action_func)
void init_scene(Scene_t* scene, system_func_t render_func, action_func_t action_func) void init_scene(Scene_t* scene, system_func_t render_func, action_func_t action_func)
{ {

View File

@ -7,15 +7,23 @@
typedef struct Scene Scene_t; typedef struct Scene Scene_t;
typedef struct SFXList
{
SFX_t sfx[N_SFX];
uint32_t sfx_queue[N_SFX];
uint32_t n_sfx;
uint32_t played_sfx;
} SFXList_t;
typedef struct GameEngine { typedef struct GameEngine {
Scene_t **scenes; Scene_t **scenes;
unsigned int max_scenes; unsigned int max_scenes;
unsigned int curr_scene; unsigned int curr_scene;
Assets_t assets; Assets_t assets;
SFXList_t sfx_list;
// Maintain own queue to handle key presses // Maintain own queue to handle key presses
struct sc_queue_32 key_buffer; struct sc_queue_32 key_buffer;
} GameEngine_t; } GameEngine_t;
void change_scene(GameEngine_t* engine, unsigned int idx);
//typedef enum SceneType { //typedef enum SceneType {
// LEVEL_SCENE = 0, // LEVEL_SCENE = 0,
@ -47,6 +55,11 @@ void init_engine(GameEngine_t* engine);
void deinit_engine(GameEngine_t* engine); void deinit_engine(GameEngine_t* engine);
void process_inputs(GameEngine_t* engine, Scene_t* scene); void process_inputs(GameEngine_t* engine, Scene_t* scene);
void change_scene(GameEngine_t* engine, unsigned int idx);
bool load_sfx(GameEngine_t* engine, const char* snd_name, uint32_t tag_idx);
void play_sfx(GameEngine_t* engine, unsigned int tag_idx);
void update_sfx_list(GameEngine_t* engine);
// Inline functions, for convenience // Inline functions, for convenience
extern void update_scene(Scene_t* scene); extern void update_scene(Scene_t* scene);
extern void render_scene(Scene_t* scene); extern void render_scene(Scene_t* scene);

View File

@ -0,0 +1,18 @@
#ifndef _ENGINE_CONF_H
#define _ENGINE_CONF_H
#define MAX_TEXTURES 16
#define MAX_SPRITES 64
#define MAX_SOUNDS 16
#define MAX_FONTS 4
#define MAX_N_TILES 4096
#define MAX_NAME_LEN 32
#define MAX_LEVEL_PACK 4
#define N_SFX 18
#define MAX_TILE_TYPES 16
#define N_TAGS 10
#define N_COMPONENTS 14
#define MAX_COMP_POOL_SIZE 1024
#endif // _ENGINE_CONF_H

View File

@ -188,21 +188,21 @@ const char** GetTextLines(const char* text, int* count)
int textSize = (int)strlen(text); int textSize = (int)strlen(text);
lines[0] = text; lines[0] = text;
int len = 0; //int len = 0;
*count = 1; *count = 1;
int lineSize = 0; // Stores current line size, not returned //int lineSize = 0; // Stores current line size, not returned
for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++) for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
{ {
if (text[i] == '\n') if (text[i] == '\n')
{ {
lineSize = len; //lineSize = len;
k++; k++;
lines[k] = &text[i + 1]; // WARNING: next value is valid? lines[k] = &text[i + 1]; // WARNING: next value is valid?
len = 0; //len = 0;
*count += 1; *count += 1;
} }
else len++; //else len++;
} }
//lines[*count - 1].size = len; //lines[*count - 1].size = len;

View File

@ -1,5 +1,5 @@
#include "mempool.h"
#include "ent_impl.h" #include "ent_impl.h"
#include "mempool.h"
#include <stdio.h> #include <stdio.h>
int main(void) int main(void)

View File

@ -1,6 +1,4 @@
#include "constants.h" #include "constants.h"
#include "mempool.h"
#include "raymath.h"
#include "scene_impl.h" #include "scene_impl.h"
#include "ent_impl.h" #include "ent_impl.h"
#include "water_flow.h" #include "water_flow.h"
@ -23,9 +21,7 @@ int main(void)
init_engine(&engine); init_engine(&engine);
InitWindow(1280, 640, "raylib"); InitWindow(1280, 640, "raylib");
SetTargetFPS(60); SetTargetFPS(60);
init_memory_pools();
init_assets(&engine.assets);
load_from_infofile("res/test_assets.info", &engine.assets); load_from_infofile("res/test_assets.info", &engine.assets);
LevelPack_t* pack = get_level_pack(&engine.assets, "TestLevels"); LevelPack_t* pack = get_level_pack(&engine.assets, "TestLevels");
assert(pack != NULL); assert(pack != NULL);
@ -61,7 +57,6 @@ int main(void)
} }
free_scene(&scene.scene); free_scene(&scene.scene);
term_level_scene_data(&scene.data); term_level_scene_data(&scene.data);
deinit_engine(&engine);
term_assets(&engine.assets);
CloseWindow(); CloseWindow();
deinit_engine(&engine);
} }

6
main.c
View File

@ -27,9 +27,6 @@ int main(void)
init_engine(&engine); init_engine(&engine);
InitWindow(screenWidth, screenHeight, "raylib"); InitWindow(screenWidth, screenHeight, "raylib");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second
init_memory_pools();
init_assets(&engine.assets);
#ifndef NDEBUG #ifndef NDEBUG
load_from_infofile("res/assets_debug.info", &engine.assets); load_from_infofile("res/assets_debug.info", &engine.assets);
init_player_creation("res/player_spr.info", &engine.assets); init_player_creation("res/player_spr.info", &engine.assets);
@ -95,7 +92,6 @@ int main(void)
free_sandbox_scene(&sandbox_scene); free_sandbox_scene(&sandbox_scene);
free_game_scene(&level_scene); free_game_scene(&level_scene);
free_menu_scene(&menu_scene); free_menu_scene(&menu_scene);
deinit_engine(&engine);
term_assets(&engine.assets);
CloseWindow(); CloseWindow();
deinit_engine(&engine);
} }

View File

@ -1,4 +1,3 @@
#include "mempool.h"
#include "scene_impl.h" #include "scene_impl.h"
#include "ent_impl.h" #include "ent_impl.h"
#include "assets_loader.h" #include "assets_loader.h"
@ -8,14 +7,14 @@
#include <emscripten/emscripten.h> #include <emscripten/emscripten.h>
#endif #endif
Scene_t* scenes[1]; Scene_t* scenes[1];
static GameEngine_t engine = static GameEngine_t engine =
{ {
.scenes = scenes, .scenes = scenes,
.max_scenes = 1, .max_scenes = 1,
.curr_scene = 0, .curr_scene = 0,
.assets = {0} .assets = {0},
.sfx_list = {0}
}; };
void update_loop(void) void update_loop(void)
@ -31,12 +30,11 @@ void update_loop(void)
int main(void) int main(void)
{ {
init_engine(&engine);
InitWindow(1280, 640, "raylib"); InitWindow(1280, 640, "raylib");
SetTargetFPS(60); SetTargetFPS(60);
init_memory_pools(); InitAudioDevice();
init_engine(&engine);
init_assets(&engine.assets);
#ifndef NDEBUG #ifndef NDEBUG
load_from_infofile("res/assets.info.raw", &engine.assets); load_from_infofile("res/assets.info.raw", &engine.assets);
@ -47,6 +45,17 @@ int main(void)
#endif #endif
init_item_creation(&engine.assets); init_item_creation(&engine.assets);
add_sound(&engine.assets, "snd_jump", "res/jump.ogg");
add_sound(&engine.assets, "snd_land", "res/land.ogg");
add_sound(&engine.assets, "snd_wdrop", "res/water_land.ogg");
add_sound(&engine.assets, "snd_bland", "res/boulder_move.ogg");
add_sound(&engine.assets, "snd_bubble", "res/bubble.ogg");
load_sfx(&engine, "snd_jump", PLAYER_JMP_SFX);
load_sfx(&engine, "snd_land", PLAYER_LAND_SFX);
load_sfx(&engine, "snd_wdrop", WATER_IN_SFX);
load_sfx(&engine, "snd_bland", BOULDER_LAND_SFX);
load_sfx(&engine, "snd_bubble", BUBBLE_SFX);
LevelScene_t scene; LevelScene_t scene;
scene.scene.engine = &engine; scene.scene.engine = &engine;
init_sandbox_scene(&scene); init_sandbox_scene(&scene);
@ -75,12 +84,12 @@ int main(void)
update_entity_manager(&scene.scene.ent_manager); update_entity_manager(&scene.scene.ent_manager);
// This is needed to advance time delta // This is needed to advance time delta
render_scene(&scene.scene); render_scene(&scene.scene);
update_sfx_list(&engine);
if (WindowShouldClose()) break; if (WindowShouldClose()) break;
} }
#endif #endif
free_sandbox_scene(&scene); free_sandbox_scene(&scene);
deinit_engine(&engine); deinit_engine(&engine);
term_assets(&engine.assets);
CloseWindow(); CloseWindow();
} }

View File

@ -1,4 +1,3 @@
add_subdirectory(engine)
add_library(lib_scenes STATIC add_library(lib_scenes STATIC
assets_loader.c assets_loader.c
player_ent.c player_ent.c

View File

@ -0,0 +1,35 @@
#ifndef _ASSETS_TAG_H
#define _ASSETS_TAG_H
typedef enum EntityTag {
NO_ENT_TAG = 0,
PLAYER_ENT_TAG,
ENEMY_ENT_TAG,
CRATES_ENT_TAG,
CHEST_ENT_TAG,
BOULDER_ENT_TAG,
LEVEL_END_TAG,
DESTRUCTABLE_ENT_TAG,
DYNMEM_ENT_TAG,
} EntityTag_t;
typedef enum SFXTag {
PLAYER_JMP_SFX = 0,
PLAYER_LAND_SFX,
PLAYER_RUN_SFX,
PLAYER_LADDER_SFX,
PLAYER_WATER_RUN_SFX,
WATER_IN_SFX,
WATER_OUT_SFX,
WOOD_LAND_SFX,
WOOD_DESTROY_SFX,
METAL_LAND_SFX,
METAL_DESTROY_SFX,
BOULDER_LAND_SFX,
BOULDER_DESTROY_SFX,
ARROW_RELEASE_SFX,
ARROW_DESTROY_SFX,
BOMB_RELEASE_SFX,
EXPLOSION_SFX,
BUBBLE_SFX,
} SFXTag_t;
#endif

View File

@ -1,23 +0,0 @@
add_subdirectory(sc)
add_library(lib_EC STATIC
mempool.c
entManager.c
)
target_include_directories(lib_EC
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
${RAYLIB_DIR}/include
)
target_link_directories(lib_EC
PUBLIC
${RAYLIB_DIR}/lib
)
target_link_libraries(lib_EC
PUBLIC
raylib
sc_queue
sc_map
sc_array
m
)

View File

@ -1,19 +1,7 @@
#ifndef __ENT_IMPL_H #ifndef __ENT_IMPL_H
#define __ENT_IMPL_H #define __ENT_IMPL_H
#include "assets.h" #include "assets.h"
#include "assets_tag.h"
typedef enum EntityTag {
NO_ENT_TAG = 0,
PLAYER_ENT_TAG,
ENEMY_ENT_TAG,
CRATES_ENT_TAG,
CHEST_ENT_TAG,
BOULDER_ENT_TAG,
LEVEL_END_TAG,
DESTRUCTABLE_ENT_TAG,
DYNMEM_ENT_TAG,
} EntityTag_t;
bool init_player_creation(const char* info_file, Assets_t* assets); bool init_player_creation(const char* info_file, Assets_t* assets);
bool init_player_creation_rres(const char* rres_file, const char* file, Assets_t* assets); bool init_player_creation_rres(const char* rres_file, const char* file, Assets_t* assets);

View File

@ -362,6 +362,7 @@ void player_movement_input_system(Scene_t* scene)
// Check if possible to jump when jump is pressed // Check if possible to jump when jump is pressed
if (p_cjump->jump_released && p_pstate->jump_pressed && p_cjump->jumps > 0 && p_cjump->jump_ready) if (p_cjump->jump_released && p_pstate->jump_pressed && p_cjump->jumps > 0 && p_cjump->jump_ready)
{ {
play_sfx(scene->engine, PLAYER_JMP_SFX);
p_cjump->jumps--; p_cjump->jumps--;
if (!in_water) if (!in_water)
{ {
@ -385,6 +386,12 @@ void player_movement_input_system(Scene_t* scene)
p_cjump->jump_ready = false; p_cjump->jump_ready = false;
p_cjump->jump_released = false; p_cjump->jump_released = false;
} }
else if (p_mstate->ground_state == 0b01)
{
// the else if check is to prevent playing the landing sfx
// on first frame jumps
play_sfx(scene->engine, PLAYER_LAND_SFX);
}
} }
} }
@ -898,6 +905,7 @@ void moveable_update_system(Scene_t* scene)
p_moveable->gridmove = false; p_moveable->gridmove = false;
p_bbox->solid = true; p_bbox->solid = true;
p_ctransform->movement_mode = REGULAR_MOVEMENT; p_ctransform->movement_mode = REGULAR_MOVEMENT;
play_sfx(scene->engine, BOULDER_LAND_SFX);
} }
else if (remaining_distance > 0.1) else if (remaining_distance > 0.1)
{ {
@ -1345,6 +1353,17 @@ void state_transition_update_system(Scene_t* scene)
{ {
p_ctransform->active = true; p_ctransform->active = true;
} }
if (p_mstate->ground_state == 0b01)
{
if (p_ent->m_tag == BOULDER_ENT_TAG)
{
play_sfx(scene->engine, BOULDER_LAND_SFX);
}
}
if (p_mstate->water_state == 0b01)
{
play_sfx(scene->engine, WATER_IN_SFX);
}
} }
} }
@ -1741,6 +1760,7 @@ void airtimer_update_system(Scene_t* scene)
{ {
p_air->curr_count--; p_air->curr_count--;
p_air->curr_ftimer = p_air->max_ftimer; p_air->curr_ftimer = p_air->max_ftimer;
play_sfx(scene->engine, BUBBLE_SFX);
} }
else else
{ {

View File

@ -1,11 +1,10 @@
#include "constants.h" #include "constants.h"
#include "mempool.h"
#include "raymath.h"
#include "scene_impl.h" #include "scene_impl.h"
#include "ent_impl.h" #include "ent_impl.h"
#include "water_flow.h" #include "water_flow.h"
#include "game_systems.h" #include "game_systems.h"
#include "assets_loader.h" #include "assets_loader.h"
#include "raymath.h"
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
@ -407,12 +406,9 @@ static void player_simple_movement_system(Scene_t* scene)
int main(void) int main(void)
{ {
init_engine(&engine);
InitWindow(1280, 640, "raylib"); InitWindow(1280, 640, "raylib");
SetTargetFPS(60); SetTargetFPS(60);
init_memory_pools(); init_engine(&engine);
init_assets(&engine.assets);
LevelScene_t scene; LevelScene_t scene;
scene.scene.engine = &engine; scene.scene.engine = &engine;
@ -474,6 +470,5 @@ int main(void)
free_scene(&scene.scene); free_scene(&scene.scene);
term_level_scene_data(&scene.data); term_level_scene_data(&scene.data);
deinit_engine(&engine); deinit_engine(&engine);
term_assets(&engine.assets);
CloseWindow(); CloseWindow();
} }