63b6584706
* initial additions * Move current_blind to game vars * tmp * tmp * tmp * tmp * tmp * tmp * tmp * Compile but is broken * temp fix for token location * tmp * Working, lets clean up * remove todo * Remove odd reroll blind variable * fix skipping blind screen * fix reroll * remove magic for blind token locations * clang format * Cleanup button highlight in blind menu * some cleanup * Add layout file for global UI rects * remove dead code * Clang format * clang format it up * Move reset top left funct to gfx utils * make note of soon-to-be removed vars * Cleanup gamevars declaration * Cleanup layout file * Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Add include for stdbool.h in common_ui.h * Cleanup rect declaration * Start moving state machine stuff to new file * quick tmp * oops, add new files * working call list * fixed pointer stuff * working as per norm * working replacement * move defines to static const * fix compile issue * Add some missing "void"s * Working new substates * add statemachine to blind select * Fix game restart statemachine leak * clang-format * Clang format * Rework shop exit logic * Use new state machine in shop * Remove substates entirely * Remove debug stuff * Clang format * document state machine better * update list tests * clang-format * Update for PR * Claaaaang format * another clang-format * Remove extra state in round_end * cleanup docs for removals in lists * clang-format... again * update doxygen format * Clang format * tmp * Update for Pr * clang-format * Cleanup for only supporting losing * bug fix, thanks logs! * Fix dangling pointer bug The control of removing statemachines may call issues if starting the function is done from another state machine call. To remedy this, add a flag to determine if a state machine is registered and return early instead of blindly removing it to re-add. * Fix bug with audio iterations possibly going in reverse * Remove extra includes * Clang-format * Add sound effects for game win/lose * adjust audio steps * tmp * Nice sounding and cleaned up * Fix and cleanup * clang-format * clang-format * clang format again --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
651 lines
21 KiB
C
651 lines
21 KiB
C
#include "blind_select.h"
|
|
|
|
#include "affine_background.h"
|
|
#include "audio_utils.h"
|
|
#include "background_blind_select_gfx.h"
|
|
#include "blind.h"
|
|
#include "button.h"
|
|
#include "game.h"
|
|
#include "game_variables.h"
|
|
#include "graphic_utils.h"
|
|
#include "layout.h"
|
|
#include "soundbank.h"
|
|
#include "sprite.h"
|
|
#include "state_machine.h"
|
|
#include "timer.h"
|
|
#include "util.h"
|
|
|
|
#include <maxmod.h>
|
|
|
|
static const u32 BLIND_SELECT_BTN_PID = 15;
|
|
static const u32 BLIND_SKIP_BTN_PID = 5;
|
|
static const u32 BLIND_SKIP_BTN_SELECTED_BORDER_PID = 10;
|
|
static const u32 BLIND_SELECT_BTN_SELECTED_BORDER_PID = 18;
|
|
|
|
static const u32 TM_DISP_BLIND_PANEL_FINISH = 7;
|
|
static const u32 TM_DISP_BLIND_PANEL_START = 1;
|
|
|
|
static int timer;
|
|
|
|
static void game_blind_select_start_anim_seq(void);
|
|
static void game_blind_select_handle_input(void);
|
|
static void game_blind_select_selected_anim_seq(void);
|
|
static void game_blind_select_display_blind_panel(void);
|
|
static void game_blind_select_exit(void);
|
|
static Rect game_blind_select_get_req_score_rect(enum BlindTokens blind);
|
|
static void game_blind_select_print_blinds_reqs_and_rewards(void);
|
|
static enum BlindType get_blind_type_from_token(enum BlindTokens blind);
|
|
static void blind_tokens_init(void);
|
|
|
|
enum BlindSelectState
|
|
{
|
|
START_ANIM_SEQ,
|
|
BLIND_SELECT,
|
|
BLIND_SELECTED_ANIM_SEQ,
|
|
DISPLAY_BLIND_PANEL,
|
|
BLIND_SELECT_EXIT,
|
|
BLIND_SELECT_MAX,
|
|
};
|
|
|
|
// TODO: this will be refactored into common state machine
|
|
static StateInfo state_info[] = {
|
|
STATE_INFO_UPDATE_FN_ONLY(game_blind_select_start_anim_seq),
|
|
STATE_INFO_UPDATE_FN_ONLY(game_blind_select_handle_input),
|
|
STATE_INFO_UPDATE_FN_ONLY(game_blind_select_selected_anim_seq),
|
|
STATE_INFO_UPDATE_FN_ONLY(game_blind_select_display_blind_panel),
|
|
STATE_INFO_UPDATE_FN_ONLY(game_blind_select_exit),
|
|
};
|
|
|
|
static StateMachine blind_select_sm = STATE_MACHINE_DEFINE(state_info, BLIND_SELECT_MAX);
|
|
|
|
// clang-format off
|
|
// Points x y
|
|
static const BG_POINT TOP_LEFT_PANEL_EMPTY_3W_ROW_POS = {29, 31};
|
|
// Rects left top right bottom
|
|
static const Rect BLIND_SKIP_BTN_GRAY_RECT = {0, 24, 4, 27};
|
|
static const Rect BLIND_SKIP_BTN_PREANIM_DEST_RECT = {9, 29, 19, 31};
|
|
static const Rect SINGLE_BLIND_SEL_REQ_SCORE_RECT = {80, 120, 104, 128};
|
|
static const Rect SINGLE_BLIND_SELECT_RECT = {9, 7, 13, 31};
|
|
// clang-format on
|
|
|
|
static const u32 TM_END_ANIM_SEQ = 12;
|
|
static const u32 TM_BLIND_SELECT_START = 1;
|
|
|
|
static const u32 BLIND_LEFT_X = 80;
|
|
static const u32 BLIND_CENTER_X = 120;
|
|
static const u32 BLIND_RIGHT_X = 160;
|
|
|
|
static const u32 BLIND_ROW = 0;
|
|
static const u32 SKIP_ROW = 1;
|
|
|
|
static int selection_x = 0;
|
|
static int selection_y = 0;
|
|
|
|
static Sprite* blind_select_tokens[NUM_BLINDS_PER_ANTE] = {NULL};
|
|
|
|
static void game_blind_select_start_anim_seq()
|
|
{
|
|
// main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT, SCREEN_UP);
|
|
main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT, SCREEN_UP);
|
|
|
|
for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
|
|
{
|
|
sprite_position(
|
|
blind_select_tokens[i],
|
|
blind_select_tokens[i]->pos.x,
|
|
blind_select_tokens[i]->pos.y - TILE_SIZE
|
|
);
|
|
}
|
|
|
|
if (timer == TM_END_ANIM_SEQ)
|
|
{
|
|
game_blind_select_print_blinds_reqs_and_rewards();
|
|
state_machine_change_state(&blind_select_sm, BLIND_SELECT);
|
|
timer = TM_ZERO; // Reset the timer
|
|
}
|
|
}
|
|
|
|
static inline void game_blind_select_erase_blind_reqs_and_rewards()
|
|
{
|
|
for (enum BlindTokens curr_blind = SMALL_BLIND; curr_blind < NUM_BLINDS_PER_ANTE; curr_blind++)
|
|
{
|
|
Rect blind_req_and_reward_rect = SINGLE_BLIND_SEL_REQ_SCORE_RECT;
|
|
|
|
// To account for both raised blind and reward
|
|
blind_req_and_reward_rect.top -= TILE_SIZE;
|
|
blind_req_and_reward_rect.bottom += TILE_SIZE;
|
|
|
|
// To account for overflow
|
|
blind_req_and_reward_rect.right += TILE_SIZE;
|
|
|
|
blind_req_and_reward_rect.left +=
|
|
curr_blind * rect_width(&SINGLE_BLIND_SELECT_RECT) * TILE_SIZE;
|
|
blind_req_and_reward_rect.right +=
|
|
curr_blind * rect_width(&SINGLE_BLIND_SELECT_RECT) * TILE_SIZE;
|
|
|
|
tte_erase_rect_wrapper(blind_req_and_reward_rect);
|
|
}
|
|
}
|
|
|
|
void increment_blind(enum BlindState increment_reason)
|
|
{
|
|
switch (g_game_vars.current_blind)
|
|
{
|
|
// defeated small blind: go to big
|
|
case BLIND_TYPE_SMALL:
|
|
g_game_vars.current_blind = BLIND_TYPE_BIG;
|
|
g_game_vars.blinds_states[SMALL_BLIND] = increment_reason;
|
|
g_game_vars.blinds_states[BIG_BLIND] = BLIND_STATE_CURRENT;
|
|
break;
|
|
// defeated big blind: go to next boss
|
|
case BLIND_TYPE_BIG:
|
|
g_game_vars.current_blind = g_game_vars.next_boss_blind;
|
|
g_game_vars.blinds_states[BIG_BLIND] = increment_reason;
|
|
g_game_vars.blinds_states[BOSS_BLIND] = BLIND_STATE_CURRENT;
|
|
break;
|
|
// defeated a boss: reset everything
|
|
default:
|
|
g_game_vars.current_blind = BLIND_TYPE_SMALL;
|
|
g_game_vars.blinds_states[SMALL_BLIND] = BLIND_STATE_CURRENT;
|
|
g_game_vars.blinds_states[BIG_BLIND] = BLIND_STATE_UPCOMING;
|
|
g_game_vars.blinds_states[BOSS_BLIND] = BLIND_STATE_UPCOMING;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// TODO: convert these to proper buttons.
|
|
static inline void highlight_select_button(void)
|
|
{
|
|
memset16(&pal_bg_mem[BLIND_SELECT_BTN_SELECTED_BORDER_PID], 0xFFFF, 1);
|
|
memcpy16(&pal_bg_mem[BLIND_SKIP_BTN_SELECTED_BORDER_PID], &pal_bg_mem[BLIND_SKIP_BTN_PID], 1);
|
|
}
|
|
|
|
static inline void highlight_skip_button(void)
|
|
{
|
|
memcpy16(
|
|
&pal_bg_mem[BLIND_SELECT_BTN_SELECTED_BORDER_PID],
|
|
&pal_bg_mem[BLIND_SELECT_BTN_PID],
|
|
1
|
|
);
|
|
memset16(&pal_bg_mem[BLIND_SKIP_BTN_SELECTED_BORDER_PID], 0xFFFF, 1);
|
|
}
|
|
|
|
static void game_blind_select_handle_input()
|
|
{
|
|
if (timer == TM_BLIND_SELECT_START && g_game_vars.current_blind == BLIND_TYPE_BOSS)
|
|
{
|
|
selection_y = BLIND_ROW;
|
|
}
|
|
|
|
// Blind select input logic
|
|
if (key_hit(KEY_UP))
|
|
{
|
|
selection_y = BLIND_ROW;
|
|
highlight_select_button();
|
|
}
|
|
else if (key_hit(KEY_DOWN) && g_game_vars.current_blind <= BLIND_TYPE_BIG)
|
|
{
|
|
selection_y = SKIP_ROW;
|
|
highlight_skip_button();
|
|
}
|
|
else if (key_hit(SELECT_CARD))
|
|
{
|
|
game_blind_select_erase_blind_reqs_and_rewards();
|
|
|
|
switch (selection_y)
|
|
{
|
|
case BLIND_ROW:
|
|
play_sfx(SFX_BUTTON, MM_BASE_PITCH_RATE, BUTTON_SFX_VOLUME);
|
|
state_machine_change_state(&blind_select_sm, BLIND_SELECTED_ANIM_SEQ);
|
|
timer = TM_ZERO;
|
|
++g_game_vars.round;
|
|
display_round();
|
|
break;
|
|
case SKIP_ROW:
|
|
if (g_game_vars.current_blind <= BLIND_TYPE_BIG)
|
|
{
|
|
play_sfx(SFX_BUTTON, MM_BASE_PITCH_RATE, BUTTON_SFX_VOLUME);
|
|
increment_blind(BLIND_STATE_SKIPPED);
|
|
|
|
selection_y = BLIND_ROW; // Reset selection to first option
|
|
|
|
change_background(BG_BLIND_SELECT, true);
|
|
|
|
// TODO: Create a generic vertical move by any number of tiles to avoid for
|
|
// loops?
|
|
for (int i = 0; i < 12; i++)
|
|
{
|
|
main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT, SCREEN_UP);
|
|
}
|
|
|
|
for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
|
|
{
|
|
sprite_position(
|
|
blind_select_tokens[i],
|
|
blind_select_tokens[i]->pos.x,
|
|
blind_select_tokens[i]->pos.y - (TILE_SIZE * 12)
|
|
);
|
|
}
|
|
|
|
game_blind_select_print_blinds_reqs_and_rewards();
|
|
highlight_select_button();
|
|
|
|
timer = TM_ZERO;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void game_blind_select_selected_anim_seq()
|
|
{
|
|
if (timer < 15)
|
|
{
|
|
Rect blinds_rect = POP_MENU_ANIM_RECT;
|
|
blinds_rect.top -= 1; // Because of the raised blind
|
|
main_bg_se_move_rect_1_tile_vert(blinds_rect, SCREEN_DOWN);
|
|
|
|
for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
|
|
{
|
|
sprite_position(
|
|
blind_select_tokens[i],
|
|
blind_select_tokens[i]->pos.x,
|
|
blind_select_tokens[i]->pos.y + TILE_SIZE
|
|
);
|
|
}
|
|
}
|
|
else if (timer >= MENU_POP_OUT_ANIM_FRAMES)
|
|
{
|
|
for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
|
|
{
|
|
obj_hide(blind_select_tokens[i]->obj);
|
|
}
|
|
|
|
timer = TM_ZERO;
|
|
state_machine_change_state(&blind_select_sm, DISPLAY_BLIND_PANEL);
|
|
}
|
|
}
|
|
|
|
static void game_blind_select_display_blind_panel()
|
|
{
|
|
if (timer >= TM_DISP_BLIND_PANEL_FINISH)
|
|
{
|
|
state_machine_change_state(&blind_select_sm, BLIND_SELECT_EXIT);
|
|
return;
|
|
}
|
|
|
|
// Switches to the selecting background and clears the blind panel area
|
|
if (timer == TM_DISP_BLIND_PANEL_START)
|
|
{
|
|
change_background(BG_CARD_SELECTING, false);
|
|
|
|
// Need to clear the top left panel as a side effect of change_background()
|
|
main_bg_se_copy_expand_3w_row(TOP_LEFT_PANEL_ANIM_RECT, TOP_LEFT_PANEL_EMPTY_3W_ROW_POS);
|
|
|
|
reset_top_left_panel_bottom_row();
|
|
|
|
if (g_game_vars.current_blind >= BLIND_TYPE_BOSS)
|
|
{
|
|
affine_background_set_color(
|
|
blind_get_color(g_game_vars.current_blind, BLIND_SHADOW_COLOR_INDEX)
|
|
);
|
|
}
|
|
}
|
|
|
|
// Shift the blind panel down onto screen
|
|
for (int y = 0; y < timer; y++)
|
|
{
|
|
int y_from = 26 + y - timer;
|
|
int y_to = 0 + y;
|
|
|
|
Rect from = {0, y_from, 8, y_from};
|
|
BG_POINT to = {0, y_to};
|
|
|
|
main_bg_se_copy_rect(from, to);
|
|
}
|
|
}
|
|
|
|
static void game_blind_select_exit(void)
|
|
{
|
|
reset_background();
|
|
game_change_state(GAME_STATE_PLAYING);
|
|
}
|
|
|
|
static Rect game_blind_select_get_req_score_rect(enum BlindTokens blind)
|
|
{
|
|
Rect blind_req_score_rect = SINGLE_BLIND_SEL_REQ_SCORE_RECT;
|
|
|
|
blind_req_score_rect.left += blind * rect_width(&SINGLE_BLIND_SELECT_RECT) * TILE_SIZE;
|
|
blind_req_score_rect.right += blind * rect_width(&SINGLE_BLIND_SELECT_RECT) * TILE_SIZE;
|
|
|
|
if (g_game_vars.blinds_states[blind] == BLIND_STATE_CURRENT)
|
|
{
|
|
// Current blind is raised
|
|
blind_req_score_rect.top -= TILE_SIZE;
|
|
blind_req_score_rect.bottom -= TILE_SIZE;
|
|
}
|
|
|
|
return blind_req_score_rect;
|
|
}
|
|
|
|
static enum BlindType get_blind_type_from_token(enum BlindTokens blind)
|
|
{
|
|
enum BlindType blind_type;
|
|
switch (blind)
|
|
{
|
|
case SMALL_BLIND:
|
|
blind_type = BLIND_TYPE_SMALL;
|
|
break;
|
|
case BIG_BLIND:
|
|
blind_type = BLIND_TYPE_BIG;
|
|
break;
|
|
default:
|
|
blind_type = g_game_vars.next_boss_blind;
|
|
break;
|
|
}
|
|
return blind_type;
|
|
}
|
|
|
|
static inline void game_blind_select_print_blind_req(enum BlindTokens blind)
|
|
{
|
|
Rect blind_req_score_rect = game_blind_select_get_req_score_rect(blind);
|
|
|
|
u32 blind_req = blind_get_requirement(get_blind_type_from_token(blind), g_game_vars.ante);
|
|
|
|
char blind_req_str_buff[UINT_MAX_DIGITS + 1];
|
|
truncate_uint_to_suffixed_str(
|
|
blind_req,
|
|
rect_width(&blind_req_score_rect) / TTE_CHAR_SIZE,
|
|
blind_req_str_buff
|
|
);
|
|
|
|
update_text_rect_to_right_align_str(&blind_req_score_rect, blind_req_str_buff, OVERFLOW_RIGHT);
|
|
|
|
tte_printf(
|
|
"#{P:%d,%d; cx:0x%X000}%s",
|
|
blind_req_score_rect.left,
|
|
blind_req_score_rect.top,
|
|
TTE_RED_PB,
|
|
blind_req_str_buff
|
|
);
|
|
}
|
|
|
|
static inline void game_blind_select_print_blind_reward(enum BlindTokens blind)
|
|
{
|
|
int blind_reward = blind_get_reward(get_blind_type_from_token(blind));
|
|
Rect blind_reward_rect = game_blind_select_get_req_score_rect(blind);
|
|
|
|
// The reward is right below the score.
|
|
blind_reward_rect.top += TILE_SIZE;
|
|
blind_reward_rect.bottom += TILE_SIZE;
|
|
|
|
char blind_reward_str_buff[UINT_MAX_DIGITS + 2]; // +2 for null terminator and "$"
|
|
snprintf(blind_reward_str_buff, sizeof(blind_reward_str_buff), "$%d", blind_reward);
|
|
|
|
update_text_rect_to_right_align_str(&blind_reward_rect, blind_reward_str_buff, OVERFLOW_RIGHT);
|
|
|
|
tte_printf(
|
|
"#{P:%d,%d; cx:0x%X000}%s",
|
|
blind_reward_rect.left,
|
|
blind_reward_rect.top,
|
|
TTE_YELLOW_PB,
|
|
blind_reward_str_buff
|
|
);
|
|
}
|
|
|
|
static void game_blind_select_print_blinds_reqs_and_rewards(void)
|
|
{
|
|
for (enum BlindTokens curr_blind = 0; curr_blind < NUM_BLINDS_PER_ANTE; curr_blind++)
|
|
{
|
|
game_blind_select_print_blind_req(curr_blind);
|
|
game_blind_select_print_blind_reward(curr_blind);
|
|
}
|
|
}
|
|
|
|
static inline void reroll_boss_blind(bool no_tiles)
|
|
{
|
|
// Showdown blinds only show up on ante 8, 16, etc...
|
|
g_game_vars.next_boss_blind =
|
|
roll_blind_type((g_game_vars.ante % 8 == 0) && (g_game_vars.ante > 0));
|
|
if (!no_tiles)
|
|
{
|
|
apply_blind_tiles(g_game_vars.next_boss_blind, BOSS_BLIND_TOKEN_LAYER);
|
|
}
|
|
}
|
|
|
|
static void blind_tokens_init()
|
|
{
|
|
if (g_game_vars.current_blind == BLIND_TYPE_SMALL)
|
|
reroll_boss_blind(true);
|
|
|
|
sprite_destroy(&blind_select_tokens[SMALL_BLIND]);
|
|
sprite_destroy(&blind_select_tokens[BIG_BLIND]);
|
|
sprite_destroy(&blind_select_tokens[BOSS_BLIND]);
|
|
|
|
blind_select_tokens[SMALL_BLIND] = blind_token_new(
|
|
BLIND_TYPE_SMALL,
|
|
CUR_BLIND_TOKEN_POS.x,
|
|
CUR_BLIND_TOKEN_POS.y,
|
|
SMALL_BLIND_TOKEN_LAYER
|
|
);
|
|
blind_select_tokens[BIG_BLIND] = blind_token_new(
|
|
BLIND_TYPE_BIG,
|
|
CUR_BLIND_TOKEN_POS.x,
|
|
CUR_BLIND_TOKEN_POS.y,
|
|
BIG_BLIND_TOKEN_LAYER
|
|
);
|
|
blind_select_tokens[BOSS_BLIND] = blind_token_new(
|
|
g_game_vars.next_boss_blind,
|
|
CUR_BLIND_TOKEN_POS.x,
|
|
CUR_BLIND_TOKEN_POS.y,
|
|
BOSS_BLIND_TOKEN_LAYER
|
|
);
|
|
|
|
for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
|
|
{
|
|
obj_hide(blind_select_tokens[i]->obj);
|
|
}
|
|
}
|
|
|
|
void game_blind_select_on_init(void)
|
|
{
|
|
timer = TM_ZERO;
|
|
state_machine_register(&blind_select_sm);
|
|
state_machine_change_state(&blind_select_sm, START_ANIM_SEQ);
|
|
|
|
selection_x = 0;
|
|
selection_y = 0;
|
|
|
|
blind_tokens_init();
|
|
|
|
// TODO: silly bug rn, the sprite tokens are unhidden on a background change.
|
|
// this probably shouldn't be here. also need to force redraw or the callback
|
|
// doesn't run that moves the tokens. that should probably happen here.
|
|
change_background(BG_BLIND_SELECT, true);
|
|
|
|
highlight_select_button();
|
|
|
|
play_sfx(SFX_POP, MM_BASE_PITCH_RATE, SFX_DEFAULT_VOLUME);
|
|
}
|
|
|
|
void game_blind_select_on_update(void)
|
|
{
|
|
timer++;
|
|
}
|
|
|
|
void game_blind_select_on_exit(void)
|
|
{
|
|
// For some reason that I haven't figured out yet,
|
|
// if I don't destroy the blind tokens they won't
|
|
// show up on the next run.
|
|
sprite_destroy(&blind_select_tokens[SMALL_BLIND]);
|
|
sprite_destroy(&blind_select_tokens[BIG_BLIND]);
|
|
sprite_destroy(&blind_select_tokens[BOSS_BLIND]);
|
|
|
|
reset_background();
|
|
selection_y = 0;
|
|
|
|
state_machine_remove(&blind_select_sm);
|
|
}
|
|
|
|
void game_blind_select_change_background(void)
|
|
{
|
|
for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
|
|
{
|
|
obj_unhide(blind_select_tokens[i]->obj, 0);
|
|
}
|
|
|
|
// Default y position for the blind select tokens. 12 is the amount of tiles the background
|
|
// is shifted down by
|
|
const int default_y = 89 + (TILE_SIZE * 12);
|
|
// TODO refactor magic numbers '80/120/160' into a map to loop with
|
|
sprite_position(blind_select_tokens[SMALL_BLIND], BLIND_LEFT_X, default_y);
|
|
sprite_position(blind_select_tokens[BIG_BLIND], BLIND_CENTER_X, default_y);
|
|
sprite_position(blind_select_tokens[BOSS_BLIND], BLIND_RIGHT_X, default_y);
|
|
|
|
toggle_windows(false, true);
|
|
|
|
GRIT_CPY(pal_bg_mem, background_blind_select_gfxPal);
|
|
GRIT_CPY(&tile_mem[MAIN_BG_CBB], background_blind_select_gfxTiles);
|
|
GRIT_CPY(&se_mem[MAIN_BG_SBB], background_blind_select_gfxMap);
|
|
|
|
// Copy boss blind colors to blind select palette
|
|
memset16(
|
|
&pal_bg_mem[1],
|
|
blind_get_color(g_game_vars.next_boss_blind, BLIND_BACKGROUND_MAIN_COLOR_INDEX),
|
|
1
|
|
);
|
|
memset16(
|
|
&pal_bg_mem[7],
|
|
blind_get_color(g_game_vars.next_boss_blind, BLIND_BACKGROUND_SHADOW_COLOR_INDEX),
|
|
1
|
|
);
|
|
|
|
// Disable the button highlight colors
|
|
// Select button PID is 15 and the outline is 18
|
|
memcpy16(
|
|
&pal_bg_mem[BLIND_SELECT_BTN_SELECTED_BORDER_PID],
|
|
&pal_bg_mem[BLIND_SELECT_BTN_PID],
|
|
1
|
|
);
|
|
// It seems the skip button (and score multiplier and deck) PB idx is
|
|
// actually 5, not 10. 10 is the selected border color
|
|
// Setting this palette value though doesn't seem to have an
|
|
// effect.
|
|
memcpy16(&pal_bg_mem[BLIND_SKIP_BTN_SELECTED_BORDER_PID], &pal_bg_mem[BLIND_SKIP_BTN_PID], 1);
|
|
|
|
for (int i = 0; i < NUM_BLINDS_PER_ANTE; i++)
|
|
{
|
|
Rect curr_blind_rect = SINGLE_BLIND_SELECT_RECT;
|
|
|
|
// There's no gap between them
|
|
curr_blind_rect.left += i * rect_width(&SINGLE_BLIND_SELECT_RECT);
|
|
curr_blind_rect.right += i * rect_width(&SINGLE_BLIND_SELECT_RECT);
|
|
|
|
if (g_game_vars.blinds_states[i] != BLIND_STATE_CURRENT &&
|
|
(i == BLIND_TYPE_SMALL || i == BLIND_TYPE_BIG)) // Make the skip button gray
|
|
{
|
|
BG_POINT skip_blind_btn_pos_dest = {
|
|
BLIND_SKIP_BTN_PREANIM_DEST_RECT.left,
|
|
BLIND_SKIP_BTN_PREANIM_DEST_RECT.top
|
|
};
|
|
skip_blind_btn_pos_dest.x = curr_blind_rect.left;
|
|
|
|
Rect skip_blind_btn_rect_src = BLIND_SKIP_BTN_GRAY_RECT;
|
|
skip_blind_btn_rect_src.top += i * rect_height(&BLIND_SKIP_BTN_GRAY_RECT);
|
|
skip_blind_btn_rect_src.bottom += i * rect_height(&BLIND_SKIP_BTN_GRAY_RECT);
|
|
|
|
main_bg_se_copy_rect(skip_blind_btn_rect_src, skip_blind_btn_pos_dest);
|
|
}
|
|
|
|
switch (g_game_vars.blinds_states[i])
|
|
{
|
|
case BLIND_STATE_CURRENT: // Raise the blind panel up a bit
|
|
{
|
|
// TODO: Replace copies with main_bg_se_copy_rect() of named rects
|
|
int x_from = 0;
|
|
int y_from = 27;
|
|
|
|
main_bg_se_copy_rect_1_tile_vert(curr_blind_rect, SCREEN_UP);
|
|
|
|
int x_to = curr_blind_rect.left;
|
|
int y_to = 31;
|
|
|
|
if (i == BLIND_TYPE_BIG)
|
|
{
|
|
y_from = 31;
|
|
}
|
|
else if (i > BLIND_TYPE_BIG)
|
|
{
|
|
x_from = x_to;
|
|
y_from = 30;
|
|
}
|
|
|
|
// Copy plain tiles onto the bottom of the raised blind panel to fill the gap
|
|
// created by the raise
|
|
Rect gap_fill_rect =
|
|
{x_from, y_from, x_from + rect_width(&SINGLE_BLIND_SELECT_RECT) - 1, y_from};
|
|
BG_POINT gap_fill_point = {x_to, y_to};
|
|
main_bg_se_copy_rect(gap_fill_rect, gap_fill_point);
|
|
|
|
// Move token up by a tile
|
|
sprite_position(
|
|
blind_select_tokens[i],
|
|
blind_select_tokens[i]->pos.x,
|
|
blind_select_tokens[i]->pos.y - TILE_SIZE
|
|
);
|
|
break;
|
|
}
|
|
case BLIND_STATE_UPCOMING: // Change the select icon to "NEXT"
|
|
{
|
|
int x_from = 0;
|
|
int y_from = 20;
|
|
|
|
int x_to = 10 + (i * rect_width(&SINGLE_BLIND_SELECT_RECT));
|
|
int y_to = 20;
|
|
|
|
memcpy16(
|
|
&se_mem[MAIN_BG_SBB][x_to + 32 * y_to],
|
|
&se_mem[MAIN_BG_SBB][x_from + 32 * y_from],
|
|
3
|
|
);
|
|
break;
|
|
}
|
|
case BLIND_STATE_SKIPPED: // Change the select icon to "SKIP"
|
|
{
|
|
int x_from = 3;
|
|
int y_from = 20;
|
|
|
|
int x_to = 10 + (i * 5);
|
|
int y_to = 20;
|
|
|
|
memcpy16(
|
|
&se_mem[MAIN_BG_SBB][x_to + 32 * y_to],
|
|
&se_mem[MAIN_BG_SBB][x_from + 32 * y_from],
|
|
3
|
|
);
|
|
break;
|
|
}
|
|
case BLIND_STATE_DEFEATED: // Change the select icon to "DEFEATED"
|
|
{
|
|
int x_from = 6;
|
|
int y_from = 20;
|
|
|
|
int x_to = 10 + (i * 5);
|
|
int y_to = 20;
|
|
|
|
memcpy16(
|
|
&se_mem[MAIN_BG_SBB][x_to + 32 * y_to],
|
|
&se_mem[MAIN_BG_SBB][x_from + 32 * y_from],
|
|
3
|
|
);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|