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 Kinoko::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 memset(m_entryIds.data(), 0xff, m_entryIds.size());
36
37 for (size_t i = 0; i < m_entryIds.size(); ++i) {
38 m_entryIds[m_entries[i].id] = i;
39 }
40 }
41
42 virtual ~StateManager() {
43 delete[] m_entryIds.data();
44 }
45
46 void calc() {
47 if (m_nextStateId >= 0) {
48 m_currentStateId = m_nextStateId;
49 m_nextStateId = -1;
50 m_currentFrame = 0;
51
52 auto enterFunc = m_entries[m_entryIds[m_currentStateId]].onEnter;
53 enterFunc(m_obj);
54 } else {
55 ++m_currentFrame;
56 }
57
58 auto calcFunc = m_entries[m_entryIds[m_currentStateId]].onCalc;
59 calcFunc(m_obj);
60 }
61
62 u16 m_currentStateId;
63 s32 m_nextStateId;
64 u32 m_currentFrame;
65 std::span<u16> m_entryIds;
66 std::span<const StateManagerEntry> m_entries;
67 void *m_obj;
68};
69
70} // namespace Kinoko::Field
Base class that represents different "states" for an object.
Pertains to collision.