Checking against `sel` is just plain wrong, since it always expected to
be non-NULL, since `h->sel` is an array defined in `struct
human_player`. Instead, `sel->d.i` is the pointer that should be
checked.
`gui` was tighly coupled to game logic, and could not be extended for
other purposes. Therefore, a generic GUI implementation, loosely
inspired by well-known GUI frameworks such as GTK, is now provided, with
the following properties:
- Does not depend on dynamic or static memory allocation, only automatic
(i.e., stack) memory allocation required.
- Portable among existing implementations.
- Simple to extend.
- Tiny memory footprint.
`gui` is now composed by GUI elements that can be chained to form a tree
structure. This is useful e.g.: to calculate X/Y coordinates for a given
GUI element given its parent(s).
This commit also refactors the older implementation, moving
game-specific logic into `player` and making use of the new component.
On platforms with PERIPHERAL_TYPE_PAD, navigating through menus and
options can be cumbersome if moving the cursor freely around the
screen.
Therefore, this commit instead defines a list of (X, Y) coordinates that
the cursor can jump to. The implementation also attempts to guess which
direction the cursor should jump to for the previous/next point, and
hence determine which button should be pressed by the user.
Whereas some actions are context-specific (e.g.: selecting a player),
some are context-independent and can be executed for all screens
(e.g.: exiting the game).
This has several advantages:
- `camera` no longer needs to define public functions for each
peripheral type.
- Peripheral-related is now no longer tighly coupled to human_player,
so peripheral logic can be reused elsewhere e.g.: on menus.
- Makes camera_update_touch consistent compared to equivalent functions,
since now `pan` has now been moved to `camera` (as it should be).
The following properties are supported:
- Sound: "loop". Must be either 0 or 1
- Images: "transparent". Must be either 0 or 1
These headers are only used for non-PS1 builds, since .TIM and .VAG
files do already implement such information.
The PS1 port relies on a heap for primitives since the GPU renders the
scene asynchronously. However, SDL-based platforms render primitives
synchronously, so structures can be allocated on the stack instead.