implement the new GUI for inventory/status (F6)

This commit is contained in:
Lephenixnoir 2022-03-18 19:36:29 +00:00
parent 28a397a6e8
commit f5eb470b13
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
13 changed files with 83 additions and 96 deletions

View File

@ -54,9 +54,9 @@ set(ASSETS
assets-cg/hud.png
assets-cg/hud_delay.png
assets-cg/hud_flag.png
assets-cg/hud_itemslots.png
assets-cg/hud_life.png
assets-cg/hud_stars.png
assets-cg/hud_window.png
assets-cg/hud_panel.png
assets-cg/hud_xp.ase
assets-cg/skillicons.png
assets-cg/font_hud.png

BIN
assets-cg/hud_itemslots.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 B

BIN
assets-cg/hud_panel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 B

View File

@ -44,9 +44,9 @@ typedef struct
/* List of skills or equipped items. The first entry (skills[0]) usually
means the normal attack and might be handled separately because of the
combo system */
int skills[5];
int skills[6];
/* Cooldown; positive while waiting, zero when the skill/item is ready */
fixed_t actions_cooldown[5];
fixed_t actions_cooldown[6];
/* Current status effects */
fixed_t stun_delay;

View File

@ -477,7 +477,7 @@ void game_run_cooldowns(game_t *g, fixed_t dt)
if(f == NULL)
continue;
for(int i = 0; i < 5; i++) {
for(int i = 0; i < 6; i++) {
fixed_t *cd = &f->actions_cooldown[i];
*cd = max(*cd - dt, fix(0.0));
}

View File

@ -52,6 +52,11 @@ typedef struct game {
/* XP bar animation */
anim_state_t hud_xp_anim;
/* Inventory/status menu opening time (0 is closed, 1 is open) */
fixed_t menu_time;
/* Whether the menu is open or closed. Dictates whether menu_time goes
towards 0 or 1 every frame */
bool menu_open;
} game_t;

View File

@ -124,7 +124,7 @@ int main(void)
player_f->skills[2] = AOE_SHOCK;
player_f->skills[3] = AOE_JUDGEMENT;
player_f->skills[4] = AOE_BULLET;
for(int i = 0; i < 5; i++)
for(int i = 0; i < 6; i++)
player_f->actions_cooldown[i] = fix(0.0);
/* Initialize stats. This will level up to level 1 */
player_add_xp(player, 0);
@ -156,8 +156,6 @@ int main(void)
timer_start(timer_id);
bool stop = false;
bool menu_stats_open = false;
bool menu_inventory_open = false;
prof_t perf_render, perf_simul;
uint32_t time_render=0, time_simul=0;
@ -167,63 +165,21 @@ int main(void)
frame_tick = 0;
bool attack = false;
bool bullet_time = menu_stats_open || menu_inventory_open;
bool bullet_time = game.menu_open;
/* This assumes the frame is not late; can do better with libprof */
fixed_t dt = fix(1) / FRAME_RATE;
fixed_t dt_rt = dt;
if(bullet_time)
dt >>= 3;
dt >>= 2;
if(debug.paused)
dt = 0;
dt = dt_rt = 0;
perf_render = prof_make();
prof_enter(perf_render);
render_game(&game, debug.show_hitboxes);
if(menu_stats_open) {
render_window(48, 24, 300, 154);
extern font_t font_rogue;
font_t const *old_font = dfont(&font_rogue);
anim_frame_render(62, 50, anims_player_Idle.start[RIGHT]);
dprint(74, 39, C_WHITE, "Rogue");
dprint(60, 58, C_WHITE, "Level %d", player_data.xp_level);
dprint(60, 72, C_WHITE, "XP to next level: %d/%d",
player_data.xp_current, player_data.xp_to_next_level);
dprint(60, 93, C_WHITE, "HP");
dprint(100, 93, C_WHITE, "%d/%d", player_f->HP, player_f->HP_max);;
dprint(60, 108, C_WHITE, "ATK");
dprint(100, 108, C_WHITE, "%d", player_f->ATK);
dprint(60, 123, C_WHITE, "MAG");
dprint(100, 123, C_WHITE, "%d", player_f->MAG);
dprint(60, 138, C_WHITE, "DEF");
dprint(100, 138, C_WHITE, "%d", player_f->DEF);
extern bopti_image_t img_hud_stars;
int w = img_hud_stars.width;
int h = img_hud_stars.height / 2;
dsubimage(182, 94, &img_hud_stars, 0, 0, w, h, DIMAGE_NONE);
dsubimage(182, 94, &img_hud_stars, 0, h+1,
w * player_data.stat_model.HP / fix(5.0), h,
DIMAGE_NONE);
dsubimage(182, 109, &img_hud_stars, 0, 0, w, h, DIMAGE_NONE);
dsubimage(182, 109, &img_hud_stars, 0, h+1,
w * player_data.stat_model.ATK / fix(5.0), h,
DIMAGE_NONE);
dsubimage(182, 124, &img_hud_stars, 0, 0, w, h, DIMAGE_NONE);
dsubimage(182, 124, &img_hud_stars, 0, h+1,
w * player_data.stat_model.MAG / fix(5.0), h,
DIMAGE_NONE);
dsubimage(182, 139, &img_hud_stars, 0, 0, w, h, DIMAGE_NONE);
dsubimage(182, 139, &img_hud_stars, 0, h+1,
w * player_data.stat_model.DEF / fix(5.0), h,
DIMAGE_NONE);
dfont(old_font);
}
else if(menu_inventory_open) {
render_window(48, 24, 300, 154);
}
/* kmalloc_arena_t *_uram = kmalloc_get_arena("_uram");
kmalloc_gint_stats_t *_uram_stats = kmalloc_get_gint_stats(_uram);
dprint(1, 15, C_WHITE, "Memory: %d", _uram_stats->used_memory); */
@ -402,10 +358,8 @@ int main(void)
attack = true;
/* Menus */
if(ev.key == KEY_F5 && !keydown(KEY_VARS))
menu_inventory_open = !menu_inventory_open;
if(ev.key == KEY_F6 && !keydown(KEY_VARS) && !keydown(KEY_ALPHA))
menu_stats_open = !menu_stats_open;
game.menu_open = !game.menu_open;
}
/* Camera movement */
@ -542,6 +496,14 @@ int main(void)
game.screenshake_amplitude = 0;
}
/* Menu animation */
if(game.menu_open && game.menu_time < fix(1)) {
game.menu_time = min(game.menu_time + 2 * dt_rt, fix(1));
}
else if(!game.menu_open && game.menu_time > fix(0)) {
game.menu_time = max(game.menu_time - 2 * dt_rt, fix(0));
}
game.time_total += dt;
game.event_time += dt;

View File

@ -391,45 +391,22 @@ static void render_info(int x, int y, game_t const *g)
}
}
void render_window(int x, int y, int w, int h)
void render_panel(int x, int y, bool hflip)
{
extern bopti_image_t img_hud_window;
w = max(w, 40);
h = max(h, 22);
int slices = w / 20 - 2;
w = (slices + 2) * 20;
extern bopti_image_t img_hud_panel;
int sx = hflip ? 0 : 14;
int sy = 0;
int w = 94;
/* Shaded background */
int x0=x, x1=x+w-2;
x0 = (x0 + (x0 & 1)) >> 1;
x1 = (x1 + (x1 & 1)) >> 1;
uint32_t *vram = (void *)gint_vram + (DWIDTH*2) * (y+9);
for(int vy = 0; vy <= h-18; vy++) {
for(int vx = x0; vx <= x1; vx++) {
vram[vx] = (vram[vx] & 0xf7def7de) >> 1;
vram[vx] = (vram[vx] & 0xf7def7de) >> 1;
}
vram += DWIDTH / 2;
dsubimage(x, y, &img_hud_panel, sx, sy, w, 30, DIMAGE_NONE);
y += 30;
sy += 30;
for(int i = 0; i < 9; i++) {
dsubimage(x, y, &img_hud_panel, sx, sy, w, 10, DIMAGE_NONE);
y += 10;
}
/* Top section */
dsubimage(x, y, &img_hud_window, 0, 0, 20, 11, DIMAGE_NONE);
for(int i = 0; i < slices; i++)
dsubimage(x+20*(i+1), y, &img_hud_window, 20, 0, 20, 11, DIMAGE_NONE);
dsubimage(x+w-20, y, &img_hud_window, 40, 0, 20, 11, DIMAGE_NONE);
/* Vertical bars */
int color = RGB24(0x66686f);
dline(x, y+10, x, y+h-11, color);
dline(x+w-1, y+10, x+w-1, y+h-11, color);
/* Bottom section */
dsubimage(x, y+h-11, &img_hud_window, 0, 11, 20, 11, DIMAGE_NONE);
for(int i = 0; i < slices; i++)
dsubimage(x+20*(i+1), y+h-11, &img_hud_window, 20, 11, 20, 11,
DIMAGE_NONE);
dsubimage(x+w-20, y+h-11, &img_hud_window, 40, 11, 20, 11, DIMAGE_NONE);
sy += 10;
dsubimage(x, y, &img_hud_panel, sx, sy, w, 30, DIMAGE_NONE);
}
uint32_t time_render_map = 0;
@ -527,7 +504,7 @@ void render_game(game_t const *g, bool show_hitboxes)
static const int skill_size = 23;
static const int skill_box_size = 27;
for(int i = 0; i < 4; i++) {
for(int i = 0; i < 5; i++) {
/* Activity and cooldown */
fixed_t cooldown_total = skill_cooldown(player_f->skills[i+1]);
fixed_t cooldown_remaining = player_f->actions_cooldown[i+1];
@ -556,6 +533,49 @@ void render_game(game_t const *g, bool show_hitboxes)
}
}
if(g->menu_time > 0) {
int x1 = cubic(-94, 0, g->menu_time, fix(1));
int x2 = DWIDTH - 94 - x1;
fighter_t *player_f = getcomp(g->player, fighter);
player_data_t *player_data = player_f->player;
render_panel(x1, 27, false);
render_panel(x2, 27, true);
extern font_t font_rogue;
font_t const *old_font = dfont(&font_rogue);
dprint_opt(x1+42, 38, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP,
"Inventory");
dprint_opt(x2+52, 38, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP,
"Status");
dprint_opt(x2+52, 49, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP,
"Lv.%d (%d/%d)", player_data->xp_level, player_data->xp_current,
player_data->xp_to_next_level);
extern bopti_image_t img_hud_itemslots;
for(int y = 0; y < 3; y++)
for(int x = 0; x < 3; x++) {
int sx = /* item selected? */ false ? 19 : 0;
dsubimage(x1+8+24*x, 58+24*y, &img_hud_itemslots, sx, 0, 19, 19,
DIMAGE_NONE);
// TODO: Show items in inventory
}
for(int x = 0; x < 3; x++) {
dsubimage(x2+20+24*x, 73, &img_hud_itemslots, 38, 0, 19, 19,
DIMAGE_NONE);
}
dprint(x2+14, 103, C_WHITE, "HP");
dprint(x2+54, 103, C_WHITE, "%d/%d", player_f->HP, player_f->HP_max);
dprint(x2+14, 118, C_WHITE, "ATK");
dprint(x2+54, 118, C_WHITE, "%d", player_f->ATK);
dprint(x2+14, 133, C_WHITE, "MAG");
dprint(x2+54, 133, C_WHITE, "%d", player_f->MAG);
dprint(x2+14, 148, C_WHITE, "DEF");
dprint(x2+54, 148, C_WHITE, "%d", player_f->DEF);
dfont(old_font);
}
prof_leave(ctx);
time_render_hud = prof_time(ctx);

View File

@ -56,8 +56,8 @@ fixed_t camera_ppu(camera_t const *c);
// Rendering
//---
/* Render window overlay. */
void render_window(int x, int y, int w, int h);
/* Render panel overlay. */
void render_panel(int x, int y, bool hflip);
/* Render a single layer of the map, with animated tiles.
ss_x and ss_y are additional displacement for screenshake; default 0.