Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Rubberduckycooly
GitHub Repository: Rubberduckycooly/RSDKv5-Decompilation
Path: blob/master/RSDKv5/RSDK/Core/Legacy/v4/RetroEnginev4.cpp
1167 views
1
#include "RetroEnginev4.hpp"
2
3
bool32 RSDK::Legacy::v4::LoadGameConfig(const char *filepath)
4
{
5
char strBuffer[0x40];
6
StrCopy(gameVerInfo.gameTitle, "Retro-Engine"); // this is the default window name
7
8
globalVariablesCount = 0;
9
#if RETRO_USE_MOD_LOADER
10
modSettings.playerCount = 0;
11
#endif
12
13
FileInfo info;
14
InitFileInfo(&info);
15
16
bool32 loaded = LoadFile(&info, filepath, FMODE_RB);
17
if (loaded) {
18
ReadString(&info, gameVerInfo.gameTitle);
19
ReadString(&info, gameVerInfo.gameSubtitle);
20
21
uint8 buf[3];
22
for (int32 c = 0; c < 0x60; ++c) {
23
ReadBytes(&info, buf, 3);
24
SetPaletteEntry(-1, c, buf[0], buf[1], buf[2]);
25
}
26
27
// Read Obect Names
28
uint8 objectCount = ReadInt8(&info);
29
for (int32 o = 0; o < objectCount; ++o) {
30
ReadString(&info, strBuffer);
31
}
32
33
// Read Script Paths
34
for (int32 s = 0; s < objectCount; ++s) {
35
ReadString(&info, strBuffer);
36
}
37
38
globalVariablesCount = ReadInt8(&info);
39
for (int32 v = 0; v < globalVariablesCount; ++v) {
40
// Read Variable Name
41
ReadString(&info, globalVariables[v].name);
42
43
// Read Variable Value
44
globalVariables[v].value = ReadInt8(&info) << 0;
45
globalVariables[v].value |= ReadInt8(&info) << 8;
46
globalVariables[v].value |= ReadInt8(&info) << 16;
47
globalVariables[v].value |= ReadInt8(&info) << 24;
48
}
49
50
// Read SFX
51
globalSFXCount = ReadInt8(&info);
52
for (int32 s = 0; s < globalSFXCount; ++s) { // Sfx Names
53
ReadString(&info, strBuffer);
54
SetSfxName(strBuffer, s);
55
}
56
57
for (int32 s = 0; s < globalSFXCount; ++s) { // Sfx Paths
58
ReadString(&info, strBuffer);
59
RSDK::Legacy::LoadSfx(strBuffer, s, SCOPE_GLOBAL);
60
}
61
62
// Read Player Names
63
uint8 plrCount = ReadInt8(&info);
64
for (uint8 p = 0; p < plrCount; ++p) {
65
ReadString(&info, strBuffer);
66
67
#if RETRO_USE_MOD_LOADER
68
// needed for PlayerName[] stuff in scripts
69
StrCopy(modSettings.playerNames[p], strBuffer);
70
modSettings.playerCount++;
71
#endif
72
}
73
74
// Read ahead and get scene count
75
int32 storedPos = info.readPos;
76
77
int32 totalSceneCount = 0;
78
sceneInfo.categoryCount = STAGELIST_MAX;
79
for (uint8 c = 0; c < sceneInfo.categoryCount; ++c) {
80
int32 count = ReadInt8(&info);
81
for (int32 s = 0; s < count; ++s) {
82
ReadString(&info, strBuffer);
83
ReadString(&info, strBuffer);
84
ReadString(&info, strBuffer);
85
ReadInt8(&info);
86
}
87
88
totalSceneCount += count;
89
}
90
91
if (!totalSceneCount)
92
totalSceneCount = 1;
93
94
int32 startScene = 0;
95
#if !RETRO_USE_ORIGINAL_CODE
96
if (strlen(currentSceneFolder) && strlen(currentSceneID)) {
97
#if RETRO_USE_MOD_LOADER
98
listData.resize(totalSceneCount + 1);
99
sceneInfo.listData = listData.data();
100
#else
101
AllocateStorage((void **)&sceneInfo.listData, sizeof(SceneListEntry) * (totalSceneCount + 1), DATASET_STG, false);
102
#endif
103
SceneListEntry *scene = &sceneInfo.listData[totalSceneCount];
104
strcpy(scene->name, "_RSDK_SCENE");
105
strcpy(scene->folder, currentSceneFolder);
106
strcpy(scene->id, currentSceneID);
107
scene->filter = sceneInfo.filter;
108
GEN_HASH_MD5(scene->name, scene->hash);
109
110
// Override existing values
111
sceneInfo.activeCategory = 0;
112
startScene = totalSceneCount;
113
currentSceneFolder[0] = 0;
114
currentSceneID[0] = 0;
115
}
116
else {
117
#endif
118
119
#if RETRO_USE_MOD_LOADER
120
listData.resize(totalSceneCount);
121
sceneInfo.listData = listData.data();
122
#else
123
AllocateStorage((void **)&sceneInfo.listData, sizeof(SceneListEntry) * totalSceneCount, DATASET_STG, false);
124
#endif //! RETRO_USE_MOD_LOADER
125
126
#if !RETRO_USE_ORIGINAL_CODE
127
}
128
#endif
129
130
AllocateStorage((void **)&sceneInfo.listCategory, sizeof(SceneListInfo) * sceneInfo.categoryCount, DATASET_STG, true);
131
132
char categoryNames[STAGELIST_MAX][0x20] = {
133
"Presentation",
134
"Regular",
135
"Special",
136
"Bonus",
137
};
138
139
// Jump back and properly load scene info
140
Seek_Set(&info, storedPos);
141
142
int32 sceneID = 0;
143
for (uint8 c = 0; c < sceneInfo.categoryCount; ++c) {
144
SceneListInfo *category = &sceneInfo.listCategory[c];
145
StrCopy(category->name, categoryNames[c]);
146
GEN_HASH_MD5(category->name, category->hash);
147
148
category->sceneOffsetStart = sceneID;
149
category->sceneCount = ReadInt8(&info);
150
for (int32 s = 0; s < category->sceneCount; ++s) {
151
SceneListEntry *scene = &sceneInfo.listData[sceneID + s];
152
153
ReadString(&info, scene->folder);
154
155
ReadString(&info, scene->id);
156
157
ReadString(&info, scene->name);
158
GEN_HASH_MD5(scene->name, scene->hash);
159
160
// highlighted (doesn't care)
161
ReadInt8(&info);
162
}
163
164
category->sceneOffsetEnd = category->sceneOffsetStart + category->sceneCount - 1;
165
sceneID += category->sceneCount;
166
}
167
168
CloseFile(&info);
169
170
sceneInfo.listPos = startScene;
171
172
#if RETRO_USE_MOD_LOADER
173
v4::LoadGameXML();
174
SetGlobalVariableByName("options.devMenuFlag", engine.devMenu ? 1 : 0);
175
SetGlobalVariableByName("engine.standalone", 0);
176
#endif
177
178
SetGlobalVariableByName("game.hasPlusDLC", !RSDK_AUTOBUILD);
179
180
usingBytecode = false;
181
InitFileInfo(&info);
182
if (useDataPack && LoadFile(&info, "Bytecode/GlobalCode.bin", FMODE_RB)) {
183
usingBytecode = true;
184
CloseFile(&info);
185
}
186
}
187
188
// These need to be set every time its reloaded
189
nativeFunctionCount = 0;
190
191
nativeFunctionCount = 0;
192
AddNativeFunction("SetAchievement", SetAchievement);
193
AddNativeFunction("SetLeaderboard", SetLeaderboard);
194
AddNativeFunction("HapticEffect", HapticEffect);
195
196
// AddNativeFunction("Connect2PVS", Connect2PVS);
197
// AddNativeFunction("Disconnect2PVS", Disconnect2PVS);
198
// AddNativeFunction("SendEntity", SendEntity);
199
// AddNativeFunction("SendValue", SendValue);
200
// AddNativeFunction("ReceiveEntity", ReceiveEntity);
201
// AddNativeFunction("ReceiveValue", ReceiveValue);
202
// AddNativeFunction("TransmitGlobal", TransmitGlobal);
203
// AddNativeFunction("ShowPromoPopup", ShowPromoPopup);
204
205
AddNativeFunction("NotifyCallback", NotifyCallback);
206
207
#if RETRO_USE_MOD_LOADER
208
AddNativeFunction("ExitGame", ExitGame);
209
AddNativeFunction("FileExists", FileExists);
210
AddNativeFunction("OpenModMenu", OpenModMenu); // Opens the dev menu-based mod menu incase you cant be bothered or smth
211
AddNativeFunction("AddAchievement", AddGameAchievement);
212
AddNativeFunction("SetAchievementDescription", SetAchievementDescription);
213
AddNativeFunction("ClearAchievements", ClearAchievements);
214
AddNativeFunction("GetAchievementCount", GetAchievementCount);
215
AddNativeFunction("GetAchievement", GetAchievement);
216
AddNativeFunction("GetAchievementName", GetAchievementName);
217
AddNativeFunction("GetAchievementDescription", GetAchievementDescription);
218
AddNativeFunction("GetScreenWidth", GetScreenWidth);
219
AddNativeFunction("SetScreenWidth", SetScreenWidth);
220
AddNativeFunction("GetWindowScale", GetWindowScale);
221
AddNativeFunction("SetWindowScale", SetWindowScale);
222
AddNativeFunction("GetWindowScaleMode", GetWindowScaleMode);
223
AddNativeFunction("SetWindowScaleMode", SetWindowScaleMode);
224
AddNativeFunction("GetWindowFullScreen", GetWindowFullScreen);
225
AddNativeFunction("SetWindowFullScreen", SetWindowFullScreen);
226
AddNativeFunction("GetWindowBorderless", GetWindowBorderless);
227
AddNativeFunction("SetWindowBorderless", SetWindowBorderless);
228
AddNativeFunction("GetWindowVSync", GetWindowVSync);
229
AddNativeFunction("SetWindowVSync", SetWindowVSync);
230
AddNativeFunction("ApplyWindowChanges", ApplyWindowChanges); // Refresh window after changing window options
231
AddNativeFunction("GetModCount", GetModCount);
232
AddNativeFunction("GetModName", GetModName);
233
AddNativeFunction("GetModDescription", GetModDescription);
234
AddNativeFunction("GetModAuthor", GetModAuthor);
235
AddNativeFunction("GetModVersion", GetModVersion);
236
AddNativeFunction("GetModActive", GetModActive);
237
AddNativeFunction("SetModActive", SetModActive);
238
AddNativeFunction("MoveMod", MoveMod);
239
AddNativeFunction("RefreshEngine", RefreshEngine); // Reload engine after changing mod status
240
#endif
241
242
return loaded;
243
}
244
245
void RSDK::Legacy::v4::ProcessEngine()
246
{
247
switch (gameMode) {
248
case ENGINE_DEVMENU:
249
ProcessInput();
250
currentScreen = &screens[0];
251
252
if (devMenu.state)
253
devMenu.state();
254
break;
255
256
case ENGINE_MAINGAME: ProcessStage(); break;
257
258
case ENGINE_INITDEVMENU:
259
LoadGameConfig("Data/Game/GameConfig.bin");
260
InitFirstStage();
261
ResetCurrentStageFolder();
262
break;
263
264
case ENGINE_WAIT:
265
break;
266
// case ENGINE_RESETGAME: break;
267
268
case ENGINE_SCRIPTERROR: {
269
currentScreen = screens;
270
FillScreen(0x000000, 0x10, 0x10, 0x10);
271
272
int32 yOff = DevOutput_GetStringYSize(scriptErrorMessage);
273
DrawDevString(scriptErrorMessage, 8, currentScreen->center.y - (yOff >> 1) + 8, 0, 0xF0F0F0);
274
275
ProcessInput();
276
if (controller[CONT_ANY].keyStart.press || controller[CONT_ANY].keyA.press) {
277
OpenDevMenu();
278
}
279
else if (controller[CONT_ANY].keyB.press) {
280
ResetCurrentStageFolder();
281
sceneInfo.activeCategory = 0;
282
gameMode = ENGINE_MAINGAME;
283
stageMode = STAGEMODE_LOAD;
284
sceneInfo.listPos = 0;
285
}
286
else if (controller[CONT_ANY].keyC.press) {
287
ResetCurrentStageFolder();
288
#if RETRO_USE_MOD_LOADER
289
RefreshModFolders();
290
#endif
291
gameMode = ENGINE_MAINGAME;
292
stageMode = STAGEMODE_LOAD;
293
}
294
break;
295
}
296
297
case ENGINE_INITPAUSE:
298
case ENGINE_EXITPAUSE: gameMode = ENGINE_MAINGAME; break;
299
300
case ENGINE_ENDGAME:
301
case ENGINE_RESETGAME:
302
sceneInfo.activeCategory = 0;
303
sceneInfo.listPos = 0;
304
gameMode = ENGINE_MAINGAME;
305
stageMode = STAGEMODE_LOAD;
306
break;
307
308
default: break;
309
}
310
}
311
312
#if RETRO_USE_MOD_LOADER
313
void RSDK::Legacy::v4::LoadGameXML(bool pal)
314
{
315
FileInfo info;
316
SortMods();
317
for (int32 m = 0; m < modList.size(); ++m) {
318
if (!modList[m].active)
319
break;
320
SetActiveMod(m);
321
InitFileInfo(&info);
322
if (LoadFile(&info, "Data/Game/Game.xml", FMODE_RB)) {
323
tinyxml2::XMLDocument *doc = new tinyxml2::XMLDocument;
324
325
char *xmlData = new char[info.fileSize + 1];
326
ReadBytes(&info, xmlData, info.fileSize);
327
xmlData[info.fileSize] = 0;
328
CloseFile(&info);
329
330
doc->Parse(xmlData);
331
const tinyxml2::XMLElement *gameElement = doc->FirstChildElement("game"); // gameElement is nullptr if parse failure
332
333
if (gameElement) {
334
if (pal)
335
LoadXMLPalettes(gameElement);
336
else {
337
LoadXMLWindowText(gameElement);
338
LoadXMLVariables(gameElement);
339
LoadXMLObjects(gameElement);
340
LoadXMLSoundFX(gameElement);
341
LoadXMLPlayers(gameElement);
342
LoadXMLStages(gameElement);
343
}
344
}
345
else {
346
PrintLog(PRINT_NORMAL, "[MOD] Failed to parse Game.xml file for mod %s", modList[m].id.c_str());
347
}
348
349
delete[] xmlData;
350
delete doc;
351
}
352
}
353
SetActiveMod(-1);
354
}
355
356
void RSDK::Legacy::v4::LoadXMLWindowText(const tinyxml2::XMLElement *gameElement)
357
{
358
const tinyxml2::XMLElement *titleElement = gameElement->FirstChildElement("title");
359
if (titleElement) {
360
const tinyxml2::XMLAttribute *nameAttr = titleElement->FindAttribute("name");
361
if (nameAttr)
362
StrCopy(gameVerInfo.gameTitle, nameAttr->Value());
363
}
364
}
365
366
void RSDK::Legacy::v4::LoadXMLVariables(const tinyxml2::XMLElement *gameElement)
367
{
368
const tinyxml2::XMLElement *variablesElement = gameElement->FirstChildElement("variables");
369
if (variablesElement) {
370
for (const tinyxml2::XMLElement *varElement = variablesElement->FirstChildElement("variable"); varElement;
371
varElement = varElement->NextSiblingElement("variable")) {
372
const tinyxml2::XMLAttribute *nameAttr = varElement->FindAttribute("name");
373
const char *varName = "unknownVariable";
374
if (nameAttr)
375
varName = nameAttr->Value();
376
377
const tinyxml2::XMLAttribute *valAttr = varElement->FindAttribute("value");
378
int32 varValue = 0;
379
if (valAttr)
380
varValue = valAttr->IntValue();
381
382
if (globalVariablesCount >= LEGACY_GLOBALVAR_COUNT)
383
PrintLog(PRINT_ERROR, "[MOD] ERROR: Failed to add global variable '%s' (max limit reached)", varName);
384
else if (GetGlobalVariableID(varName) == 0xFF) {
385
StrCopy(globalVariables[globalVariablesCount].name, varName);
386
globalVariables[globalVariablesCount].value = varValue;
387
globalVariablesCount++;
388
}
389
}
390
}
391
}
392
393
void RSDK::Legacy::v4::LoadXMLPalettes(const tinyxml2::XMLElement *gameElement)
394
{
395
const tinyxml2::XMLElement *paletteElement = gameElement->FirstChildElement("palette");
396
if (paletteElement) {
397
for (const tinyxml2::XMLElement *clrElement = paletteElement->FirstChildElement("color"); clrElement;
398
clrElement = clrElement->NextSiblingElement("color")) {
399
const tinyxml2::XMLAttribute *bankAttr = clrElement->FindAttribute("bank");
400
int32 clrBank = 0;
401
if (bankAttr)
402
clrBank = bankAttr->IntValue();
403
404
const tinyxml2::XMLAttribute *indAttr = clrElement->FindAttribute("index");
405
int32 clrInd = 0;
406
if (indAttr)
407
clrInd = indAttr->IntValue();
408
409
const tinyxml2::XMLAttribute *rAttr = clrElement->FindAttribute("r");
410
int32 clrR = 0;
411
if (rAttr)
412
clrR = rAttr->IntValue();
413
414
const tinyxml2::XMLAttribute *gAttr = clrElement->FindAttribute("g");
415
int32 clrG = 0;
416
if (gAttr)
417
clrG = gAttr->IntValue();
418
419
const tinyxml2::XMLAttribute *bAttr = clrElement->FindAttribute("b");
420
int32 clrB = 0;
421
if (bAttr)
422
clrB = bAttr->IntValue();
423
424
SetPaletteEntry(clrBank, clrInd, clrR, clrG, clrB);
425
}
426
427
for (const tinyxml2::XMLElement *clrsElement = paletteElement->FirstChildElement("colors"); clrsElement;
428
clrsElement = clrsElement->NextSiblingElement("colors")) {
429
const tinyxml2::XMLAttribute *bankAttr = clrsElement->FindAttribute("bank");
430
int32 bank = 0;
431
if (bankAttr)
432
bank = bankAttr->IntValue();
433
434
const tinyxml2::XMLAttribute *indAttr = clrsElement->FindAttribute("start");
435
int32 index = 0;
436
if (indAttr)
437
index = indAttr->IntValue();
438
439
std::string text = clrsElement->GetText();
440
// working: AABBFF #FFaaFF (12, 32, 34) (145 53 234)
441
std::regex search(R"((?:#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2}))|(?:\((\d+),?\s*(\d+),?\s*(\d+)\)))",
442
std::regex_constants::icase | std::regex_constants::ECMAScript);
443
std::smatch match;
444
while (std::regex_search(text, match, search)) {
445
int32 r, g, b;
446
int32 base, start;
447
if (match[1].matched) {
448
// we have hex
449
base = 16;
450
start = 1;
451
}
452
else {
453
// triplet
454
base = 10;
455
start = 4;
456
}
457
458
r = std::stoi(match[start + 0].str(), nullptr, base);
459
g = std::stoi(match[start + 1].str(), nullptr, base);
460
b = std::stoi(match[start + 2].str(), nullptr, base);
461
462
SetPaletteEntry(bank, index++, r, g, b);
463
text = match.suffix();
464
}
465
}
466
}
467
}
468
469
void RSDK::Legacy::v4::LoadXMLObjects(const tinyxml2::XMLElement *gameElement)
470
{
471
modObjCount = 0;
472
473
const tinyxml2::XMLElement *objectsElement = gameElement->FirstChildElement("objects");
474
if (objectsElement) {
475
for (const tinyxml2::XMLElement *objElement = objectsElement->FirstChildElement("object"); objElement;
476
objElement = objElement->NextSiblingElement("object")) {
477
const tinyxml2::XMLAttribute *nameAttr = objElement->FindAttribute("name");
478
const char *objName = "unknownObject";
479
if (nameAttr)
480
objName = nameAttr->Value();
481
482
const tinyxml2::XMLAttribute *scrAttr = objElement->FindAttribute("script");
483
const char *objScript = "unknownObject.txt";
484
if (scrAttr)
485
objScript = scrAttr->Value();
486
487
uint8 flags = 0;
488
489
// forces the object to be loaded, this means the object doesn't have to be and *SHOULD NOT* be in the stage object list
490
// if it is, it'll cause issues!!!!
491
const tinyxml2::XMLAttribute *loadAttr = objElement->FindAttribute("forceLoad");
492
int32 objForceLoad = false;
493
if (loadAttr)
494
objForceLoad = loadAttr->BoolValue();
495
496
flags |= (objForceLoad & 1);
497
498
StrCopy(modTypeNames[modObjCount], objName);
499
StrCopy(modScriptPaths[modObjCount], objScript);
500
modScriptFlags[modObjCount] = flags;
501
modObjCount++;
502
}
503
}
504
}
505
506
void RSDK::Legacy::v4::LoadXMLSoundFX(const tinyxml2::XMLElement *gameElement)
507
{
508
const tinyxml2::XMLElement *soundsElement = gameElement->FirstChildElement("sounds");
509
if (soundsElement) {
510
for (const tinyxml2::XMLElement *sfxElement = soundsElement->FirstChildElement("soundfx"); sfxElement;
511
sfxElement = sfxElement->NextSiblingElement("soundfx")) {
512
const tinyxml2::XMLAttribute *nameAttr = sfxElement->FindAttribute("name");
513
const char *sfxName = "unknownSFX";
514
if (nameAttr)
515
sfxName = nameAttr->Value();
516
517
const tinyxml2::XMLAttribute *valAttr = sfxElement->FindAttribute("path");
518
const char *sfxPath = "unknownSFX.wav";
519
if (valAttr)
520
sfxPath = valAttr->Value();
521
522
SetSfxName(sfxName, globalSFXCount);
523
524
RSDK::Legacy::LoadSfx((char *)sfxPath, globalSFXCount, SCOPE_GLOBAL);
525
globalSFXCount++;
526
}
527
}
528
}
529
530
void RSDK::Legacy::v4::LoadXMLPlayers(const tinyxml2::XMLElement *gameElement)
531
{
532
const tinyxml2::XMLElement *playersElement = gameElement->FirstChildElement("players");
533
if (playersElement) {
534
for (const tinyxml2::XMLElement *plrElement = playersElement->FirstChildElement("player"); plrElement;
535
plrElement = plrElement->NextSiblingElement("player")) {
536
const tinyxml2::XMLAttribute *nameAttr = plrElement->FindAttribute("name");
537
const char *plrName = "unknownPlayer";
538
if (nameAttr)
539
plrName = nameAttr->Value();
540
541
StrCopy(modSettings.playerNames[modSettings.playerCount++], plrName);
542
}
543
}
544
}
545
546
void RSDK::Legacy::v4::LoadXMLStages(const tinyxml2::XMLElement *gameElement)
547
{
548
const char *elementNames[] = { "presentationStages", "regularStages", "bonusStages", "specialStages" };
549
550
for (int32 l = 0; l < sceneInfo.categoryCount; ++l) {
551
const tinyxml2::XMLElement *listElement = gameElement->FirstChildElement(elementNames[l]);
552
SceneListInfo *list = &sceneInfo.listCategory[l];
553
if (listElement) {
554
for (const tinyxml2::XMLElement *stgElement = listElement->FirstChildElement("stage"); stgElement;
555
stgElement = stgElement->NextSiblingElement("stage")) {
556
const tinyxml2::XMLAttribute *nameAttr = stgElement->FindAttribute("name");
557
const char *stgName = "unknownStage";
558
if (nameAttr)
559
stgName = nameAttr->Value();
560
561
const tinyxml2::XMLAttribute *folderAttr = stgElement->FindAttribute("folder");
562
const char *stgFolder = "unknownStageFolder";
563
if (folderAttr)
564
stgFolder = folderAttr->Value();
565
566
const tinyxml2::XMLAttribute *idAttr = stgElement->FindAttribute("id");
567
const char *stgID = "unknownStageID";
568
if (idAttr)
569
stgID = idAttr->Value();
570
571
listData.emplace(listData.begin() + list->sceneOffsetEnd);
572
SceneListEntry *scene = &listData[list->sceneOffsetEnd];
573
574
sprintf_s(scene->name, sizeof(scene->name), "%s", stgName);
575
GEN_HASH_MD5(scene->name, scene->hash);
576
sprintf_s(scene->folder, sizeof(scene->folder), "%s", stgFolder);
577
sprintf_s(scene->id, sizeof(scene->id), "%s", stgID);
578
579
scene->filter = 0xFF;
580
581
list->sceneCount++;
582
list->sceneOffsetEnd++;
583
for (int32 c = l + 1; c < sceneInfo.categoryCount; ++c) sceneInfo.listCategory[c].sceneOffsetStart++;
584
}
585
}
586
}
587
sceneInfo.listData = listData.data();
588
}
589
590
#endif
591
592