Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Rubberduckycooly
GitHub Repository: Rubberduckycooly/RSDKv5-Decompilation
Path: blob/master/RSDKv5/RSDK/Scene/Scene.hpp
1167 views
1
#ifndef SCENE_H
2
#define SCENE_H
3
4
namespace RSDK
5
{
6
7
#define TILE_COUNT (0x400)
8
#define TILE_SIZE (0x10)
9
#define TILE_DATASIZE (TILE_SIZE * TILE_SIZE)
10
#define TILESET_SIZE (TILE_COUNT * TILE_DATASIZE)
11
12
#define CPATH_COUNT (2)
13
14
#define RSDK_SIGNATURE_CFG (0x474643) // "CFG"
15
#define RSDK_SIGNATURE_SCN (0x4E4353) // "SCN"
16
#define RSDK_SIGNATURE_TIL (0x4C4954) // "TIL"
17
18
enum LayerTypes {
19
LAYER_HSCROLL,
20
LAYER_VSCROLL,
21
LAYER_ROTOZOOM,
22
LAYER_BASIC,
23
};
24
25
struct SceneListInfo {
26
RETRO_HASH_MD5(hash);
27
char name[0x20];
28
uint16 sceneOffsetStart;
29
uint16 sceneOffsetEnd;
30
uint8 sceneCount;
31
};
32
33
struct SceneListEntry {
34
RETRO_HASH_MD5(hash);
35
char name[0x20];
36
char folder[0x10];
37
char id[0x08];
38
#if RETRO_REV02
39
uint8 filter;
40
#endif
41
};
42
43
enum CollisionModes {
44
CMODE_FLOOR,
45
CMODE_LWALL,
46
CMODE_ROOF,
47
CMODE_RWALL,
48
};
49
50
enum EngineStates {
51
ENGINESTATE_LOAD,
52
ENGINESTATE_REGULAR,
53
ENGINESTATE_PAUSED,
54
ENGINESTATE_FROZEN,
55
ENGINESTATE_STEPOVER = 4,
56
ENGINESTATE_DEVMENU = 8,
57
ENGINESTATE_VIDEOPLAYBACK,
58
ENGINESTATE_SHOWIMAGE,
59
#if RETRO_REV02
60
ENGINESTATE_ERRORMSG,
61
ENGINESTATE_ERRORMSG_FATAL,
62
#endif
63
ENGINESTATE_NONE,
64
#if RETRO_REV0U
65
// Prolly origins-only, called by the ending so I assume this handles playing ending movies and returning to menu
66
ENGINESTATE_GAME_FINISHED,
67
#endif
68
};
69
70
struct SceneInfo {
71
Entity *entity;
72
SceneListEntry *listData;
73
SceneListInfo *listCategory;
74
int32 timeCounter;
75
int32 currentDrawGroup;
76
int32 currentScreenID;
77
uint16 listPos;
78
uint16 entitySlot;
79
uint16 createSlot;
80
uint16 classCount;
81
bool32 inEditor;
82
bool32 effectGizmo;
83
bool32 debugMode;
84
bool32 useGlobalObjects;
85
bool32 timeEnabled;
86
uint8 activeCategory;
87
uint8 categoryCount;
88
uint8 state;
89
#if RETRO_REV02
90
uint8 filter;
91
#endif
92
uint8 milliseconds;
93
uint8 seconds;
94
uint8 minutes;
95
};
96
97
struct ScrollInfo {
98
int32 tilePos;
99
int32 parallaxFactor;
100
int32 scrollSpeed;
101
int32 scrollPos;
102
uint8 deform;
103
uint8 unknown; // stored in the scene, but always 0, never referenced in-engine either...
104
};
105
106
struct ScanlineInfo {
107
Vector2 position; // position of the scanline
108
Vector2 deform; // deformation that should be applied (only applies to RotoZoom type)
109
};
110
111
struct TileLayer {
112
uint8 type;
113
uint8 drawGroup[CAMERA_COUNT];
114
uint8 widthShift;
115
uint8 heightShift;
116
uint16 xsize;
117
uint16 ysize;
118
Vector2 position;
119
int32 parallaxFactor;
120
int32 scrollSpeed;
121
int32 scrollPos;
122
int32 deformationOffset;
123
int32 deformationOffsetW;
124
int32 deformationData[0x400];
125
int32 deformationDataW[0x400];
126
void (*scanlineCallback)(ScanlineInfo *scanlines);
127
uint16 scrollInfoCount;
128
ScrollInfo scrollInfo[0x100];
129
RETRO_HASH_MD5(name);
130
uint16 *layout;
131
uint8 *lineScroll;
132
};
133
134
struct CollisionMask {
135
uint8 floorMasks[TILE_SIZE];
136
uint8 lWallMasks[TILE_SIZE];
137
uint8 rWallMasks[TILE_SIZE];
138
uint8 roofMasks[TILE_SIZE];
139
};
140
141
struct TileInfo {
142
uint8 floorAngle;
143
uint8 lWallAngle;
144
uint8 rWallAngle;
145
uint8 roofAngle;
146
uint8 flag;
147
};
148
149
extern ScanlineInfo *scanlines;
150
extern TileLayer tileLayers[LAYER_COUNT];
151
152
extern CollisionMask collisionMasks[CPATH_COUNT][TILE_COUNT * 4]; // 1024 * 1 per direction
153
extern TileInfo tileInfo[CPATH_COUNT][TILE_COUNT * 4]; // 1024 * 1 per direction
154
155
#if RETRO_REV02
156
extern bool32 forceHardReset;
157
#endif
158
extern char currentSceneFolder[0x10];
159
extern char currentSceneID[0x10];
160
#if RETRO_REV02
161
extern uint8 currentSceneFilter;
162
#endif
163
164
extern SceneInfo sceneInfo;
165
166
extern uint8 tilesetPixels[TILESET_SIZE * 4];
167
168
void LoadSceneFolder();
169
void LoadSceneAssets();
170
void LoadTileConfig(char *filepath);
171
void LoadStageGIF(char *filepath);
172
173
void ProcessParallaxAutoScroll();
174
void ProcessParallax(TileLayer *layer);
175
void ProcessSceneTimer();
176
177
void SetScene(const char *categoryName, const char *sceneName);
178
inline void LoadScene()
179
{
180
if ((sceneInfo.state & ENGINESTATE_STEPOVER) == ENGINESTATE_STEPOVER)
181
sceneInfo.state = ENGINESTATE_LOAD | ENGINESTATE_STEPOVER;
182
else
183
sceneInfo.state = ENGINESTATE_LOAD;
184
}
185
186
#if RETRO_REV02
187
inline void ForceHardReset(bool32 shouldHardReset) { forceHardReset = shouldHardReset; }
188
#endif
189
190
inline bool32 CheckValidScene()
191
{
192
if (sceneInfo.activeCategory >= sceneInfo.categoryCount)
193
return false;
194
195
SceneListInfo *list = &sceneInfo.listCategory[sceneInfo.activeCategory];
196
return sceneInfo.listPos >= list->sceneOffsetStart && sceneInfo.listPos <= list->sceneOffsetEnd;
197
}
198
199
inline bool32 CheckSceneFolder(const char *folderName) { return strcmp(folderName, sceneInfo.listData[sceneInfo.listPos].folder) == 0; }
200
201
inline uint16 GetTileLayerID(const char *name)
202
{
203
RETRO_HASH_MD5(hash);
204
GEN_HASH_MD5(name, hash);
205
206
for (int32 i = 0; i < LAYER_COUNT; ++i) {
207
if (HASH_MATCH_MD5(tileLayers[i].name, hash))
208
return i;
209
}
210
211
return (uint16)-1;
212
}
213
214
inline TileLayer *GetTileLayer(uint16 layerID) { return layerID < LAYER_COUNT ? &tileLayers[layerID] : NULL; }
215
216
inline void GetLayerSize(uint16 layerID, Vector2 *size, bool32 usePixelUnits)
217
{
218
if (layerID < LAYER_COUNT && size) {
219
TileLayer *layer = &tileLayers[layerID];
220
221
if (usePixelUnits) {
222
size->x = TILE_SIZE * layer->xsize;
223
size->y = TILE_SIZE * layer->ysize;
224
}
225
else {
226
size->x = layer->xsize;
227
size->y = layer->ysize;
228
}
229
}
230
}
231
232
inline uint16 GetTile(uint16 layerID, int32 tileX, int32 tileY)
233
{
234
if (layerID < LAYER_COUNT) {
235
TileLayer *layer = &tileLayers[layerID];
236
if (tileX >= 0 && tileX < layer->xsize && tileY >= 0 && tileY < layer->ysize)
237
return layer->layout[tileX + (tileY << layer->widthShift)];
238
}
239
240
return (uint16)-1;
241
}
242
243
inline void SetTile(uint16 layerID, int32 tileX, int32 tileY, uint16 tile)
244
{
245
if (layerID < LAYER_COUNT) {
246
TileLayer *layer = &tileLayers[layerID];
247
if (tileX >= 0 && tileX < layer->xsize && tileY >= 0 && tileY < layer->ysize)
248
layer->layout[tileX + (tileY << layer->widthShift)] = tile;
249
}
250
}
251
252
inline int32 GetTileAngle(uint16 tile, uint8 cPlane, uint8 cMode)
253
{
254
switch (cMode) {
255
default: return 0;
256
case CMODE_FLOOR: return tileInfo[cPlane & 1][tile & 0xFFF].floorAngle;
257
case CMODE_LWALL: return tileInfo[cPlane & 1][tile & 0xFFF].lWallAngle;
258
case CMODE_ROOF: return tileInfo[cPlane & 1][tile & 0xFFF].roofAngle;
259
case CMODE_RWALL: return tileInfo[cPlane & 1][tile & 0xFFF].rWallAngle;
260
}
261
}
262
inline void SetTileAngle(uint16 tile, uint8 cPlane, uint8 cMode, uint8 angle)
263
{
264
switch (cMode) {
265
default: break;
266
case CMODE_FLOOR: tileInfo[cPlane & 1][tile & 0x3FF].floorAngle = angle; break;
267
case CMODE_LWALL: tileInfo[cPlane & 1][tile & 0x3FF].lWallAngle = angle; break;
268
case CMODE_ROOF: tileInfo[cPlane & 1][tile & 0x3FF].roofAngle = angle; break;
269
case CMODE_RWALL: tileInfo[cPlane & 1][tile & 0x3FF].rWallAngle = angle; break;
270
}
271
}
272
273
inline uint8 GetTileFlags(uint16 tile, uint8 cPlane) { return tileInfo[cPlane & 1][tile & 0x3FF].flag; }
274
inline void SetTileFlags(uint16 tile, uint8 cPlane, uint8 flag) { tileInfo[cPlane & 1][tile & 0x3FF].flag = flag; }
275
276
void CopyTileLayer(uint16 dstLayerID, int32 dstStartX, int32 dstStartY, uint16 srcLayerID, int32 srcStartX, int32 srcStartY, int32 countX,
277
int32 countY);
278
279
inline void CopyTile(uint16 dest, uint16 src, uint16 count)
280
{
281
if (dest > TILE_COUNT)
282
dest = TILE_COUNT - 1;
283
284
if (src > TILE_COUNT)
285
src = TILE_COUNT - 1;
286
287
if (count > TILE_COUNT)
288
count = TILE_COUNT - 1;
289
290
uint8 *destPixels = &tilesetPixels[TILE_DATASIZE * dest];
291
uint8 *srcPixels = &tilesetPixels[TILE_DATASIZE * src];
292
293
uint8 *destPixelsX = &tilesetPixels[(TILE_DATASIZE * dest) + ((TILE_COUNT * TILE_DATASIZE) * FLIP_X)];
294
uint8 *srcPixelsX = &tilesetPixels[(TILE_DATASIZE * src) + ((TILE_COUNT * TILE_DATASIZE) * FLIP_X)];
295
296
uint8 *destPixelsY = &tilesetPixels[(TILE_DATASIZE * dest) + ((TILE_COUNT * TILE_DATASIZE) * FLIP_Y)];
297
uint8 *srcPixelsY = &tilesetPixels[(TILE_DATASIZE * src) + ((TILE_COUNT * TILE_DATASIZE) * FLIP_Y)];
298
299
uint8 *destPixelsXY = &tilesetPixels[(TILE_DATASIZE * dest) + ((TILE_COUNT * TILE_DATASIZE) * FLIP_XY)];
300
uint8 *srcPixelsXY = &tilesetPixels[(TILE_DATASIZE * src) + ((TILE_COUNT * TILE_DATASIZE) * FLIP_XY)];
301
302
for (int32 t = 0; t < count; ++t) {
303
for (int32 p = 0; p < TILE_DATASIZE; ++p) {
304
*destPixels++ = *srcPixels++;
305
*destPixelsX++ = *srcPixelsX++;
306
*destPixelsY++ = *srcPixelsY++;
307
*destPixelsXY++ = *srcPixelsXY++;
308
}
309
}
310
}
311
312
inline ScanlineInfo *GetScanlines() { return scanlines; }
313
314
// Draw a layer with horizonal scrolling capabilities
315
void DrawLayerHScroll(TileLayer *layer);
316
// Draw a layer with vertical scrolling capabilities
317
void DrawLayerVScroll(TileLayer *layer);
318
// Draw a layer with rotozoom (via scanline callback) capabilities
319
void DrawLayerRotozoom(TileLayer *layer);
320
// Draw a "basic" layer, no special capabilities, but it's the fastest to draw
321
void DrawLayerBasic(TileLayer *layer);
322
323
#if RETRO_REV0U
324
#include "Legacy/SceneLegacy.hpp"
325
#endif
326
327
} // namespace RSDK
328
329
#endif
330
331