CHGame 0.3.0
Libraries for the CHGame handheld
Loading...
Searching...
No Matches
Fx.h
Go to the documentation of this file.
1/// @file Fx.h
2/// @brief Motion maths and the screen shake: easing, integer sine, randomness.
3///
4/// Integer maths only: soft-float trig once cost a demo on this chip 8.5 KB
5/// of flash and half its frame rate.
6///
7/// A game's own effects (its particle kinds, banners, floating texts) live in
8/// the same namespace in the game's code, built from these (see chgame/Sizzle.h).
9#pragma once
10#include <stdint.h>
11
12/// @defgroup chgame_fx Effects maths
13/// @ingroup lib_chgame
14/// @brief fx::: easing curves, integer sine and cosine, presentation
15/// randomness and the screen shake.
16///
17/// @code
18/// int y = 20 + fx::ease(fx::OUT_BACK, t, 30) * 60 / 256; // slide in over 30 frames
19/// int bob = fx::isin(chgame.frameCount * 4) * 3 / 256; // +-3 px, a turn every 64 frames
20/// @endcode
21/// @{
22
23/// @brief Effects: motion maths, the screen shake, and (chgame/Sizzle.h) particles,
24/// banners and floating texts.
25namespace fx {
26
27/// @brief Easing curves for ease().
28/// @details Each curve is a 17-point table; ease() is inline, so a call with a
29/// constant curve links only that curve's table.
30enum Ease : uint8_t {
31 LINEAR, ///< Straight.
32 OUT_CUBIC, ///< Fast, then slowing to a stop.
33 OUT_BACK, ///< Overshoots the end, then settles back (goes past 256).
34 IN_OUT, ///< Slow, fast, slow.
35 OUT_BOUNCE ///< Drops and bounces to a stop (overshoots).
36};
37/// @brief The curves' tables (17 points, 0..256), for easeCurve().
38extern const int16_t EASE_CUBIC[17], EASE_BACK[17], EASE_INOUT[17], EASE_BOUNCE[17];
39/// @brief Ease through a curve table.
40/// @param curve A 17-point table (EASE_CUBIC ...), or nullptr for linear.
41/// @param t Time, 0..n.
42/// @param n Duration.
43/// @return 0 at t <= 0, 256 at t >= n, the curve in between (interpolated).
44int easeCurve(const int16_t *curve, int t, int n); // curve nullptr: linear
45/// @brief Ease: progress through a curve.
46/// @param e Which curve.
47/// @param t Time, 0..n (clamped).
48/// @param n Duration (frames, for instance).
49/// @return 0..256 (OUT_BACK and OUT_BOUNCE overshoot 256 on the way).
50inline int ease(Ease e, int t, int n) {
51 return easeCurve(e == OUT_CUBIC ? EASE_CUBIC : e == OUT_BACK ? EASE_BACK : e == IN_OUT ? EASE_INOUT
52 : e == OUT_BOUNCE ? EASE_BOUNCE : nullptr, t, n);
53}
54/// @brief The OUT_BOUNCE curve.
55/// @param t Time, 0..n.
56/// @param n Duration.
57/// @return 0..256 (with the bounces).
58inline int bounce(int t, int n) { return easeCurve(EASE_BOUNCE, t, n); }
59/// @brief Integer sine.
60/// @param a Angle in 1/256 turns (any value: it wraps).
61/// @return -256..256.
62int isin(int a); // a in 1/256 turns -> -256..256
63/// @brief Integer cosine.
64/// @param a Angle in 1/256 turns.
65/// @return -256..256.
66inline int icos(int a) { return isin(a + 64); }
67
68/// @brief A random number for presentation (xorshift32).
69/// @details Presentation-only randomness: sparkle, confetti, shake. It never
70/// touches game outcomes (those use the game's own generator), and reseed()
71/// restarts it so scripted runs repeat.
72/// @return 32 random bits.
73uint32_t rnd();
74/// @brief A random number in a range, for presentation.
75/// @param lo The smallest value.
76/// @param hi One past the largest value.
77/// @return lo .. hi-1 (lo if hi <= lo).
78int rndRange(int lo, int hi); // lo .. hi-1
79/// @brief Restart rnd() from its fixed seed.
80void reseed();
81
82/// @brief Start a screen shake.
83/// @details shake() starts it; applyShake() moves the finished frame and
84/// shakeTick() counts it down once per logic tick.
85/// @param frames How many ticks it lasts.
86/// @param amplitude The vertical jolt in pixels at 10 ticks left; it scales
87/// with the ticks left, so the shake dies away (at least 1 px).
88/// It also moves 2 px sideways.
89void shake(uint8_t frames, uint8_t amplitude);
90/// @brief Whether a shake is running.
91/// @return true until it has counted down.
92bool shaking();
93/// @brief Shake the finished framebuffer: call after drawing, before the flush.
94/// @param y0,y1 The band of rows to move (inclusive).
95/// @param fill < 0 (default): rows the move uncovers keep their pixels,
96/// shifted in place; else they are filled with this colour.
97void applyShake(int y0, int y1, int fill = -1);
98/// @brief Count the shake down one tick: once per logic tick.
99void shakeTick();
100/// @brief Stop the shake at once.
102
103} // namespace fx
104
105/// @}
Effects: motion maths, the screen shake, and (chgame/Sizzle.h) particles, banners and floating texts.
Definition Fx.h:25
Ease
Easing curves for ease().
Definition Fx.h:30
@ LINEAR
Straight.
Definition Fx.h:31
@ OUT_BACK
Overshoots the end, then settles back (goes past 256).
Definition Fx.h:33
@ OUT_BOUNCE
Drops and bounces to a stop (overshoots).
Definition Fx.h:35
@ IN_OUT
Slow, fast, slow.
Definition Fx.h:34
@ OUT_CUBIC
Fast, then slowing to a stop.
Definition Fx.h:32
bool shaking()
Whether a shake is running.
void applyShake(int y0, int y1, int fill=-1)
Shake the finished framebuffer: call after drawing, before the flush.
int bounce(int t, int n)
The OUT_BOUNCE curve.
Definition Fx.h:58
void shake(uint8_t frames, uint8_t amplitude)
Start a screen shake.
int ease(Ease e, int t, int n)
Ease: progress through a curve.
Definition Fx.h:50
void shakeStop()
Stop the shake at once.
void reseed()
Restart rnd() from its fixed seed.
uint32_t rnd()
A random number for presentation (xorshift32).
int easeCurve(const int16_t *curve, int t, int n)
Ease through a curve table.
int rndRange(int lo, int hi)
A random number in a range, for presentation.
int isin(int a)
Integer sine.
void shakeTick()
Count the shake down one tick: once per logic tick.
const int16_t EASE_CUBIC[17]
The curves' tables (17 points, 0..256), for easeCurve().
int icos(int a)
Integer cosine.
Definition Fx.h:66