Files
balatro-gba-chinese-jocker-…/include/state_machine.h
T
Rickey 63b6584706 Feature/game over audio (#494)
* 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>
2026-05-27 21:57:30 -07:00

121 lines
3.4 KiB
C

/**
* @file state_machine.h
*
* @brief State Machine
*
* This file is the interface into a generic state machine system.
*
* State machines are defined as an array of function callbacks where each state
* is an index in the array with three functions per state: `on_init()`,
* `on_update()`, and `on_exit()`.
*
* **`on_init()`** Ran once when transitioning into the new state
* **`on_update()`** Ran once every frame
* **`on_exit()`** Ran once when exiting a state, for cleanup.
*
* The state machine `on_update()` function is "registered" to a linked-list of
* other state machine update functions. This list will call the state machines
* active `on_update()` function. This allows much of the complexity of state
* transitions to remain central to `state_machine.c`. Also, multiple state
* machines can be registered to this list. This allows using substates within
* states, or have one off state machines like animation controllers.
*
* When a state machine is finished, it can "remove" itself from the main update
* callback list. This can be done within the update method of its own state
* machine. This can be used to start a self destructing state machine.
*/
#ifndef STATE_MACHINE_H
#define STATE_MACHINE_H
/**
* @brief State machine callback function pointer type
*/
typedef void (*StateCallback)(void);
/**
* @brief State machine callbacks
*/
typedef struct
{
StateCallback on_init;
StateCallback on_update;
StateCallback on_exit;
} StateInfo;
/**
* @brief State machine instance
*/
typedef struct
{
/**
* @brief Pointer to the active update function in `state_infos`
*/
StateCallback active_update;
/**
* @brief Array of @ref StateCallbacks , one entry per state
*/
StateInfo* state_infos;
/**
* @brief Number of elements in the `state_infos` array
*/
unsigned int num_infos;
/**
* @brief The current state of the state machine, the offset into state_infos
*/
int state;
/**
* @brief Flag to determine if statemachine is already running it's active_update function
*/
bool registered;
} StateMachine;
/**
* @brief Register a statemachine to run it's update function once per frame
*
* @param state_machine pointer to @ref StateMachine to register, cannot be NULL
*/
void state_machine_register(StateMachine* state_machine);
/**
* @brief Remove a statemachine's update function
*
* @param state_machine pointer to @ref StateMachine to remove, cannot be NULL
*/
void state_machine_remove(StateMachine* state_machine);
/**
* @brief Update registered state machines' update functions
*/
void state_machine_update(void);
/**
* @brief Calls the current state's on_exit, the new state's on_init, and sets the active update fn
*
* @param state_machine pointer to @ref StateMachine, cannot be NULL
* @param new_state offset into `state_infos` array to transition to
*/
void state_machine_change_state(StateMachine* state_machine, int new_state);
/**
* @brief no operation
*/
void noop(void);
// clang-format off
#define STATE_INFO_UPDATE_FN_ONLY(fn) {.on_init = noop, .on_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