A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
GameScene.cc
1#include "GameScene.hh"
2
3#include "game/render/KartCamera.hh"
4
5#include "game/system/KPadDirector.hh"
6#include "game/system/ResourceManager.hh"
7
8#include <egg/core/SceneManager.hh>
9
10namespace Kinoko::Scene {
11
13GameScene::GameScene() {
14 m_heap->setName("DefaultGameSceneHeap");
15 m_nextSceneId = -1;
16
17#ifdef BUILD_DEBUG
18 m_totalMemoryUsed = 0;
19 EGG::ExpHeap *heap = EGG::Heap::dynamicCastToExp(m_heap);
20 ASSERT(heap);
21
22 heap->calcGroupSize(&m_groupSizeRecord);
23 for (u16 groupID = 0; groupID < m_groupSizeRecord.size(); ++groupID) {
24 m_totalMemoryUsed += m_groupSizeRecord.getGroupSize(groupID);
25 }
26#endif // BUILD_DEBUG
27}
28
30GameScene::~GameScene() {
31 m_resources.clear();
32
33#ifdef BUILD_DEBUG
34 EGG::ExpHeap *heap = EGG::Heap::dynamicCastToExp(m_heap);
35 ASSERT(heap);
36
37 heap->calcGroupSize(&m_groupSizeRecord);
38 size_t sum = 0;
39 for (u16 groupID = 0; groupID < m_groupSizeRecord.size(); ++groupID) {
40 sum += m_groupSizeRecord.getGroupSize(groupID);
41 }
42
43 if (sum > m_totalMemoryUsed) {
44 WARN("MEMORY LEAK DETECTED: %zu bytes", sum - m_totalMemoryUsed);
45 getMemoryLeakTags();
46 }
47#endif // BUILD_DEBUG
48}
49
51void GameScene::calc() {
52 System::KPadDirector::Instance()->calc();
53 calcEngines();
54 calcCamera();
55}
56
58void GameScene::enter() {
59 configure();
60 initScene();
61}
62
64void GameScene::exit() {
65 deinitScene();
66 unmountResources();
67}
68
70void GameScene::reinit() {
71 exit();
72 if (m_nextSceneId < 0) {
73 onReinit();
74 initScene();
75 } else {
76 m_sceneMgr->changeSiblingScene(m_nextSceneId);
77 }
78}
79
81void GameScene::initCamera() {
82 Render::KartCamera::Instance()->init();
83}
84
86void GameScene::calcCamera() {
87 Render::KartCamera::Instance()->calc();
88}
89
91void GameScene::appendResource(System::MultiDvdArchive *archive, s32 id) {
92 m_resources.push_back(new Resource(archive, id));
93}
94
96GameScene::Resource::Resource(System::MultiDvdArchive *archive, s32 id)
97 : archive(archive), id(id) {}
98
100void GameScene::initScene() {
101 createEngines();
102 System::KPadDirector::Instance()->reset();
103 initEngines();
104#ifdef BUILD_DEBUG
105 checkMemory();
106#endif // BUILD_DEBUG
107}
108
110void GameScene::deinitScene() {
111 if (m_nextSceneId >= 0) {
112 return;
113 }
114
115 destroyEngines();
116 System::KPadDirector::Instance()->clear();
117}
118
120void GameScene::unmountResources() {
121 auto *resourceManager = System::ResourceManager::Instance();
122 for (auto iter = m_resources.begin(); iter != m_resources.end();) {
123 Resource *resource = *iter;
124 resourceManager->unmount(resource->archive);
125 iter = m_resources.erase(iter);
126 delete resource;
127 }
128}
129
130#ifdef BUILD_DEBUG
131void GameScene::checkMemory() {
132 EGG::ExpHeap *heap = EGG::Heap::dynamicCastToExp(m_heap);
133 ASSERT(heap);
134
135 heap->calcGroupSize(&m_groupSizeRecord);
136 size_t defaultSize = m_groupSizeRecord.getGroupSize(static_cast<u16>(GroupID::None));
137
138 // Because we're working with a class that can be inherited (but not doubly-inherited),
139 // it's possible that derived classes can have a different size compared to GameScene
140 // We don't need to know the exact derived class, though, as we have the memory block head
141 // The scene is the first, always group ID 0 allocation to happen in the scene's heap
144 SubOffset(this, sizeof(Abstract::Memory::MEMiExpBlockHead)));
145 size_t initialAllocSize = blockHead->m_size;
146 ASSERT(defaultSize >= initialAllocSize);
147
148 defaultSize -= initialAllocSize;
149 if (defaultSize > 0) {
150 WARN("Default memory usage found! %zu bytes", defaultSize);
151 }
152
153 for (u16 groupID = 1; groupID < m_groupSizeRecord.size(); ++groupID) {
154 size_t size = m_groupSizeRecord.getGroupSize(groupID);
155 if (size == 0) {
156 continue;
157 }
158
159 DEBUG("Group ID %d: Allocated %zu bytes", groupID, size);
160 }
161}
162
163void GameScene::getMemoryLeakTags() {
164 size_t count = getMemoryLeakTagCount();
165 if (count == 0) {
166 return;
167 }
168
170 for (auto &tag : tags) {
171 tag = 0; // empty tag
172 }
173
174 EGG::Heap::dynamicCastToExp(m_heap)->dynamicCastHandleToExp()->visitAllocated(ViewTags,
175 GetAddrNum(&tags));
176
177 DEBUG("TAGGED MEMORY BLOCKS:");
178 printf("[%d", tags[0]);
179 for (u32 i = 1; i < tags.size(); ++i) {
180 printf(", %d", tags[i]);
181 }
182 printf("]\n");
183}
184
185size_t GameScene::getMemoryLeakTagCount() {
186 size_t count = 0;
187 EGG::Heap::dynamicCastToExp(m_heap)->dynamicCastHandleToExp()->visitAllocated(IncreaseTagCount,
188 GetAddrNum(&count));
189 return count;
190}
191
192void GameScene::ViewTags(void *block, Abstract::Memory::MEMiHeapHead * /*heap*/, uintptr_t param) {
195 SubOffset(block, sizeof(Abstract::Memory::MEMiExpBlockHead)));
196 owning_span<u32> *span = reinterpret_cast<owning_span<u32> *>(param);
197 for (auto &tag : *span) {
198 if (tag == 0) {
199 tag = blockHead->m_tag;
200 break;
201 }
202 }
203}
204
205void GameScene::IncreaseTagCount(void * /*block*/, Abstract::Memory::MEMiHeapHead * /*heap*/,
206 uintptr_t param) {
207 size_t &count = *reinterpret_cast<size_t *>(param);
208 ++count;
209}
210#endif // BUILD_DEBUG
211
212} // namespace Kinoko::Scene
A low-level representation of a memory heap for managing dynamic memory allocation....
Definition HeapCommon.hh:21
High-level implementation of a memory heap for managing dynamic memory allocation....
Definition ExpHeap.hh:15
std::list< Resource * > m_resources
List of all active resources in the scene.
Definition GameScene.hh:60
A contiguous storage container that manages the lifecycle of a buffer of a given size.
Definition Types.hh:29
size_t size() const
Returns the number of elements that fit in the buffer.
Definition Types.hh:152
Pertains to scene handling.
Definition GameScene.cc:10
Head of the memory block. Contains information about the block and a link in the corresponding used/f...
Definition ExpHeap.hh:38