[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:
@@ -191,3 +191,94 @@ uint16_t u16_protected_mult(uint16_t a, uint16_t b)
|
||||
{
|
||||
return (a == 0 || b == 0) ? 0 : (a > (UINT16_MAX / b) ? UINT16_MAX : a * b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the numerical value of a base-36 digit.
|
||||
* Allowed values are [0-9, A-Z], with letters mapped to values of 10-35.
|
||||
* Lowercase letters are mapped to the same values as the uppercase ones.
|
||||
* Any other char is invalid and will be attributed a value of 0.
|
||||
*
|
||||
* @param c the char representing a digit in base-36
|
||||
* @return u32
|
||||
*/
|
||||
static inline uint32_t base36_digit_value(char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '0' ... '9':
|
||||
return c - '0';
|
||||
case 'A' ... 'Z':
|
||||
return 10 + c - 'A';
|
||||
case 'a' ... 'z':
|
||||
return 10 + c - 'a';
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the char corresponding to a base-36 digit's numerical value.
|
||||
* Inverse operation of base36_digit_value
|
||||
*
|
||||
* @param n decimal value of the base-36 char we want to get
|
||||
* @return char
|
||||
*
|
||||
* @sa base36_digit_value
|
||||
*/
|
||||
static inline char base36_digit_char(uint32_t n)
|
||||
{
|
||||
switch (n)
|
||||
{
|
||||
case 0 ... 9:
|
||||
return n + '0';
|
||||
case 10 ... 35:
|
||||
return n - 10 + 'A';
|
||||
default:
|
||||
return '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get 36 to the power `i`
|
||||
*
|
||||
* @param i power of 36 we want, between 0 and `BASE36_MAX_DIGITS - 1`
|
||||
* @return 36 to the power `i`
|
||||
*
|
||||
* @sa base36_digit_value
|
||||
*/
|
||||
static inline uint32_t get_base36_power(uint8_t i)
|
||||
{
|
||||
if (i >= BASE36_MAX_DIGITS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const uint32_t powers_of_36[BASE36_MAX_DIGITS] = {1, 36, 1296, 46656, 1679616, 60466176};
|
||||
return powers_of_36[i];
|
||||
}
|
||||
|
||||
uint32_t base36_to_u32(const char b36_str[])
|
||||
{
|
||||
uint32_t res = 0;
|
||||
|
||||
for (uint8_t i = 0; i < BASE36_MAX_DIGITS; i++)
|
||||
{
|
||||
res += base36_digit_value(b36_str[i]) * get_base36_power(BASE36_MAX_DIGITS - i - 1);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void u32_to_base36(const uint32_t n, char b36_str[])
|
||||
{
|
||||
uint32_t power;
|
||||
uint32_t acc = (n > MAX_BASE36) ? MAX_BASE36 : n;
|
||||
for (int i = 0; i < BASE36_MAX_DIGITS; i++)
|
||||
{
|
||||
power = get_base36_power(BASE36_MAX_DIGITS - i - 1);
|
||||
b36_str[i] = base36_digit_char(acc / power);
|
||||
acc = acc % power;
|
||||
}
|
||||
// Properly end the string
|
||||
b36_str[BASE36_MAX_DIGITS] = '\0';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user