Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Rubberduckycooly
GitHub Repository: Rubberduckycooly/RSDKv5-Decompilation
Path: blob/master/RSDKv5/RSDK/Scene/Object.cpp
1163 views
1
#include "RSDK/Core/RetroEngine.hpp"
2
3
using namespace RSDK;
4
5
#if RETRO_REV0U
6
#include "Legacy/ObjectLegacy.cpp"
7
#endif
8
9
ObjectClass RSDK::objectClassList[OBJECT_COUNT];
10
int32 RSDK::objectClassCount = 0;
11
12
int32 RSDK::globalObjectCount = 0;
13
int32 RSDK::globalObjectIDs[OBJECT_COUNT];
14
int32 RSDK::stageObjectIDs[OBJECT_COUNT];
15
16
EntityBase RSDK::objectEntityList[ENTITY_COUNT];
17
18
EditableVarInfo *RSDK::editableVarList;
19
int32 RSDK::editableVarCount = 0;
20
21
TypeGroupList RSDK::typeGroups[TYPEGROUP_COUNT];
22
23
bool32 RSDK::validDraw = false;
24
25
ForeachStackInfo RSDK::foreachStackList[FOREACH_STACK_COUNT];
26
ForeachStackInfo *RSDK::foreachStackPtr = NULL;
27
28
#if RETRO_REV0U
29
#if RETRO_USE_MOD_LOADER
30
void RSDK::RegisterObject(Object **staticVars, const char *name, uint32 entityClassSize, uint32 staticClassSize, void (*update)(),
31
void (*lateUpdate)(), void (*staticUpdate)(), void (*draw)(), void (*create)(void *), void (*stageLoad)(),
32
void (*editorLoad)(), void (*editorDraw)(), void (*serialize)(), void (*staticLoad)(Object *))
33
{
34
return RegisterObject_STD(staticVars, name, entityClassSize, staticClassSize, update, lateUpdate, staticUpdate, draw, create, stageLoad,
35
editorLoad, editorDraw, serialize, staticLoad);
36
}
37
38
void RSDK::RegisterObject_STD(Object **staticVars, const char *name, uint32 entityClassSize, uint32 staticClassSize, std::function<void()> update,
39
std::function<void()> lateUpdate, std::function<void()> staticUpdate, std::function<void()> draw,
40
std::function<void(void *)> create, std::function<void()> stageLoad, std::function<void()> editorLoad,
41
std::function<void()> editorDraw, std::function<void()> serialize, std::function<void(Object *)> staticLoad)
42
#else
43
void RSDK::RegisterObject(Object **staticVars, const char *name, uint32 entityClassSize, uint32 staticClassSize, void (*update)(),
44
void (*lateUpdate)(), void (*staticUpdate)(), void (*draw)(), void (*create)(void *), void (*stageLoad)(),
45
void (*editorLoad)(), void (*editorDraw)(), void (*serialize)(), void (*staticLoad)(Object *))
46
#endif
47
#else
48
#if RETRO_USE_MOD_LOADER
49
void RSDK::RegisterObject(Object **staticVars, const char *name, uint32 entityClassSize, uint32 staticClassSize, void (*update)(),
50
void (*lateUpdate)(), void (*staticUpdate)(), void (*draw)(), void (*create)(void *), void (*stageLoad)(),
51
void (*editorLoad)(), void (*editorDraw)(), void (*serialize)())
52
{
53
return RegisterObject_STD(staticVars, name, entityClassSize, staticClassSize, update, lateUpdate, staticUpdate, draw, create, stageLoad,
54
editorLoad, editorDraw, serialize);
55
}
56
57
void RSDK::RegisterObject_STD(Object **staticVars, const char *name, uint32 entityClassSize, uint32 staticClassSize, std::function<void()> update,
58
std::function<void()> lateUpdate, std::function<void()> staticUpdate, std::function<void()> draw,
59
std::function<void(void *)> create, std::function<void()> stageLoad, std::function<void()> editorLoad,
60
std::function<void()> editorDraw, std::function<void()> serialize)
61
#else
62
void RSDK::RegisterObject(Object **staticVars, const char *name, uint32 entityClassSize, uint32 staticClassSize, void (*update)(),
63
void (*lateUpdate)(), void (*staticUpdate)(), void (*draw)(), void (*create)(void *), void (*stageLoad)(),
64
void (*editorLoad)(), void (*editorDraw)(), void (*serialize)())
65
#endif
66
#endif
67
{
68
if (objectClassCount < OBJECT_COUNT) {
69
if (entityClassSize > sizeof(EntityBase))
70
PrintLog(PRINT_NORMAL, "Class exceeds max entity memory: %s", name);
71
72
ObjectClass *classInfo = &objectClassList[objectClassCount];
73
GEN_HASH_MD5(name, classInfo->hash);
74
classInfo->staticVars = staticVars;
75
classInfo->entityClassSize = entityClassSize;
76
classInfo->staticClassSize = staticClassSize;
77
classInfo->update = update;
78
classInfo->lateUpdate = lateUpdate;
79
classInfo->staticUpdate = staticUpdate;
80
classInfo->draw = draw;
81
classInfo->create = create;
82
classInfo->stageLoad = stageLoad;
83
classInfo->editorLoad = editorLoad;
84
classInfo->editorDraw = editorDraw;
85
classInfo->serialize = serialize;
86
#if RETRO_REV0U
87
classInfo->staticLoad = staticLoad;
88
#endif
89
90
#if !RETRO_USE_ORIGINAL_CODE
91
classInfo->name = name;
92
#endif
93
94
++objectClassCount;
95
}
96
}
97
98
#if RETRO_REV02 || RETRO_USE_MOD_LOADER
99
void RSDK::RegisterStaticVariables(void **staticVars, const char *name, uint32 classSize)
100
{
101
RETRO_HASH_MD5(hash);
102
GEN_HASH_MD5(name, hash);
103
AllocateStorage((void **)staticVars, classSize, DATASET_STG, true);
104
LoadStaticVariables((uint8 *)*staticVars, hash, 0);
105
}
106
#endif
107
108
#define ALIGN_TO(type) \
109
aligned = dataPos & -(int32)sizeof(type); \
110
if (aligned < dataPos) \
111
dataPos = aligned + sizeof(type);
112
113
void RSDK::LoadStaticVariables(uint8 *classPtr, uint32 *hash, int32 readOffset)
114
{
115
char fullFilePath[0x40];
116
117
const char *hexChars = "0123456789ABCDEF";
118
char classHash[] = "00000000000000000000000000000000";
119
120
int32 strPos = 0;
121
for (int32 i = 0; i < 32; i += 4) classHash[strPos++] = hexChars[(hash[0] >> i) & 0xF];
122
for (int32 i = 0; i < 32; i += 4) classHash[strPos++] = hexChars[(hash[1] >> i) & 0xF];
123
for (int32 i = 0; i < 32; i += 4) classHash[strPos++] = hexChars[(hash[2] >> i) & 0xF];
124
for (int32 i = 0; i < 32; i += 4) classHash[strPos++] = hexChars[(hash[3] >> i) & 0xF];
125
126
sprintf_s(fullFilePath, sizeof(fullFilePath), "Data/Objects/Static/%s.bin", classHash);
127
128
FileInfo info;
129
InitFileInfo(&info);
130
if (LoadFile(&info, fullFilePath, FMODE_RB)) {
131
uint32 sig = ReadInt32(&info, false);
132
133
if (sig != RSDK_SIGNATURE_OBJ) {
134
CloseFile(&info);
135
return;
136
}
137
138
int32 dataPos = readOffset;
139
while (info.readPos < info.fileSize) {
140
int32 type = ReadInt8(&info);
141
int32 arraySize = ReadInt32(&info, false);
142
143
bool32 hasValues = (type & 0x80) != 0;
144
type &= 0x7F;
145
146
int32 aligned = 0;
147
if (hasValues) {
148
uint32 count = ReadInt32(&info, false);
149
150
switch (type) {
151
default:
152
#if !RETRO_USE_ORIGINAL_CODE
153
PrintLog(PRINT_NORMAL, "Invalid static variable type: %d", type);
154
#endif
155
break;
156
157
case SVAR_UINT8:
158
case SVAR_INT8:
159
if (info.readPos + (count * sizeof(uint8)) <= info.fileSize && &classPtr[dataPos]) {
160
for (int32 i = 0; i < count * sizeof(uint8); i += sizeof(uint8)) ReadBytes(&info, &classPtr[dataPos + i], sizeof(uint8));
161
}
162
else {
163
info.readPos += count * sizeof(uint8);
164
}
165
166
dataPos += count * sizeof(uint8);
167
break;
168
169
case SVAR_UINT16:
170
case SVAR_INT16: {
171
ALIGN_TO(int16);
172
173
if (info.readPos + (count * sizeof(int16)) <= info.fileSize && &classPtr[dataPos]) {
174
for (int32 i = 0; i < count * sizeof(int16); i += sizeof(int16)) {
175
#if !RETRO_USE_ORIGINAL_CODE
176
*(int16 *)&classPtr[dataPos + i] = ReadInt16(&info);
177
#else
178
// This only works as intended on little-endian CPUs.
179
ReadBytes(&info, &classPtr[dataPos + i], sizeof(int16));
180
#endif
181
}
182
}
183
else {
184
info.readPos += count * sizeof(int16);
185
}
186
187
dataPos += sizeof(int16) * count;
188
break;
189
}
190
191
case SVAR_UINT32:
192
case SVAR_INT32: {
193
ALIGN_TO(int32);
194
195
if (info.readPos + (count * sizeof(int32)) <= info.fileSize && &classPtr[dataPos]) {
196
for (int32 i = 0; i < count * sizeof(int32); i += sizeof(int32)) {
197
#if !RETRO_USE_ORIGINAL_CODE
198
*(int32 *)&classPtr[dataPos + i] = ReadInt32(&info, false);
199
#else
200
// This only works as intended on little-endian CPUs.
201
ReadBytes(&info, &classPtr[dataPos + i], sizeof(int32));
202
#endif
203
}
204
}
205
else {
206
info.readPos += count * sizeof(int32);
207
}
208
209
dataPos += sizeof(int32) * count;
210
break;
211
}
212
213
case SVAR_BOOL: {
214
ALIGN_TO(bool32);
215
216
if (info.readPos + (count * sizeof(bool32)) <= info.fileSize && &classPtr[dataPos]) {
217
for (int32 i = 0; i < count * sizeof(bool32); i += sizeof(bool32)) {
218
#if !RETRO_USE_ORIGINAL_CODE
219
*(bool32 *)&classPtr[dataPos + i] = (bool32)ReadInt32(&info, false);
220
#else
221
// This only works as intended on little-endian CPUs.
222
ReadBytes(&info, &classPtr[dataPos + i], sizeof(bool32));
223
#endif
224
}
225
}
226
else {
227
info.readPos += count * sizeof(bool32);
228
}
229
230
dataPos += sizeof(bool32) * count;
231
break;
232
}
233
}
234
}
235
else {
236
switch (type) {
237
case SVAR_UINT8:
238
case SVAR_INT8: dataPos += sizeof(uint8) * arraySize; break;
239
240
case SVAR_UINT16:
241
case SVAR_INT16:
242
ALIGN_TO(int16);
243
244
dataPos += sizeof(int16) * arraySize;
245
break;
246
247
case SVAR_UINT32:
248
case SVAR_INT32:
249
ALIGN_TO(int32);
250
251
dataPos += sizeof(int32) * arraySize;
252
break;
253
254
case SVAR_BOOL:
255
ALIGN_TO(bool32);
256
257
dataPos += sizeof(bool32) * arraySize;
258
break;
259
260
case SVAR_POINTER:
261
ALIGN_TO(void *);
262
263
dataPos += sizeof(void *) * arraySize;
264
break;
265
266
case SVAR_VECTOR2:
267
ALIGN_TO(int32);
268
269
dataPos += sizeof(Vector2) * arraySize;
270
break;
271
272
case SVAR_STRING:
273
ALIGN_TO(void *);
274
275
dataPos += sizeof(String) * arraySize;
276
break;
277
278
case SVAR_ANIMATOR:
279
ALIGN_TO(void *);
280
281
dataPos += sizeof(Animator) * arraySize;
282
break;
283
284
case SVAR_HITBOX:
285
ALIGN_TO(int16);
286
287
dataPos += sizeof(Hitbox) * arraySize;
288
break;
289
290
case SVAR_SPRITEFRAME:
291
ALIGN_TO(int16);
292
293
dataPos += sizeof(GameSpriteFrame) * arraySize;
294
break;
295
296
default:
297
#if !RETRO_USE_ORIGINAL_CODE
298
PrintLog(PRINT_NORMAL, "Invalid data type: %d", type);
299
#endif
300
break;
301
}
302
}
303
}
304
305
CloseFile(&info);
306
}
307
}
308
309
void RSDK::InitObjects()
310
{
311
sceneInfo.entitySlot = 0;
312
sceneInfo.createSlot = ENTITY_COUNT - 0x100;
313
cameraCount = 0;
314
315
for (int32 o = 0; o < sceneInfo.classCount; ++o) {
316
#if RETRO_USE_MOD_LOADER
317
currentObjectID = o;
318
#endif
319
320
if (objectClassList[stageObjectIDs[o]].stageLoad)
321
objectClassList[stageObjectIDs[o]].stageLoad();
322
}
323
324
#if RETRO_USE_MOD_LOADER
325
RunModCallbacks(MODCB_ONSTAGELOAD, NULL);
326
#endif
327
328
for (int32 e = 0; e < ENTITY_COUNT; ++e) {
329
sceneInfo.entitySlot = e;
330
sceneInfo.entity = &objectEntityList[e];
331
332
if (sceneInfo.entity->classID) {
333
if (objectClassList[stageObjectIDs[sceneInfo.entity->classID]].create) {
334
sceneInfo.entity->interaction = true;
335
objectClassList[stageObjectIDs[sceneInfo.entity->classID]].create(NULL);
336
}
337
}
338
}
339
340
sceneInfo.state = ENGINESTATE_REGULAR;
341
342
if (!cameraCount)
343
AddCamera(&screens[0].position, TO_FIXED(screens[0].center.x), TO_FIXED(screens[0].center.y), false);
344
}
345
void RSDK::ProcessObjects()
346
{
347
for (int32 i = 0; i < DRAWGROUP_COUNT; ++i) drawGroups[i].entityCount = 0;
348
349
for (int32 o = 0; o < sceneInfo.classCount; ++o) {
350
#if RETRO_USE_MOD_LOADER
351
currentObjectID = o;
352
#endif
353
354
ObjectClass *classInfo = &objectClassList[stageObjectIDs[o]];
355
if ((*classInfo->staticVars)->active == ACTIVE_ALWAYS || (*classInfo->staticVars)->active == ACTIVE_NORMAL) {
356
if (classInfo->staticUpdate)
357
classInfo->staticUpdate();
358
}
359
}
360
361
#if RETRO_USE_MOD_LOADER
362
RunModCallbacks(MODCB_ONSTATICUPDATE, INT_TO_VOID(ENGINESTATE_REGULAR));
363
#endif
364
365
for (int32 s = 0; s < cameraCount; ++s) {
366
CameraInfo *camera = &cameras[s];
367
368
if (camera->targetPos) {
369
if (camera->worldRelative) {
370
camera->position.x = camera->targetPos->x;
371
camera->position.y = camera->targetPos->y;
372
}
373
else {
374
camera->position.x = TO_FIXED(camera->targetPos->x);
375
camera->position.y = TO_FIXED(camera->targetPos->y);
376
}
377
}
378
}
379
380
sceneInfo.entitySlot = 0;
381
for (int32 e = 0; e < ENTITY_COUNT; ++e) {
382
sceneInfo.entity = &objectEntityList[e];
383
if (sceneInfo.entity->classID) {
384
switch (sceneInfo.entity->active) {
385
default:
386
case ACTIVE_DISABLED: break;
387
388
case ACTIVE_NEVER:
389
case ACTIVE_PAUSED: sceneInfo.entity->inRange = false; break;
390
391
case ACTIVE_ALWAYS:
392
case ACTIVE_NORMAL: sceneInfo.entity->inRange = true; break;
393
394
case ACTIVE_BOUNDS:
395
sceneInfo.entity->inRange = false;
396
397
for (int32 s = 0; s < cameraCount; ++s) {
398
int32 sx = abs(sceneInfo.entity->position.x - cameras[s].position.x);
399
int32 sy = abs(sceneInfo.entity->position.y - cameras[s].position.y);
400
401
if (sx <= sceneInfo.entity->updateRange.x + cameras[s].offset.x
402
&& sy <= sceneInfo.entity->updateRange.y + cameras[s].offset.y) {
403
sceneInfo.entity->inRange = true;
404
break;
405
}
406
}
407
break;
408
409
case ACTIVE_XBOUNDS:
410
sceneInfo.entity->inRange = false;
411
412
for (int32 s = 0; s < cameraCount; ++s) {
413
int32 sx = abs(sceneInfo.entity->position.x - cameras[s].position.x);
414
415
if (sx <= sceneInfo.entity->updateRange.x + cameras[s].offset.x) {
416
sceneInfo.entity->inRange = true;
417
break;
418
}
419
}
420
break;
421
422
case ACTIVE_YBOUNDS:
423
sceneInfo.entity->inRange = false;
424
425
for (int32 s = 0; s < cameraCount; ++s) {
426
int32 sy = abs(sceneInfo.entity->position.y - cameras[s].position.y);
427
428
if (sy <= sceneInfo.entity->updateRange.y + cameras[s].offset.y) {
429
sceneInfo.entity->inRange = true;
430
break;
431
}
432
}
433
break;
434
435
case ACTIVE_RBOUNDS:
436
sceneInfo.entity->inRange = false;
437
438
for (int32 s = 0; s < cameraCount; ++s) {
439
int32 sx = FROM_FIXED(abs(sceneInfo.entity->position.x - cameras[s].position.x));
440
int32 sy = FROM_FIXED(abs(sceneInfo.entity->position.y - cameras[s].position.y));
441
442
if (sx * sx + sy * sy <= sceneInfo.entity->updateRange.x + cameras[s].offset.x) {
443
sceneInfo.entity->inRange = true;
444
break;
445
}
446
}
447
break;
448
}
449
450
if (sceneInfo.entity->inRange) {
451
if (objectClassList[stageObjectIDs[sceneInfo.entity->classID]].update)
452
objectClassList[stageObjectIDs[sceneInfo.entity->classID]].update();
453
454
if (sceneInfo.entity->drawGroup < DRAWGROUP_COUNT)
455
drawGroups[sceneInfo.entity->drawGroup].entries[drawGroups[sceneInfo.entity->drawGroup].entityCount++] = sceneInfo.entitySlot;
456
}
457
}
458
else {
459
sceneInfo.entity->inRange = false;
460
}
461
462
sceneInfo.entitySlot++;
463
}
464
465
#if RETRO_USE_MOD_LOADER
466
RunModCallbacks(MODCB_ONUPDATE, INT_TO_VOID(ENGINESTATE_REGULAR));
467
#endif
468
469
for (int32 i = 0; i < TYPEGROUP_COUNT; ++i) typeGroups[i].entryCount = 0;
470
471
sceneInfo.entitySlot = 0;
472
for (int32 e = 0; e < ENTITY_COUNT; ++e) {
473
sceneInfo.entity = &objectEntityList[e];
474
475
if (sceneInfo.entity->inRange && sceneInfo.entity->interaction) {
476
typeGroups[GROUP_ALL].entries[typeGroups[GROUP_ALL].entryCount++] = e; // All active objects
477
478
typeGroups[sceneInfo.entity->classID].entries[typeGroups[sceneInfo.entity->classID].entryCount++] = e; // class-based groups
479
480
if (sceneInfo.entity->group >= TYPE_COUNT)
481
typeGroups[sceneInfo.entity->group].entries[typeGroups[sceneInfo.entity->group].entryCount++] = e; // extra groups
482
}
483
484
sceneInfo.entitySlot++;
485
}
486
487
sceneInfo.entitySlot = 0;
488
for (int32 e = 0; e < ENTITY_COUNT; ++e) {
489
sceneInfo.entity = &objectEntityList[e];
490
491
if (sceneInfo.entity->inRange) {
492
if (objectClassList[stageObjectIDs[sceneInfo.entity->classID]].lateUpdate)
493
objectClassList[stageObjectIDs[sceneInfo.entity->classID]].lateUpdate();
494
}
495
496
sceneInfo.entity->onScreen = 0;
497
sceneInfo.entitySlot++;
498
}
499
500
#if RETRO_USE_MOD_LOADER
501
RunModCallbacks(MODCB_ONLATEUPDATE, INT_TO_VOID(ENGINESTATE_REGULAR));
502
#endif
503
}
504
void RSDK::ProcessPausedObjects()
505
{
506
for (int32 i = 0; i < DRAWGROUP_COUNT; ++i) drawGroups[i].entityCount = 0;
507
508
for (int32 o = 0; o < sceneInfo.classCount; ++o) {
509
#if RETRO_USE_MOD_LOADER
510
currentObjectID = o;
511
#endif
512
513
ObjectClass *classInfo = &objectClassList[stageObjectIDs[o]];
514
if ((*classInfo->staticVars)->active == ACTIVE_ALWAYS || (*classInfo->staticVars)->active == ACTIVE_PAUSED) {
515
if (classInfo->staticUpdate)
516
classInfo->staticUpdate();
517
}
518
}
519
520
#if RETRO_USE_MOD_LOADER
521
RunModCallbacks(MODCB_ONSTATICUPDATE, INT_TO_VOID(ENGINESTATE_PAUSED));
522
#endif
523
524
sceneInfo.entitySlot = 0;
525
for (int32 e = 0; e < ENTITY_COUNT; ++e) {
526
sceneInfo.entity = &objectEntityList[e];
527
528
if (sceneInfo.entity->classID) {
529
if (sceneInfo.entity->active == ACTIVE_ALWAYS || sceneInfo.entity->active == ACTIVE_PAUSED) {
530
if (objectClassList[stageObjectIDs[sceneInfo.entity->classID]].update)
531
objectClassList[stageObjectIDs[sceneInfo.entity->classID]].update();
532
533
if (sceneInfo.entity->drawGroup < DRAWGROUP_COUNT)
534
drawGroups[sceneInfo.entity->drawGroup].entries[drawGroups[sceneInfo.entity->drawGroup].entityCount++] = sceneInfo.entitySlot;
535
}
536
}
537
else {
538
sceneInfo.entity->inRange = false;
539
}
540
541
sceneInfo.entitySlot++;
542
}
543
544
#if RETRO_USE_MOD_LOADER
545
RunModCallbacks(MODCB_ONUPDATE, INT_TO_VOID(ENGINESTATE_PAUSED));
546
#endif
547
548
sceneInfo.entitySlot = 0;
549
for (int32 e = 0; e < ENTITY_COUNT; ++e) {
550
sceneInfo.entity = &objectEntityList[e];
551
552
if (sceneInfo.entity->active == ACTIVE_ALWAYS || sceneInfo.entity->active == ACTIVE_PAUSED) {
553
if (objectClassList[stageObjectIDs[sceneInfo.entity->classID]].lateUpdate)
554
objectClassList[stageObjectIDs[sceneInfo.entity->classID]].lateUpdate();
555
}
556
557
sceneInfo.entity->onScreen = 0;
558
sceneInfo.entitySlot++;
559
}
560
561
#if RETRO_USE_MOD_LOADER
562
RunModCallbacks(MODCB_ONLATEUPDATE, INT_TO_VOID(ENGINESTATE_PAUSED));
563
#endif
564
}
565
void RSDK::ProcessFrozenObjects()
566
{
567
for (int32 i = 0; i < DRAWGROUP_COUNT; ++i) drawGroups[i].entityCount = 0;
568
569
for (int32 o = 0; o < sceneInfo.classCount; ++o) {
570
#if RETRO_USE_MOD_LOADER
571
currentObjectID = o;
572
#endif
573
574
ObjectClass *classInfo = &objectClassList[stageObjectIDs[o]];
575
if ((*classInfo->staticVars)->active == ACTIVE_ALWAYS || (*classInfo->staticVars)->active == ACTIVE_PAUSED) {
576
if (classInfo->staticUpdate)
577
classInfo->staticUpdate();
578
}
579
}
580
581
#if RETRO_USE_MOD_LOADER
582
RunModCallbacks(MODCB_ONSTATICUPDATE, INT_TO_VOID(ENGINESTATE_FROZEN));
583
#endif
584
585
for (int32 s = 0; s < cameraCount; ++s) {
586
CameraInfo *camera = &cameras[s];
587
588
if (camera->targetPos) {
589
if (camera->worldRelative) {
590
camera->position.x = camera->targetPos->x;
591
camera->position.y = camera->targetPos->y;
592
}
593
else {
594
camera->position.x = TO_FIXED(camera->targetPos->x);
595
camera->position.y = TO_FIXED(camera->targetPos->y);
596
}
597
}
598
}
599
600
sceneInfo.entitySlot = 0;
601
for (int32 e = 0; e < ENTITY_COUNT; ++e) {
602
sceneInfo.entity = &objectEntityList[e];
603
604
if (sceneInfo.entity->classID) {
605
switch (sceneInfo.entity->active) {
606
default:
607
case ACTIVE_DISABLED: break;
608
609
case ACTIVE_NEVER:
610
case ACTIVE_PAUSED: sceneInfo.entity->inRange = false; break;
611
612
case ACTIVE_ALWAYS:
613
case ACTIVE_NORMAL: sceneInfo.entity->inRange = true; break;
614
615
case ACTIVE_BOUNDS:
616
sceneInfo.entity->inRange = false;
617
618
for (int32 s = 0; s < cameraCount; ++s) {
619
int32 sx = abs(sceneInfo.entity->position.x - cameras[s].position.x);
620
int32 sy = abs(sceneInfo.entity->position.y - cameras[s].position.y);
621
622
if (sx <= sceneInfo.entity->updateRange.x + cameras[s].offset.x
623
&& sy <= sceneInfo.entity->updateRange.y + cameras[s].offset.y) {
624
sceneInfo.entity->inRange = true;
625
break;
626
}
627
}
628
break;
629
630
case ACTIVE_XBOUNDS:
631
sceneInfo.entity->inRange = false;
632
633
for (int32 s = 0; s < cameraCount; ++s) {
634
int32 sx = abs(sceneInfo.entity->position.x - cameras[s].position.x);
635
636
if (sx <= sceneInfo.entity->updateRange.x + cameras[s].offset.x) {
637
sceneInfo.entity->inRange = true;
638
break;
639
}
640
}
641
break;
642
643
case ACTIVE_YBOUNDS:
644
sceneInfo.entity->inRange = false;
645
646
for (int32 s = 0; s < cameraCount; ++s) {
647
int32 sy = abs(sceneInfo.entity->position.y - cameras[s].position.y);
648
649
if (sy <= sceneInfo.entity->updateRange.y + cameras[s].offset.y) {
650
sceneInfo.entity->inRange = true;
651
break;
652
}
653
}
654
break;
655
656
case ACTIVE_RBOUNDS:
657
sceneInfo.entity->inRange = false;
658
659
for (int32 s = 0; s < cameraCount; ++s) {
660
int32 sx = FROM_FIXED(abs(sceneInfo.entity->position.x - cameras[s].position.x));
661
int32 sy = FROM_FIXED(abs(sceneInfo.entity->position.y - cameras[s].position.y));
662
663
if (sx * sx + sy * sy <= sceneInfo.entity->updateRange.x + cameras[s].offset.x) {
664
sceneInfo.entity->inRange = true;
665
break;
666
}
667
}
668
break;
669
}
670
671
if (sceneInfo.entity->inRange) {
672
if (sceneInfo.entity->active == ACTIVE_ALWAYS || sceneInfo.entity->active == ACTIVE_PAUSED) {
673
if (objectClassList[stageObjectIDs[sceneInfo.entity->classID]].update)
674
objectClassList[stageObjectIDs[sceneInfo.entity->classID]].update();
675
}
676
677
if (sceneInfo.entity->drawGroup < DRAWGROUP_COUNT)
678
drawGroups[sceneInfo.entity->drawGroup].entries[drawGroups[sceneInfo.entity->drawGroup].entityCount++] = sceneInfo.entitySlot;
679
}
680
}
681
else {
682
sceneInfo.entity->inRange = false;
683
}
684
685
sceneInfo.entitySlot++;
686
}
687
688
#if RETRO_USE_MOD_LOADER
689
RunModCallbacks(MODCB_ONUPDATE, INT_TO_VOID(ENGINESTATE_FROZEN));
690
#endif
691
692
for (int32 i = 0; i < TYPEGROUP_COUNT; ++i) typeGroups[i].entryCount = 0;
693
694
sceneInfo.entitySlot = 0;
695
for (int32 e = 0; e < ENTITY_COUNT; ++e) {
696
sceneInfo.entity = &objectEntityList[e];
697
698
if (sceneInfo.entity->inRange) {
699
if (sceneInfo.entity->active == ACTIVE_ALWAYS || sceneInfo.entity->active == ACTIVE_PAUSED) {
700
if (objectClassList[stageObjectIDs[sceneInfo.entity->classID]].lateUpdate)
701
objectClassList[stageObjectIDs[sceneInfo.entity->classID]].lateUpdate();
702
}
703
704
if (sceneInfo.entity->interaction) {
705
typeGroups[GROUP_ALL].entries[typeGroups[GROUP_ALL].entryCount++] = e; // All active entities
706
707
typeGroups[sceneInfo.entity->classID].entries[typeGroups[sceneInfo.entity->classID].entryCount++] = e; // type-based groups
708
709
if (sceneInfo.entity->group >= TYPE_COUNT)
710
typeGroups[sceneInfo.entity->group].entries[typeGroups[sceneInfo.entity->group].entryCount++] = e; // extra groups
711
}
712
}
713
714
sceneInfo.entity->onScreen = 0;
715
sceneInfo.entitySlot++;
716
}
717
718
#if RETRO_USE_MOD_LOADER
719
RunModCallbacks(MODCB_ONLATEUPDATE, INT_TO_VOID(ENGINESTATE_FROZEN));
720
#endif
721
}
722
void RSDK::ProcessObjectDrawLists()
723
{
724
if (sceneInfo.state != ENGINESTATE_LOAD && sceneInfo.state != (ENGINESTATE_LOAD | ENGINESTATE_STEPOVER)) {
725
for (int32 s = 0; s < videoSettings.screenCount; ++s) {
726
currentScreen = &screens[s];
727
sceneInfo.currentScreenID = s;
728
729
for (int32 l = 0; l < DRAWGROUP_COUNT; ++l) drawGroups[l].layerCount = 0;
730
731
for (int32 t = 0; t < LAYER_COUNT; ++t) {
732
uint8 drawGroup = tileLayers[t].drawGroup[s];
733
734
if (drawGroup < DRAWGROUP_COUNT)
735
drawGroups[drawGroup].layerDrawList[drawGroups[drawGroup].layerCount++] = t;
736
}
737
738
sceneInfo.currentDrawGroup = 0;
739
for (int32 l = 0; l < DRAWGROUP_COUNT; ++l) {
740
if (engine.drawGroupVisible[l]) {
741
DrawList *list = &drawGroups[l];
742
743
if (list->hookCB)
744
list->hookCB();
745
746
if (list->sorted) {
747
for (int32 e = 0; e < list->entityCount; ++e) {
748
for (int32 i = list->entityCount - 1; i > e; --i) {
749
int32 slot1 = list->entries[i - 1];
750
int32 slot2 = list->entries[i];
751
if (objectEntityList[slot2].zdepth > objectEntityList[slot1].zdepth) {
752
list->entries[i - 1] = slot2;
753
list->entries[i] = slot1;
754
}
755
}
756
}
757
}
758
759
for (int32 i = 0; i < list->entityCount; ++i) {
760
sceneInfo.entitySlot = list->entries[i];
761
validDraw = false;
762
sceneInfo.entity = &objectEntityList[list->entries[i]];
763
if (sceneInfo.entity->visible) {
764
if (objectClassList[stageObjectIDs[sceneInfo.entity->classID]].draw)
765
objectClassList[stageObjectIDs[sceneInfo.entity->classID]].draw();
766
767
#if RETRO_VER_EGS || RETRO_USE_DUMMY_ACHIEVEMENTS
768
if (i == list->entityCount - 1)
769
SKU::DrawAchievements();
770
#endif
771
772
sceneInfo.entity->onScreen |= validDraw << sceneInfo.currentScreenID;
773
}
774
}
775
776
for (int32 i = 0; i < list->layerCount; ++i) {
777
TileLayer *layer = &tileLayers[list->layerDrawList[i]];
778
779
#if RETRO_USE_MOD_LOADER
780
RunModCallbacks(MODCB_ONSCANLINECB, (void *)layer->scanlineCallback);
781
#endif
782
if (layer->scanlineCallback)
783
layer->scanlineCallback(scanlines);
784
else
785
ProcessParallax(layer);
786
787
switch (layer->type) {
788
case LAYER_HSCROLL: DrawLayerHScroll(layer); break;
789
case LAYER_VSCROLL: DrawLayerVScroll(layer); break;
790
case LAYER_ROTOZOOM: DrawLayerRotozoom(layer); break;
791
case LAYER_BASIC: DrawLayerBasic(layer); break;
792
default: break;
793
}
794
}
795
796
#if RETRO_USE_MOD_LOADER
797
RunModCallbacks(MODCB_ONDRAW, INT_TO_VOID(l));
798
#endif
799
800
if (currentScreen->clipBound_X1 > 0)
801
currentScreen->clipBound_X1 = 0;
802
803
if (currentScreen->clipBound_Y1 > 0)
804
currentScreen->clipBound_Y1 = 0;
805
806
if (currentScreen->size.x >= 0) {
807
if (currentScreen->clipBound_X2 < currentScreen->size.x)
808
currentScreen->clipBound_X2 = currentScreen->size.x;
809
}
810
else {
811
currentScreen->clipBound_X2 = 0;
812
}
813
814
if (currentScreen->size.y >= 0) {
815
if (currentScreen->clipBound_Y2 < currentScreen->size.y)
816
currentScreen->clipBound_Y2 = currentScreen->size.y;
817
}
818
else {
819
currentScreen->clipBound_Y2 = 0;
820
}
821
}
822
823
sceneInfo.currentDrawGroup++;
824
}
825
826
#if !RETRO_USE_ORIGINAL_CODE
827
if (engine.showUpdateRanges) {
828
for (int32 l = 0; l < DRAWGROUP_COUNT; ++l) {
829
if (engine.drawGroupVisible[l]) {
830
DrawList *list = &drawGroups[l];
831
for (int32 i = 0; i < list->entityCount; ++i) {
832
Entity *entity = &objectEntityList[list->entries[i]];
833
834
if (entity->visible || (engine.showUpdateRanges & 2)) {
835
switch (entity->active) {
836
default:
837
case ACTIVE_DISABLED:
838
case ACTIVE_NEVER: break;
839
840
case ACTIVE_ALWAYS:
841
case ACTIVE_NORMAL:
842
case ACTIVE_PAUSED:
843
DrawRectangle(entity->position.x, entity->position.y, TO_FIXED(1), TO_FIXED(1), 0x0000FF, 0xFF, INK_NONE,
844
false);
845
break;
846
847
case ACTIVE_BOUNDS:
848
DrawLine(entity->position.x - entity->updateRange.x, entity->position.y - entity->updateRange.y,
849
entity->position.x + entity->updateRange.x, entity->position.y - entity->updateRange.y, 0x0000FF,
850
0xFF, INK_NONE, false);
851
852
DrawLine(entity->position.x - entity->updateRange.x, entity->position.y + entity->updateRange.y,
853
entity->position.x + entity->updateRange.x, entity->position.y + entity->updateRange.y, 0x0000FF,
854
0xFF, INK_NONE, false);
855
856
DrawLine(entity->position.x - entity->updateRange.x, entity->position.y - entity->updateRange.y,
857
entity->position.x - entity->updateRange.x, entity->position.y + entity->updateRange.y, 0x0000FF,
858
0xFF, INK_NONE, false);
859
860
DrawLine(entity->position.x + entity->updateRange.x, entity->position.y - entity->updateRange.y,
861
entity->position.x + entity->updateRange.x, entity->position.y + entity->updateRange.y, 0x0000FF,
862
0xFF, INK_NONE, false);
863
break;
864
865
case ACTIVE_XBOUNDS:
866
DrawLine(entity->position.x - entity->updateRange.x, TO_FIXED(currentScreen->position.y),
867
entity->position.x - entity->updateRange.x,
868
TO_FIXED(currentScreen->position.y + currentScreen->size.y), 0x0000FF, 0xFF, INK_NONE, false);
869
870
DrawLine(entity->position.x + entity->updateRange.x, TO_FIXED(currentScreen->position.y),
871
entity->position.x + entity->updateRange.x,
872
TO_FIXED(currentScreen->position.y + currentScreen->size.y), 0x0000FF, 0xFF, INK_NONE, false);
873
break;
874
875
case ACTIVE_YBOUNDS:
876
DrawLine(TO_FIXED(currentScreen->position.x), entity->position.y - entity->updateRange.y,
877
TO_FIXED(currentScreen->position.x + currentScreen->size.x),
878
entity->position.y - entity->updateRange.y, 0x0000FF, 0xFF, INK_NONE, false);
879
880
DrawLine(TO_FIXED(currentScreen->position.x), entity->position.y + entity->updateRange.y,
881
TO_FIXED(currentScreen->position.x + currentScreen->size.x),
882
entity->position.y + entity->updateRange.y, 0x0000FF, 0xFF, INK_NONE, false);
883
break;
884
885
case ACTIVE_RBOUNDS:
886
DrawCircleOutline(entity->position.x, entity->position.y, FROM_FIXED(entity->updateRange.x),
887
FROM_FIXED(entity->updateRange.x) + 1, 0x0000FF, 0xFF, INK_NONE, false);
888
break;
889
}
890
}
891
}
892
}
893
}
894
}
895
896
if (engine.showEntityInfo) {
897
for (int32 l = 0; l < DRAWGROUP_COUNT; ++l) {
898
if (engine.drawGroupVisible[l]) {
899
DrawList *list = &drawGroups[l];
900
for (int32 i = 0; i < list->entityCount; ++i) {
901
Entity *entity = &objectEntityList[list->entries[i]];
902
903
if (entity->visible || (engine.showEntityInfo & 2)) {
904
char buffer[0x100];
905
sprintf_s(buffer, sizeof(buffer), "%s\nx: %g\ny: %g", objectClassList[stageObjectIDs[entity->classID]].name,
906
entity->position.x / 65536.0f, entity->position.y / 65536.0f);
907
908
DrawDevString(buffer, FROM_FIXED(entity->position.x) - currentScreen->position.x,
909
FROM_FIXED(entity->position.y) - currentScreen->position.y, ALIGN_LEFT, 0xF0F0F0);
910
}
911
}
912
}
913
}
914
}
915
916
if (showHitboxes) {
917
for (int32 i = 0; i < debugHitboxCount; ++i) {
918
DebugHitboxInfo *info = &debugHitboxList[i];
919
int32 x = info->pos.x + TO_FIXED(info->hitbox.left);
920
int32 y = info->pos.y + TO_FIXED(info->hitbox.top);
921
int32 w = abs((info->pos.x + TO_FIXED(info->hitbox.right)) - x);
922
int32 h = abs((info->pos.y + TO_FIXED(info->hitbox.bottom)) - y);
923
924
switch (info->type) {
925
case H_TYPE_TOUCH: DrawRectangle(x, y, w, h, info->collision ? 0x808000 : 0xFF0000, 0x60, INK_ALPHA, false); break;
926
927
case H_TYPE_CIRCLE:
928
DrawCircle(info->pos.x, info->pos.y, info->hitbox.left, info->collision ? 0x808000 : 0xFF0000, 0x60, INK_ALPHA, false);
929
break;
930
931
case H_TYPE_BOX:
932
DrawRectangle(x, y, w, h, 0x0000FF, 0x60, INK_ALPHA, false);
933
934
if (info->collision & 1) // top
935
DrawRectangle(x, y, w, TO_FIXED(1), 0xFFFF00, 0xC0, INK_ALPHA, false);
936
937
if (info->collision & 8) // bottom
938
DrawRectangle(x, y + h, w, TO_FIXED(1), 0xFFFF00, 0xC0, INK_ALPHA, false);
939
940
if (info->collision & 2) { // left
941
int32 sy = y;
942
int32 sh = h;
943
944
if (info->collision & 1) {
945
sy += TO_FIXED(1);
946
sh -= TO_FIXED(1);
947
}
948
949
if (info->collision & 8)
950
sh -= TO_FIXED(1);
951
952
DrawRectangle(x, sy, TO_FIXED(1), sh, 0xFFFF00, 0xC0, INK_ALPHA, false);
953
}
954
955
if (info->collision & 4) { // right
956
int32 sy = y;
957
int32 sh = h;
958
959
if (info->collision & 1) {
960
sy += TO_FIXED(1);
961
sh -= TO_FIXED(1);
962
}
963
964
if (info->collision & 8)
965
sh -= TO_FIXED(1);
966
967
DrawRectangle(x + w, sy, TO_FIXED(1), sh, 0xFFFF00, 0xC0, INK_ALPHA, false);
968
}
969
break;
970
971
case H_TYPE_PLAT:
972
DrawRectangle(x, y, w, h, 0x00FF00, 0x60, INK_ALPHA, false);
973
974
if (info->collision & 1) // top
975
DrawRectangle(x, y, w, TO_FIXED(1), 0xFFFF00, 0xC0, INK_ALPHA, false);
976
977
if (info->collision & 8) // bottom
978
DrawRectangle(x, y + h, w, TO_FIXED(1), 0xFFFF00, 0xC0, INK_ALPHA, false);
979
break;
980
}
981
}
982
}
983
984
if (engine.showPaletteOverlay) {
985
for (int32 p = 0; p < PALETTE_BANK_COUNT; ++p) {
986
int32 x = (videoSettings.pixWidth - (0x10 << 3));
987
int32 y = (SCREEN_YSIZE - (0x10 << 2));
988
989
for (int32 c = 0; c < PALETTE_BANK_SIZE; ++c) {
990
uint32 clr = GetPaletteEntry(p, c);
991
992
DrawRectangle(x + ((c & 0xF) << 1) + ((p % (PALETTE_BANK_COUNT / 2)) * (2 * 16)),
993
y + ((c >> 4) << 1) + ((p / (PALETTE_BANK_COUNT / 2)) * (2 * 16)), 2, 2, clr, 0xFF, INK_NONE, true);
994
}
995
}
996
}
997
998
#endif
999
1000
currentScreen++;
1001
sceneInfo.currentScreenID++;
1002
}
1003
}
1004
}
1005
1006
uint16 RSDK::FindObject(const char *name)
1007
{
1008
RETRO_HASH_MD5(hash);
1009
GEN_HASH_MD5(name, hash);
1010
1011
for (int32 o = 0; o < sceneInfo.classCount; ++o) {
1012
if (HASH_MATCH_MD5(hash, objectClassList[stageObjectIDs[o]].hash))
1013
return o;
1014
}
1015
1016
return TYPE_DEFAULTOBJECT;
1017
}
1018
1019
int32 RSDK::GetEntityCount(uint16 classID, bool32 isActive)
1020
{
1021
if (classID >= TYPE_COUNT)
1022
return 0;
1023
if (isActive)
1024
return typeGroups[classID].entryCount;
1025
1026
int32 entityCount = 0;
1027
for (int32 i = 0; i < ENTITY_COUNT; ++i) {
1028
if (objectEntityList[i].classID == classID)
1029
entityCount++;
1030
}
1031
1032
return entityCount;
1033
}
1034
1035
void RSDK::ResetEntity(Entity *entity, uint16 classID, void *data)
1036
{
1037
if (entity) {
1038
ObjectClass *info = &objectClassList[stageObjectIDs[classID]];
1039
memset(entity, 0, info->entityClassSize);
1040
1041
if (info->create) {
1042
Entity *curEnt = sceneInfo.entity;
1043
1044
sceneInfo.entity = entity;
1045
sceneInfo.entity->interaction = true;
1046
#if RETRO_USE_MOD_LOADER
1047
int32 superStore = superLevels[inheritLevel];
1048
superLevels[inheritLevel] = 0;
1049
#endif
1050
info->create(data);
1051
#if RETRO_USE_MOD_LOADER
1052
superLevels[inheritLevel] = superStore;
1053
#endif
1054
sceneInfo.entity->classID = classID;
1055
1056
sceneInfo.entity = curEnt;
1057
}
1058
1059
entity->classID = classID;
1060
}
1061
}
1062
1063
void RSDK::ResetEntitySlot(uint16 slot, uint16 classID, void *data)
1064
{
1065
ObjectClass *object = &objectClassList[stageObjectIDs[classID]];
1066
slot = slot < ENTITY_COUNT ? slot : (ENTITY_COUNT - 1);
1067
1068
Entity *entity = &objectEntityList[slot];
1069
memset(&objectEntityList[slot], 0, object->entityClassSize);
1070
1071
if (object->create) {
1072
Entity *curEnt = sceneInfo.entity;
1073
1074
sceneInfo.entity = entity;
1075
entity->interaction = true;
1076
#if RETRO_USE_MOD_LOADER
1077
int32 superStore = superLevels[inheritLevel];
1078
superLevels[inheritLevel] = 0;
1079
#endif
1080
object->create(data);
1081
#if RETRO_USE_MOD_LOADER
1082
superLevels[inheritLevel] = superStore;
1083
#endif
1084
entity->classID = classID;
1085
1086
sceneInfo.entity = curEnt;
1087
}
1088
else {
1089
entity->classID = classID;
1090
}
1091
}
1092
1093
Entity *RSDK::CreateEntity(uint16 classID, void *data, int32 x, int32 y)
1094
{
1095
ObjectClass *object = &objectClassList[stageObjectIDs[classID]];
1096
Entity *entity = &objectEntityList[sceneInfo.createSlot];
1097
1098
int32 permCnt = 0, loopCnt = 0;
1099
while (entity->classID) {
1100
// after 16 loops, the game says fuck it and will start overwriting non-temp objects
1101
if (!entity->isPermanent && loopCnt >= 16)
1102
break;
1103
1104
if (entity->isPermanent)
1105
++permCnt;
1106
1107
sceneInfo.createSlot++;
1108
if (sceneInfo.createSlot == ENTITY_COUNT) {
1109
sceneInfo.createSlot = TEMPENTITY_START;
1110
entity = &objectEntityList[sceneInfo.createSlot];
1111
}
1112
else {
1113
entity = &objectEntityList[sceneInfo.createSlot];
1114
}
1115
1116
if (permCnt >= TEMPENTITY_COUNT)
1117
break;
1118
1119
++loopCnt;
1120
}
1121
1122
memset(entity, 0, object->entityClassSize);
1123
entity->position.x = x;
1124
entity->position.y = y;
1125
entity->interaction = true;
1126
1127
if (object->create) {
1128
Entity *curEnt = sceneInfo.entity;
1129
1130
sceneInfo.entity = entity;
1131
#if RETRO_USE_MOD_LOADER
1132
int32 superStore = superLevels[inheritLevel];
1133
superLevels[inheritLevel] = 0;
1134
#endif
1135
object->create(data);
1136
#if RETRO_USE_MOD_LOADER
1137
superLevels[inheritLevel] = superStore;
1138
#endif
1139
entity->classID = classID;
1140
1141
sceneInfo.entity = curEnt;
1142
}
1143
else {
1144
entity->classID = classID;
1145
entity->active = ACTIVE_NORMAL;
1146
entity->visible = true;
1147
}
1148
1149
return entity;
1150
}
1151
1152
bool32 RSDK::GetActiveEntities(uint16 group, Entity **entity)
1153
{
1154
if (group >= TYPEGROUP_COUNT)
1155
return false;
1156
1157
if (!entity)
1158
return false;
1159
1160
if (*entity) {
1161
++foreachStackPtr->id;
1162
}
1163
else {
1164
foreachStackPtr++;
1165
foreachStackPtr->id = 0;
1166
}
1167
1168
for (Entity *nextEntity = &objectEntityList[typeGroups[group].entries[foreachStackPtr->id]]; foreachStackPtr->id < typeGroups[group].entryCount;
1169
++foreachStackPtr->id, nextEntity = &objectEntityList[typeGroups[group].entries[foreachStackPtr->id]]) {
1170
if (nextEntity->classID == group) {
1171
*entity = nextEntity;
1172
return true;
1173
}
1174
}
1175
1176
foreachStackPtr--;
1177
1178
return false;
1179
}
1180
bool32 RSDK::GetAllEntities(uint16 classID, Entity **entity)
1181
{
1182
if (classID >= OBJECT_COUNT)
1183
return false;
1184
1185
if (!entity)
1186
return false;
1187
1188
if (*entity) {
1189
++foreachStackPtr->id;
1190
}
1191
else {
1192
foreachStackPtr++;
1193
foreachStackPtr->id = 0;
1194
}
1195
1196
for (; foreachStackPtr->id < ENTITY_COUNT; ++foreachStackPtr->id) {
1197
Entity *nextEntity = &objectEntityList[foreachStackPtr->id];
1198
if (nextEntity->classID == classID) {
1199
*entity = nextEntity;
1200
return true;
1201
}
1202
}
1203
1204
foreachStackPtr--;
1205
1206
return false;
1207
}
1208
1209
bool32 RSDK::CheckOnScreen(Entity *entity, Vector2 *range)
1210
{
1211
if (!entity)
1212
return false;
1213
1214
if (!range)
1215
range = &entity->updateRange;
1216
1217
return CheckPosOnScreen(&entity->position, range);
1218
}
1219
bool32 RSDK::CheckPosOnScreen(Vector2 *position, Vector2 *range)
1220
{
1221
if (!position || !range)
1222
return false;
1223
1224
for (int32 s = 0; s < cameraCount; ++s) {
1225
int32 sx = abs(position->x - cameras[s].position.x);
1226
int32 sy = abs(position->y - cameras[s].position.y);
1227
1228
if (sx <= range->x + cameras[s].offset.x && sy <= range->y + cameras[s].offset.y)
1229
return true;
1230
}
1231
1232
return false;
1233
}
1234
1235
void RSDK::ClearStageObjects()
1236
{
1237
// Unload static object classes
1238
for (int32 o = 0; o < sceneInfo.classCount; ++o) {
1239
if (objectClassList[stageObjectIDs[o]].staticVars) {
1240
*objectClassList[stageObjectIDs[o]].staticVars = NULL;
1241
}
1242
}
1243
}
1244
1245