Main menu prototype

This commit is contained in:
cellos51
2025-08-09 21:49:37 -04:00
parent 8a905907fc
commit 164f58aa1e
11 changed files with 200 additions and 30 deletions
@@ -0,0 +1 @@
-gt -gB8 -mLa -mRa
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

+1
View File
@@ -0,0 +1 @@
-gB8 -mR8 -mLs -mRtf
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

+9 -2
View File
@@ -5,13 +5,20 @@
#include "graphic_utils.h" #include "graphic_utils.h"
#define AFFINE_BG_PAL_LEN 5 #define AFFINE_BG_PAL_LEN 16
#define AFFINE_BG_PB (PAL_ROW_LEN * 15) // This isn't really a palette bank, just the starting index of the palette #define AFFINE_BG_PB (PAL_ROW_LEN * 10) // This isn't really a palette bank, just the starting index of the palette
enum AffineBackgroundID
{
AFFINE_BG_MAIN_MENU,
AFFINE_BG_GAME,
};
void affine_background_init(); void affine_background_init();
void affine_background_update(); void affine_background_update();
void affine_background_set_color(COLOR color); void affine_background_set_color(COLOR color);
// Must be called with an array of size at least AFFINE_BG_PAL_LEN // Must be called with an array of size at least AFFINE_BG_PAL_LEN
void affine_background_load_palette(const u16 *src); void affine_background_load_palette(const u16 *src);
void affine_background_change_background(enum AffineBackgroundID new_bg);
#endif // AFFINE_BACKGROUND_H #endif // AFFINE_BACKGROUND_H
+2
View File
@@ -16,6 +16,7 @@
#define BG_ID_ROUND_END 3 #define BG_ID_ROUND_END 3
#define BG_ID_SHOP 4 #define BG_ID_SHOP 4
#define BG_ID_BLIND_SELECT 5 #define BG_ID_BLIND_SELECT 5
#define BG_ID_MAIN_MENU 6
// Input bindings // Input bindings
#define SELECT_CARD KEY_A #define SELECT_CARD KEY_A
@@ -26,6 +27,7 @@
enum GameState enum GameState
{ {
GAME_MAIN_MENU,
GAME_PLAYING, GAME_PLAYING,
GAME_ROUND_END, GAME_ROUND_END,
GAME_SHOP, GAME_SHOP,
+6
View File
@@ -138,4 +138,10 @@ void memcpy16_tile8_with_palette_offset(u16* dst, const u16* src, uint hwcount,
*/ */
void memcpy32_tile8_with_palette_offset(u32* dst, const u32* src, uint wcount, u8 palette_offset); void memcpy32_tile8_with_palette_offset(u32* dst, const u32* src, uint wcount, u8 palette_offset);
/* Toggles the visibility of the window layers.
* win0 and win1 are the visibility states for the two windows.
* These windows are primarily used for the shadows on held jokers, consumables and cards.
*/
void toggle_windows(bool win0, bool win1);
#endif //GRAPHIC_UTILS_H #endif //GRAPHIC_UTILS_H
+55 -12
View File
@@ -1,16 +1,17 @@
#include "affine_background.h" #include "affine_background.h"
#include "affine_background_gfx.h" #include "affine_background_gfx.h"
#include "affine_main_menu_background_gfx.h"
#include "graphic_utils.h" #include "graphic_utils.h"
BG_AFFINE bgaff; BG_AFFINE bgaff;
AFF_SRC_EX asx = {32<<8, 64<<8, 120, 80, 0x0100, 0x0100, 0}; AFF_SRC_EX asx = {0};
enum AffineBackgroundID background = AFFINE_BG_MAIN_MENU;
void affine_background_init() void affine_background_init()
{ {
memcpy32_tile8_with_palette_offset((u32*)&tile8_mem[AFFINE_BG_CBB], (const u32*)affine_background_gfxTiles, affine_background_gfxTilesLen/4, AFFINE_BG_PB); affine_background_change_background(background);
GRIT_CPY(&se_mem[AFFINE_BG_SBB], affine_background_gfxMap);
affine_background_load_palette(affine_background_gfxPal);
bgaff = bg_aff_default; bgaff = bg_aff_default;
} }
@@ -20,20 +21,37 @@ void affine_background_update()
static uint timer = 0; static uint timer = 0;
timer++; timer++;
// These values are not permament, just the current configuration for the affine background switch (background)
asx.tex_x += 5; {
asx.tex_y += 12; case AFFINE_BG_MAIN_MENU:
asx.sx = (lu_sin(timer * 100)) >> 8; // Scale the sine value to fit in a s16 asx.scr_x = SCREEN_WIDTH / 2;
asx.sx += 256; // Add 256 to the sine value to make it positive asx.scr_y = SCREEN_HEIGHT / 2;
asx.sy = (lu_sin(timer * 100 + 0x4000)) >> 8; // Scale the sine value to fit in a s16 asx.tex_x = 16560;
asx.sy += 256; // Add 256 to the sine value to make it positive asx.tex_y = 14400;
asx.sx = 128;
asx.sy = 128;
asx.alpha = 1000; // This slightly rotates it which increases the percieved resolution of the background
break;
case AFFINE_BG_GAME:
asx.scr_x = 0;
asx.scr_y = 0;
asx.tex_x += 5;
asx.tex_y += 12;
asx.sx = (lu_sin(timer * 100)) >> 8; // Scale the sine value to fit in a s16
asx.sx += 256; // Add 256 to the sine value to make it positive
asx.sy = (lu_sin(timer * 100 + 0x4000)) >> 8; // Scale the sine value to fit in a s16
asx.sy += 256; // Add 256 to the sine value to make it positive
asx.alpha = 0;
break;
}
bg_rotscale_ex(&bgaff, &asx); bg_rotscale_ex(&bgaff, &asx);
REG_BG_AFFINE[2] = bgaff; REG_BG_AFFINE[2] = bgaff;
} }
void affine_background_set_color(COLOR color) void affine_background_set_color(COLOR color)
{ {
memcpy16(&pal_bg_mem[AFFINE_BG_PB], affine_background_gfxPal, AFFINE_BG_PAL_LEN); memcpy16(&pal_bg_mem[AFFINE_BG_PB], affine_main_menu_background_gfxPal, AFFINE_BG_PAL_LEN);
for (int i = 0; i < AFFINE_BG_PAL_LEN; i++) for (int i = 0; i < AFFINE_BG_PAL_LEN; i++)
{ {
clr_rgbscale(&pal_bg_mem[AFFINE_BG_PB] + i, &pal_bg_mem[AFFINE_BG_PB] + i, 1, color); clr_rgbscale(&pal_bg_mem[AFFINE_BG_PB] + i, &pal_bg_mem[AFFINE_BG_PB] + i, 1, color);
@@ -44,3 +62,28 @@ void affine_background_load_palette(const u16 *src)
{ {
memcpy16(&pal_bg_mem[AFFINE_BG_PB], src, AFFINE_BG_PAL_LEN); memcpy16(&pal_bg_mem[AFFINE_BG_PB], src, AFFINE_BG_PAL_LEN);
} }
void affine_background_change_background(enum AffineBackgroundID new_bg)
{
background = new_bg;
switch (background)
{
case AFFINE_BG_MAIN_MENU:
REG_BG2CNT &= ~BG_AFF_32x32;
REG_BG2CNT |= BG_AFF_16x16;
memcpy32_tile8_with_palette_offset((u32*)&tile8_mem[AFFINE_BG_CBB], (const u32*)affine_main_menu_background_gfxTiles, affine_main_menu_background_gfxTilesLen/4, AFFINE_BG_PB);
GRIT_CPY(&se_mem[AFFINE_BG_SBB], affine_main_menu_background_gfxMap);
affine_background_load_palette(affine_main_menu_background_gfxPal);
break;
case AFFINE_BG_GAME:
REG_BG2CNT &= ~BG_AFF_16x16;
REG_BG2CNT |= BG_AFF_32x32;
memcpy32_tile8_with_palette_offset((u32*)&tile8_mem[AFFINE_BG_CBB], (const u32*)affine_background_gfxTiles, affine_background_gfxTilesLen/4, AFFINE_BG_PB);
GRIT_CPY(&se_mem[AFFINE_BG_SBB], affine_background_gfxMap);
affine_background_load_palette(affine_background_gfxPal);
break;
}
}
+94 -14
View File
@@ -20,6 +20,8 @@
#include "background_shop_gfx.h" #include "background_shop_gfx.h"
#include "background_blind_select_gfx.h" #include "background_blind_select_gfx.h"
#include "affine_background_gfx.h" #include "affine_background_gfx.h"
#include "background_main_menu_gfx.h"
#include "affine_main_menu_background_gfx.h"
#include "soundbank.h" #include "soundbank.h"
@@ -33,7 +35,7 @@ static uint timer = 0; // This might already exist in libtonc but idk so i'm jus
static int game_speed = 1; static int game_speed = 1;
static int background = 0; static int background = 0;
static enum GameState game_state = GAME_BLIND_SELECT; // The current game state, this is used to determine what the game is doing at any given time static enum GameState game_state = GAME_MAIN_MENU; // The current game state, this is used to determine what the game is doing at any given time
static enum HandState hand_state = HAND_DRAW; static enum HandState hand_state = HAND_DRAW;
static enum PlayState play_state = PLAY_PLAYING; static enum PlayState play_state = PLAY_PLAYING;
static int state = 0; // General state variable, used for switch statements in each game state related function static int state = 0; // General state variable, used for switch statements in each game state related function
@@ -241,6 +243,8 @@ static const Rect CASHOUT_RECT = {88, 72, UNDEFINED, UNDEF
static const Rect SHOP_REROLL_RECT = {88, 96, UNDEFINED, UNDEFINED }; static const Rect SHOP_REROLL_RECT = {88, 96, UNDEFINED, UNDEFINED };
//TODO: Properly define and use //TODO: Properly define and use
#define MAIN_MENU_BUTTONS 4
#define MENU_POP_OUT_ANIM_FRAMES 20 #define MENU_POP_OUT_ANIM_FRAMES 20
#define SCORED_CARD_TEXT_Y 48 #define SCORED_CARD_TEXT_Y 48
@@ -429,7 +433,8 @@ void change_background(int id)
} }
else else
{ {
REG_DISPCNT |= DCNT_WIN0; // Enable window 0 to make hand background transparent toggle_windows(true, true); // Enable window 0 for the hand shadow
// Load the tiles and palette // Load the tiles and palette
// Background // Background
memcpy(pal_bg_mem, background_gfxPal, 64); // This '64" isn't a specific number, I'm just using it to prevent the text colors from being overridden memcpy(pal_bg_mem, background_gfxPal, 64); // This '64" isn't a specific number, I'm just using it to prevent the text colors from being overridden
@@ -484,16 +489,16 @@ void change_background(int id)
background = BG_ID_ROUND_END; background = BG_ID_ROUND_END;
} }
REG_DISPCNT &= ~DCNT_WIN0; // Disable window 0 so it doesn't make the cashout menu transparent toggle_windows(false, true); // Disable window 0 so it doesn't make the cashout menu transparent
main_bg_se_clear_rect(ROUND_END_MENU_RECT); main_bg_se_clear_rect(ROUND_END_MENU_RECT);
tte_erase_rect_wrapper(HAND_SIZE_RECT); tte_erase_rect_wrapper(HAND_SIZE_RECT);
} }
else if (id == BG_ID_SHOP) else if (id == BG_ID_SHOP)
{ {
REG_DISPCNT &= ~DCNT_WIN0; toggle_windows(false, true);
memcpy(pal_bg_mem, background_shop_gfxPal, 64); memcpy16(pal_bg_mem, background_shop_gfxPal, 64);
GRIT_CPY(&tile_mem[MAIN_BG_CBB], background_shop_gfxTiles); GRIT_CPY(&tile_mem[MAIN_BG_CBB], background_shop_gfxTiles);
GRIT_CPY(&se_mem[MAIN_BG_SBB], background_shop_gfxMap); GRIT_CPY(&se_mem[MAIN_BG_SBB], background_shop_gfxMap);
@@ -520,7 +525,7 @@ void change_background(int id)
sprite_position(blind_select_tokens[BIG_BLIND], 120, default_y); sprite_position(blind_select_tokens[BIG_BLIND], 120, default_y);
sprite_position(blind_select_tokens[BOSS_BLIND], 160, default_y); sprite_position(blind_select_tokens[BOSS_BLIND], 160, default_y);
REG_DISPCNT &= ~DCNT_WIN0; toggle_windows(false, true);
memcpy16(pal_bg_mem, background_blind_select_gfxPal, 64); memcpy16(pal_bg_mem, background_blind_select_gfxPal, 64);
GRIT_CPY(&tile_mem[MAIN_BG_CBB], background_blind_select_gfxTiles); GRIT_CPY(&tile_mem[MAIN_BG_CBB], background_blind_select_gfxTiles);
@@ -619,6 +624,21 @@ void change_background(int id)
} }
} }
} }
else if (id == BG_ID_MAIN_MENU)
{
toggle_windows(false, false);
tte_erase_screen();
memcpy16(pal_bg_mem, background_main_menu_gfxPal, PAL_ROW_LEN * 9);
GRIT_CPY(&tile_mem[MAIN_BG_CBB], background_main_menu_gfxTiles);
GRIT_CPY(&se_mem[MAIN_BG_SBB], background_main_menu_gfxMap);
// Disable the button highlight colors
// Select button PID is 5 and the outline is 3
memcpy16(&pal_bg_mem[3], &pal_bg_mem[5], 1);
affine_background_change_background(AFFINE_BG_MAIN_MENU);
}
else else
{ {
return; // Invalid background ID return; // Invalid background ID
@@ -1015,10 +1035,7 @@ void jokers_avialable_to_shop_init()
void game_init() void game_init()
{ {
jokers_avialable_to_shop_init(); change_background(BG_ID_MAIN_MENU);
hands = max_hands;
discards = max_discards;
blind_select_tokens[SMALL_BLIND] = blind_token_new(SMALL_BLIND, 8, 18, MAX_SELECTION_SIZE + MAX_HAND_SIZE + 3); blind_select_tokens[SMALL_BLIND] = blind_token_new(SMALL_BLIND, 8, 18, MAX_SELECTION_SIZE + MAX_HAND_SIZE + 3);
blind_select_tokens[BIG_BLIND] = blind_token_new(BIG_BLIND, 8, 18, MAX_SELECTION_SIZE + MAX_HAND_SIZE + 4); blind_select_tokens[BIG_BLIND] = blind_token_new(BIG_BLIND, 8, 18, MAX_SELECTION_SIZE + MAX_HAND_SIZE + 4);
@@ -1037,8 +1054,26 @@ void game_init()
deck_push(card); deck_push(card);
} }
} }
}
change_background(BG_ID_BLIND_SELECT); void game_start()
{
affine_background_change_background(AFFINE_BG_GAME);
jokers_avialable_to_shop_init();
hands = max_hands;
discards = max_discards;
// Fill the deck with all the cards. Later on this can be replaced with a more dynamic system that allows for different decks and card types.
for (int suit = 0; suit < NUM_SUITS; suit++)
{
for (int rank = 0; rank < NUM_RANKS; rank++)
{
Card *card = card_new(suit, rank);
deck_push(card);
}
}
tte_printf("#{P:%d,%d; cx:0xF000}%d/%d", DECK_SIZE_RECT.left, DECK_SIZE_RECT.top, deck_get_size(), deck_get_max_size()); // Deck size/max size tte_printf("#{P:%d,%d; cx:0xF000}%d/%d", DECK_SIZE_RECT.left, DECK_SIZE_RECT.top, deck_get_size(), deck_get_max_size()); // Deck size/max size
@@ -1055,6 +1090,9 @@ void game_init()
display_money(money); // Set the money display display_money(money); // Set the money display
tte_printf("#{P:%d,%d; cx:0xC000}%d#{cx:0xF000}/%d", ANTE_TEXT_RECT.left, ANTE_TEXT_RECT.top, ante, MAX_ANTE); // Ante tte_printf("#{P:%d,%d; cx:0xC000}%d#{cx:0xF000}/%d", ANTE_TEXT_RECT.left, ANTE_TEXT_RECT.top, ante, MAX_ANTE); // Ante
change_background(BG_ID_BLIND_SELECT);
game_set_state(GAME_BLIND_SELECT);
} }
static void game_playing_process_hand_select_input() static void game_playing_process_hand_select_input()
@@ -2375,7 +2413,6 @@ static void game_shop_lights_anim_frame()
memcpy16(&pal_bg_mem[8], &shifted_palette[3], 1); memcpy16(&pal_bg_mem[8], &shifted_palette[3], 1);
} }
void game_shop() void game_shop()
{ {
change_background(BG_ID_SHOP); change_background(BG_ID_SHOP);
@@ -2473,8 +2510,6 @@ void game_shop()
} }
} }
void game_blind_select() void game_blind_select()
{ {
switch (state) // I'm only using magic numbers here for the sake of simplicity since it's just sequential, but you can replace them with named constants or enums if it makes it clearer switch (state) // I'm only using magic numbers here for the sake of simplicity since it's just sequential, but you can replace them with named constants or enums if it makes it clearer
@@ -2639,6 +2674,48 @@ void game_blind_select()
} }
} }
void game_main_menu()
{
change_background(BG_ID_MAIN_MENU);
if (key_hit(KEY_LEFT))
{
if (selection_x > 0)
{
selection_x--;
}
}
else if (key_hit(KEY_RIGHT))
{
// TODO: Don't allow cursor on sold items
if (selection_x < MAIN_MENU_BUTTONS)
{
selection_x++;
}
else if (selection_x < MAIN_MENU_BUTTONS)
{
selection_x++;
}
}
if (selection_x == 0) // Play button
{
// Select button PID is 5 and the outline is 3
memset16(&pal_bg_mem[3], CLR_WHITE, 1);
if (key_hit(KEY_A))
{
// Start the game
game_start();
}
}
else
{
// Select button PID is 5 and the outline is 3
memcpy16(&pal_bg_mem[3], &pal_bg_mem[5], 1);
}
}
void game_update() void game_update()
{ {
timer++; timer++;
@@ -2656,6 +2733,9 @@ void game_update()
switch (game_state) switch (game_state)
{ {
case GAME_MAIN_MENU:
game_main_menu();
break;
case GAME_PLAYING: case GAME_PLAYING:
game_playing(); game_playing();
break; break;
+30
View File
@@ -187,3 +187,33 @@ void memcpy32_tile8_with_palette_offset(u32* dst, const u32* src, uint wcount, u
dst[i] = src[i] + offset; dst[i] = src[i] + offset;
} }
} }
void toggle_windows(bool win0, bool win1)
{
if (win0)
{
REG_DISPCNT |= DCNT_WIN0;
}
else
{
REG_DISPCNT &= ~DCNT_WIN0;
}
if (win1)
{
REG_DISPCNT |= DCNT_WIN1;
}
else
{
REG_DISPCNT &= ~DCNT_WIN1;
}
if (win0 || win1)
{
REG_BLDCNT = BLD_BUILD(BLD_BG1, BLD_BG2, 1);
}
else
{
REG_BLDCNT = 0;
}
}
+1 -1
View File
@@ -44,7 +44,7 @@ void init()
// BG1 is the main background layer // BG1 is the main background layer
REG_BG1CNT = BG_PRIO(1) | BG_CBB(MAIN_BG_CBB) | BG_SBB(MAIN_BG_SBB) | BG_8BPP; REG_BG1CNT = BG_PRIO(1) | BG_CBB(MAIN_BG_CBB) | BG_SBB(MAIN_BG_SBB) | BG_8BPP;
// BG2 is the affine background layer // BG2 is the affine background layer
REG_BG2CNT = BG_PRIO(2) | BG_CBB(AFFINE_BG_CBB) | BG_SBB(AFFINE_BG_CBB) | BG_8BPP | BG_WRAP | BG_AFF_32x32; REG_BG2CNT = BG_PRIO(2) | BG_CBB(AFFINE_BG_CBB) | BG_SBB(AFFINE_BG_CBB) | BG_8BPP | BG_WRAP | BG_AFF_16x16;
int win1_left = 72; int win1_left = 72;
int win1_top = 44; int win1_top = 44;