Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-1-2-2013-Decompilation
Path: blob/main/RSDKv4/Object.cpp
817 views
1
#include "RetroEngine.hpp"
2
3
// Native Objects
4
int nativeEntityPos;
5
6
int activeEntityList[NATIVEENTITY_COUNT];
7
byte objectRemoveFlag[NATIVEENTITY_COUNT];
8
NativeEntity objectEntityBank[NATIVEENTITY_COUNT];
9
int nativeEntityCount = 0;
10
11
int nativeEntityCountBackup = 0;
12
int backupEntityList[NATIVEENTITY_COUNT];
13
NativeEntity objectEntityBackup[NATIVEENTITY_COUNT];
14
15
int nativeEntityCountBackupS = 0;
16
int backupEntityListS[NATIVEENTITY_COUNT];
17
NativeEntity objectEntityBackupS[NATIVEENTITY_COUNT];
18
19
// Game Objects
20
int objectEntityPos = 0;
21
int curObjectType = 0;
22
Entity objectEntityList[ENTITY_COUNT * 2]; //"regular" list & "storage" list
23
int processObjectFlag[ENTITY_COUNT];
24
TypeGroupList objectTypeGroupList[TYPEGROUP_COUNT];
25
26
char typeNames[OBJECT_COUNT][0x40];
27
28
int OBJECT_BORDER_X1 = 0x80;
29
int OBJECT_BORDER_X2 = SCREEN_XSIZE + 0x80;
30
int OBJECT_BORDER_X3 = 0x20;
31
int OBJECT_BORDER_X4 = SCREEN_XSIZE + 0x20;
32
33
const int OBJECT_BORDER_Y1 = 0x100;
34
const int OBJECT_BORDER_Y2 = SCREEN_YSIZE + 0x100;
35
const int OBJECT_BORDER_Y3 = 0x80;
36
const int OBJECT_BORDER_Y4 = SCREEN_YSIZE + 0x80;
37
38
int playerListPos = 0;
39
40
void ProcessStartupObjects()
41
{
42
scriptFrameCount = 0;
43
ClearAnimationData();
44
scriptEng.arrayPosition[8] = TEMPENTITY_START;
45
OBJECT_BORDER_X1 = 0x80;
46
OBJECT_BORDER_X3 = 0x20;
47
OBJECT_BORDER_X2 = SCREEN_XSIZE + 0x80;
48
OBJECT_BORDER_X4 = SCREEN_XSIZE + 0x20;
49
Entity *entity = &objectEntityList[TEMPENTITY_START];
50
// Dunno what this is meant for, but it's here in the original code so...
51
objectEntityList[TEMPENTITY_START + 1].type = objectEntityList[0].type;
52
53
memset(foreachStack, -1, sizeof(foreachStack));
54
memset(jumpTableStack, 0, sizeof(jumpTableStack));
55
56
for (int i = 0; i < OBJECT_COUNT; ++i) {
57
ObjectScript *scriptInfo = &objectScriptList[i];
58
objectEntityPos = TEMPENTITY_START;
59
curObjectType = i;
60
scriptInfo->frameListOffset = scriptFrameCount;
61
scriptInfo->spriteSheetID = 0;
62
entity->type = i;
63
64
if (scriptCode[scriptInfo->eventStartup.scriptCodePtr] > 0)
65
ProcessScript(scriptInfo->eventStartup.scriptCodePtr, scriptInfo->eventStartup.jumpTablePtr, EVENT_SETUP);
66
scriptInfo->frameCount = scriptFrameCount - scriptInfo->frameListOffset;
67
}
68
entity->type = 0;
69
curObjectType = 0;
70
}
71
72
void ProcessObjects()
73
{
74
for (int i = 0; i < DRAWLAYER_COUNT; ++i) drawListEntries[i].listSize = 0;
75
76
for (objectEntityPos = 0; objectEntityPos < ENTITY_COUNT; ++objectEntityPos) {
77
processObjectFlag[objectEntityPos] = false;
78
int x = 0, y = 0;
79
Entity *entity = &objectEntityList[objectEntityPos];
80
x = entity->xpos >> 16;
81
y = entity->ypos >> 16;
82
83
switch (entity->priority) {
84
case PRIORITY_BOUNDS:
85
processObjectFlag[objectEntityPos] = x > xScrollOffset - OBJECT_BORDER_X1 && x < xScrollOffset + OBJECT_BORDER_X2
86
&& y > yScrollOffset - OBJECT_BORDER_Y1 && y < yScrollOffset + OBJECT_BORDER_Y2;
87
break;
88
89
case PRIORITY_ACTIVE:
90
case PRIORITY_ALWAYS:
91
case PRIORITY_ACTIVE_SMALL: processObjectFlag[objectEntityPos] = true; break;
92
93
case PRIORITY_XBOUNDS:
94
processObjectFlag[objectEntityPos] = x > xScrollOffset - OBJECT_BORDER_X1 && x < OBJECT_BORDER_X2 + xScrollOffset;
95
break;
96
97
case PRIORITY_XBOUNDS_DESTROY:
98
processObjectFlag[objectEntityPos] = x > xScrollOffset - OBJECT_BORDER_X1 && x < xScrollOffset + OBJECT_BORDER_X2;
99
if (!processObjectFlag[objectEntityPos]) {
100
processObjectFlag[objectEntityPos] = false;
101
entity->type = OBJ_TYPE_BLANKOBJECT;
102
}
103
break;
104
105
case PRIORITY_INACTIVE: processObjectFlag[objectEntityPos] = false; break;
106
case PRIORITY_BOUNDS_SMALL:
107
processObjectFlag[objectEntityPos] = x > xScrollOffset - OBJECT_BORDER_X3 && x < OBJECT_BORDER_X4 + xScrollOffset
108
&& y > yScrollOffset - OBJECT_BORDER_Y3 && y < yScrollOffset + OBJECT_BORDER_Y4;
109
break;
110
111
default: break;
112
}
113
114
if (processObjectFlag[objectEntityPos] && entity->type > OBJ_TYPE_BLANKOBJECT) {
115
ObjectScript *scriptInfo = &objectScriptList[entity->type];
116
if (scriptCode[scriptInfo->eventUpdate.scriptCodePtr] > 0)
117
ProcessScript(scriptInfo->eventUpdate.scriptCodePtr, scriptInfo->eventUpdate.jumpTablePtr, EVENT_MAIN);
118
119
if (entity->drawOrder < DRAWLAYER_COUNT)
120
drawListEntries[entity->drawOrder].entityRefs[drawListEntries[entity->drawOrder].listSize++] = objectEntityPos;
121
}
122
}
123
124
for (int i = 0; i < TYPEGROUP_COUNT; ++i) objectTypeGroupList[i].listSize = 0;
125
126
for (objectEntityPos = 0; objectEntityPos < ENTITY_COUNT; ++objectEntityPos) {
127
Entity *entity = &objectEntityList[objectEntityPos];
128
if (processObjectFlag[objectEntityPos] && entity->objectInteractions) {
129
// Custom Group
130
if (entity->groupID >= OBJECT_COUNT) {
131
TypeGroupList *listCustom = &objectTypeGroupList[objectEntityList[objectEntityPos].groupID];
132
listCustom->entityRefs[listCustom->listSize++] = objectEntityPos;
133
}
134
135
// Type-Specific list
136
TypeGroupList *listType = &objectTypeGroupList[objectEntityList[objectEntityPos].type];
137
listType->entityRefs[listType->listSize++] = objectEntityPos;
138
139
// All Entities list
140
TypeGroupList *listAll = &objectTypeGroupList[GROUP_ALL];
141
listAll->entityRefs[listAll->listSize++] = objectEntityPos;
142
}
143
}
144
}
145
void ProcessPausedObjects()
146
{
147
for (int i = 0; i < DRAWLAYER_COUNT; ++i) drawListEntries[i].listSize = 0;
148
149
for (objectEntityPos = 0; objectEntityPos < ENTITY_COUNT; ++objectEntityPos) {
150
Entity *entity = &objectEntityList[objectEntityPos];
151
152
if (entity->priority == PRIORITY_ALWAYS && entity->type > OBJ_TYPE_BLANKOBJECT) {
153
ObjectScript *scriptInfo = &objectScriptList[entity->type];
154
if (scriptCode[scriptInfo->eventUpdate.scriptCodePtr] > 0)
155
ProcessScript(scriptInfo->eventUpdate.scriptCodePtr, scriptInfo->eventUpdate.jumpTablePtr, EVENT_MAIN);
156
157
if (entity->drawOrder < DRAWLAYER_COUNT && entity->drawOrder >= 0)
158
drawListEntries[entity->drawOrder].entityRefs[drawListEntries[entity->drawOrder].listSize++] = objectEntityPos;
159
}
160
}
161
}
162
void ProcessFrozenObjects()
163
{
164
for (int i = 0; i < DRAWLAYER_COUNT; ++i) drawListEntries[i].listSize = 0;
165
166
for (objectEntityPos = 0; objectEntityPos < ENTITY_COUNT; ++objectEntityPos) {
167
processObjectFlag[objectEntityPos] = false;
168
int x = 0, y = 0;
169
Entity *entity = &objectEntityList[objectEntityPos];
170
x = entity->xpos >> 16;
171
y = entity->ypos >> 16;
172
173
switch (entity->priority) {
174
case PRIORITY_BOUNDS:
175
processObjectFlag[objectEntityPos] = x > xScrollOffset - OBJECT_BORDER_X1 && x < xScrollOffset + OBJECT_BORDER_X2
176
&& y > yScrollOffset - OBJECT_BORDER_Y1 && y < yScrollOffset + OBJECT_BORDER_Y2;
177
break;
178
179
case PRIORITY_ACTIVE:
180
case PRIORITY_ALWAYS:
181
case PRIORITY_ACTIVE_SMALL: processObjectFlag[objectEntityPos] = true; break;
182
183
case PRIORITY_XBOUNDS:
184
processObjectFlag[objectEntityPos] = x > xScrollOffset - OBJECT_BORDER_X1 && x < OBJECT_BORDER_X2 + xScrollOffset;
185
break;
186
187
case PRIORITY_XBOUNDS_DESTROY:
188
processObjectFlag[objectEntityPos] = x > xScrollOffset - OBJECT_BORDER_X1 && x < xScrollOffset + OBJECT_BORDER_X2;
189
if (!processObjectFlag[objectEntityPos]) {
190
processObjectFlag[objectEntityPos] = false;
191
entity->type = OBJ_TYPE_BLANKOBJECT;
192
}
193
break;
194
195
case PRIORITY_INACTIVE: processObjectFlag[objectEntityPos] = false; break;
196
197
case PRIORITY_BOUNDS_SMALL:
198
processObjectFlag[objectEntityPos] = x > xScrollOffset - OBJECT_BORDER_X3 && x < OBJECT_BORDER_X4 + xScrollOffset
199
&& y > yScrollOffset - OBJECT_BORDER_Y3 && y < yScrollOffset + OBJECT_BORDER_Y4;
200
break;
201
202
default: break;
203
}
204
205
if (processObjectFlag[objectEntityPos] && entity->type > OBJ_TYPE_BLANKOBJECT) {
206
ObjectScript *scriptInfo = &objectScriptList[entity->type];
207
if (scriptCode[scriptInfo->eventUpdate.scriptCodePtr] > 0 && entity->priority == PRIORITY_ALWAYS)
208
ProcessScript(scriptInfo->eventUpdate.scriptCodePtr, scriptInfo->eventUpdate.jumpTablePtr, EVENT_MAIN);
209
210
if (entity->drawOrder < DRAWLAYER_COUNT && entity->drawOrder >= 0)
211
drawListEntries[entity->drawOrder].entityRefs[drawListEntries[entity->drawOrder].listSize++] = objectEntityPos;
212
}
213
}
214
215
for (int i = 0; i < TYPEGROUP_COUNT; ++i) objectTypeGroupList[i].listSize = 0;
216
217
for (objectEntityPos = 0; objectEntityPos < ENTITY_COUNT; ++objectEntityPos) {
218
Entity *entity = &objectEntityList[objectEntityPos];
219
if (processObjectFlag[objectEntityPos] && entity->objectInteractions) {
220
// Custom Group
221
if (entity->groupID >= OBJECT_COUNT) {
222
TypeGroupList *listCustom = &objectTypeGroupList[objectEntityList[objectEntityPos].groupID];
223
listCustom->entityRefs[listCustom->listSize++] = objectEntityPos;
224
}
225
// Type-Specific list
226
TypeGroupList *listType = &objectTypeGroupList[objectEntityList[objectEntityPos].type];
227
listType->entityRefs[listType->listSize++] = objectEntityPos;
228
229
// All Entities list
230
TypeGroupList *listAll = &objectTypeGroupList[GROUP_ALL];
231
listAll->entityRefs[listAll->listSize++] = objectEntityPos;
232
}
233
}
234
}
235
#if !RETRO_REV00
236
void Process2PObjects()
237
{
238
for (int i = 0; i < DRAWLAYER_COUNT; ++i) drawListEntries[i].listSize = 0;
239
240
int boundX1 = -(0x200 << 16);
241
int boundX2 = (0x200 << 16);
242
int boundX3 = -(0x180 << 16);
243
int boundX4 = (0x180 << 16);
244
245
int boundY1 = -(0x180 << 16);
246
int boundY2 = (0x180 << 16);
247
int boundY3 = -(0x100 << 16);
248
int boundY4 = (0x100 << 16);
249
250
for (objectEntityPos = 0; objectEntityPos < ENTITY_COUNT; ++objectEntityPos) {
251
processObjectFlag[objectEntityPos] = false;
252
int x = 0, y = 0;
253
254
Entity *entity = &objectEntityList[objectEntityPos];
255
x = entity->xpos;
256
y = entity->ypos;
257
258
// Set these here, they could (and prolly are) updated after objects
259
Entity *entityP1 = &objectEntityList[0];
260
int XPosP1 = entityP1->xpos;
261
int YPosP1 = entityP1->ypos;
262
Entity *entityP2 = &objectEntityList[1];
263
int XPosP2 = entityP2->xpos;
264
int YPosP2 = entityP2->ypos;
265
266
switch (entity->priority) {
267
case PRIORITY_BOUNDS:
268
processObjectFlag[objectEntityPos] = x > XPosP1 + boundX1 && x < XPosP1 + boundX2 && y > YPosP1 + boundY1 && y < YPosP1 + boundY2;
269
if (!processObjectFlag[objectEntityPos]) {
270
processObjectFlag[objectEntityPos] = x > XPosP2 + boundX1 && x < XPosP2 + boundX2 && y > YPosP2 + boundY1 && y < YPosP2 + boundY2;
271
}
272
break;
273
274
case PRIORITY_ACTIVE:
275
case PRIORITY_ALWAYS:
276
case PRIORITY_ACTIVE_SMALL: processObjectFlag[objectEntityPos] = true; break;
277
278
case PRIORITY_XBOUNDS:
279
processObjectFlag[objectEntityPos] = x > XPosP1 + boundX1 && x < XPosP1 + boundX2;
280
if (!processObjectFlag[objectEntityPos]) {
281
processObjectFlag[objectEntityPos] = x > XPosP2 + boundX1 && x < XPosP2 + boundX2;
282
}
283
break;
284
285
case PRIORITY_XBOUNDS_DESTROY:
286
processObjectFlag[objectEntityPos] = x > XPosP1 + boundX1 && x < XPosP1 + boundX2;
287
if (!processObjectFlag[objectEntityPos]) {
288
processObjectFlag[objectEntityPos] = x > XPosP2 + boundX1 && x < XPosP2 + boundX2;
289
}
290
291
if (!processObjectFlag[objectEntityPos])
292
entity->type = OBJ_TYPE_BLANKOBJECT;
293
break;
294
295
case PRIORITY_INACTIVE: processObjectFlag[objectEntityPos] = false; break;
296
case PRIORITY_BOUNDS_SMALL:
297
processObjectFlag[objectEntityPos] = x > XPosP1 + boundX3 && x < XPosP1 + boundX4 && y > YPosP1 + boundY3 && y < YPosP1 + boundY4;
298
if (!processObjectFlag[objectEntityPos]) {
299
processObjectFlag[objectEntityPos] = x > XPosP2 + boundX3 && x < XPosP2 + boundX4 && y > YPosP2 + boundY3 && y < YPosP2 + boundY4;
300
}
301
break;
302
303
default: break;
304
}
305
306
if (processObjectFlag[objectEntityPos] && entity->type > OBJ_TYPE_BLANKOBJECT) {
307
ObjectScript *scriptInfo = &objectScriptList[entity->type];
308
if (scriptCode[scriptInfo->eventUpdate.scriptCodePtr] > 0)
309
ProcessScript(scriptInfo->eventUpdate.scriptCodePtr, scriptInfo->eventUpdate.jumpTablePtr, EVENT_MAIN);
310
311
if (entity->drawOrder < DRAWLAYER_COUNT && entity->drawOrder >= 0)
312
drawListEntries[entity->drawOrder].entityRefs[drawListEntries[entity->drawOrder].listSize++] = objectEntityPos;
313
}
314
}
315
316
for (int i = 0; i < TYPEGROUP_COUNT; ++i) objectTypeGroupList[i].listSize = 0;
317
318
for (objectEntityPos = 0; objectEntityPos < ENTITY_COUNT; ++objectEntityPos) {
319
Entity *entity = &objectEntityList[objectEntityPos];
320
if (processObjectFlag[objectEntityPos] && entity->objectInteractions) {
321
// Custom Group
322
if (entity->groupID >= OBJECT_COUNT) {
323
TypeGroupList *listCustom = &objectTypeGroupList[objectEntityList[objectEntityPos].groupID];
324
listCustom->entityRefs[listCustom->listSize++] = objectEntityPos;
325
}
326
// Type-Specific list
327
TypeGroupList *listType = &objectTypeGroupList[objectEntityList[objectEntityPos].type];
328
listType->entityRefs[listType->listSize++] = objectEntityPos;
329
330
// All Entities list
331
TypeGroupList *listAll = &objectTypeGroupList[GROUP_ALL];
332
listAll->entityRefs[listAll->listSize++] = objectEntityPos;
333
}
334
}
335
}
336
#endif
337
338
void SetObjectTypeName(const char *objectName, int objectID)
339
{
340
int objPos = 0;
341
int typePos = 0;
342
while (objectName[objPos]) {
343
if (objectName[objPos] != ' ')
344
typeNames[objectID][typePos++] = objectName[objPos];
345
++objPos;
346
}
347
typeNames[objectID][typePos] = 0;
348
PrintLog("Set Object (%d) name to: %s", objectID, objectName);
349
}
350
351
void ProcessObjectControl(Entity *entity)
352
{
353
if (entity->controlMode == 0) {
354
entity->up = keyDown.up;
355
entity->down = keyDown.down;
356
if (!keyDown.left || !keyDown.right) {
357
entity->left = keyDown.left;
358
entity->right = keyDown.right;
359
}
360
else {
361
entity->left = false;
362
entity->right = false;
363
}
364
entity->jumpHold = keyDown.C || keyDown.B || keyDown.A;
365
entity->jumpPress = keyPress.C || keyPress.B || keyPress.A;
366
}
367
}
368
369
void InitNativeObjectSystem()
370
{
371
InitLocalizedStrings();
372
373
nativeEntityCount = 0;
374
memset(activeEntityList, 0, sizeof(activeEntityList));
375
memset(objectRemoveFlag, 0, sizeof(objectRemoveFlag));
376
memset(objectEntityBank, 0, sizeof(objectEntityBank));
377
378
nativeEntityCountBackup = 0;
379
memset(backupEntityList, 0, sizeof(backupEntityList));
380
memset(objectEntityBackup, 0, sizeof(objectEntityBackup));
381
382
nativeEntityCountBackupS = 0;
383
memset(backupEntityListS, 0, sizeof(backupEntityListS));
384
memset(objectEntityBackupS, 0, sizeof(objectEntityBackupS));
385
386
ReadSaveRAMData();
387
388
SaveGame *saveGame = (SaveGame *)saveRAM;
389
if (!saveGame->saveInitialized) {
390
saveGame->saveInitialized = true;
391
saveGame->musVolume = MAX_VOLUME;
392
saveGame->sfxVolume = MAX_VOLUME;
393
saveGame->spindashEnabled = true;
394
saveGame->boxRegion = 0;
395
saveGame->vDPadSize = 64;
396
saveGame->vDPadOpacity = 160;
397
saveGame->vDPadX_Move = 56;
398
saveGame->vDPadY_Move = 184;
399
saveGame->vDPadX_Jump = -56;
400
saveGame->vDPadY_Jump = 188;
401
saveGame->tailsUnlocked = Engine.gameType != GAME_SONIC1;
402
saveGame->knuxUnlocked = Engine.gameType != GAME_SONIC1;
403
saveGame->unlockedActs = 0;
404
WriteSaveRAMData();
405
}
406
#if !RETRO_USE_ORIGINAL_CODE
407
else if (Engine.gameType == GAME_SONIC2) {
408
// ensure tails and knuckles are unlocked in sonic 2
409
// they weren't automatically unlocked in older versions of the decomp
410
saveGame->tailsUnlocked = true;
411
saveGame->knuxUnlocked = true;
412
WriteSaveRAMData();
413
}
414
#endif
415
saveGame->musVolume = bgmVolume;
416
saveGame->sfxVolume = sfxVolume;
417
418
if (!saveGame->musVolume)
419
musicEnabled = false;
420
421
if (!saveGame->vDPadX_Move) {
422
saveGame->vDPadX_Move = 60;
423
saveGame->vDPadY_Move = 176;
424
saveGame->vDPadX_Jump = -56;
425
saveGame->vDPadY_Jump = 180;
426
}
427
428
Engine.globalBoxRegion = saveGame->boxRegion;
429
SetGameVolumes(saveGame->musVolume, saveGame->sfxVolume);
430
#if !RETRO_USE_ORIGINAL_CODE
431
if (skipStartMenu) {
432
CREATE_ENTITY(RetroGameLoop);
433
if (Engine.gameDeviceType == RETRO_MOBILE)
434
CREATE_ENTITY(VirtualDPad);
435
}
436
else
437
#endif
438
CREATE_ENTITY(SegaSplash);
439
}
440
NativeEntity *CreateNativeObject(void (*create)(void *objPtr), void (*main)(void *objPtr))
441
{
442
if (!nativeEntityCount) {
443
memset(objectEntityBank, 0, sizeof(objectEntityBank));
444
NativeEntity *entity = &objectEntityBank[0];
445
entity->eventCreate = create;
446
entity->eventMain = main;
447
activeEntityList[0] = 0;
448
nativeEntityCount++;
449
if (entity->eventCreate)
450
entity->eventCreate(entity);
451
return entity;
452
}
453
else if (nativeEntityCount >= NATIVEENTITY_COUNT) {
454
// TODO, probably never
455
return NULL;
456
}
457
else {
458
int slot = 0;
459
for (; slot < NATIVEENTITY_COUNT; ++slot) {
460
if (!objectEntityBank[slot].eventMain)
461
break;
462
}
463
NativeEntity *entity = &objectEntityBank[slot];
464
memset(entity, 0, sizeof(NativeEntity));
465
entity->slotID = slot;
466
entity->objectID = nativeEntityCount;
467
entity->eventCreate = create;
468
entity->eventMain = main;
469
activeEntityList[nativeEntityCount++] = slot;
470
if (entity->eventCreate)
471
entity->eventCreate(entity);
472
return entity;
473
}
474
}
475
void RemoveNativeObject(NativeEntityBase *entity)
476
{
477
#if !RETRO_USE_ORIGINAL_CODE
478
if (!entity)
479
return;
480
memmove(&activeEntityList[entity->objectID], &activeEntityList[entity->objectID + 1], sizeof(int) * (NATIVEENTITY_COUNT - (entity->objectID + 2)));
481
--nativeEntityCount;
482
for (int i = entity->slotID; objectEntityBank[i].eventMain; ++i) objectEntityBank[i].objectID--;
483
#else
484
// this actually behaves COMPLETELY improperly, duplicating the deleted one instead
485
// the above code is my attempt to make a proper version
486
if (nativeEntityCount <= 0) {
487
objectRemoveFlag[entity->slotID] = true;
488
}
489
else {
490
memset(objectRemoveFlag, 0, nativeEntityCount);
491
int slotStore = 0;
492
objectRemoveFlag[entity->slotID] = true;
493
int s = 0;
494
do {
495
if (!objectRemoveFlag[s]) {
496
if (s != slotStore) {
497
int store = activeEntityList[s];
498
objectRemoveFlag[slotStore] = false;
499
activeEntityList[slotStore] = store;
500
}
501
++slotStore;
502
}
503
++s;
504
} while (s != nativeEntityCount);
505
nativeEntityCount = s - 1;
506
}
507
#endif
508
}
509
void ResetNativeObject(NativeEntityBase *obj, void (*create)(void *objPtr), void (*main)(void *objPtr))
510
{
511
int slotID = obj->slotID;
512
int objID = obj->objectID;
513
memset(&objectEntityBank[slotID], 0, sizeof(NativeEntity));
514
obj->slotID = slotID;
515
obj->eventMain = main;
516
obj->eventCreate = create;
517
obj->objectID = objID;
518
if (create)
519
create(obj);
520
}
521
void ProcessNativeObjects()
522
{
523
ResetRenderStates();
524
for (nativeEntityPos = 0; nativeEntityPos < nativeEntityCount; ++nativeEntityPos) {
525
NativeEntity *entity = &objectEntityBank[activeEntityList[nativeEntityPos]];
526
entity->eventMain(entity);
527
}
528
RenderScene();
529
}
530
531
void RestoreNativeObjects()
532
{
533
memcpy(activeEntityList, backupEntityList, sizeof(activeEntityList));
534
memcpy(objectEntityBank, objectEntityBackup, sizeof(objectEntityBank));
535
nativeEntityCount = nativeEntityCountBackup;
536
537
CREATE_ENTITY(FadeScreen)->state = FADESCREEN_STATE_MENUFADEIN;
538
}
539
540
void RestoreNativeObjectsNoFade()
541
{
542
memcpy(activeEntityList, backupEntityList, sizeof(activeEntityList));
543
memcpy(objectEntityBank, objectEntityBackup, sizeof(objectEntityBank));
544
nativeEntityCount = nativeEntityCountBackup;
545
}
546
void RestoreNativeObjectsSettings()
547
{
548
memcpy(activeEntityList, backupEntityListS, sizeof(activeEntityList));
549
memcpy(objectEntityBank, objectEntityBackupS, sizeof(objectEntityBank));
550
nativeEntityCount = nativeEntityCountBackupS;
551
}
552
553