278 lines
6.7 KiB
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);
|
|
}
|
|
|