#include "asset.h" #include "enemy.h" #include "game.h" #include "platform.h" #include "sprite.h" #include "standard.h" #include "systems.h" static void menu_new(Menu* menu) { Game* game; game = menu->ptr; game_change_state(game, game_state_game); } static void menu_restart(Menu* menu) { Game* game; game = menu->ptr; game_change_state(game, game_state_game); } static void menu_main_menu(Menu* menu) { Game* game; game = menu->ptr; game_change_state(game, game_state_menu); } static void menu_quit(Menu* menu) { (void)menu; platform_quit(); } static void menu_credits(Menu* menu) { Game* game; game = menu->ptr; game_change_state(game, game_state_credits); } static void menu_init(Game* game) { const BM_Font* font; font = get_default_font(); init_menu(&game->menu, game); menu_add(&game->menu, "Play", menu_new, font); menu_add(&game->menu, "Credits", menu_credits, font); menu_add(&game->menu, "Quit", menu_quit, font); } static void menu_update(Game* game) { const Sprite* msg; const Bitmap* bmp; int y; update_menu(&game->menu); y = game->menu.y; msg = get_sprite(sprite_author); bmp = get_bitmap(msg->bitmap); render_bitmap( bmp, renderer_w / 2 - msg->rect.w / 2, renderer_h - 26, &msg->rect ); msg = get_sprite(sprite_free); bmp = get_bitmap(msg->bitmap); render_bitmap( bmp, renderer_w / 2 - msg->rect.w / 2, renderer_h - 15, &msg->rect ); /* Logo. */ msg = get_sprite(sprite_logo); bmp = get_bitmap(msg->bitmap); render_bitmap( bmp, renderer_w / 2 - msg->rect.w / 2, y - msg->rect.h - 8, &msg->rect ); render_menu(&game->menu, get_default_font()); } static void menu_deinit(Game* game) { } static void gameplay_init(Game* game) { World* world; world = &game->world; seed_rng(500); init_world(&game->world); init_map(&world->map, world); init_player(&world->player, world); init_waver(&world->waver); world->gmemory = gmemory_max; } static void render_hud(Game* game) { int i, g; const Sprite* sprite; const Bitmap* bitmap; World* world; Player* player; world = &game->world; player = &world->player; sprite = get_sprite(sprite_heart_full); bitmap = get_bitmap(sprite->bitmap); for (i = 0; i < player->hp; i++) { render_bitmap( bitmap, 1 + i * (sprite->rect.w + 1), 1, &sprite->rect ); } sprite = get_sprite(sprite_heart_empty); bitmap = get_bitmap(sprite->bitmap); for (; i < player_max_hp; i++) { render_bitmap( bitmap, 1 + i * (sprite->rect.w + 1), 1, &sprite->rect ); } sprite = get_sprite(sprite_ram_full); bitmap = get_bitmap(sprite->bitmap); g = world->gmemory / gmemory_units; for (i = 0; i < g; i++) { render_bitmap( bitmap, 1 + i * (sprite->rect.w + 1), 8, &sprite->rect ); } sprite = get_sprite(sprite_ram_empty); bitmap = get_bitmap(sprite->bitmap); g = gmemory_max / gmemory_units; for (; i < g; i++) { render_bitmap( bitmap, 1 + i * (sprite->rect.w + 1), 8, &sprite->rect ); } } static void gameplay_update(Game* game) { int cx, cy; World* world; Player* player; cx = game->world.cam_x; cy = game->world.cam_y; world = &game->world; player = &world->player; update_waver(&world->waver, world); update_player(player, world); enemy_system(world); debris_system(world); bullet_system(world); collision_system(world); animation_system(world); update_camera(player, world); render_map(&world->map, cx, cy); sprite_system(world); render_hud(game); if (world->gmemory <= 0) { world->oom = 1; game_change_state(game, game_state_dead); } } static void gameplay_deinit(Game* game) { } static void credits_init(Game* game) { } static void credits_update(Game* game) { } static void credits_deinit(Game* game) { } static void dead_init(Game* game) { const BM_Font* font = get_default_font(); init_menu(&game->menu, game); menu_add(&game->menu, "Restart", menu_restart, font); menu_add(&game->menu, "Main Menu", menu_main_menu, font); } static void dead_update(Game* game) { const BM_Font* font; int cx, cy; World* world; font = get_default_font(); world = &game->world; update_menu(&game->menu); cx = game->world.cam_x; cy = game->world.cam_y; render_map(&game->world.map, cx, cy); sprite_system(&game->world); if (world->oom) { rfont_text( font, renderer_w / 2 - 65, game->menu.y - 15, "Out of Memory" ); } else { rfont_text( font, renderer_w / 2 - 40, game->menu.y - 15, "You died" ); } render_menu(&game->menu, get_default_font()); } static void dead_deinit(Game* game) { } static const Game_State_Fns game_state_fns[] = { /* game_state_menu */ { menu_init, menu_update, menu_deinit }, /* game_state_game */ { gameplay_init, gameplay_update, gameplay_deinit }, /* game_state_credits */ { credits_init, credits_update, credits_deinit }, /* game_state_dead */ { dead_init, dead_update, dead_deinit } }; static const Game_State_Fns* get_state_fns(Game_State state) { return &game_state_fns[state]; } void game_init(Game* game, Game_State state) { game->state = state; game->fns = get_state_fns(state); game->fns->state_init(game); } void game_update(Game* game) { game->fns->state_update(game); } void game_deinit(Game* game) { game->fns->state_deinit(game); } void game_change_state(Game* game, Game_State state) { game->fns->state_deinit(game); game->state = state; game->fns = get_state_fns(state); game->fns->state_init(game); }