[Feature] Implement seeded runs by adding a Seed selection menu (#482)
* initial commit * wip * WIP * WIP * clang format * Choose Seed navigation mostly done * seed input navigation done * seed input done * cleanup and clang format * Implement base 10 to 36 conversions * Enable seeded runs * clang format * show default deck sprite, name and description * Rename Deck enum to DeckType * Implement arbitrary 9-patch expand system * Make 9-patch example smaller in the docs * Improve NinePatchRect docs * fix Deck back side sprite palette * clang format * Add last deck description * clang format * Fix 'Z' in seed input keyboard * Fix rebase issue * fix deck sprite not updating * Documents static funcs in run_setup.c * more documentation * clang format * Move Play button to the left in its row * Tests WIP * removing tests for random.h * use the new StateMachine struct * First wave of fixes * Fix the 9-patch again * Changed the base 36 logic so it's in big endian * properly set end of base 36 string to '\0' * typos * fix cursor position after rolling a seed + fix random seed generation * Make keyboard more intuitive to use * static const var * Address more comment from @ricfehr3 * clang format * clang format * clang format * clang format * clang format * clang format * clang format * fix deck palette * create the `DEF_SEED_KEYBOARD_BUTTON_OBJECT` macro * Replace `expand_3x3` by a call to `expand_9-patch` * clang format * clang format * clang format * fix rebase iussue in state_machine.h --------- Co-authored-by: MathisMartin31 <mathis.martin31@gmail.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#ifndef CARD_H
|
||||
#define CARD_H
|
||||
|
||||
#include "deck_types.h"
|
||||
#include "sprite.h"
|
||||
|
||||
#include <maxmod.h>
|
||||
@@ -58,6 +59,8 @@ typedef struct CardObject
|
||||
bool selected;
|
||||
} CardObject;
|
||||
|
||||
void card_init(void);
|
||||
|
||||
// Card sprites accessibility functions
|
||||
void set_cards_high_contrast(bool enable);
|
||||
void set_cards_more_readable(bool enable);
|
||||
@@ -74,6 +77,7 @@ CardObject* card_object_new(Card* card);
|
||||
void card_object_destroy(CardObject** card_object);
|
||||
void card_object_update(CardObject* card_object); // Update the card object position and scale
|
||||
void card_object_set_sprite(CardObject* card_object, int layer);
|
||||
void card_object_set_sprite_face_down(CardObject* card_object, enum DeckType deck, int layer);
|
||||
void card_object_shake(CardObject* card_object, mm_word sound_id);
|
||||
|
||||
void card_object_set_selected(CardObject* card_object, bool selected);
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @file deck_types.h
|
||||
*
|
||||
* @brief Functions related to the different types of Decks.
|
||||
*/
|
||||
#ifndef DECK_TYPES_H
|
||||
#define DECK_TYPES_H
|
||||
|
||||
#include "graphic_utils.h"
|
||||
|
||||
#define DECK_SPRITES_PB 1
|
||||
|
||||
#define DECK_NAME_LENGTH 14 // 13 chars + '\0'
|
||||
#define DECK_DESC_WIDTH DECK_NAME_LENGTH
|
||||
#define DECK_DESC_HEIGHT 5
|
||||
|
||||
enum DeckType
|
||||
{
|
||||
DECK_TYPE_RED,
|
||||
DECK_TYPE_BLUE,
|
||||
DECK_TYPE_YELLOW,
|
||||
DECK_TYPE_GREEN,
|
||||
DECK_TYPE_BLACK,
|
||||
DECK_TYPE_PAINTED,
|
||||
DECK_TYPE_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Prints the Deck name string to the screen at the given position.
|
||||
*
|
||||
* @param deck Decktype we want the name of.
|
||||
* @param pos screen position in pixels to print the name at.
|
||||
*/
|
||||
void print_deck_name(enum DeckType deck, BG_POINT pos);
|
||||
|
||||
/**
|
||||
* @brief Prints the Deck description string to the screen at the given position.
|
||||
*
|
||||
* @param deck DeckType we want the description of.
|
||||
* @param pos screen position in pixels of the top-left corner of the rectangle
|
||||
* we'll print the Deck description into
|
||||
*/
|
||||
void print_deck_description(enum DeckType deck, BG_POINT pos);
|
||||
|
||||
#endif // DECK_TYPES_H
|
||||
@@ -3,6 +3,7 @@
|
||||
DEF_STATE_INFO(GAME_STATE_SPLASH_SCREEN, splash_screen_on_init, splash_screen_on_update, splash_screen_on_exit )
|
||||
DEF_STATE_INFO(GAME_STATE_MAIN_MENU, game_main_menu_on_init, game_main_menu_on_update, game_main_menu_on_exit )
|
||||
DEF_STATE_INFO(GAME_STATE_OPTIONS_MENU, game_options_menu_on_init, game_options_menu_on_update, game_options_menu_on_exit)
|
||||
DEF_STATE_INFO(GAME_STATE_RUN_SETUP , game_run_setup_on_init, game_run_setup_on_update, game_run_setup_on_exit )
|
||||
DEF_STATE_INFO(GAME_STATE_GAME_START, noop, game_start, noop )
|
||||
DEF_STATE_INFO(GAME_STATE_PLAYING, game_round_on_init, game_playing_on_update, noop )
|
||||
DEF_STATE_INFO(GAME_STATE_ROUND_END, game_round_end_on_init, game_round_end_on_update, game_round_end_on_exit )
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#define SORT_HAND KEY_R
|
||||
#define PAUSE_GAME KEY_START // Not implemented
|
||||
#define SELL_KEY KEY_L
|
||||
#define TAB_LEFT KEY_L
|
||||
#define TAB_RIGHT KEY_R
|
||||
|
||||
// Matching the position of the on-screen buttons
|
||||
#define PLAY_HAND_KEY KEY_L
|
||||
|
||||
@@ -19,6 +19,7 @@ enum BackgroundId
|
||||
BG_ROUND_END,
|
||||
BG_SHOP,
|
||||
BG_BLIND_SELECT,
|
||||
BG_RUN_SETUP,
|
||||
BG_OPTIONS_MENU,
|
||||
BG_MAIN_MENU
|
||||
};
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @file run_setup.h
|
||||
*
|
||||
* @brief Setup Run menu state functions.
|
||||
*/
|
||||
#ifndef GAME_RUN_SETUP_H
|
||||
#define GAME_RUN_SETUP_H
|
||||
|
||||
/**
|
||||
* @brief Change to the Run Setup menu background
|
||||
*/
|
||||
void game_run_setup_change_background(void);
|
||||
|
||||
/**
|
||||
* @brief Run Setup menu state initialization
|
||||
*/
|
||||
void game_run_setup_on_init(void);
|
||||
|
||||
/**
|
||||
* @brief Run Setup menu state update
|
||||
*/
|
||||
void game_run_setup_on_update(void);
|
||||
|
||||
/**
|
||||
* @brief Run Setup menu cleanup
|
||||
*/
|
||||
void game_run_setup_on_exit(void);
|
||||
|
||||
#endif // GAME_RUN_SETUP_H
|
||||
@@ -47,6 +47,7 @@ typedef struct
|
||||
s32 ante;
|
||||
s32 money;
|
||||
s32 hand_size;
|
||||
s32 deck;
|
||||
|
||||
// Blind variables
|
||||
|
||||
|
||||
+61
-1
@@ -63,6 +63,9 @@
|
||||
/** @def TTE_BIT_ON_CLR_IDX */
|
||||
#define TTE_BIT_ON_CLR_IDX TTE_BIT_UNPACK_OFFSET + 1
|
||||
|
||||
/** @def TTE_BLACK_PB */
|
||||
#define TTE_BLACK_PB 0 // 0x0
|
||||
|
||||
/** @def TTE_YELLOW_PB */
|
||||
#define TTE_YELLOW_PB 12 // 0xC
|
||||
|
||||
@@ -149,6 +152,37 @@ enum OverflowDir
|
||||
// When making this, missed that it already exists in tonc_math.h
|
||||
typedef RECT Rect;
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Structure to represent arbitrary-sized 9-patches.
|
||||
*
|
||||
* While expanding a 3x3 rect is simple enough and has its purpose, this is an attempt
|
||||
* to generalize the idea to a struct representing a 9-patch like this, such that areas
|
||||
* 1, 2, 3 and 4 have no null dimensions and don't overlap:
|
||||
* ```
|
||||
* margins.left margins.right │ Such as:
|
||||
* ╭───┴───╮ ╭─┴─╮ │
|
||||
* ╔═══════╤═════╤═══╗ ╮ │ 1) margins.left + margins.right <= width (patch_rect)
|
||||
* ║ 1 │ 6 │ 2 ║ ├─ margins.top │
|
||||
* ╟───────┼─────┼───╢ ╯ │ 2) margins.top + margins.bottom <= height(patch_rect)
|
||||
* ║ 5 │ 0 │ 7 ║ │
|
||||
* ║ │ │ ║ │ 3) margins values are inclusive, in number of tiles
|
||||
* ╟───────┼─────┼───╢ ╮ │
|
||||
* ║ │ │ ║ │ │
|
||||
* ║ 4 │ 8 │ 3 ║ ├─ margins.bottom │
|
||||
* ║ │ │ ║ │ │
|
||||
* ╚═══════╧═════╧═══╝ ╯ │
|
||||
* ╰────────┬────────╯ │
|
||||
* patch_rect │
|
||||
* ```
|
||||
*/
|
||||
// clang-format on
|
||||
typedef struct NinePatchRect
|
||||
{
|
||||
Rect patch_rect;
|
||||
Rect margins;
|
||||
} NinePatchRect;
|
||||
|
||||
/**
|
||||
* @brief Get the width of a rectangle
|
||||
*
|
||||
@@ -218,7 +252,33 @@ void main_bg_se_copy_rect_1_tile_vert(Rect se_rect, enum ScreenVertDir direction
|
||||
void main_bg_se_copy_rect(Rect se_rect, BG_POINT dest_pos);
|
||||
|
||||
/**
|
||||
* @brief Copies a 3x3 rect and expands it to fit a passed rect.
|
||||
* @brief Copies a tile in the main background at se_tile_src to fill se_rect_dest.
|
||||
*
|
||||
* @param se_rect_dest dimensions are in number of tiles.
|
||||
* @param se_tile_src x and y are the coordinates in number of tiles.
|
||||
*/
|
||||
void main_bg_se_copy_expand_tile(Rect se_rect_dest, BG_POINT se_tile_src);
|
||||
|
||||
/**
|
||||
* @brief Copies a 9-patch and expands it to fit a passed rect.
|
||||
*
|
||||
* Performs the following operation:
|
||||
*
|
||||
* 1. The corners are copied
|
||||
* 2. The sides are stretched
|
||||
* 3. The center is stretched to fill `se_rect_dest` minus the patch's margins.
|
||||
*
|
||||
* @param se_rect_dest Destination for the 9-patch copy. Needs to be at least large enough to fit
|
||||
* the corners and sides of the patch, (`margins.left + margins.right` by
|
||||
* `margins.top + margins.bottom`) in which case only the corners are copied.
|
||||
* @param src_9_ptch Pointer to the properties of the 9-patch we want to stretch.
|
||||
*
|
||||
* @sa NinePatchRect
|
||||
*/
|
||||
void main_bg_se_copy_expand_9_patch(Rect se_dest_rect, const NinePatchRect* src_9_ptch);
|
||||
|
||||
/**
|
||||
* @brief Copies a 3x3 rect and expands it to fit a passed rect. Special case of the 9-patch.
|
||||
*
|
||||
* Performs the following operation:
|
||||
*
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
#define JOKER_STARTING_LAYER 26
|
||||
// Tile ID for the starting index in the tile memory
|
||||
#define JOKER_TID (JOKER_STARTING_LAYER * JOKER_SPRITE_OFFSET)
|
||||
#define JOKER_BASE_PB 3 // The starting palette index for the jokers
|
||||
#define JOKER_BASE_PB 4 // The starting palette index for the jokers, after the boss blind tokens
|
||||
#define JOKER_LAST_PB (NUM_PALETTES - 1)
|
||||
// Currently allocating the rest of the palettes for the jokers.
|
||||
// This number needs to be decreased once we need to allocated palettes for other sprites
|
||||
|
||||
+1
-6
@@ -12,11 +12,6 @@
|
||||
|
||||
#include <tonc.h>
|
||||
|
||||
/**
|
||||
* @brief Hex value of "ZZZZZZ" in base 36
|
||||
*/
|
||||
#define MAX_SEED 0x81BF0FFF
|
||||
|
||||
/**
|
||||
* @brief Information to track and restore RNG state
|
||||
*/
|
||||
@@ -41,7 +36,7 @@ void rng_update(void);
|
||||
|
||||
/**
|
||||
* @brief Set the rng seed to the chosen value, and reset the step counter to 0.
|
||||
* The seed will be capped at `MAX_SEED` for compatibility with the Seed Input screen
|
||||
* The seed will be capped at `MAX_BASE36` for compatibility with the Seed Input screen
|
||||
* used to choose a seed for seeded runs.
|
||||
*
|
||||
* @param seed the new RNG seed
|
||||
|
||||
@@ -31,6 +31,13 @@
|
||||
|
||||
#include <tonc.h>
|
||||
|
||||
/**
|
||||
* @brief Checks whether the SaveGame section is present and valid.
|
||||
*
|
||||
* @returns true if it is, false if not.
|
||||
*/
|
||||
bool is_game_data_valid(void);
|
||||
|
||||
/**
|
||||
* @brief Save current run data to SRAM.
|
||||
*/
|
||||
|
||||
@@ -106,15 +106,14 @@ void state_machine_change_state(StateMachine* state_machine, int new_state);
|
||||
void noop(void);
|
||||
|
||||
// clang-format off
|
||||
#define STATE_INFO_UPDATE_FN_ONLY(fn) {.on_init = noop, .on_update = fn, .on_exit = noop}
|
||||
|
||||
#define STATE_INFO_UPDATE_FN_ONLY(fn) {.on_init = noop, .on_update = fn, .on_exit = noop}
|
||||
#define STATE_INFO_INIT_UPDATE_FN(init_fn, update_fn) {.on_init = init_fn, .on_update = update_fn, .on_exit = noop}
|
||||
#define STATE_MACHINE_DEFINE(infos, num) \
|
||||
{ \
|
||||
.state_infos = &infos[0], \
|
||||
.num_infos = num, \
|
||||
.registered = false, \
|
||||
};
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // STATE_MACHINE_H
|
||||
|
||||
+52
-3
@@ -17,6 +17,12 @@
|
||||
|
||||
#define UNDEFINED -1
|
||||
|
||||
/**
|
||||
* @def MAX_BASE36
|
||||
* @brief Hex value of "ZZZZZZ" in base 36
|
||||
*/
|
||||
#define MAX_BASE36 0x81BF0FFF
|
||||
|
||||
/**
|
||||
* @def SIGN
|
||||
* @brief Get the sign (signum) of an integer
|
||||
@@ -33,9 +39,10 @@
|
||||
*/
|
||||
#define NUM_ELEM_IN_ARR(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
#define INT_MAX_DIGITS 11 // strlen(str(INT_MAX)) = strlen("-2147483647")
|
||||
#define UINT_MAX_DIGITS 10 // strlen(str(UINT32_MAX)) = strlen("4294967295")
|
||||
#define UINT8_MAX_DIGITS 3 // strlen(str(UINT8_MAX)) = strlen("255")
|
||||
#define INT_MAX_DIGITS 11 // strlen(str(INT_MAX)) = strlen("-2147483647")
|
||||
#define UINT_MAX_DIGITS 10 // strlen(str(UINT32_MAX)) = strlen("4294967295")
|
||||
#define UINT8_MAX_DIGITS 3 // strlen(str(UINT8_MAX)) = strlen("255")
|
||||
#define BASE36_MAX_DIGITS 6 // strlen("ZZZZZZ")
|
||||
|
||||
#define ONE_K 1000
|
||||
#define ONE_M 1000000
|
||||
@@ -150,4 +157,46 @@ static inline int u32_get_digits(uint32_t n)
|
||||
return 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a base-36 string representation to a 32-bit unsigned integer.
|
||||
* Since we are dealing with base-36 instead of decimal, the 32-bit decimal
|
||||
* value of a base-36 string representation `b36` is equal to:
|
||||
*
|
||||
* \f( b36[0] * 36^0 + b36[1] * 36^1 + b36[2] * 36^2 ... \f)
|
||||
*
|
||||
* @param b36_str input char[] to convert to decimal, must be of size `BASE36_MAX_DIGITS+1`
|
||||
*
|
||||
* @returns the 32-bit unsigned value of `b36_str`
|
||||
*/
|
||||
uint32_t base36_to_u32(const char b36_str[]);
|
||||
|
||||
/**
|
||||
* @brief Convert a 32-bit unsigned integer to its base-36 string representation.
|
||||
* This will perform 6 divisions, so it will be significantly more expensive
|
||||
* than its `base36_to_u32` counterpart.
|
||||
*
|
||||
* We will iterate over all digits from `BASE36_MAX_DIGITS-1` to 0 and determine
|
||||
* their values in base-36, to then construct the string representation `b36_str`
|
||||
* in base-36 or the integer `n`
|
||||
*
|
||||
* Initially set to `n`, the variable `acc` will contain any given stage `i`:
|
||||
* ```
|
||||
* b32[i] * 36^i + b32[i-1] * 36^(i-1) + ... + b32[0]
|
||||
* ```
|
||||
*
|
||||
* And we can thus extract the two following values:
|
||||
* ```
|
||||
* b32[i] = acc / 36^i
|
||||
* acc = acc mod 36^i = b32[i-1] * 36^(i-1) + ... + b32[0]
|
||||
* ```
|
||||
*
|
||||
* So that acc can now be used for the following step, until `i` hits 0
|
||||
*
|
||||
* @param n integer value to convert to a base-36 representation
|
||||
* @param b36_str output char[], representation of `n` in base-36
|
||||
*
|
||||
* @sa base36_to_u32
|
||||
*/
|
||||
void u32_to_base36(uint32_t n, char b36_str[]);
|
||||
|
||||
#endif // UTIL_H
|
||||
|
||||
Reference in New Issue
Block a user