Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Rubberduckycooly
GitHub Repository: Rubberduckycooly/RSDKv5-Decompilation
Path: blob/master/RSDKv5/RSDK/Scene/Object.hpp
1163 views
1
#ifndef OBJECT_H
2
#define OBJECT_H
3
4
#if RETRO_USE_MOD_LOADER
5
#include <functional>
6
#endif
7
8
namespace RSDK
9
{
10
11
#define RSDK_SIGNATURE_OBJ (0x4A424F) // "OBJ"
12
13
#define OBJECT_COUNT (0x400)
14
15
// 0x800 scene objects, 0x40 reserved ones, and 0x100 spare slots for creation
16
#define RESERVE_ENTITY_COUNT (0x40)
17
#define TEMPENTITY_COUNT (0x100)
18
#define SCENEENTITY_COUNT (0x800)
19
#define ENTITY_COUNT (RESERVE_ENTITY_COUNT + SCENEENTITY_COUNT + TEMPENTITY_COUNT)
20
#define TEMPENTITY_START (ENTITY_COUNT - TEMPENTITY_COUNT)
21
22
#define TYPE_COUNT (0x100)
23
#define EDITABLEVAR_COUNT (0x100)
24
#define TYPEGROUP_COUNT (0x104)
25
26
#define FOREACH_STACK_COUNT (0x400)
27
28
// Used for DefaultObject & DevOutput
29
#define RSDK_THIS(class) Entity##class *self = (Entity##class *)sceneInfo.entity
30
31
enum StaticVariableTypes {
32
SVAR_UINT8,
33
SVAR_UINT16,
34
SVAR_UINT32,
35
SVAR_INT8,
36
SVAR_INT16,
37
SVAR_INT32,
38
SVAR_BOOL,
39
SVAR_POINTER,
40
SVAR_VECTOR2,
41
SVAR_STRING,
42
SVAR_ANIMATOR,
43
SVAR_HITBOX,
44
SVAR_SPRITEFRAME,
45
};
46
47
enum TypeGroups {
48
GROUP_ALL = 0,
49
50
GROUP_CUSTOM0 = TYPE_COUNT,
51
GROUP_CUSTOM1,
52
GROUP_CUSTOM2,
53
GROUP_CUSTOM3,
54
};
55
56
enum VariableTypes {
57
VAR_UINT8,
58
VAR_UINT16,
59
VAR_UINT32,
60
VAR_INT8,
61
VAR_INT16,
62
VAR_INT32,
63
VAR_ENUM,
64
VAR_BOOL,
65
VAR_STRING,
66
VAR_VECTOR2,
67
VAR_FLOAT, // Not actually used in Sonic Mania so it's just an assumption, but this is the only thing that'd fit the 32 bit limit and make sense
68
VAR_COLOR,
69
};
70
71
enum ActiveFlags {
72
ACTIVE_NEVER, // never update
73
ACTIVE_ALWAYS, // always update (even if paused/frozen)
74
ACTIVE_NORMAL, // always update (unless paused/frozen)
75
ACTIVE_PAUSED, // update only when paused/frozen
76
ACTIVE_BOUNDS, // update if in x & y bounds
77
ACTIVE_XBOUNDS, // update only if in x bounds (y bounds dont matter)
78
ACTIVE_YBOUNDS, // update only if in y bounds (x bounds dont matter)
79
ACTIVE_RBOUNDS, // update based on radius boundaries (updateRange.x == radius)
80
81
// Not really even a real active value, but some objects set their active states to this so here it is I suppose
82
ACTIVE_DISABLED = 0xFF,
83
};
84
85
enum DefaultObjects {
86
TYPE_DEFAULTOBJECT = 0,
87
#if RETRO_REV02
88
TYPE_DEVOUTPUT,
89
#endif
90
91
TYPE_DEFAULT_COUNT, // max
92
};
93
94
struct Object {
95
int16 classID;
96
uint8 active;
97
};
98
99
struct Entity {
100
#if RETRO_REV0U
101
// used for languages such as beeflang that always have vfTables in classes
102
void *vfTable;
103
#endif
104
Vector2 position;
105
Vector2 scale;
106
Vector2 velocity;
107
Vector2 updateRange;
108
int32 angle;
109
int32 alpha;
110
int32 rotation;
111
int32 groundVel;
112
int32 zdepth;
113
uint16 group;
114
uint16 classID;
115
bool32 inRange;
116
bool32 isPermanent;
117
bool32 tileCollisions;
118
bool32 interaction;
119
bool32 onGround;
120
uint8 active;
121
#if RETRO_REV02
122
uint8 filter;
123
#endif
124
uint8 direction;
125
uint8 drawGroup;
126
uint8 collisionLayers;
127
uint8 collisionPlane;
128
uint8 collisionMode;
129
uint8 drawFX;
130
uint8 inkEffect;
131
uint8 visible;
132
uint8 onScreen;
133
};
134
135
struct EntityBase : Entity {
136
void *data[0x100];
137
#if RETRO_REV0U
138
void *unknown;
139
#endif
140
};
141
142
struct ObjectClass {
143
RETRO_HASH_MD5(hash);
144
145
// Events
146
#if RETRO_USE_MOD_LOADER // using std::function makes it easier to use stuff like lambdas
147
std::function<void()> update;
148
std::function<void()> lateUpdate;
149
std::function<void()> staticUpdate;
150
std::function<void()> draw;
151
std::function<void(void *)> create;
152
std::function<void()> stageLoad;
153
std::function<void()> editorLoad;
154
std::function<void()> editorDraw;
155
std::function<void()> serialize;
156
#if RETRO_REV0U
157
std::function<void(Object *)> staticLoad;
158
#endif
159
#else
160
void (*update)();
161
void (*lateUpdate)();
162
void (*staticUpdate)();
163
void (*draw)();
164
void (*create)(void *);
165
void (*stageLoad)();
166
void (*editorLoad)();
167
void (*editorDraw)();
168
void (*serialize)();
169
#if RETRO_REV0U
170
void (*staticLoad)(Object *);
171
#endif
172
#endif
173
174
// Classes
175
Object **staticVars;
176
int32 entityClassSize;
177
int32 staticClassSize;
178
179
#if RETRO_USE_MOD_LOADER
180
ObjectClass *inherited;
181
#endif
182
183
#if !RETRO_USE_ORIGINAL_CODE
184
const char *name; // for debugging purposes
185
#endif
186
};
187
188
struct EditableVarInfo {
189
RETRO_HASH_MD5(hash);
190
int32 offset;
191
int32 active;
192
uint8 type;
193
};
194
195
struct ForeachStackInfo {
196
int32 id;
197
};
198
199
struct TypeGroupList {
200
uint16 entries[ENTITY_COUNT];
201
int32 entryCount;
202
};
203
204
extern ObjectClass objectClassList[OBJECT_COUNT];
205
extern int32 objectClassCount;
206
207
// Loaded Global Objects
208
extern int32 globalObjectCount;
209
extern int32 globalObjectIDs[OBJECT_COUNT];
210
211
// Loaded Stage Objects (includes Globals if "loadGlobals" is enabled)
212
extern int32 stageObjectIDs[OBJECT_COUNT];
213
214
extern EntityBase objectEntityList[ENTITY_COUNT];
215
216
extern EditableVarInfo *editableVarList;
217
extern int32 editableVarCount;
218
219
extern ForeachStackInfo foreachStackList[FOREACH_STACK_COUNT];
220
extern ForeachStackInfo *foreachStackPtr;
221
222
extern TypeGroupList typeGroups[TYPEGROUP_COUNT];
223
224
extern bool32 validDraw;
225
226
#if RETRO_REV0U
227
void RegisterObject(Object **staticVars, const char *name, uint32 entityClassSize, uint32 staticClassSize, void (*update)(), void (*lateUpdate)(),
228
void (*staticUpdate)(), void (*draw)(), void (*create)(void *), void (*stageLoad)(), void (*editorLoad)(), void (*editorDraw)(),
229
void (*serialize)(), void (*staticLoad)(Object *));
230
231
#if RETRO_USE_MOD_LOADER
232
void RegisterObject_STD(Object **staticVars, const char *name, uint32 entityClassSize, uint32 staticClassSize, std::function<void()> update,
233
std::function<void()> lateUpdate, std::function<void()> staticUpdate, std::function<void()> draw,
234
std::function<void(void *)> create, std::function<void()> stageLoad, std::function<void()> editorLoad,
235
std::function<void()> editorDraw, std::function<void()> serialize, std::function<void(Object *)> staticLoad);
236
#endif
237
#else
238
void RegisterObject(Object **staticVars, const char *name, uint32 entityClassSize, uint32 staticClassSize, void (*update)(), void (*lateUpdate)(),
239
void (*staticUpdate)(), void (*draw)(), void (*create)(void *), void (*stageLoad)(), void (*editorLoad)(), void (*editorDraw)(),
240
void (*serialize)());
241
242
#if RETRO_USE_MOD_LOADER
243
void RegisterObject_STD(Object **staticVars, const char *name, uint32 entityClassSize, uint32 staticClassSize, std::function<void()> update,
244
std::function<void()> lateUpdate, std::function<void()> staticUpdate, std::function<void()> draw,
245
std::function<void(void *)> create, std::function<void()> stageLoad, std::function<void()> editorLoad,
246
std::function<void()> editorDraw, std::function<void()> serialize);
247
#endif
248
#endif
249
250
#if RETRO_REV02 || RETRO_USE_MOD_LOADER
251
void RegisterStaticVariables(void **varClass, const char *name, uint32 classSize);
252
#endif
253
254
void LoadStaticVariables(uint8 *classPtr, uint32 *hash, int32 readOffset);
255
256
#define RSDK_EDITABLE_VAR(object, type, var) RSDK.SetEditableVar(type, #var, (uint8)object->classID, offsetof(Entity##object, var))
257
258
// Bug Details(?):
259
// classID isn't used AND is a uint8, how strange
260
// assuming classID would be used in-editor (it is in RetroED2, but not sure about official RSDK SDK)
261
// not sure why it's a uint8, given the original value is a uint16, so there's some small warnings about that
262
inline void SetEditableVar(uint8 type, const char *name, uint8 classID, int32 offset)
263
{
264
if (editableVarCount < EDITABLEVAR_COUNT - 1) {
265
EditableVarInfo *var = &editableVarList[editableVarCount];
266
267
GEN_HASH_MD5(name, var->hash);
268
var->type = type;
269
var->offset = offset;
270
var->active = true;
271
272
editableVarCount++;
273
}
274
}
275
276
inline void SetActiveVariable(int32 classID, const char *name)
277
{
278
// Editor-Only function
279
}
280
inline void AddEnumVariable(const char *name)
281
{
282
// Editor-Only function
283
}
284
285
void InitObjects();
286
void ProcessObjects();
287
void ProcessPausedObjects();
288
void ProcessFrozenObjects();
289
void ProcessObjectDrawLists();
290
291
uint16 FindObject(const char *name);
292
293
inline Entity *GetEntity(uint16 slot) { return &objectEntityList[slot < ENTITY_COUNT ? slot : (ENTITY_COUNT - 1)]; }
294
inline int32 GetEntitySlot(EntityBase *entity) { return (int32)((uint32)(entity - objectEntityList) < ENTITY_COUNT ? entity - objectEntityList : 0); }
295
int32 GetEntityCount(uint16 classID, bool32 isActive);
296
297
void ResetEntity(Entity *entity, uint16 classID, void *data);
298
void ResetEntitySlot(uint16 slot, uint16 classID, void *data);
299
Entity *CreateEntity(uint16 classID, void *data, int32 x, int32 y);
300
301
inline void CopyEntity(void *destEntity, void *srcEntity, bool32 clearSrcEntity)
302
{
303
if (destEntity && srcEntity) {
304
memcpy(destEntity, srcEntity, sizeof(EntityBase));
305
306
if (clearSrcEntity)
307
memset(srcEntity, 0, sizeof(EntityBase));
308
}
309
}
310
311
bool32 GetActiveEntities(uint16 group, Entity **entity);
312
bool32 GetAllEntities(uint16 classID, Entity **entity);
313
314
inline void BreakForeachLoop() { --foreachStackPtr; }
315
316
// CheckPosOnScreen but if range is NULL it'll use entity->updateRange
317
bool32 CheckOnScreen(Entity *entity, Vector2 *range);
318
// Checks if a position is on screen & within range
319
bool32 CheckPosOnScreen(Vector2 *position, Vector2 *range);
320
321
void ClearStageObjects();
322
323
#if RETRO_REV0U
324
#include "Legacy/ObjectLegacy.hpp"
325
#endif
326
327
} // namespace RSDK
328
329
#endif // !OBJECT_H
330
331