Path: blob/master/RSDKv5/RSDK/Scene/Scene.hpp
1167 views
#ifndef SCENE_H1#define SCENE_H23namespace RSDK4{56#define TILE_COUNT (0x400)7#define TILE_SIZE (0x10)8#define TILE_DATASIZE (TILE_SIZE * TILE_SIZE)9#define TILESET_SIZE (TILE_COUNT * TILE_DATASIZE)1011#define CPATH_COUNT (2)1213#define RSDK_SIGNATURE_CFG (0x474643) // "CFG"14#define RSDK_SIGNATURE_SCN (0x4E4353) // "SCN"15#define RSDK_SIGNATURE_TIL (0x4C4954) // "TIL"1617enum LayerTypes {18LAYER_HSCROLL,19LAYER_VSCROLL,20LAYER_ROTOZOOM,21LAYER_BASIC,22};2324struct SceneListInfo {25RETRO_HASH_MD5(hash);26char name[0x20];27uint16 sceneOffsetStart;28uint16 sceneOffsetEnd;29uint8 sceneCount;30};3132struct SceneListEntry {33RETRO_HASH_MD5(hash);34char name[0x20];35char folder[0x10];36char id[0x08];37#if RETRO_REV0238uint8 filter;39#endif40};4142enum CollisionModes {43CMODE_FLOOR,44CMODE_LWALL,45CMODE_ROOF,46CMODE_RWALL,47};4849enum EngineStates {50ENGINESTATE_LOAD,51ENGINESTATE_REGULAR,52ENGINESTATE_PAUSED,53ENGINESTATE_FROZEN,54ENGINESTATE_STEPOVER = 4,55ENGINESTATE_DEVMENU = 8,56ENGINESTATE_VIDEOPLAYBACK,57ENGINESTATE_SHOWIMAGE,58#if RETRO_REV0259ENGINESTATE_ERRORMSG,60ENGINESTATE_ERRORMSG_FATAL,61#endif62ENGINESTATE_NONE,63#if RETRO_REV0U64// Prolly origins-only, called by the ending so I assume this handles playing ending movies and returning to menu65ENGINESTATE_GAME_FINISHED,66#endif67};6869struct SceneInfo {70Entity *entity;71SceneListEntry *listData;72SceneListInfo *listCategory;73int32 timeCounter;74int32 currentDrawGroup;75int32 currentScreenID;76uint16 listPos;77uint16 entitySlot;78uint16 createSlot;79uint16 classCount;80bool32 inEditor;81bool32 effectGizmo;82bool32 debugMode;83bool32 useGlobalObjects;84bool32 timeEnabled;85uint8 activeCategory;86uint8 categoryCount;87uint8 state;88#if RETRO_REV0289uint8 filter;90#endif91uint8 milliseconds;92uint8 seconds;93uint8 minutes;94};9596struct ScrollInfo {97int32 tilePos;98int32 parallaxFactor;99int32 scrollSpeed;100int32 scrollPos;101uint8 deform;102uint8 unknown; // stored in the scene, but always 0, never referenced in-engine either...103};104105struct ScanlineInfo {106Vector2 position; // position of the scanline107Vector2 deform; // deformation that should be applied (only applies to RotoZoom type)108};109110struct TileLayer {111uint8 type;112uint8 drawGroup[CAMERA_COUNT];113uint8 widthShift;114uint8 heightShift;115uint16 xsize;116uint16 ysize;117Vector2 position;118int32 parallaxFactor;119int32 scrollSpeed;120int32 scrollPos;121int32 deformationOffset;122int32 deformationOffsetW;123int32 deformationData[0x400];124int32 deformationDataW[0x400];125void (*scanlineCallback)(ScanlineInfo *scanlines);126uint16 scrollInfoCount;127ScrollInfo scrollInfo[0x100];128RETRO_HASH_MD5(name);129uint16 *layout;130uint8 *lineScroll;131};132133struct CollisionMask {134uint8 floorMasks[TILE_SIZE];135uint8 lWallMasks[TILE_SIZE];136uint8 rWallMasks[TILE_SIZE];137uint8 roofMasks[TILE_SIZE];138};139140struct TileInfo {141uint8 floorAngle;142uint8 lWallAngle;143uint8 rWallAngle;144uint8 roofAngle;145uint8 flag;146};147148extern ScanlineInfo *scanlines;149extern TileLayer tileLayers[LAYER_COUNT];150151extern CollisionMask collisionMasks[CPATH_COUNT][TILE_COUNT * 4]; // 1024 * 1 per direction152extern TileInfo tileInfo[CPATH_COUNT][TILE_COUNT * 4]; // 1024 * 1 per direction153154#if RETRO_REV02155extern bool32 forceHardReset;156#endif157extern char currentSceneFolder[0x10];158extern char currentSceneID[0x10];159#if RETRO_REV02160extern uint8 currentSceneFilter;161#endif162163extern SceneInfo sceneInfo;164165extern uint8 tilesetPixels[TILESET_SIZE * 4];166167void LoadSceneFolder();168void LoadSceneAssets();169void LoadTileConfig(char *filepath);170void LoadStageGIF(char *filepath);171172void ProcessParallaxAutoScroll();173void ProcessParallax(TileLayer *layer);174void ProcessSceneTimer();175176void SetScene(const char *categoryName, const char *sceneName);177inline void LoadScene()178{179if ((sceneInfo.state & ENGINESTATE_STEPOVER) == ENGINESTATE_STEPOVER)180sceneInfo.state = ENGINESTATE_LOAD | ENGINESTATE_STEPOVER;181else182sceneInfo.state = ENGINESTATE_LOAD;183}184185#if RETRO_REV02186inline void ForceHardReset(bool32 shouldHardReset) { forceHardReset = shouldHardReset; }187#endif188189inline bool32 CheckValidScene()190{191if (sceneInfo.activeCategory >= sceneInfo.categoryCount)192return false;193194SceneListInfo *list = &sceneInfo.listCategory[sceneInfo.activeCategory];195return sceneInfo.listPos >= list->sceneOffsetStart && sceneInfo.listPos <= list->sceneOffsetEnd;196}197198inline bool32 CheckSceneFolder(const char *folderName) { return strcmp(folderName, sceneInfo.listData[sceneInfo.listPos].folder) == 0; }199200inline uint16 GetTileLayerID(const char *name)201{202RETRO_HASH_MD5(hash);203GEN_HASH_MD5(name, hash);204205for (int32 i = 0; i < LAYER_COUNT; ++i) {206if (HASH_MATCH_MD5(tileLayers[i].name, hash))207return i;208}209210return (uint16)-1;211}212213inline TileLayer *GetTileLayer(uint16 layerID) { return layerID < LAYER_COUNT ? &tileLayers[layerID] : NULL; }214215inline void GetLayerSize(uint16 layerID, Vector2 *size, bool32 usePixelUnits)216{217if (layerID < LAYER_COUNT && size) {218TileLayer *layer = &tileLayers[layerID];219220if (usePixelUnits) {221size->x = TILE_SIZE * layer->xsize;222size->y = TILE_SIZE * layer->ysize;223}224else {225size->x = layer->xsize;226size->y = layer->ysize;227}228}229}230231inline uint16 GetTile(uint16 layerID, int32 tileX, int32 tileY)232{233if (layerID < LAYER_COUNT) {234TileLayer *layer = &tileLayers[layerID];235if (tileX >= 0 && tileX < layer->xsize && tileY >= 0 && tileY < layer->ysize)236return layer->layout[tileX + (tileY << layer->widthShift)];237}238239return (uint16)-1;240}241242inline void SetTile(uint16 layerID, int32 tileX, int32 tileY, uint16 tile)243{244if (layerID < LAYER_COUNT) {245TileLayer *layer = &tileLayers[layerID];246if (tileX >= 0 && tileX < layer->xsize && tileY >= 0 && tileY < layer->ysize)247layer->layout[tileX + (tileY << layer->widthShift)] = tile;248}249}250251inline int32 GetTileAngle(uint16 tile, uint8 cPlane, uint8 cMode)252{253switch (cMode) {254default: return 0;255case CMODE_FLOOR: return tileInfo[cPlane & 1][tile & 0xFFF].floorAngle;256case CMODE_LWALL: return tileInfo[cPlane & 1][tile & 0xFFF].lWallAngle;257case CMODE_ROOF: return tileInfo[cPlane & 1][tile & 0xFFF].roofAngle;258case CMODE_RWALL: return tileInfo[cPlane & 1][tile & 0xFFF].rWallAngle;259}260}261inline void SetTileAngle(uint16 tile, uint8 cPlane, uint8 cMode, uint8 angle)262{263switch (cMode) {264default: break;265case CMODE_FLOOR: tileInfo[cPlane & 1][tile & 0x3FF].floorAngle = angle; break;266case CMODE_LWALL: tileInfo[cPlane & 1][tile & 0x3FF].lWallAngle = angle; break;267case CMODE_ROOF: tileInfo[cPlane & 1][tile & 0x3FF].roofAngle = angle; break;268case CMODE_RWALL: tileInfo[cPlane & 1][tile & 0x3FF].rWallAngle = angle; break;269}270}271272inline uint8 GetTileFlags(uint16 tile, uint8 cPlane) { return tileInfo[cPlane & 1][tile & 0x3FF].flag; }273inline void SetTileFlags(uint16 tile, uint8 cPlane, uint8 flag) { tileInfo[cPlane & 1][tile & 0x3FF].flag = flag; }274275void CopyTileLayer(uint16 dstLayerID, int32 dstStartX, int32 dstStartY, uint16 srcLayerID, int32 srcStartX, int32 srcStartY, int32 countX,276int32 countY);277278inline void CopyTile(uint16 dest, uint16 src, uint16 count)279{280if (dest > TILE_COUNT)281dest = TILE_COUNT - 1;282283if (src > TILE_COUNT)284src = TILE_COUNT - 1;285286if (count > TILE_COUNT)287count = TILE_COUNT - 1;288289uint8 *destPixels = &tilesetPixels[TILE_DATASIZE * dest];290uint8 *srcPixels = &tilesetPixels[TILE_DATASIZE * src];291292uint8 *destPixelsX = &tilesetPixels[(TILE_DATASIZE * dest) + ((TILE_COUNT * TILE_DATASIZE) * FLIP_X)];293uint8 *srcPixelsX = &tilesetPixels[(TILE_DATASIZE * src) + ((TILE_COUNT * TILE_DATASIZE) * FLIP_X)];294295uint8 *destPixelsY = &tilesetPixels[(TILE_DATASIZE * dest) + ((TILE_COUNT * TILE_DATASIZE) * FLIP_Y)];296uint8 *srcPixelsY = &tilesetPixels[(TILE_DATASIZE * src) + ((TILE_COUNT * TILE_DATASIZE) * FLIP_Y)];297298uint8 *destPixelsXY = &tilesetPixels[(TILE_DATASIZE * dest) + ((TILE_COUNT * TILE_DATASIZE) * FLIP_XY)];299uint8 *srcPixelsXY = &tilesetPixels[(TILE_DATASIZE * src) + ((TILE_COUNT * TILE_DATASIZE) * FLIP_XY)];300301for (int32 t = 0; t < count; ++t) {302for (int32 p = 0; p < TILE_DATASIZE; ++p) {303*destPixels++ = *srcPixels++;304*destPixelsX++ = *srcPixelsX++;305*destPixelsY++ = *srcPixelsY++;306*destPixelsXY++ = *srcPixelsXY++;307}308}309}310311inline ScanlineInfo *GetScanlines() { return scanlines; }312313// Draw a layer with horizonal scrolling capabilities314void DrawLayerHScroll(TileLayer *layer);315// Draw a layer with vertical scrolling capabilities316void DrawLayerVScroll(TileLayer *layer);317// Draw a layer with rotozoom (via scanline callback) capabilities318void DrawLayerRotozoom(TileLayer *layer);319// Draw a "basic" layer, no special capabilities, but it's the fastest to draw320void DrawLayerBasic(TileLayer *layer);321322#if RETRO_REV0U323#include "Legacy/SceneLegacy.hpp"324#endif325326} // namespace RSDK327328#endif329330331