1
0
Fork 0
2022-untitled-game/code/src/game.c

278 lines
6.7 KiB
C

void
game_startup(memory_t* memory)
{
if (SDL_BYTEORDER != SDL_LIL_ENDIAN)
{
LOG_ERROR("Machine is Big Endian; expected Little Endian.");
exit(EXIT_FAILURE);
}
g_memory = memory;
engine_t* engine = engine_mem_alloc(1, sizeof(*engine));
g_engine = engine;
game_t* game = game_mem_alloc(1, sizeof(*game));
g_game = game;
g_asset_mgr = &engine->asset_mgr;
g_audio_mgr = &engine->audio_mgr;
g_render_mgr = &engine->render_mgr;
asset_mgr_startup();
audio_mgr_startup();
render_mgr_startup();
// Load data
game->data = data_load("data.bin");
data_t* data = &game->data;
state_t* state = &game->state;
ui_t* ui = &game->ui;
state->mode = MODE_MAIN_MENU;
state->mode_last = MODE_MAIN_MENU;
// Set up menus
ui->main_menu = (ui_menu_t){
.widget_count = 3,
.widgets = {
{"Play", WINDOW_WIDTH/2, WINDOW_HEIGHT/2, menu_play},
{"Options", WINDOW_WIDTH/2, WINDOW_HEIGHT/2 + 40, menu_options},
{"Quit", WINDOW_WIDTH/2, WINDOW_HEIGHT/2 + 80, menu_quit}},
};
ui->pause_menu = (ui_menu_t){
.widget_count = 3,
.widgets = {
{"Resume", WINDOW_WIDTH/2, WINDOW_HEIGHT/2, menu_play},
{"Options", WINDOW_WIDTH/2, WINDOW_HEIGHT/2 + 40, menu_options},
{"Quit", WINDOW_WIDTH/2, WINDOW_HEIGHT/2 + 80, menu_quit}},
};
ui->options_menu = (ui_menu_t){
.widget_count = 1,
.widgets = {
{"Exit", WINDOW_WIDTH/2, WINDOW_HEIGHT/2, menu_exit}},
};
// Create systems
state->camera = camera_create((vec3){28.0f, 29.0f, 1.0f});
audio_source_t audio_source = {
.wav = get_sfx_by_name("SFX_Enemy"),
.is_looping = true,
.stereo = true};
// Set up world
state->skulls[0].tile_pos.x = 1;
state->skulls[0].tile_pos.y = 1;
state->skulls[0].front = (vec3){0.0f, 1.0f, 0.0f};
audio_source.position = (vec3){
state->skulls[0].tile_pos.x*2.0f+1.0f,
state->skulls[0].tile_pos.y*2.0f+1.0f,
1.0f};
state->skulls[0].audio_source_handle = play_sound(audio_source);
state->skulls[1].tile_pos.x = 26;
state->skulls[1].tile_pos.y = 1;
state->skulls[1].front = (vec3){0.0f, 1.0f, 0.0f};
audio_source.position = (vec3){
state->skulls[1].tile_pos.x*2.0f+1.0f,
state->skulls[1].tile_pos.y*2.0f+1.0f,
1.0f};
state->skulls[1].audio_source_handle = play_sound(audio_source);
state->skulls[2].tile_pos.x = 1;
state->skulls[2].tile_pos.y = 29;
state->skulls[2].front = (vec3){0.0f, -1.0f, 0.0f};
audio_source.position = (vec3){
state->skulls[2].tile_pos.x*2.0f+1.0f,
state->skulls[2].tile_pos.y*2.0f+1.0f,
1.0f};
state->skulls[2].audio_source_handle = play_sound(audio_source);
state->skulls[3].tile_pos.x = 26;
state->skulls[3].tile_pos.y = 29;
state->skulls[3].front = (vec3){0.0f, -1.0f, 0.0f};
audio_source.position = (vec3){
state->skulls[3].tile_pos.x*2.0f+1.0f,
state->skulls[3].tile_pos.y*2.0f+1.0f,
1.0f};
state->skulls[3].audio_source_handle = play_sound(audio_source);
state->nodes[0] = (node_t){
.transform = (transform_t){(vec3){28.0f, 33.0f, 1.5f}, (vec3){0.0f, 0.0f, 0.0f}, (vec3){0.5f, 0.5f, 0.5f}},
.parent = -1,
.children = {1, 2, 3},
.matrix = mat4_identity(),
.rotation = mat4_identity()};
state->nodes[1] = (node_t){
.transform = (transform_t){(vec3){-0.5f, 0.0f, 0.0f}, (vec3){0.0f, 0.0f, 0.0f}, (vec3){1.0f, 1.0f, 1.0f}},
.parent = 0,
.children = {-1, -1, -1},
.matrix = mat4_identity(),
.rotation = mat4_identity()};
state->nodes[2] = (node_t){
.transform = (transform_t){(vec3){0.0f, 0.0f, 0.0f}, (vec3){0.0f, 0.0f, 0.0f}, (vec3){1.0f, 1.0f, 1.0f}},
.parent = 0,
.children = {-1, -1, -1},
.matrix = mat4_identity(),
.rotation = mat4_identity()};
state->nodes[3] = (node_t){
.transform = (transform_t){(vec3){0.5f, 0.0f, 0.0f}, (vec3){0.0f, 0.0f, 0.0f}, (vec3){1.0f, 1.0f, 1.0f}},
.parent = 0,
.children = {-1, -1, -1},
.matrix = mat4_identity(),
.rotation = mat4_identity()};
// Initalize footsteps
state->footstep_timer = FOOTSTEP_TIMER;
state->footstep_cycle = false;
// Create a copy of the game items so we can restore the original layout on new game/level
state->coin_count = data->items.coin_count;
state->eyeball_count = data->items.eyeball_count;
state->coins = game_mem_alloc(data->items.coin_count, sizeof(*state->coins));
state->eyeballs = game_mem_alloc(data->items.eyeball_count, sizeof(*state->eyeballs));
memcpy(state->coins, data->items.coins, data->items.coin_count * sizeof(*data->items.coins));
for (int i = 0; i < state->eyeball_count; i++)
{
state->eyeballs[i].transform = data->items.eyeballs[i];
state->eyeballs[i].used = false;
}
g_audio_mgr->listener.position = state->camera.position;
g_audio_mgr->listener.front = state->camera.front;
g_audio_mgr->listener.up = WORLD_UP;
audio_source_t creepy_music = {
.wav = get_music_by_name("MUS_Ambience"),
.is_looping = true};
state->background_music_handle = play_sound(creepy_music);
audio_source_t enemy_sfx = {
.position = {28.0f, 33.0f, 1.0f},
.wav = get_sfx_by_name("SFX_SafeZone"),
.stereo = true,
.is_looping = true};
play_sound(enemy_sfx);
}
void
game_shutdown(void)
{
}
void
game_update(memory_t* memory, float dt, input_t input, bool* quit_requested)
{
// Re-cache memory pointer in case of DLL reload
g_memory = memory;
engine_t* engine = (engine_t*)memory->engine.begin;
game_t* game = (game_t*)memory->game.begin;
state_t* state = &game->state;
ui_t* ui = &game->ui;
// Re-cache
g_game = game;
g_asset_mgr = &engine->asset_mgr;
g_audio_mgr = &engine->audio_mgr;
g_render_mgr = &engine->render_mgr;
state->time += dt;
if (input.pause && input.pause != state->input_prev.pause)
{
state->mode = MODE_PAUSE;
}
switch (state->mode)
{
case MODE_MAIN_MENU:
{
menu_update(input, &ui->main_menu);
} break;
case MODE_OPTIONS:
{
menu_update(input, &ui->options_menu);
} break;
case MODE_PAUSE:
{
menu_update(input, &ui->pause_menu);
} break;
case MODE_PLAY:
{
play(dt, input);
} break;
case MODE_QUIT:
{
*quit_requested = true;
}
default: break;
}
state->input_prev = input;
}
void
game_render(void)
{
state_t* state = &g_game->state;
ui_t* ui = &g_game->ui;
reload_shaders();
switch (state->mode)
{
case MODE_MAIN_MENU:
{
menu_render(&ui->main_menu);
} break;
case MODE_OPTIONS:
{
menu_render(&ui->options_menu);
} break;
case MODE_PAUSE:
{
menu_render(&ui->pause_menu);
} break;
case MODE_PLAY:
{
render_geo();
render_screen();
} break;
default: break;
}
}
void
game_debug(uint64_t update_time, uint64_t render_time, uint64_t frame_time)
{
state_t* state = &g_game->state;
switch (state->mode)
{
case MODE_PLAY:
{
debug(update_time, render_time, frame_time);
} break;
default: break;
}
}
void
game_audio_callback(void* userdata, uint8_t* stream, int len)
{
(void)userdata; (void)stream; (void)len;
fill_audio_buffer(stream, len);
}