diff --git a/CMakeLists.txt b/CMakeLists.txt index 36f791b..665ce22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,8 @@ set(ASSETS assets-cg/lepheyatis_logo.png assets-cg/font_boson.png assets-cg/font_energy.png + assets-cg/font_energy2.png + assets-cg/font_energy3.png assets-cg/erik_running.gif assets-cg/erik_jumping.gif assets-cg/stages/stage1.png diff --git a/assets-cg/font_boson.png b/assets-cg/font_boson.png index d04b98d..7516047 100644 Binary files a/assets-cg/font_boson.png and b/assets-cg/font_boson.png differ diff --git a/assets-cg/font_energy2.png b/assets-cg/font_energy2.png new file mode 100644 index 0000000..7b0b21d Binary files /dev/null and b/assets-cg/font_energy2.png differ diff --git a/assets-cg/font_energy3.png b/assets-cg/font_energy3.png new file mode 100644 index 0000000..3d2d44a Binary files /dev/null and b/assets-cg/font_energy3.png differ diff --git a/assets-cg/fxconv-metadata.txt b/assets-cg/fxconv-metadata.txt index 15684c8..376a963 100644 --- a/assets-cg/fxconv-metadata.txt +++ b/assets-cg/fxconv-metadata.txt @@ -33,9 +33,9 @@ font_boson.png: proportional: true height: 9 -font_energy.png: +font_energy*.png: type: bopti-image - name: img_font_energy + name_regex: (.*)\.png img_\1 profile: p8_rgb565a *.gif: diff --git a/src/level.cpp b/src/level.cpp index beb2dab..e5c9dc9 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -9,14 +9,17 @@ struct level level_create(int level) switch(level) { default: + l.name = "geon"; l.gen = std::make_unique(); l.bgcolor = RGB24(0x49759f); break; case 2: + l.name = "acceleron"; l.gen = std::make_unique(); l.bgcolor = RGB24(0xe7c272); break; case 3: + l.name = "radion"; l.gen = std::make_unique(); l.bgcolor = C_WHITE; break; diff --git a/src/level.h b/src/level.h index 5811ff5..c140bbb 100644 --- a/src/level.h +++ b/src/level.h @@ -32,6 +32,7 @@ struct platform { struct Generator; struct level { + char const *name; std::vector platform_buffer; std::unique_ptr gen; uint16_t bgcolor; diff --git a/src/main.cpp b/src/main.cpp index 8a47412..838219a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -311,7 +311,7 @@ int play_level(int level_id) } } - if(game.t_death >= TIME_DEATH_ANIMATION) + if(game.t_death >= TIME_DEATH_ANIMATION && keybuffer.shift) break; game_advance(&game); diff --git a/src/render.cpp b/src/render.cpp index 0335efd..e8cc20c 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -169,35 +169,47 @@ void render_anim_frame(int x, int y, struct anim *anim, int frame) anim->frames[frame]); } -static bool render_energy_str_glyph_params(int c, int *ix, int *w) +static bool render_energy_str_glyph_params(int size, int c, int *ix, int *w) { + size = (size >= 1 && size <= 3) ? size-1 : 0; + int dw[3] = { 11, 14, 18 }; + int ow[3] = { 8, 11, 16 }; + int dotx[3] = { 127, 157, 198 }; + int dotw[3] = { 4, 5, 7 }; + int perx[3] = { 132, 164, 207 }; + int perw[3] = { 8, 13, 16 }; + if(c >= '0' && c <= '9') { - *ix = 13 * (c - '0') - (c >= '2' ? 3 : 0); - *w = (c == '1') ? 8 : 11; + *ix = (dw[size] + 2) * (c-'0') - (c >= '2' ? (dw[size]-ow[size]) : 0); + *w = (c == '1') ? ow[size] : dw[size]; return true; } if(c == '.') { - *ix = 127; - *w = 4; + *ix = dotx[size]; + *w = dotw[size]; return true; } if(c == '%') { - *ix = 132; - *w = 8; + *ix = perx[size]; + *w = perw[size]; return true; } return false; } -void render_energy_str(int x, int y, int halign, char const *str) +void render_energy_str(int x, int y, int halign, int size, char const *str) { - extern image_t img_font_energy; + extern image_t img_font_energy, img_font_energy2, img_font_energy3; + image_t const *img = + (size == 3) ? &img_font_energy3 : + (size == 2) ? &img_font_energy2 : + &img_font_energy; int ix, w; /* First compute width of string */ int total_width = 0; for(int i = 0; str[i]; i++) { - if(render_energy_str_glyph_params(str[i], &ix, &w)) + if(render_energy_str_glyph_params(size, str[i], &ix, &w)) total_width += w + 2; } total_width -= (total_width ? 2 : 0); @@ -210,10 +222,9 @@ void render_energy_str(int x, int y, int halign, char const *str) /* Render string */ for(int i = 0; str[i]; i++) { - if(!render_energy_str_glyph_params(str[i], &ix, &w)) + if(!render_energy_str_glyph_params(size, str[i], &ix, &w)) continue; - azrp_subimage(x, y, &img_font_energy, ix, 0, w, - img_font_energy.height, DIMAGE_NONE); + azrp_subimage(x, y, img, ix, 0, w, img->height, DIMAGE_NONE); x += w + 2; } } @@ -324,6 +335,16 @@ static void render_game_platforms(struct game &game) /* Blue platform particle effect's buffer image */ static image_t *_effect_bpp = NULL; +static int cubic(int start, int end, num t, num tmax) +{ + if(t >= tmax) + return end; + t = t / tmax; + + num x = num(1.0) - (num(1.0) - t) * (num(1.0) - t) * (num(1.0) - t); + return (int)(num(start) + num(end - start) * x + num(0.5)); +} + void render_game(struct game &game, prof_t *perf_comp) { azrp_perf_clear(); @@ -335,6 +356,9 @@ void render_game(struct game &game, prof_t *perf_comp) bool alive = (player->stance != player::Collided); struct platform *standing_on = game_platform_under_player(&game, player); + char energy_str[32]; + sprintf(energy_str, "%.2f%%", (float)player->energy_percent); + /* Standard gameplay before collision */ if(alive) { prof_enter_norec(*perf_comp); @@ -357,10 +381,8 @@ void render_game(struct game &game, prof_t *perf_comp) } /* Render energy score */ - char energy_str[32]; - sprintf(energy_str, "%.2f%%", (float)player->energy_percent); azrp_rect(DWIDTH-100, 4, 96, 20, AZRP_RECT_DARKEN); - render_energy_str(DWIDTH-8, 8, DTEXT_RIGHT, energy_str); + render_energy_str(DWIDTH-8, 8, DTEXT_RIGHT, 1, energy_str); } /* End transition and end screen */ else { @@ -384,13 +406,54 @@ void render_game(struct game &game, prof_t *perf_comp) } /* End screen elements appearing in order */ - num t_endscreen = game.t_death - TIME_DEATH_ANIMATION - num(0.5); + num t_endscreen = game.t_death - num(1.0); + int xe = 40, ye0 = 20, ye = ye0; if(t_endscreen >= num(0.0)) { + azrp_print(xe, ye, C_WHITE, "experiments %s", game.level.name); } if(t_endscreen >= num(0.1)) { + ye += 15; + azrp_text(xe, ye, C_WHITE, "UNDISCOVERED"); } if(t_endscreen >= num(0.2)) { + ye += 20; + azrp_text(xe, ye+2, C_WHITE, "energy"); + azrp_text(xe, ye+11, C_WHITE, "reading"); + render_energy_str(xe+65, ye, DTEXT_LEFT, 3, energy_str); + azrp_text(xe+65, ye+22, RGB24(0x9cefe3), "new peak"); + } + if(t_endscreen >= num(0.3)) { + ye += 40; + azrp_text(xe, ye+1, C_WHITE, "old peak"); + // TODO: Old energy str + render_energy_str(xe+65, ye, DTEXT_LEFT, 1, "0.00%"); + } + if(t_endscreen >= num(0.4)) { + ye += 20; + azrp_text(xe, ye, C_WHITE, "100%"); + azrp_rect(xe, ye+10, 160, 40, AZRP_RECT_WHITEN); + azrp_text(xe, ye+49, C_WHITE, "0%"); + + int h_footer = 30; + int y_footer = cubic(DHEIGHT, DHEIGHT - h_footer, + t_endscreen - num(0.4), num(0.2)); + azrp_rect(0, y_footer, DWIDTH, h_footer, C_WHITE); + azrp_text_opt(8, y_footer + 14, NULL, RGB24(0x49759f), + DTEXT_LEFT, DTEXT_MIDDLE, "exit: back", -1); + azrp_text_opt(DWIDTH-8, y_footer + 14, NULL, RGB24(0x49759f), + DTEXT_RIGHT, DTEXT_MIDDLE, "SHIFT: AGAIN",-1); + } + if(t_endscreen >= num(0.5)) { + xe = 230; + ye = ye0; + // TODO: Run count + azrp_text(xe, ye, C_WHITE, "run count 42"); + azrp_text(xe, ye+10, C_WHITE, "particle trace"); + } + if(t_endscreen >= num(0.6)) { + ye += 30; + // TODO: Crazy particle trace animation } }