Merge pull request #93 from cellos51/main_menu_and_splash_screen

Main menu and splash screen
This commit is contained in:
Elliptical
2025-08-28 19:35:55 -04:00
committed by GitHub
17 changed files with 289 additions and 58 deletions
+1 -1
View File
@@ -1 +1 @@
-gt -gB8 -mLa -mRa -gt -gB8 -mLa -mRa -pe 16
@@ -0,0 +1 @@
-gt -gB8 -mLa -mRa -pe 16
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

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

After

Width:  |  Height:  |  Size: 8.2 KiB

+1 -1
View File
@@ -1 +1 @@
-gB8 -mR8 -mLs -mRtf -gB8 -mR8 -mLs -mRtf -pe 160
+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
+4
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
@@ -27,6 +28,8 @@
enum GameState enum GameState
{ {
GAME_SPLASH_SCREEN,
GAME_MAIN_MENU,
GAME_PLAYING, GAME_PLAYING,
GAME_ROUND_END, GAME_ROUND_END,
GAME_SHOP, GAME_SHOP,
@@ -75,6 +78,7 @@ enum HandType
// Game functions // Game functions
void game_init(); void game_init();
void game_update(); void game_update();
void game_set_state(enum GameState new_game_state);
// Forward declaration // Forward declaration
struct List; struct List;
+6
View File
@@ -173,4 +173,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
+13
View File
@@ -0,0 +1,13 @@
#ifndef SPLASH_SCREEN_H
#define SPLASH_SCREEN_H
#include <tonc.h>
#define SPLASH_FPS 60
#define SPLASH_DURATION_SECONDS 10
#define SPLASH_DURATION_FRAMES (SPLASH_FPS * SPLASH_DURATION_SECONDS)
void splash_screen_init();
void splash_screen_update(uint timer);
#endif // SPLASH_SCREEN_H
+56 -13
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_update();
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 perceived 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); affine_background_change_background(background); // Reload the palette to reset any previous color scaling
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);
@@ -43,4 +61,29 @@ void affine_background_set_color(COLOR color)
void affine_background_load_palette(const u16 *src) 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;
}
} }
+130 -34
View File
@@ -16,31 +16,34 @@
#include "tonc_video.h" #include "tonc_video.h"
#include "audio_utils.h" #include "audio_utils.h"
#include "selection_grid.h" #include "selection_grid.h"
#include "splash_screen.h"
#include "background_gfx.h" #include "background_gfx.h"
#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"
#include "list.h" #include "list.h"
// This seed system is temporary. static uint rng_seed = 0;
static uint rng_seed = 2048;
static bool seeded = false;
static uint timer = 0; // This might already exist in libtonc but idk so i'm just making my own static uint timer = 0; // This might already exist in libtonc but idk so i'm just making my own
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_SPLASH_SCREEN; // 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
static enum HandType hand_type = NONE; static enum HandType hand_type = NONE;
static CardObject *main_menu_ace = NULL;
static Sprite *playing_blind_token = NULL; // The sprite that displays the blind when in "GAME_PLAYING/GAME_ROUND_END" state static Sprite *playing_blind_token = NULL; // The sprite that displays the blind when in "GAME_PLAYING/GAME_ROUND_END" state
static Sprite *round_end_blind_token = NULL; // The sprite that displays the blind when in "GAME_ROUND_END" state static Sprite *round_end_blind_token = NULL; // The sprite that displays the blind when in "GAME_ROUND_END" state
@@ -249,6 +252,11 @@ static const BG_POINT JOKER_DISCARD_TARGET = {240, 30};
#define ITEM_SHOP_Y 71 // TODO: Needs to be a rect? #define ITEM_SHOP_Y 71 // TODO: Needs to be a rect?
#define MAIN_MENU_BUTTONS 2
#define MAIN_MENU_IMPLEMENTED_BUTTONS 1 // Remove this once all buttons are implemented
#define MAIN_MENU_PLAY_BUTTON_MAIN_COLOR_PID 5
#define MAIN_MENU_PLAY_BUTTON_OUTLINE_COLOR_PID 2
//TODO: Properly define and use //TODO: Properly define and use
#define MENU_POP_OUT_ANIM_FRAMES 20 #define MENU_POP_OUT_ANIM_FRAMES 20
#define GAME_OVER_ANIM_FRAMES 15 #define GAME_OVER_ANIM_FRAMES 15
@@ -265,12 +273,8 @@ static const BG_POINT JOKER_DISCARD_TARGET = {240, 30};
// General functions // General functions
void set_seed(int seed) void set_seed(int seed)
{ {
if (!seeded) rng_seed = seed;
{ srand(rng_seed);
seeded = true;
rng_seed = seed;
srand(rng_seed);
}
} }
void sort_hand_by_suit() void sort_hand_by_suit()
@@ -437,11 +441,12 @@ 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 GRIT_CPY(pal_bg_mem, background_gfxPal);
GRIT_CPY(&tile8_mem[MAIN_BG_CBB], background_gfxTiles); // Deadass i have no clue how any of these memory things work but I just messed with them until stuff worked GRIT_CPY(&tile8_mem[MAIN_BG_CBB], background_gfxTiles);
GRIT_CPY(&se_mem[MAIN_BG_SBB], background_gfxMap); GRIT_CPY(&se_mem[MAIN_BG_SBB], background_gfxMap);
if (current_blind == BIG_BLIND) // Change text and palette depending on blind type if (current_blind == BIG_BLIND) // Change text and palette depending on blind type
@@ -476,6 +481,7 @@ void change_background(int id)
} }
REG_WIN0V = (REG_WIN0V << 8) | 0xA0; // Set window 0 bottom to 160 REG_WIN0V = (REG_WIN0V << 8) | 0xA0; // Set window 0 bottom to 160
toggle_windows(true, true);
for (int i = 0; i <= 2; i++) for (int i = 0; i <= 2; i++)
{ {
@@ -492,16 +498,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); GRIT_CPY(pal_bg_mem, background_shop_gfxPal);
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);
@@ -528,9 +534,9 @@ 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); GRIT_CPY(pal_bg_mem, background_blind_select_gfxPal);
GRIT_CPY(&tile_mem[MAIN_BG_CBB], background_blind_select_gfxTiles); GRIT_CPY(&tile_mem[MAIN_BG_CBB], background_blind_select_gfxTiles);
GRIT_CPY(&se_mem[MAIN_BG_SBB], background_blind_select_gfxMap); GRIT_CPY(&se_mem[MAIN_BG_SBB], background_blind_select_gfxMap);
@@ -542,7 +548,7 @@ void change_background(int id)
// Select button PID is 15 and the outline is 18 // Select button PID is 15 and the outline is 18
memcpy16(&pal_bg_mem[18], &pal_bg_mem[15], 1); memcpy16(&pal_bg_mem[18], &pal_bg_mem[15], 1);
// Skip button PID is 10 and the outline is 5 // Skip button PID is 10 and the outline is 5
memcpy16(&pal_bg_mem[10 ], &pal_bg_mem[5], 1); memcpy16(&pal_bg_mem[10], &pal_bg_mem[5], 1);
for (int i = 0; i < MAX_BLINDS; i++) for (int i = 0; i < MAX_BLINDS; i++)
{ {
@@ -627,6 +633,18 @@ void change_background(int id)
} }
} }
} }
else if (id == BG_ID_MAIN_MENU)
{
toggle_windows(false, false);
tte_erase_screen();
GRIT_CPY(pal_bg_mem, background_main_menu_gfxPal);
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
memcpy16(&pal_bg_mem[MAIN_MENU_PLAY_BUTTON_OUTLINE_COLOR_PID], &pal_bg_mem[MAIN_MENU_PLAY_BUTTON_MAIN_COLOR_PID], 1);
}
else else
{ {
return; // Invalid background ID return; // Invalid background ID
@@ -931,9 +949,6 @@ void increment_blind(enum BlindState increment_reason)
static void game_round_init() static void game_round_init()
{ {
// once we have a main menu, move the seed set there. this is only here now because there isn't a way to set the seed to a psudorandom value unless there is something to wait on
set_seed(rng_seed);
hand_state = HAND_DRAW; hand_state = HAND_DRAW;
cards_drawn = 0; cards_drawn = 0;
hand_selections = 0; hand_selections = 0;
@@ -981,6 +996,20 @@ static void game_round_init()
deck_shuffle(); // Shuffle the deck at the start of the round deck_shuffle(); // Shuffle the deck at the start of the round
} }
static void game_main_menu_init()
{
affine_background_change_background(AFFINE_BG_MAIN_MENU);
change_background(BG_ID_MAIN_MENU);
main_menu_ace = card_object_new(card_new(SPADES, ACE));
card_object_set_sprite(main_menu_ace, 0); // Set the sprite for the ace of spades
main_menu_ace->sprite_object->sprite->obj->attr0 |= ATTR0_AFF_DBL; // Make the sprite double sized
main_menu_ace->sprite_object->tx = int2fx(88);
main_menu_ace->sprite_object->x = main_menu_ace->sprite_object->tx;
main_menu_ace->sprite_object->ty = int2fx(26);
main_menu_ace->sprite_object->y = main_menu_ace->sprite_object->ty;
main_menu_ace->sprite_object->tscale = float2fx(0.8f);
}
static void game_over_init() static void game_over_init()
{ {
// Clears the round end menu // Clears the round end menu
@@ -1008,6 +1037,12 @@ static void init_game_state(enum GameState game_state_to_init)
// Switch written out, add init for states as needed // Switch written out, add init for states as needed
switch (game_state_to_init) switch (game_state_to_init)
{ {
case GAME_SPLASH_SCREEN:
splash_screen_init();
break;
case GAME_MAIN_MENU:
game_main_menu_init();
break;
case GAME_PLAYING: case GAME_PLAYING:
game_round_init(); game_round_init();
break; break;
@@ -1029,7 +1064,7 @@ static void init_game_state(enum GameState game_state_to_init)
} }
// Game functions // Game functions
static void game_set_state(enum GameState new_game_state) void game_set_state(enum GameState new_game_state)
{ {
timer = 0; // Reset the timer timer = 0; // Reset the timer
init_game_state(new_game_state); init_game_state(new_game_state);
@@ -1069,6 +1104,22 @@ void game_init()
obj_hide(blind_select_tokens[BIG_BLIND]->obj); obj_hide(blind_select_tokens[BIG_BLIND]->obj);
obj_hide(blind_select_tokens[BOSS_BLIND]->obj); obj_hide(blind_select_tokens[BOSS_BLIND]->obj);
game_set_state(game_state);
}
void game_start()
{
set_seed(rng_seed);
affine_background_change_background(AFFINE_BG_GAME);
// Normally I would just cache these and hide/unhide but I didn't feel like dealing with defining a layer for it
card_destroy(&main_menu_ace->card);
card_object_destroy(&main_menu_ace);
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. // 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 suit = 0; suit < NUM_SUITS; suit++)
{ {
@@ -1095,6 +1146,8 @@ void game_init()
display_money(money); // Set the money display display_money(money); // Set the money display
tte_printf("#{P:%d,%d; cx:0x%X000}%d#{cx:0x%X000}/%d", ANTE_TEXT_RECT.left, ANTE_TEXT_RECT.top, TTE_YELLOW_PB, ante, TTE_WHITE_PB, MAX_ANTE); // Ante tte_printf("#{P:%d,%d; cx:0x%X000}%d#{cx:0x%X000}/%d", ANTE_TEXT_RECT.left, ANTE_TEXT_RECT.top, TTE_YELLOW_PB, ante, TTE_WHITE_PB, MAX_ANTE); // Ante
game_set_state(GAME_BLIND_SELECT);
} }
static void game_playing_process_hand_select_input() static void game_playing_process_hand_select_input()
@@ -2613,7 +2666,6 @@ void game_shop()
} }
} }
} }
if (timer % 20 == 0) if (timer % 20 == 0)
{ {
@@ -2824,6 +2876,54 @@ void game_blind_select()
} }
} }
void game_main_menu()
{
change_background(BG_ID_MAIN_MENU);
card_object_update(main_menu_ace);
main_menu_ace->sprite_object->trotation = lu_sin((timer << 8) / 2) / 3;
main_menu_ace->sprite_object->rotation = main_menu_ace->sprite_object->trotation;
// Seed randomization
rng_seed++;
if (key_curr_state() != key_prev_state()) // If the keys have changed, make it more pseudo-random
{
rng_seed *= 2;
}
if (key_hit(KEY_LEFT))
{
if (selection_x > 0)
{
selection_x--;
}
}
else if (key_hit(KEY_RIGHT))
{
if (selection_x < MAIN_MENU_IMPLEMENTED_BUTTONS - 1)
{
selection_x++;
}
}
if (selection_x == 0) // Play button
{
// Select button PID is 5 and the outline is 3
memset16(&pal_bg_mem[MAIN_MENU_PLAY_BUTTON_OUTLINE_COLOR_PID], HIGHLIGHT_COLOR, 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[MAIN_MENU_PLAY_BUTTON_OUTLINE_COLOR_PID], &pal_bg_mem[MAIN_MENU_PLAY_BUTTON_MAIN_COLOR_PID], 1);
}
}
static void discarded_jokers_update_loop() static void discarded_jokers_update_loop()
{ {
if (discarded_jokers == NULL) if (discarded_jokers == NULL)
@@ -2841,7 +2941,6 @@ static void discarded_jokers_update_loop()
joker_object_destroy(&joker_object); joker_object_destroy(&joker_object);
} }
} }
} }
static void held_jokers_update_loop() static void held_jokers_update_loop()
@@ -2906,19 +3005,16 @@ void game_update()
{ {
timer++; timer++;
if (seeded == false)
{
rng_seed++;
if (key_curr_state() != key_prev_state()) // If the keys have changed, make it more pseudo-random
{
rng_seed *= 2;
}
}
jokers_update_loop(); jokers_update_loop();
switch (game_state) switch (game_state)
{ {
case GAME_SPLASH_SCREEN:
splash_screen_update(timer);
break;
case GAME_MAIN_MENU:
game_main_menu();
break;
case GAME_PLAYING: case GAME_PLAYING:
game_playing(); game_playing();
break; break;
+30
View File
@@ -269,4 +269,34 @@ void memcpy32_tile8_with_palette_offset(u32* dst, const u32* src, uint wcount, u
// Copying u8 data 4 times across u32 data // Copying u8 data 4 times across u32 data
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;
}
} }
+3 -5
View File
@@ -23,10 +23,6 @@ void init()
irq_init(NULL); irq_init(NULL);
irq_add(II_VBLANK, mmVBlank); irq_add(II_VBLANK, mmVBlank);
// Initialize maxmod
mmInitDefault((mm_addr)soundbank_bin, 12);
mmStart(MOD_MAIN_THEME, MM_PLAY_LOOP);
// Initialize text engine // Initialize text engine
tte_init_se(0, BG_CBB(TTE_CBB) | BG_SBB(TTE_SBB), 0, CLR_WHITE, TTE_BIT_UNPACK_OFFSET, NULL, NULL); tte_init_se(0, BG_CBB(TTE_CBB) | BG_SBB(TTE_SBB), 0, CLR_WHITE, TTE_BIT_UNPACK_OFFSET, NULL, NULL);
tte_erase_screen(); tte_erase_screen();
@@ -44,7 +40,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_SBB) | BG_8BPP | BG_WRAP | BG_AFF_32x32; REG_BG2CNT = BG_PRIO(2) | BG_CBB(AFFINE_BG_CBB) | BG_SBB(AFFINE_BG_SBB) | BG_8BPP | BG_WRAP;
int win1_left = 72; int win1_left = 72;
int win1_top = 44; int win1_top = 44;
@@ -72,6 +68,8 @@ void init()
REG_DISPCNT = DCNT_MODE1 | DCNT_OBJ_1D | DCNT_BG0 | DCNT_BG1 | DCNT_BG2 | DCNT_OBJ | DCNT_WIN0 | DCNT_WIN1; REG_DISPCNT = DCNT_MODE1 | DCNT_OBJ_1D | DCNT_BG0 | DCNT_BG1 | DCNT_BG2 | DCNT_OBJ | DCNT_WIN0 | DCNT_WIN1;
// Initialize subsystems // Initialize subsystems
mmInitDefault((mm_addr)soundbank_bin, 12);
mmStart(MOD_MAIN_THEME, MM_PLAY_LOOP);
affine_background_init(); affine_background_init();
sprite_init(); sprite_init();
card_init(); card_init();
+32
View File
@@ -0,0 +1,32 @@
#include "splash_screen.h"
#include <tonc.h>
#include "graphic_utils.h"
#include "game.h"
static const Rect COUNTDOWN_TIMER_RECT = {208, 144, 240, 152};
void splash_screen_init()
{
tte_printf("#{P:72,8; cx:0xF000}DISCLAIMER");
tte_printf("#{P:8,24; cx:0xF000}This project is NOT endorsed \n by or affiliated with \n Playstack or LocalThunk.\n\n If you have paid for this, \n you have been scammed \n and should request a refund \n IMMEDIATELY. \n\n The only official place \n to obtain this is from: \n\n 'github.com/\n cellos51/balatro-gba'");
tte_printf("#{P:8,144; cx:0xF000}(Press any key to skip)");
}
void splash_screen_update(uint timer)
{
if (timer < SPLASH_DURATION_FRAMES)
{
tte_erase_rect_wrapper(COUNTDOWN_TIMER_RECT);
tte_printf("#{P:%d,%d; cx:0xF000}%d", COUNTDOWN_TIMER_RECT.left, COUNTDOWN_TIMER_RECT.top, 1 + (SPLASH_DURATION_FRAMES - timer) / SPLASH_FPS);
if (!key_hit(KEY_ANY))
{
return;
}
}
game_set_state(GAME_MAIN_MENU);
tte_erase_screen();
}