diff options
Diffstat (limited to 'game.c')
-rw-r--r-- | game.c | 172 |
1 files changed, 172 insertions, 0 deletions
@@ -0,0 +1,172 @@ +#include "animation.h" +#include "asset.h" +#include "game.h" +#include "plat.h" +#include "render.h" + +const Rect logo_rect = { 47, 0, 54, 16 }; + +void init_game(Game* g, Game_State s) { + World* w = &g->w; + g->st = s; + g->frame = 0; + g->want_next = 0; + init_world(w); +} + +void update_menu(Game* g, App* a) { + int i; + for (i = 0; i < btn_count; i++) + if (a->btn_states[i] & btn_state_pressed) { + queue_gs(g, game_state_fade_out); + queue_gs(g, game_state_generate); + queue_gs(g, game_state_fade_in); + queue_gs(g, game_state_play); + g->want_next = 1; + return; + } +} + +void queue_gs(Game* g, Game_State s) { + assert(g->qt < game_max_state_queue); + g->sq[g->qt++] = s; +} + +void on_transition(Game* g) { + g->ff = 0; +} + +void next_gs(Game* g) { + int i, e = --g->qt; + g->ps = g->st; + g->st = g->sq[0]; + for (i = 0; i < e; i++) + g->sq[i] = g->sq[i + 1]; + on_transition(g); +} + +void detect_next(Game* g, const World* w) { + const Player* p = &w->player; + if (p->y < 0) /* next level */ { + queue_gs(g, game_state_fade_out); + queue_gs(g, game_state_generate); + queue_gs(g, game_state_fade_in); + queue_gs(g, game_state_play); + g->want_next = 1; + } +} + +void update_game(Game* g, App* a) { + const Animation* fa; + if (g->want_next) { + next_gs(g); + g->want_next = 0; + } + switch (g->st) { + case game_state_menu: + update_menu(g, a); + break; + case game_state_over: + break; + case game_state_fade_in: + fa = get_animation(asset_id_fade_in_anm); + if (g->ff < fa->fc * fa->s - 1) + update_anim(fa, &g->ff, &g->fr); + else + g->want_next = 1; + break; + case game_state_fade_out: + fa = get_animation(asset_id_fade_out_anm); + if (g->ff < fa->fc * fa->s - 1) + update_anim(fa, &g->ff, &g->fr); + else + g->want_next = 1; + break; + case game_state_generate: + generate_floor(&g->w.map, &g->w); + g->want_next = 1; + break; + case game_state_play: + update_world(&g->w, a); + detect_next(g, &g->w); + break; + } + g->frame++; +} + +void ren_menu(const Game* g, Renderer* r) { + const Bitmap* bm = get_bitmap(asset_id_hud_img); + const int hv = viewport_w >> 1; + ren_map( + r, + hv - (logo_rect.w >> 1), + 100, + &logo_rect, + bm + ); + if (g->frame & 3) + ren_text( + r, + hv - 38, + 155, + "ANY BUTTON TO START" + ); + ren_text( + r, + hv - 24, + 200, + "made by quou" + ); + ren_text( + r, + hv - 44, + 205, + "public domain software" + ); + ren_text( + r, + hv - 16, + 210, + "quou.xyz" + ); +} + +void ren_state(const Game* g, Game_State s, Renderer* r) { + switch (s) { + case game_state_menu: + ren_menu(g, r); + break; + case game_state_over: + break; + case game_state_generate: + break; + case game_state_play: + ren_world(&g->w, r); + break; + default: break; + } +} + +void ren_fade(const Game* g, Renderer* r) { + const Bitmap* bm = get_bitmap(asset_id_hud_img); + const Rect* re = &g->fr; + int x, y; + for (y = 0; y < viewport_h; y += re->h) + for (x = 0; x < viewport_w; x += re->w) + ren_cmap(r, x, y, re, bm); +} + +void ren_game(const Game* g, Renderer* r) { + switch (g->st) { + case game_state_fade_in: + ren_state(g, g->sq[1], r); + ren_fade(g, r); + break; + case game_state_fade_out: + ren_state(g, g->ps, r); + ren_fade(g, r); + break; + default: + ren_state(g, g->st, r); + } +} |