2022-04-02 02:50:42 +00:00
|
|
|
#include "dynos.cpp.h"
|
2022-04-02 22:14:04 +00:00
|
|
|
extern "C" {
|
|
|
|
#include "behavior_table.h"
|
2022-04-03 10:30:47 +00:00
|
|
|
#include "levels/scripts.h"
|
2022-04-02 22:14:04 +00:00
|
|
|
}
|
2022-04-03 10:30:47 +00:00
|
|
|
|
2022-04-02 02:50:42 +00:00
|
|
|
/////////////
|
|
|
|
// Writing //
|
|
|
|
/////////////
|
|
|
|
|
|
|
|
typedef Pair<String, u32> PointerData;
|
|
|
|
static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) {
|
|
|
|
// Lights
|
|
|
|
for (auto& _Node : aGfxData->mLights) {
|
|
|
|
if (&_Node->mData->l[0] == aPtr) { // Light *, not Lights1 *
|
|
|
|
return { _Node->mName, 1 };
|
|
|
|
}
|
|
|
|
if (&_Node->mData->a == aPtr) { // Ambient *, not Lights1 *
|
|
|
|
return { _Node->mName, 2 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-07 04:32:55 +00:00
|
|
|
// Light_ts
|
2022-04-05 04:25:40 +00:00
|
|
|
for (auto& _Node : aGfxData->mLightTs) {
|
|
|
|
if (&_Node->mData->col[0] == aPtr) {
|
|
|
|
return { _Node->mName, 1 };
|
|
|
|
}
|
|
|
|
if (&_Node->mData->colc[0] == aPtr) {
|
|
|
|
return { _Node->mName, 2 };
|
|
|
|
}
|
|
|
|
if (&_Node->mData->dir[0] == aPtr) {
|
|
|
|
return { _Node->mName, 3 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-07 04:32:55 +00:00
|
|
|
// Ambient_ts
|
2022-04-05 04:25:40 +00:00
|
|
|
for (auto& _Node : aGfxData->mAmbientTs) {
|
|
|
|
if (&_Node->mData->col[0] == aPtr) {
|
|
|
|
return { _Node->mName, 1 };
|
|
|
|
}
|
|
|
|
if (&_Node->mData->colc[0] == aPtr) {
|
|
|
|
return { _Node->mName, 2 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 02:50:42 +00:00
|
|
|
// Textures
|
|
|
|
for (auto& _Node : aGfxData->mTextures) {
|
|
|
|
if (_Node == aPtr) {
|
|
|
|
return { _Node->mName, 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-06 05:56:03 +00:00
|
|
|
// Texture Lists
|
|
|
|
for (auto& _Node : aGfxData->mTextureLists) {
|
|
|
|
if (_Node == aPtr) {
|
|
|
|
return { _Node->mName, 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 02:50:42 +00:00
|
|
|
// Display lists
|
|
|
|
for (auto& _Node : aGfxData->mDisplayLists) {
|
|
|
|
if (_Node == aPtr) {
|
|
|
|
return { _Node->mName, 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Geo layouts
|
|
|
|
for (auto& _Node : aGfxData->mGeoLayouts) {
|
|
|
|
if (_Node->mData == aPtr) {
|
|
|
|
return { _Node->mName, 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Collisions
|
|
|
|
for (auto& _Node : aGfxData->mCollisions) {
|
|
|
|
if (_Node->mData == aPtr) {
|
|
|
|
return { _Node->mName, 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Level scripts
|
|
|
|
for (auto& _Node : aGfxData->mLevelScripts) {
|
|
|
|
if (_Node->mData == aPtr) {
|
|
|
|
return { _Node->mName, 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Macro objects
|
|
|
|
for (auto& _Node : aGfxData->mMacroObjects) {
|
|
|
|
if (_Node->mData == aPtr) {
|
|
|
|
return { _Node->mName, 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 23:08:19 +00:00
|
|
|
// Trajectories
|
|
|
|
for (auto& _Node : aGfxData->mTrajectories) {
|
|
|
|
if (_Node->mData == aPtr) {
|
|
|
|
return { _Node->mName, 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-04 05:12:17 +00:00
|
|
|
// Movtexs
|
|
|
|
for (auto& _Node : aGfxData->mMovtexs) {
|
|
|
|
if (_Node->mData == aPtr) {
|
|
|
|
return { _Node->mName, 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MovtexQCs
|
|
|
|
for (auto& _Node : aGfxData->mMovtexQCs) {
|
|
|
|
if (_Node->mData == aPtr) {
|
|
|
|
return { _Node->mName, 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-04 06:42:25 +00:00
|
|
|
// Rooms
|
|
|
|
for (auto& _Node : aGfxData->mRooms) {
|
|
|
|
if (_Node->mData == aPtr) {
|
|
|
|
return { _Node->mName, 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 22:14:04 +00:00
|
|
|
// Behaviors
|
|
|
|
enum BehaviorId id = get_id_from_vanilla_behavior((const BehaviorScript*) aPtr);
|
|
|
|
if (id >= 0 && id < id_bhv_max_count) {
|
|
|
|
return { get_behavior_name_from_id(id), 0 };
|
|
|
|
}
|
|
|
|
|
2022-04-05 04:25:40 +00:00
|
|
|
// Vanilla Actors
|
2022-04-03 10:30:47 +00:00
|
|
|
s32 actorCount = DynOS_Geo_GetActorCount();
|
|
|
|
for (s32 i = 0; i < actorCount; i++) {
|
|
|
|
if (DynOS_Geo_IsCustomActor(i)) { break; }
|
|
|
|
if (aPtr == DynOS_Geo_GetActorLayout(i)) {
|
|
|
|
return { DynOS_Geo_GetActorName(i), 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-05 04:25:40 +00:00
|
|
|
// Vanilla Lvl Geos
|
2022-04-07 04:32:55 +00:00
|
|
|
auto vanillaGeo = DynOS_Mgr_VanillaLvlGeo_GetFromData((const GeoLayout*)aPtr);
|
|
|
|
if (vanillaGeo != NULL) {
|
|
|
|
return { vanillaGeo, 0 };
|
2022-04-05 04:25:40 +00:00
|
|
|
}
|
|
|
|
|
2022-04-07 04:32:55 +00:00
|
|
|
// Vanilla Script Pointers
|
|
|
|
auto vanillaScriptPtr = DynOS_Mgr_VanillaScriptPtr_GetFromData(aPtr);
|
|
|
|
if (vanillaScriptPtr != NULL) {
|
|
|
|
return { vanillaScriptPtr, 0 };
|
|
|
|
}
|
|
|
|
|
|
|
|
// Vanilla Textures
|
|
|
|
auto vanillaTex = DynOS_Mgr_VanillaTex_GetFromData((const Texture*)aPtr);
|
|
|
|
if (vanillaTex != NULL) {
|
|
|
|
return { vanillaTex, 0 };
|
2022-04-03 10:30:47 +00:00
|
|
|
}
|
|
|
|
|
2022-04-02 02:50:42 +00:00
|
|
|
// Vertices
|
|
|
|
String _VtxArrayName = "";
|
|
|
|
uintptr_t _VtxArrayStart = 0;
|
|
|
|
for (auto& _Node : aGfxData->mVertices) {
|
|
|
|
if (_Node->mData == aPtr) {
|
|
|
|
return { _Node->mName, 0 };
|
|
|
|
}
|
|
|
|
if ((uintptr_t)_Node->mData <= (uintptr_t)aPtr &&
|
|
|
|
(uintptr_t)_Node->mData >= _VtxArrayStart) {
|
|
|
|
_VtxArrayName = _Node->mName;
|
|
|
|
_VtxArrayStart = (uintptr_t)_Node->mData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return { _VtxArrayName, (u32)((const Vtx*)aPtr - (const Vtx*)_VtxArrayStart) };
|
2022-04-07 04:32:55 +00:00
|
|
|
|
2022-04-02 02:50:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-05 07:22:09 +00:00
|
|
|
void DynOS_Pointer_Lua_Write(FILE* aFile, u32 index, GfxData* aGfxData) {
|
|
|
|
String& token = aGfxData->mLuaTokenList[index];
|
|
|
|
WriteBytes<u32>(aFile, LUA_VAR_CODE);
|
|
|
|
token.Write(aFile);
|
|
|
|
}
|
|
|
|
|
2022-04-02 02:50:42 +00:00
|
|
|
void DynOS_Pointer_Write(FILE* aFile, const void* aPtr, GfxData* aGfxData) {
|
|
|
|
|
|
|
|
// NULL
|
|
|
|
if (!aPtr) {
|
|
|
|
WriteBytes<u32>(aFile, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-05 07:22:09 +00:00
|
|
|
// Lua variable
|
|
|
|
for (s32 i = 0; i < aGfxData->mLuaPointerList.Count(); i++) {
|
|
|
|
if (aPtr == aGfxData->mLuaPointerList[i]) {
|
|
|
|
u32 index = *((u32*)aPtr);
|
|
|
|
String& token = aGfxData->mLuaTokenList[index];
|
|
|
|
WriteBytes<u32>(aFile, LUA_VAR_CODE);
|
|
|
|
token.Write(aFile);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 02:50:42 +00:00
|
|
|
// Geo function
|
|
|
|
s32 _GeoFunctionIndex = DynOS_Geo_GetFunctionIndex(aPtr);
|
|
|
|
if (_GeoFunctionIndex != -1) {
|
|
|
|
WriteBytes<u32>(aFile, FUNCTION_CODE);
|
|
|
|
WriteBytes<s32>(aFile, _GeoFunctionIndex);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-02 22:14:04 +00:00
|
|
|
// Lvl function
|
|
|
|
s32 _LvlFunctionIndex = DynOS_Lvl_GetFunctionIndex(aPtr);
|
|
|
|
if (_LvlFunctionIndex != -1) {
|
|
|
|
WriteBytes<u32>(aFile, FUNCTION_CODE);
|
|
|
|
WriteBytes<s32>(aFile, _LvlFunctionIndex);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-02 02:50:42 +00:00
|
|
|
// Pointer
|
|
|
|
PointerData _PtrData = GetDataFromPointer(aPtr, aGfxData);
|
|
|
|
WriteBytes<u32>(aFile, POINTER_CODE);
|
|
|
|
_PtrData.first.Write(aFile);
|
|
|
|
WriteBytes<u32>(aFile, _PtrData.second);
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////
|
|
|
|
// Reading //
|
|
|
|
/////////////
|
|
|
|
|
|
|
|
static void *GetPointerFromData(GfxData *aGfxData, const String &aPtrName, u32 aPtrData) {
|
|
|
|
|
|
|
|
// Lights
|
|
|
|
for (auto& _Node : aGfxData->mLights) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
if (aPtrData == 1) {
|
|
|
|
return (void *) &_Node->mData->l[0];
|
|
|
|
}
|
|
|
|
if (aPtrData == 2) {
|
|
|
|
return (void *) &_Node->mData->a;
|
|
|
|
}
|
|
|
|
sys_fatal("Unknown Light type: %u", aPtrData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-07 04:32:55 +00:00
|
|
|
// Light_ts
|
2022-04-05 04:25:40 +00:00
|
|
|
for (auto& _Node : aGfxData->mLightTs) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
if (aPtrData == 1) {
|
|
|
|
return (void *) &_Node->mData->col[0];
|
|
|
|
}
|
|
|
|
if (aPtrData == 2) {
|
|
|
|
return (void *) &_Node->mData->colc[0];
|
|
|
|
}
|
|
|
|
if (aPtrData == 3) {
|
|
|
|
return (void *) &_Node->mData->dir[0];
|
|
|
|
}
|
|
|
|
sys_fatal("Unknown Light type: %u", aPtrData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-07 04:32:55 +00:00
|
|
|
// Ambient_ts
|
2022-04-05 04:25:40 +00:00
|
|
|
for (auto& _Node : aGfxData->mAmbientTs) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
if (aPtrData == 1) {
|
|
|
|
return (void *) &_Node->mData->col[0];
|
|
|
|
}
|
|
|
|
if (aPtrData == 2) {
|
|
|
|
return (void *) &_Node->mData->colc[0];
|
|
|
|
}
|
|
|
|
sys_fatal("Unknown Light type: %u", aPtrData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 02:50:42 +00:00
|
|
|
// Textures
|
|
|
|
for (auto& _Node : aGfxData->mTextures) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
return (void *) _Node;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-06 05:56:03 +00:00
|
|
|
// Texture Lists
|
|
|
|
for (auto& _Node : aGfxData->mTextureLists) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
return (void *) _Node;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 02:50:42 +00:00
|
|
|
// Display lists
|
|
|
|
for (auto &_Node : aGfxData->mDisplayLists) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
return (void *) _Node->mData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Geo layouts
|
|
|
|
for (auto &_Node : aGfxData->mGeoLayouts) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
return (void *) _Node->mData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Vertices
|
|
|
|
for (auto &_Node : aGfxData->mVertices) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
return (void *) (_Node->mData + aPtrData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Collisions
|
|
|
|
for (auto &_Node : aGfxData->mCollisions) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
return (void *) _Node->mData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Level scripts
|
|
|
|
for (auto &_Node : aGfxData->mLevelScripts) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
return (void *) _Node->mData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Macro objects
|
|
|
|
for (auto &_Node : aGfxData->mMacroObjects) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
return (void *) _Node->mData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 23:08:19 +00:00
|
|
|
// Trajectories
|
|
|
|
for (auto &_Node : aGfxData->mTrajectories) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
return (void *) _Node->mData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-04 05:12:17 +00:00
|
|
|
// Movtexs
|
|
|
|
for (auto &_Node : aGfxData->mMovtexs) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
return (void *) _Node->mData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MovtexQCs
|
|
|
|
for (auto &_Node : aGfxData->mMovtexQCs) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
return (void *) _Node->mData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-04 06:42:25 +00:00
|
|
|
// Rooms
|
|
|
|
for (auto &_Node : aGfxData->mRooms) {
|
|
|
|
if (_Node->mName == aPtrName) {
|
|
|
|
return (void *) _Node->mData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 22:14:04 +00:00
|
|
|
// Behaviors
|
|
|
|
enum BehaviorId id = get_id_from_behavior_name(aPtrName.begin());
|
|
|
|
if (id >= 0 && id < id_bhv_max_count) {
|
|
|
|
return (void*)get_behavior_from_id(id);
|
|
|
|
}
|
|
|
|
|
2022-04-05 04:25:40 +00:00
|
|
|
// Vanilla Actors
|
2022-04-03 10:30:47 +00:00
|
|
|
s32 actorCount = DynOS_Geo_GetActorCount();
|
|
|
|
for (s32 i = 0; i < actorCount; i++) {
|
|
|
|
if (DynOS_Geo_IsCustomActor(i)) { break; }
|
|
|
|
if (!strcmp(aPtrName.begin(), DynOS_Geo_GetActorName(i))) {
|
|
|
|
return (void*)DynOS_Geo_GetActorLayout(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-05 04:25:40 +00:00
|
|
|
// Vanilla Lvl Geos
|
2022-04-07 04:32:55 +00:00
|
|
|
auto vanillaGeo = DynOS_Mgr_VanillaLvlGeo_GetFromName(aPtrName.begin());
|
|
|
|
if (vanillaGeo != NULL) {
|
|
|
|
return (void*)vanillaGeo;
|
2022-04-05 04:25:40 +00:00
|
|
|
}
|
|
|
|
|
2022-04-07 04:32:55 +00:00
|
|
|
// Vanilla Script Pointers
|
|
|
|
auto vanillaScriptPtr = DynOS_Mgr_VanillaScriptPtr_GetFromName(aPtrName.begin());
|
|
|
|
if (vanillaScriptPtr != NULL) {
|
|
|
|
return (void*)vanillaScriptPtr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Vanilla Textures
|
|
|
|
auto vanillaTex = DynOS_Mgr_VanillaTex_GetFromName(aPtrName.begin());
|
|
|
|
if (vanillaTex != NULL) {
|
|
|
|
return (void*)vanillaTex;
|
2022-04-03 10:30:47 +00:00
|
|
|
}
|
|
|
|
|
2022-04-02 02:50:42 +00:00
|
|
|
// Error
|
|
|
|
sys_fatal("Pointer not found: %s", aPtrName.begin());
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2022-04-02 22:14:04 +00:00
|
|
|
void *DynOS_Pointer_Load(FILE *aFile, GfxData *aGfxData, u32 aValue, bool isLvl) {
|
2022-04-02 02:50:42 +00:00
|
|
|
|
2022-04-05 07:22:09 +00:00
|
|
|
// LUAV
|
|
|
|
if (aValue == LUA_VAR_CODE) {
|
|
|
|
String token; token.Read(aFile);
|
|
|
|
u32 index = aGfxData->mLuaTokenList.Count();
|
|
|
|
aGfxData->mLuaTokenList.Add(token);
|
|
|
|
return aGfxData->mLuaTokenList[index].begin();
|
|
|
|
}
|
|
|
|
|
2022-04-02 02:50:42 +00:00
|
|
|
// FUNC
|
|
|
|
if (aValue == FUNCTION_CODE) {
|
2022-04-02 22:14:04 +00:00
|
|
|
s32 _FunctionIndex = ReadBytes<s32>(aFile);
|
|
|
|
return isLvl
|
|
|
|
? DynOS_Lvl_GetFunctionPointerFromIndex(_FunctionIndex)
|
|
|
|
: DynOS_Geo_GetFunctionPointerFromIndex(_FunctionIndex);
|
2022-04-02 02:50:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// PNTR
|
|
|
|
if (aValue == POINTER_CODE) {
|
|
|
|
String _PtrName; _PtrName.Read(aFile);
|
|
|
|
u32 _PtrData = ReadBytes<u32>(aFile);
|
|
|
|
return GetPointerFromData(aGfxData, _PtrName, _PtrData);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Not a pointer
|
|
|
|
return NULL;
|
|
|
|
}
|