A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
StateManager.hh
1#pragma once
2
3#include "game/field/obj/ObjectBase.hh"
4
5namespace Field {
6
8 u16 id;
9 void (*onEnter)(void *);
10 void (*onCalc)(void *);
11};
12
13template <typename T, void (T::*Enter)(), void (T::*Calc)()>
14constexpr StateManagerEntry StateEntry(u16 id) {
15 auto enter = [](void *obj) { (reinterpret_cast<T *>(obj)->*Enter)(); };
16 auto calc = [](void *obj) { (reinterpret_cast<T *>(obj)->*Calc)(); };
17 return {id, enter, calc};
18}
19
28protected:
29 StateManager(void *obj, const std::span<const StateManagerEntry> &entries)
30 : m_currentStateId(0), m_nextStateId(-1), m_currentFrame(0), m_entries(entries),
31 m_obj(obj) {
32 m_entryIds = std::span(new u16[m_entries.size()], m_entries.size());
33
34 // The base game initializes all entries to 0xffff, possibly to avoid an uninitialized value
35 for (auto &id : m_entryIds) {
36 id = 0xffff;
37 }
38
39 for (size_t i = 0; i < m_entryIds.size(); ++i) {
40 m_entryIds[m_entries[i].id] = i;
41 }
42 }
43
44 virtual ~StateManager() {
45 delete[] m_entryIds.data();
46 }
47
48 void calc() {
49 if (m_nextStateId >= 0) {
50 m_currentStateId = m_nextStateId;
51 m_nextStateId = -1;
52 m_currentFrame = 0;
53
54 auto enterFunc = m_entries[m_entryIds[m_currentStateId]].onEnter;
55 enterFunc(m_obj);
56 } else {
57 ++m_currentFrame;
58 }
59
60 auto calcFunc = m_entries[m_entryIds[m_currentStateId]].onCalc;
61 calcFunc(m_obj);
62 }
63
64 u16 m_currentStateId;
65 s32 m_nextStateId;
66 u32 m_currentFrame;
67 std::span<u16> m_entryIds;
68 std::span<const StateManagerEntry> m_entries;
69 void *m_obj;
70};
71
72} // namespace Field
Base class that represents different "states" for an object.
Pertains to collision.