Massive DynOS refactor for performance/organization
This commit is contained in:
parent
dd6f6c430e
commit
78bda75e45
|
@ -22,13 +22,14 @@ bool dynos_warp_exit_level(s32 aDelay);
|
|||
bool dynos_warp_to_castle(s32 aLevel);
|
||||
|
||||
// -- dynos packs -- //
|
||||
int dynos_packs_get_count(void);
|
||||
const char* dynos_packs_get(s32 index);
|
||||
bool dynos_packs_get_enabled(s32 index);
|
||||
void dynos_packs_set_enabled(s32 index, bool value);
|
||||
int dynos_pack_get_count(void);
|
||||
const char* dynos_pack_get_name(s32 index);
|
||||
bool dynos_pack_get_enabled(s32 index);
|
||||
void dynos_pack_set_enabled(s32 index, bool value);
|
||||
void dynos_generate_packs(const char* directory);
|
||||
|
||||
// -- geos -- //
|
||||
void dynos_actor_override(void** aSharedChild);
|
||||
void dynos_add_actor_custom(const char *filePath, const char* geoName);
|
||||
const void* dynos_geolayout_get(const char *name);
|
||||
|
||||
|
|
|
@ -474,7 +474,11 @@ struct ActorGfx {
|
|||
};
|
||||
|
||||
struct PackData {
|
||||
s32 mIndex;
|
||||
bool mEnabled;
|
||||
SysPath mPath;
|
||||
String mDisplayName;
|
||||
Array<Pair<const char *, GfxData *>> mGfxData;
|
||||
};
|
||||
|
||||
typedef Pair<String, const u8 *> Label;
|
||||
|
@ -672,12 +676,8 @@ void DynOS_Opt_DrawPrompt(DynosOption *aCurrentMenu, DynosOption *aOptionsMenu,
|
|||
// Gfx
|
||||
//
|
||||
|
||||
Array<ActorGfx> &DynOS_Gfx_GetActorList();
|
||||
Array<PackData *> &DynOS_Gfx_GetPacks();
|
||||
Array<bool> &DynOS_Gfx_GetPacksEnabled();
|
||||
Array<String> DynOS_Gfx_Init();
|
||||
void DynOS_Gfx_Init();
|
||||
void DynOS_Gfx_Update();
|
||||
void DynOS_Gfx_SwapAnimations(void *aPtr);
|
||||
void DynOS_Gfx_Free(GfxData *aGfxData);
|
||||
|
||||
//
|
||||
|
@ -745,17 +745,35 @@ const void* DynOS_Builtin_Func_GetFromName(const char* aDataName);
|
|||
const void* DynOS_Builtin_Func_GetFromIndex(s32 aIndex);
|
||||
s32 DynOS_Builtin_Func_GetIndexFromData(const void* aData);
|
||||
|
||||
//
|
||||
// Pack Manager
|
||||
//
|
||||
|
||||
s32 DynOS_Pack_GetCount();
|
||||
void DynOS_Pack_SetEnabled(PackData* aPack, bool aEnabled);
|
||||
PackData* DynOS_Pack_GetFromIndex(s32 aIndex);
|
||||
PackData* DynOS_Pack_GetFromPath(const SysPath& aPath);
|
||||
PackData* DynOS_Pack_Add(const SysPath& aPath);
|
||||
Pair<const char *, GfxData *>* DynOS_Pack_GetActor(PackData* aPackData, const char* aActorName);
|
||||
void DynOS_Pack_AddActor(PackData* aPackData, const char* aActorName, GfxData* aGfxData);
|
||||
|
||||
//
|
||||
// Actor Manager
|
||||
//
|
||||
|
||||
void DynOS_Actor_AddCustom(const SysPath &aFilename, const char *aActorName);
|
||||
s32 DynOS_Actor_GetCount();
|
||||
const char *DynOS_Actor_GetName(s32 aIndex);
|
||||
const void *DynOS_Actor_GetLayoutFromIndex(s32 aIndex);
|
||||
const void *DynOS_Actor_GetLayoutFromName(const char *aActorName);
|
||||
s32 DynOS_Actor_GetIndex(const void *aGeoLayout);
|
||||
bool DynOS_Actor_IsCustom(s32 aIndex);
|
||||
ActorGfx* DynOS_Actor_GetActorGfx(const void* aGeoref);
|
||||
void DynOS_Actor_Valid(const void* aGeoref, ActorGfx& aActorGfx);
|
||||
void DynOS_Actor_Invalid(const void* aGeoref, s32 aPackIndex);
|
||||
void DynOS_Actor_Override(void** aSharedChild);
|
||||
void DynOS_Actor_Override_All(void);
|
||||
|
||||
//
|
||||
// Anim Manager
|
||||
//
|
||||
|
||||
void DynOS_Anim_Swap(void *aPtr);
|
||||
|
||||
//
|
||||
// Tex Manager
|
||||
|
@ -880,7 +898,7 @@ void *DynOS_Pointer_Load(FILE *aFile, GfxData *aGfxData, u32 aValue);
|
|||
|
||||
void DynOS_GfxDynCmd_Load(FILE *aFile, GfxData *aGfxData);
|
||||
|
||||
GfxData *DynOS_Actor_LoadFromBinary(const SysPath &aPackFolder, const char *aActorName, const SysPath &aFilename);
|
||||
GfxData *DynOS_Actor_LoadFromBinary(const SysPath &aPackFolder, const char *aActorName, const SysPath &aFilename, bool aAddToPack);
|
||||
void DynOS_Actor_GeneratePack(const SysPath &aPackFolder);
|
||||
|
||||
DataNode<LevelScript>* DynOS_Lvl_Parse(GfxData* aGfxData, DataNode<LevelScript>* aNode, bool aDisplayPercent);
|
||||
|
|
|
@ -72,25 +72,15 @@ static bool DynOS_Actor_WriteBinary(const SysPath &aOutputFilename, GfxData *aGf
|
|||
// Reading //
|
||||
/////////////
|
||||
|
||||
GfxData *DynOS_Actor_LoadFromBinary(const SysPath &aPackFolder, const char *aActorName, const SysPath &aFilename) {
|
||||
struct DynosGfxDataCache { SysPath mPackFolder; Array<Pair<const char *, GfxData *>> mGfxData; };
|
||||
static Array<DynosGfxDataCache *> sDynosGfxDataCache = {};
|
||||
|
||||
GfxData *DynOS_Actor_LoadFromBinary(const SysPath &aPackFolder, const char *aActorName, const SysPath &aFilename, bool aAddToPack) {
|
||||
// Look for pack in cache
|
||||
DynosGfxDataCache *_Pack = NULL;
|
||||
for (s32 i = 0; i != sDynosGfxDataCache.Count(); ++i) {
|
||||
if (sDynosGfxDataCache[i]->mPackFolder == aPackFolder) {
|
||||
_Pack = sDynosGfxDataCache[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
PackData* _Pack = DynOS_Pack_GetFromPath(aPackFolder);
|
||||
|
||||
// Look for actor in pack
|
||||
if (_Pack) {
|
||||
for (s32 i = 0; i != _Pack->mGfxData.Count(); ++i) {
|
||||
if (!strcmp(_Pack->mGfxData[i].first, aActorName)) {
|
||||
return _Pack->mGfxData[i].second;
|
||||
}
|
||||
auto _ActorPair = DynOS_Pack_GetActor(_Pack, aActorName);
|
||||
if (_ActorPair != NULL) {
|
||||
return _ActorPair->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,13 +109,13 @@ GfxData *DynOS_Actor_LoadFromBinary(const SysPath &aPackFolder, const char *aAct
|
|||
}
|
||||
|
||||
// Add data to cache, even if not loaded
|
||||
if (_Pack) {
|
||||
_Pack->mGfxData.Add({ aActorName, _GfxData });
|
||||
} else {
|
||||
_Pack = New<DynosGfxDataCache>();
|
||||
_Pack->mPackFolder = aPackFolder;
|
||||
_Pack->mGfxData.Add({ aActorName, _GfxData });
|
||||
sDynosGfxDataCache.Add(_Pack);
|
||||
if (aAddToPack) {
|
||||
if (_Pack) {
|
||||
DynOS_Pack_AddActor(_Pack, aActorName, _GfxData);
|
||||
} else {
|
||||
_Pack = DynOS_Pack_Add(aPackFolder);
|
||||
DynOS_Pack_AddActor(_Pack, aActorName, _GfxData);
|
||||
}
|
||||
}
|
||||
|
||||
return _GfxData;
|
||||
|
|
|
@ -25,7 +25,7 @@ s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **has
|
|||
}
|
||||
|
||||
void dynos_gfx_swap_animations(void *ptr) {
|
||||
return DynOS_Gfx_SwapAnimations(ptr);
|
||||
return DynOS_Anim_Swap(ptr);
|
||||
}
|
||||
|
||||
// -- warps -- //
|
||||
|
@ -48,34 +48,31 @@ bool dynos_warp_to_castle(s32 aLevel) {
|
|||
|
||||
// -- dynos packs -- //
|
||||
|
||||
int dynos_packs_get_count(void) {
|
||||
return DynOS_Gfx_GetPacks().Count();
|
||||
int dynos_pack_get_count(void) {
|
||||
return DynOS_Pack_GetCount();
|
||||
}
|
||||
|
||||
const char* dynos_packs_get(s32 index) {
|
||||
const char* path = DynOS_Gfx_GetPacks()[index]->mPath.c_str();
|
||||
|
||||
// extract basename
|
||||
const char* cpath = path;
|
||||
const char* ctoken = cpath;
|
||||
while (*ctoken != '\0') {
|
||||
if (*ctoken == '/' || *ctoken == '\\') {
|
||||
if (*(ctoken + 1) != '\0') {
|
||||
cpath = (ctoken + 1);
|
||||
}
|
||||
}
|
||||
ctoken++;
|
||||
const char* dynos_pack_get_name(s32 index) {
|
||||
PackData* _Pack = DynOS_Pack_GetFromIndex(index);
|
||||
if (_Pack) {
|
||||
return _Pack->mDisplayName.begin();
|
||||
}
|
||||
|
||||
return cpath;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool dynos_packs_get_enabled(s32 index) {
|
||||
return DynOS_Gfx_GetPacksEnabled()[index];
|
||||
bool dynos_pack_get_enabled(s32 index) {
|
||||
PackData* _Pack = DynOS_Pack_GetFromIndex(index);
|
||||
if (_Pack) {
|
||||
return _Pack->mEnabled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void dynos_packs_set_enabled(s32 index, bool value) {
|
||||
DynOS_Gfx_GetPacksEnabled()[index] = value;
|
||||
void dynos_pack_set_enabled(s32 index, bool value) {
|
||||
PackData* _Pack = DynOS_Pack_GetFromIndex(index);
|
||||
if (_Pack) {
|
||||
DynOS_Pack_SetEnabled(_Pack, value);
|
||||
}
|
||||
}
|
||||
|
||||
void dynos_generate_packs(const char* directory) {
|
||||
|
@ -84,6 +81,10 @@ void dynos_generate_packs(const char* directory) {
|
|||
|
||||
// -- geos -- //
|
||||
|
||||
void dynos_actor_override(void** aSharedChild) {
|
||||
DynOS_Actor_Override(aSharedChild);
|
||||
}
|
||||
|
||||
void dynos_add_actor_custom(const char *filePath, const char* geoName) {
|
||||
DynOS_Actor_AddCustom(filePath, geoName);
|
||||
}
|
||||
|
|
|
@ -1,20 +1,5 @@
|
|||
#include "dynos.cpp.h"
|
||||
|
||||
Array<ActorGfx> &DynOS_Gfx_GetActorList() {
|
||||
static Array<ActorGfx> sActorGfxList;
|
||||
return sActorGfxList;
|
||||
}
|
||||
|
||||
Array<PackData *> &DynOS_Gfx_GetPacks() {
|
||||
static Array<PackData *> sPacks;
|
||||
return sPacks;
|
||||
}
|
||||
|
||||
Array<bool> &DynOS_Gfx_GetPacksEnabled() {
|
||||
static Array<bool> sPacksEnabled;
|
||||
return sPacksEnabled;
|
||||
}
|
||||
|
||||
void DynOS_Gfx_GeneratePacks(const char* directory) {
|
||||
DIR *modsDir = opendir(directory);
|
||||
if (!modsDir) { return; }
|
||||
|
@ -39,8 +24,31 @@ void DynOS_Gfx_GeneratePacks(const char* directory) {
|
|||
closedir(modsDir);
|
||||
}
|
||||
|
||||
static void ScanPackBins(SysPath aPackFolder) {
|
||||
DIR *_PackDir = opendir(aPackFolder.c_str());
|
||||
if (!_PackDir) { return; }
|
||||
|
||||
struct dirent *_PackEnt = NULL;
|
||||
while ((_PackEnt = readdir(_PackDir)) != NULL) {
|
||||
// Skip . and ..
|
||||
if (SysPath(_PackEnt->d_name) == ".") continue;
|
||||
if (SysPath(_PackEnt->d_name) == "..") continue;
|
||||
|
||||
// Skip non .bin
|
||||
s32 length = strlen(_PackEnt->d_name);
|
||||
if (length < 5) { continue; }
|
||||
if (strncmp(&_PackEnt->d_name[length - 4], ".bin", 4)) { continue; }
|
||||
|
||||
String _ActorName = _PackEnt->d_name;
|
||||
_ActorName[length - 4] = '\0';
|
||||
|
||||
SysPath _FileName = fstring("%s/%s", aPackFolder.begin(), _PackEnt->d_name);
|
||||
|
||||
DynOS_Actor_LoadFromBinary(aPackFolder, strdup(_ActorName.begin()), _FileName, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void ScanPacksFolder(SysPath _DynosPacksFolder) {
|
||||
Array<PackData *> &pDynosPacks = DynOS_Gfx_GetPacks();
|
||||
DIR *_DynosPacksDir = opendir(_DynosPacksFolder.c_str());
|
||||
if (_DynosPacksDir) {
|
||||
struct dirent *_DynosPacksEnt = NULL;
|
||||
|
@ -53,34 +61,16 @@ static void ScanPacksFolder(SysPath _DynosPacksFolder) {
|
|||
// If pack folder exists, add it to the pack list
|
||||
SysPath _PackFolder = fstring("%s/%s", _DynosPacksFolder.c_str(), _DynosPacksEnt->d_name);
|
||||
if (fs_sys_dir_exists(_PackFolder.c_str())) {
|
||||
PackData *_Pack = New<PackData>();
|
||||
|
||||
// Scan folder for subfolders to convert into .bin files
|
||||
_Pack->mPath = _PackFolder;
|
||||
struct PackData* _Pack = DynOS_Pack_Add(_PackFolder);
|
||||
DynOS_Actor_GeneratePack(_PackFolder);
|
||||
|
||||
// Add pack to pack list
|
||||
pDynosPacks.Add(_Pack);
|
||||
|
||||
// Add enabled flag
|
||||
DynOS_Gfx_GetPacksEnabled().Add(true);
|
||||
ScanPackBins(_PackFolder);
|
||||
}
|
||||
}
|
||||
closedir(_DynosPacksDir);
|
||||
}
|
||||
}
|
||||
|
||||
Array<String> DynOS_Gfx_Init() {
|
||||
|
||||
// Alloc and init the actors gfx list
|
||||
Array<ActorGfx> &pActorGfxList = DynOS_Gfx_GetActorList();
|
||||
pActorGfxList.Resize(DynOS_Actor_GetCount());
|
||||
for (s32 i = 0; i != DynOS_Actor_GetCount(); ++i) {
|
||||
pActorGfxList[i].mPackIndex = -1;
|
||||
pActorGfxList[i].mGfxData = NULL;
|
||||
pActorGfxList[i].mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(DynOS_Actor_GetLayoutFromIndex(i), false);
|
||||
}
|
||||
|
||||
void DynOS_Gfx_Init() {
|
||||
// Scan the DynOS packs folder
|
||||
SysPath _DynosPacksFolder = fstring("%s/%s", DYNOS_EXE_FOLDER, DYNOS_PACKS_FOLDER);
|
||||
ScanPacksFolder(_DynosPacksFolder);
|
||||
|
@ -88,18 +78,4 @@ Array<String> DynOS_Gfx_Init() {
|
|||
// Scan the user path folder
|
||||
SysPath _DynosPacksUserFolder = fstring("%s/%s", DYNOS_USER_FOLDER, DYNOS_PACKS_FOLDER);
|
||||
ScanPacksFolder(_DynosPacksUserFolder);
|
||||
|
||||
// Return a list of pack names
|
||||
Array<PackData *> &pDynosPacks = DynOS_Gfx_GetPacks();
|
||||
Array<String> _PackNames;
|
||||
for (const auto& _Pack : pDynosPacks) {
|
||||
u64 _DirSep1 = _Pack->mPath.find_last_of('\\');
|
||||
u64 _DirSep2 = _Pack->mPath.find_last_of('/');
|
||||
if (_DirSep1++ == SysPath::npos) _DirSep1 = 0;
|
||||
if (_DirSep2++ == SysPath::npos) _DirSep2 = 0;
|
||||
SysPath _DirName = _Pack->mPath.substr(MAX(_DirSep1, _DirSep2));
|
||||
_PackNames.Add(_DirName.c_str());
|
||||
}
|
||||
|
||||
return _PackNames;
|
||||
}
|
||||
|
|
|
@ -1,169 +1,6 @@
|
|||
#include "dynos.cpp.h"
|
||||
extern "C" {
|
||||
#include "object_fields.h"
|
||||
#include "game/level_update.h"
|
||||
#include "game/object_list_processor.h"
|
||||
#include "pc/configfile.h"
|
||||
}
|
||||
|
||||
//
|
||||
// Update animations
|
||||
//
|
||||
|
||||
// Retrieve the current Mario's animation index
|
||||
static s32 RetrieveCurrentMarioAnimationIndex() {
|
||||
struct MarioAnimDmaRelatedThing *_AnimDmaTable = gMarioState->animation->animDmaTable;
|
||||
for (s32 i = 0; i != (s32) _AnimDmaTable->count; ++i) {
|
||||
void *_AnimAddr = _AnimDmaTable->srcAddr + _AnimDmaTable->anim[i].offset;
|
||||
if (_AnimAddr == gMarioState->animation->currentAnimAddr) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Retrieve the current animation index
|
||||
// As we don't know the length of the table, let's hope that we'll always find the animation...
|
||||
static s32 RetrieveCurrentAnimationIndex(struct Object *aObject) {
|
||||
if (!aObject->oAnimations || !aObject->header.gfx.animInfo.curAnim) {
|
||||
return -1;
|
||||
}
|
||||
for (s32 i = 0; aObject->oAnimations[i] != NULL; ++i) {
|
||||
if (aObject->oAnimations[i] == aObject->header.gfx.animInfo.curAnim) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Must be called twice, before and after geo_set_animation_globals
|
||||
void DynOS_Gfx_SwapAnimations(void *aPtr) {
|
||||
static Animation *pDefaultAnimation = NULL;
|
||||
static Animation sGfxDataAnimation;
|
||||
|
||||
// Does the object has a model?
|
||||
struct Object *_Object = (struct Object *) aPtr;
|
||||
if (!_Object->header.gfx.sharedChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Swap the current animation with the one from the Gfx data
|
||||
if (!pDefaultAnimation) {
|
||||
pDefaultAnimation = _Object->header.gfx.animInfo.curAnim;
|
||||
|
||||
// Actor index
|
||||
s32 _ActorIndex = DynOS_Actor_GetIndex(_Object->header.gfx.sharedChild->georef);
|
||||
if (_ActorIndex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Gfx data
|
||||
GfxData *_GfxData = DynOS_Gfx_GetActorList()[_ActorIndex].mGfxData;
|
||||
if (!_GfxData) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Animation table
|
||||
if (_GfxData->mAnimationTable.Empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Animation index
|
||||
s32 _AnimIndex = (_Object == gMarioObject ? RetrieveCurrentMarioAnimationIndex() : RetrieveCurrentAnimationIndex(_Object));
|
||||
if (_AnimIndex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Animation data
|
||||
const AnimData *_AnimData = (const AnimData *) _GfxData->mAnimationTable[_AnimIndex].second;
|
||||
if (_AnimData) {
|
||||
sGfxDataAnimation.flags = _AnimData->mFlags;
|
||||
sGfxDataAnimation.animYTransDivisor = _AnimData->mUnk02;
|
||||
sGfxDataAnimation.startFrame = _AnimData->mUnk04;
|
||||
sGfxDataAnimation.loopStart = _AnimData->mUnk06;
|
||||
sGfxDataAnimation.loopEnd = _AnimData->mUnk08;
|
||||
sGfxDataAnimation.unusedBoneCount = _AnimData->mUnk0A.second;
|
||||
sGfxDataAnimation.values = _AnimData->mValues.second.begin();
|
||||
sGfxDataAnimation.index = _AnimData->mIndex.second.begin();
|
||||
sGfxDataAnimation.length = _AnimData->mLength;
|
||||
_Object->header.gfx.animInfo.curAnim = &sGfxDataAnimation;
|
||||
}
|
||||
|
||||
// Restore the default animation
|
||||
} else {
|
||||
_Object->header.gfx.animInfo.curAnim = pDefaultAnimation;
|
||||
pDefaultAnimation = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update models
|
||||
//
|
||||
|
||||
void DynOS_Gfx_Update() {
|
||||
if (!gObjectLists) { return; }
|
||||
|
||||
// Check packs
|
||||
Array<bool> &_Enabled = DynOS_Gfx_GetPacksEnabled();
|
||||
const Array<PackData *> &pDynosPacks = DynOS_Gfx_GetPacks();
|
||||
while (_Enabled.Count() < pDynosPacks.Count()) {
|
||||
_Enabled.Add(true);
|
||||
}
|
||||
|
||||
// Loop through all object lists
|
||||
for (s32 list : { OBJ_LIST_PLAYER, OBJ_LIST_DESTRUCTIVE, OBJ_LIST_GENACTOR, OBJ_LIST_PUSHABLE, OBJ_LIST_LEVEL, OBJ_LIST_DEFAULT, OBJ_LIST_SURFACE, OBJ_LIST_POLELIKE, OBJ_LIST_UNIMPORTANT }) {
|
||||
struct Object *_Head = (struct Object *) &gObjectLists[list];
|
||||
for (struct Object *_Object = (struct Object *) _Head->header.next; _Object != _Head; _Object = (struct Object *) _Object->header.next) {
|
||||
// Make sure it's non-null
|
||||
if (!_Object->header.gfx.sharedChild) { continue; }
|
||||
|
||||
// Actor index
|
||||
s32 _ActorIndex = DynOS_Actor_GetIndex(_Object->header.gfx.sharedChild->georef);
|
||||
if (_ActorIndex == -1) { continue; }
|
||||
|
||||
// Replace the object's model and animations
|
||||
ActorGfx *_ActorGfx = &DynOS_Gfx_GetActorList()[_ActorIndex];
|
||||
|
||||
// Check for disabled downloaded models
|
||||
if (configDisableDownloadedModels && _ActorGfx->mPackIndex == 99) {
|
||||
extern const GeoLayout error_model_geo[];
|
||||
s32 actorIndex = DynOS_Actor_IsCustom(_ActorIndex) ? DynOS_Actor_GetIndex(error_model_geo) : _ActorIndex;
|
||||
const void* geoLayout = DynOS_Actor_GetLayoutFromIndex(actorIndex);
|
||||
_ActorGfx->mPackIndex = -1;
|
||||
_ActorGfx->mGfxData = NULL;
|
||||
_ActorGfx->mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(geoLayout, true);
|
||||
}
|
||||
|
||||
for (s32 i = 0; i != pDynosPacks.Count(); ++i) {
|
||||
// If enabled and no pack is selected
|
||||
// load the pack's model and replace the default actor's model
|
||||
if (_Enabled[i] && _ActorGfx->mPackIndex == -1) {
|
||||
|
||||
// Load Gfx data from binary
|
||||
SysPath _Filename = fstring("%s/%s.bin", pDynosPacks[i]->mPath.begin(), DynOS_Actor_GetName(_ActorIndex));
|
||||
GfxData *_GfxData = DynOS_Actor_LoadFromBinary(pDynosPacks[i]->mPath, DynOS_Actor_GetName(_ActorIndex), _Filename);
|
||||
if (_GfxData) {
|
||||
_ActorGfx->mPackIndex = i;
|
||||
_ActorGfx->mGfxData = _GfxData;
|
||||
_ActorGfx->mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode((*(_GfxData->mGeoLayouts.end() - 1))->mData, true);
|
||||
_ActorGfx->mGraphNode->georef = DynOS_Actor_GetLayoutFromIndex(_ActorIndex);
|
||||
DynOS_Tex_Valid(_GfxData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If disabled and this pack is the one selected
|
||||
// replace the actor's model by the default one
|
||||
else if (!_Enabled[i] && _ActorGfx->mPackIndex == i) {
|
||||
DynOS_Tex_Invalid(_ActorGfx->mGfxData);
|
||||
_ActorGfx->mPackIndex = -1;
|
||||
_ActorGfx->mGfxData = NULL;
|
||||
_ActorGfx->mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(DynOS_Actor_GetLayoutFromIndex(_ActorIndex), true);
|
||||
}
|
||||
}
|
||||
|
||||
// Update object
|
||||
_Object->header.gfx.sharedChild = _ActorGfx->mGraphNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,36 @@
|
|||
#include <map>
|
||||
#include "dynos.cpp.h"
|
||||
|
||||
static Array<Pair<const char*, void *>> sDynosCustomActors;
|
||||
extern "C" {
|
||||
#include "object_fields.h"
|
||||
#include "game/level_update.h"
|
||||
#include "game/object_list_processor.h"
|
||||
#include "pc/configfile.h"
|
||||
}
|
||||
|
||||
// Static maps/arrays
|
||||
static std::map<const void*, ActorGfx>& DynosValidActors() {
|
||||
static std::map<const void*, ActorGfx> sDynosValidActors;
|
||||
return sDynosValidActors;
|
||||
}
|
||||
|
||||
static Array<Pair<const char*, void *>>& DynosCustomActors() {
|
||||
static Array<Pair<const char*, void *>> sDynosCustomActors;
|
||||
return sDynosCustomActors;
|
||||
}
|
||||
|
||||
// TODO: the cleanup/refactor didn't really go as planned.
|
||||
// clean up the actor management code more
|
||||
|
||||
void DynOS_Actor_AddCustom(const SysPath &aFilename, const char *aActorName) {
|
||||
// check for duplicates
|
||||
bool isUnique = true;
|
||||
s32 foundIndex = -1;
|
||||
for (s32 i = 0; i < DynOS_Actor_GetCount(); ++i) {
|
||||
if (!strcmp(DynOS_Actor_GetName(i), aActorName)) {
|
||||
isUnique = false;
|
||||
foundIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const void* georef = DynOS_Builtin_Actor_GetFromName(aActorName);
|
||||
|
||||
u16 actorLen = strlen(aActorName);
|
||||
char* actorName = (char*)calloc(1, sizeof(char) * (actorLen + 1));
|
||||
strcpy(actorName, aActorName);
|
||||
|
||||
GfxData *_GfxData = DynOS_Actor_LoadFromBinary(aFilename, actorName, aFilename);
|
||||
GfxData *_GfxData = DynOS_Actor_LoadFromBinary(aFilename, actorName, aFilename, false);
|
||||
if (!_GfxData) {
|
||||
Print(" ERROR: Couldn't load Actor Binary \"%s\" from \"%s\"", actorName, aFilename.c_str());
|
||||
free(actorName);
|
||||
|
@ -36,36 +45,20 @@ void DynOS_Actor_AddCustom(const SysPath &aFilename, const char *aActorName) {
|
|||
}
|
||||
|
||||
// Add to custom actors
|
||||
s32 index = DynOS_Actor_GetCount();
|
||||
if (isUnique) {
|
||||
sDynosCustomActors.Add({ actorName, geoLayout });
|
||||
} else {
|
||||
index = foundIndex;
|
||||
if (georef == NULL) {
|
||||
DynosCustomActors().Add({ actorName, geoLayout });
|
||||
georef = geoLayout;
|
||||
}
|
||||
|
||||
// Alloc and init the actors gfx list
|
||||
Array<ActorGfx> &pActorGfxList = DynOS_Gfx_GetActorList();
|
||||
pActorGfxList.Resize(DynOS_Actor_GetCount());
|
||||
pActorGfxList[index].mPackIndex = 99;
|
||||
pActorGfxList[index].mGfxData = _GfxData;
|
||||
pActorGfxList[index].mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(geoLayout, false);
|
||||
DynOS_Tex_Valid(_GfxData);
|
||||
}
|
||||
ActorGfx actorGfx = {
|
||||
.mGfxData = _GfxData,
|
||||
.mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(geoLayout, false),
|
||||
.mPackIndex = 99,
|
||||
};
|
||||
|
||||
s32 DynOS_Actor_GetCount() {
|
||||
return (s32) DynOS_Builtin_Actor_GetCount() + sDynosCustomActors.Count();
|
||||
}
|
||||
|
||||
const char *DynOS_Actor_GetName(s32 aIndex) {
|
||||
s32 builtinCount = DynOS_Builtin_Actor_GetCount();
|
||||
if (aIndex < builtinCount) { return (const char *) DynOS_Builtin_Actor_GetNameFromIndex(aIndex); }
|
||||
return sDynosCustomActors[aIndex - builtinCount].first;
|
||||
}
|
||||
|
||||
const void *DynOS_Actor_GetLayoutFromIndex(s32 aIndex) {
|
||||
s32 builtinCount = DynOS_Builtin_Actor_GetCount();
|
||||
if (aIndex < builtinCount) { return (const void *) DynOS_Builtin_Actor_GetFromIndex(aIndex); }
|
||||
return sDynosCustomActors[aIndex - builtinCount].second;
|
||||
// Add to list
|
||||
DynOS_Actor_Valid(georef, actorGfx);
|
||||
}
|
||||
|
||||
const void *DynOS_Actor_GetLayoutFromName(const char *aActorName) {
|
||||
|
@ -81,26 +74,73 @@ const void *DynOS_Actor_GetLayoutFromName(const char *aActorName) {
|
|||
}
|
||||
}
|
||||
|
||||
// check actors
|
||||
for (s32 i = 0; i < DynOS_Actor_GetCount(); ++i) {
|
||||
if (!strcmp(DynOS_Actor_GetName(i), aActorName)) {
|
||||
return DynOS_Actor_GetLayoutFromIndex(i);
|
||||
// check loaded actors
|
||||
for (auto& pair : DynosValidActors()) {
|
||||
for (auto& geo : pair.second.mGfxData->mGeoLayouts) {
|
||||
if (!strcmp(aActorName, geo->mName.begin())) {
|
||||
return geo->mData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check built in actors
|
||||
for (s32 i = 0; i < DynOS_Builtin_Actor_GetCount(); ++i) {
|
||||
auto name = DynOS_Builtin_Actor_GetNameFromIndex(i);
|
||||
if (!strcmp(aActorName, name)) {
|
||||
return DynOS_Builtin_Actor_GetFromIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s32 DynOS_Actor_GetIndex(const void *aGeoLayout) {
|
||||
for (s32 i = 0; i < DynOS_Actor_GetCount(); ++i) {
|
||||
if (DynOS_Actor_GetLayoutFromIndex(i) == aGeoLayout) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
ActorGfx* DynOS_Actor_GetActorGfx(const void* aGeoref) {
|
||||
if (aGeoref == NULL) { return NULL; }
|
||||
auto& _ValidActors = DynosValidActors();
|
||||
if (_ValidActors.count(aGeoref) == 0) { return NULL; }
|
||||
return &_ValidActors[aGeoref];
|
||||
}
|
||||
|
||||
bool DynOS_Actor_IsCustom(s32 aIndex) {
|
||||
s32 builtinCount = DynOS_Builtin_Actor_GetCount();
|
||||
return aIndex >= builtinCount;
|
||||
void DynOS_Actor_Valid(const void* aGeoref, ActorGfx& aActorGfx) {
|
||||
if (aGeoref == NULL) { return; }
|
||||
auto& _ValidActors = DynosValidActors();
|
||||
_ValidActors[aGeoref] = aActorGfx;
|
||||
DynOS_Tex_Valid(aActorGfx.mGfxData);
|
||||
}
|
||||
|
||||
void DynOS_Actor_Invalid(const void* aGeoref, s32 aPackIndex) {
|
||||
if (aGeoref == NULL) { return; }
|
||||
auto& _ValidActors = DynosValidActors();
|
||||
if (_ValidActors.count(aGeoref) == 0) { return; }
|
||||
if (_ValidActors[aGeoref].mPackIndex != aPackIndex) { return; }
|
||||
|
||||
DynOS_Tex_Invalid(_ValidActors[aGeoref].mGfxData);
|
||||
_ValidActors.erase(aGeoref);
|
||||
}
|
||||
|
||||
void DynOS_Actor_Override(void** aSharedChild) {
|
||||
if ((aSharedChild == NULL) || (*aSharedChild == NULL)) { return; }
|
||||
|
||||
const void* georef = (*(GraphNode**)aSharedChild)->georef;
|
||||
if (georef == NULL) { return; }
|
||||
|
||||
auto& _ValidActors = DynosValidActors();
|
||||
if (_ValidActors.count(georef) == 0) { return; }
|
||||
|
||||
*aSharedChild = (void*)_ValidActors[georef].mGraphNode;
|
||||
}
|
||||
|
||||
void DynOS_Actor_Override_All(void) {
|
||||
if (!gObjectLists) { return; }
|
||||
// Loop through all object lists
|
||||
for (s32 list : { OBJ_LIST_PLAYER, OBJ_LIST_DESTRUCTIVE, OBJ_LIST_GENACTOR, OBJ_LIST_PUSHABLE, OBJ_LIST_LEVEL, OBJ_LIST_DEFAULT, OBJ_LIST_SURFACE, OBJ_LIST_POLELIKE, OBJ_LIST_UNIMPORTANT }) {
|
||||
struct Object *_Head = (struct Object *) &gObjectLists[list];
|
||||
for (struct Object *_Object = (struct Object *) _Head->header.next; _Object != _Head; _Object = (struct Object *) _Object->header.next) {
|
||||
if (_Object->header.gfx.sharedChild != NULL && _Object->header.gfx.sharedChild->georef != NULL) {
|
||||
GraphNode* georef =(GraphNode*)_Object->header.gfx.sharedChild->georef;
|
||||
_Object->header.gfx.sharedChild = (GraphNode *) DynOS_Geo_GetGraphNode(georef, true);
|
||||
}
|
||||
DynOS_Actor_Override((void**)&_Object->header.gfx.sharedChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
#include "dynos.cpp.h"
|
||||
extern "C" {
|
||||
#include "object_fields.h"
|
||||
#include "game/level_update.h"
|
||||
#include "game/object_list_processor.h"
|
||||
#include "pc/configfile.h"
|
||||
}
|
||||
|
||||
//
|
||||
// Update animations
|
||||
//
|
||||
|
||||
// Retrieve the current Mario's animation index
|
||||
static s32 RetrieveCurrentMarioAnimationIndex(u32 aPlayerIndex) {
|
||||
struct MarioAnimDmaRelatedThing *_AnimDmaTable = gMarioStates[aPlayerIndex].animation->animDmaTable;
|
||||
for (s32 i = 0; i != (s32) _AnimDmaTable->count; ++i) {
|
||||
void *_AnimAddr = _AnimDmaTable->srcAddr + _AnimDmaTable->anim[i].offset;
|
||||
if (_AnimAddr == gMarioStates[aPlayerIndex].animation->currentAnimAddr) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Retrieve the current animation index
|
||||
// As we don't know the length of the table, let's hope that we'll always find the animation...
|
||||
static s32 RetrieveCurrentAnimationIndex(struct Object *aObject) {
|
||||
if (!aObject->oAnimations || !aObject->header.gfx.animInfo.curAnim) {
|
||||
return -1;
|
||||
}
|
||||
for (s32 i = 0; aObject->oAnimations[i] != NULL; ++i) {
|
||||
if (aObject->oAnimations[i] == aObject->header.gfx.animInfo.curAnim) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Must be called twice, before and after geo_set_animation_globals
|
||||
void DynOS_Anim_Swap(void *aPtr) {
|
||||
static Animation *pDefaultAnimation = NULL;
|
||||
static Animation sGfxDataAnimation;
|
||||
|
||||
// Does the object has a model?
|
||||
struct Object *_Object = (struct Object *) aPtr;
|
||||
if (!_Object->header.gfx.sharedChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Swap the current animation with the one from the Gfx data
|
||||
if (!pDefaultAnimation) {
|
||||
pDefaultAnimation = _Object->header.gfx.animInfo.curAnim;
|
||||
|
||||
// ActorGfx data
|
||||
ActorGfx* _ActorGfx = DynOS_Actor_GetActorGfx(_Object->header.gfx.sharedChild->georef);
|
||||
if (!_ActorGfx) {
|
||||
return;
|
||||
}
|
||||
|
||||
// GfxData
|
||||
GfxData* _GfxData = _ActorGfx->mGfxData;
|
||||
if (!_GfxData) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Animation table
|
||||
if (_GfxData->mAnimationTable.Empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Animation index
|
||||
s32 _AnimIndex = -1;
|
||||
for (u32 i = 0; i < MAX_PLAYERS; i++) {
|
||||
if (gMarioStates[i].marioObj == NULL) { continue; }
|
||||
if (_Object == gMarioStates[i].marioObj) {
|
||||
_AnimIndex = RetrieveCurrentMarioAnimationIndex(i);
|
||||
}
|
||||
}
|
||||
if (_AnimIndex == -1) {
|
||||
_AnimIndex = RetrieveCurrentAnimationIndex(_Object);
|
||||
}
|
||||
if (_AnimIndex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Animation data
|
||||
const AnimData *_AnimData = (const AnimData *) _GfxData->mAnimationTable[_AnimIndex].second;
|
||||
if (_AnimData) {
|
||||
sGfxDataAnimation.flags = _AnimData->mFlags;
|
||||
sGfxDataAnimation.animYTransDivisor = _AnimData->mUnk02;
|
||||
sGfxDataAnimation.startFrame = _AnimData->mUnk04;
|
||||
sGfxDataAnimation.loopStart = _AnimData->mUnk06;
|
||||
sGfxDataAnimation.loopEnd = _AnimData->mUnk08;
|
||||
sGfxDataAnimation.unusedBoneCount = _AnimData->mUnk0A.second;
|
||||
sGfxDataAnimation.values = _AnimData->mValues.second.begin();
|
||||
sGfxDataAnimation.index = _AnimData->mIndex.second.begin();
|
||||
sGfxDataAnimation.length = _AnimData->mLength;
|
||||
_Object->header.gfx.animInfo.curAnim = &sGfxDataAnimation;
|
||||
}
|
||||
|
||||
// Restore the default animation
|
||||
} else {
|
||||
_Object->header.gfx.animInfo.curAnim = pDefaultAnimation;
|
||||
pDefaultAnimation = NULL;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,16 @@
|
|||
#include "dynos.cpp.h"
|
||||
|
||||
static Array<Pair<const char*, DataNode<Collision>*>> sDynosCollisions;
|
||||
static Array<Pair<const char*, DataNode<Collision>*>>& DynosCollisions() {
|
||||
static Array<Pair<const char*, DataNode<Collision>*>> sDynosCollisions;
|
||||
return sDynosCollisions;
|
||||
}
|
||||
|
||||
void DynOS_Col_Activate(const SysPath &aFilename, const char *aCollisionName) {
|
||||
auto& _DynosCollisions = DynosCollisions();
|
||||
|
||||
// check for duplicates
|
||||
for (s32 i = 0; i < sDynosCollisions.Count(); ++i) {
|
||||
if (!strcmp(sDynosCollisions[i].first, aCollisionName)) {
|
||||
for (s32 i = 0; i < _DynosCollisions.Count(); ++i) {
|
||||
if (!strcmp(_DynosCollisions[i].first, aCollisionName)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -23,10 +28,12 @@ void DynOS_Col_Activate(const SysPath &aFilename, const char *aCollisionName) {
|
|||
}
|
||||
|
||||
// Add to collisions
|
||||
sDynosCollisions.Add({ collisionName, _Node });
|
||||
_DynosCollisions.Add({ collisionName, _Node });
|
||||
}
|
||||
|
||||
Collision* DynOS_Col_Get(const char* collisionName) {
|
||||
auto& _DynosCollisions = DynosCollisions();
|
||||
|
||||
// check levels
|
||||
auto& levelsArray = DynOS_Lvl_GetArray();
|
||||
for (auto& lvl : levelsArray) {
|
||||
|
@ -38,9 +45,9 @@ Collision* DynOS_Col_Get(const char* collisionName) {
|
|||
}
|
||||
|
||||
// check mod actor collisions
|
||||
for (s32 i = 0; i < sDynosCollisions.Count(); ++i) {
|
||||
if (!strcmp(sDynosCollisions[i].first, collisionName)) {
|
||||
return sDynosCollisions[i].second->mData;
|
||||
for (s32 i = 0; i < _DynosCollisions.Count(); ++i) {
|
||||
if (!strcmp(_DynosCollisions[i].first, collisionName)) {
|
||||
return _DynosCollisions[i].second->mData;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,20 +10,26 @@ struct OverrideLevelScript {
|
|||
GfxData* gfxData;
|
||||
};
|
||||
|
||||
static Array<Pair<const char*, GfxData*>> sDynosCustomLevelScripts;
|
||||
static Array<struct OverrideLevelScript> sDynosOverrideLevelScripts;
|
||||
static Array<struct OverrideLevelScript>& DynosOverrideLevelScripts() {
|
||||
static Array<struct OverrideLevelScript> sDynosOverrideLevelScripts;
|
||||
return sDynosOverrideLevelScripts;
|
||||
}
|
||||
|
||||
Array<Pair<const char*, GfxData*>> &DynOS_Lvl_GetArray() {
|
||||
static Array<Pair<const char*, GfxData*>> sDynosCustomLevelScripts;
|
||||
return sDynosCustomLevelScripts;
|
||||
}
|
||||
|
||||
void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLevelName) {
|
||||
auto& _CustomLevelScripts = DynOS_Lvl_GetArray();
|
||||
auto& _OverrideLevelScripts = DynosOverrideLevelScripts();
|
||||
|
||||
// make sure vanilla levels were parsed
|
||||
DynOS_Level_GetCount();
|
||||
|
||||
// check for duplicates
|
||||
for (s32 i = 0; i < sDynosCustomLevelScripts.Count(); ++i) {
|
||||
if (!strcmp(sDynosCustomLevelScripts[i].first, aLevelName)) {
|
||||
for (s32 i = 0; i < _CustomLevelScripts.Count(); ++i) {
|
||||
if (!strcmp(_CustomLevelScripts[i].first, aLevelName)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +48,7 @@ void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLev
|
|||
_Node->mModIndex = modIndex;
|
||||
|
||||
// Add to levels
|
||||
sDynosCustomLevelScripts.Add({ levelName, _Node });
|
||||
_CustomLevelScripts.Add({ levelName, _Node });
|
||||
|
||||
// Override vanilla script
|
||||
auto& newScripts = _Node->mLevelScripts;
|
||||
|
@ -54,13 +60,15 @@ void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLev
|
|||
}
|
||||
|
||||
DynOS_Level_Override((void*)originalScript, newScriptNode->mData);
|
||||
sDynosOverrideLevelScripts.Add({ originalScript, newScriptNode->mData, _Node});
|
||||
_OverrideLevelScripts.Add({ originalScript, newScriptNode->mData, _Node});
|
||||
DynOS_Tex_Valid(_Node);
|
||||
}
|
||||
|
||||
GfxData* DynOS_Lvl_GetActiveGfx(void) {
|
||||
for (s32 i = 0; i < sDynosCustomLevelScripts.Count(); ++i) {
|
||||
auto& gfxData = sDynosCustomLevelScripts[i].second;
|
||||
auto& _CustomLevelScripts = DynOS_Lvl_GetArray();
|
||||
|
||||
for (s32 i = 0; i < _CustomLevelScripts.Count(); ++i) {
|
||||
auto& gfxData = _CustomLevelScripts[i].second;
|
||||
auto& scripts = gfxData->mLevelScripts;
|
||||
if (gLevelScriptActive == scripts[scripts.Count() - 1]->mData) {
|
||||
return gfxData;
|
||||
|
@ -86,7 +94,9 @@ const char* DynOS_Lvl_GetToken(u32 index) {
|
|||
}
|
||||
|
||||
Trajectory* DynOS_Lvl_GetTrajectory(const char* aName) {
|
||||
for (auto& script : sDynosCustomLevelScripts) {
|
||||
auto& _CustomLevelScripts = DynOS_Lvl_GetArray();
|
||||
|
||||
for (auto& script : _CustomLevelScripts) {
|
||||
for (auto& trajectoryNode : script.second->mTrajectories) {
|
||||
if (trajectoryNode->mName == aName) {
|
||||
return trajectoryNode->mData;
|
||||
|
@ -97,10 +107,12 @@ Trajectory* DynOS_Lvl_GetTrajectory(const char* aName) {
|
|||
}
|
||||
|
||||
void DynOS_Lvl_LoadBackground(void *aPtr) {
|
||||
auto& _CustomLevelScripts = DynOS_Lvl_GetArray();
|
||||
|
||||
// ensure this texture list exists
|
||||
GfxData* foundGfxData = NULL;
|
||||
DataNode<TexData*>* foundList = NULL;
|
||||
for (auto& script : sDynosCustomLevelScripts) {
|
||||
for (auto& script : _CustomLevelScripts) {
|
||||
auto &textureLists = script.second->mTextureLists;
|
||||
for (auto& textureList : textureLists) {
|
||||
if (textureList == aPtr) {
|
||||
|
@ -130,7 +142,9 @@ double_break:
|
|||
}
|
||||
|
||||
void *DynOS_Lvl_Override(void *aCmd) {
|
||||
for (auto& overrideStruct : sDynosOverrideLevelScripts) {
|
||||
auto& _OverrideLevelScripts = DynosOverrideLevelScripts();
|
||||
|
||||
for (auto& overrideStruct : _OverrideLevelScripts) {
|
||||
if (aCmd == overrideStruct.originalScript || aCmd == overrideStruct.newScript) {
|
||||
aCmd = (void*)overrideStruct.newScript;
|
||||
gLevelScriptModIndex = overrideStruct.gfxData->mModIndex;
|
||||
|
|
|
@ -10,11 +10,16 @@ struct RegisteredMovtexQC {
|
|||
s16 type;
|
||||
};
|
||||
|
||||
static Array<RegisteredMovtexQC> sDynosRegisteredMovtexQCs;
|
||||
static Array<RegisteredMovtexQC>& DynosRegisteredMovtexQCs() {
|
||||
static Array<RegisteredMovtexQC> sDynosRegisteredMovtexQCs;
|
||||
return sDynosRegisteredMovtexQCs;
|
||||
}
|
||||
|
||||
void DynOS_MovtexQC_Register(const char* name, s16 level, s16 area, s16 type) {
|
||||
auto& _DynosRegisteredMovtexQCs = DynosRegisteredMovtexQCs();
|
||||
|
||||
// check for duplicates
|
||||
for (auto& registered : sDynosRegisteredMovtexQCs) {
|
||||
for (auto& registered : _DynosRegisteredMovtexQCs) {
|
||||
if (registered.level == level && registered.area == area && registered.type == type) { return; }
|
||||
}
|
||||
|
||||
|
@ -23,7 +28,7 @@ void DynOS_MovtexQC_Register(const char* name, s16 level, s16 area, s16 type) {
|
|||
for (auto& node : lvlPair.second->mMovtexQCs) {
|
||||
if (node->mName == name) {
|
||||
// add it
|
||||
sDynosRegisteredMovtexQCs.Add({
|
||||
_DynosRegisteredMovtexQCs.Add({
|
||||
.dataNode = node,
|
||||
.level = level,
|
||||
.area = area,
|
||||
|
@ -35,9 +40,11 @@ void DynOS_MovtexQC_Register(const char* name, s16 level, s16 area, s16 type) {
|
|||
}
|
||||
|
||||
DataNode<MovtexQC>* DynOS_MovtexQC_GetFromId(u32 id) {
|
||||
auto& _DynosRegisteredMovtexQCs = DynosRegisteredMovtexQCs();
|
||||
|
||||
// find the datanode
|
||||
s16 type = (id & 0xF);
|
||||
for (auto& registered : sDynosRegisteredMovtexQCs) {
|
||||
for (auto& registered : _DynosRegisteredMovtexQCs) {
|
||||
if (registered.level == gCurrLevelNum && registered.area == gCurrAreaIndex && registered.type == type) {
|
||||
return registered.dataNode;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
#include "dynos.cpp.h"
|
||||
|
||||
static Array<PackData>& DynosPacks() {
|
||||
static Array<PackData> sDynosPacks;
|
||||
return sDynosPacks;
|
||||
}
|
||||
|
||||
static void DynOS_Pack_ActivateActor(s32 aPackIndex, Pair<const char *, GfxData *>& pair) {
|
||||
const char* aActorName = pair.first;
|
||||
GfxData* aGfxData = pair.second;
|
||||
|
||||
GraphNode* graphNode = (GraphNode *) DynOS_Geo_GetGraphNode((*(aGfxData->mGeoLayouts.end() - 1))->mData, false);
|
||||
if (graphNode == NULL) { return; }
|
||||
|
||||
const void* georef = DynOS_Builtin_Actor_GetFromName(aActorName);
|
||||
graphNode->georef = georef;
|
||||
|
||||
ActorGfx actorGfx = {
|
||||
.mGfxData = aGfxData,
|
||||
.mGraphNode = graphNode,
|
||||
.mPackIndex = aPackIndex,
|
||||
};
|
||||
|
||||
DynOS_Actor_Valid(georef, actorGfx);
|
||||
}
|
||||
|
||||
static void DynOS_Pack_DeactivateActor(s32 aPackIndex, Pair<const char *, GfxData *>& pair) {
|
||||
const char* aActorName = pair.first;
|
||||
const void* georef = DynOS_Builtin_Actor_GetFromName(aActorName);
|
||||
DynOS_Actor_Invalid(georef, aPackIndex);
|
||||
|
||||
// figure out which actor to replace it with
|
||||
Pair<const char *, GfxData *>* _Replacement = NULL;
|
||||
s32 _ReplacementPackIndex = 0;
|
||||
for (auto& _Pack : DynosPacks()) {
|
||||
if (!_Pack.mEnabled) { continue; }
|
||||
auto _Tmp = DynOS_Pack_GetActor(&_Pack, aActorName);
|
||||
if (_Tmp != NULL) {
|
||||
_Replacement = _Tmp;
|
||||
_ReplacementPackIndex = _Pack.mIndex;
|
||||
}
|
||||
}
|
||||
if (_Replacement != NULL) {
|
||||
DynOS_Pack_ActivateActor(_ReplacementPackIndex, *_Replacement);
|
||||
}
|
||||
}
|
||||
|
||||
s32 DynOS_Pack_GetCount() {
|
||||
return DynosPacks().Count();
|
||||
}
|
||||
|
||||
void DynOS_Pack_SetEnabled(PackData* aPack, bool aEnabled) {
|
||||
if (aPack == NULL) { return; }
|
||||
aPack->mEnabled = aEnabled;
|
||||
|
||||
if (aEnabled) {
|
||||
for (auto& pair : aPack->mGfxData) {
|
||||
DynOS_Pack_ActivateActor(aPack->mIndex, pair);
|
||||
}
|
||||
} else {
|
||||
for (auto& pair : aPack->mGfxData) {
|
||||
DynOS_Pack_DeactivateActor(aPack->mIndex, pair);
|
||||
}
|
||||
}
|
||||
DynOS_Actor_Override_All();
|
||||
}
|
||||
|
||||
PackData* DynOS_Pack_GetFromIndex(s32 aIndex) {
|
||||
auto& _DynosPacks = DynosPacks();
|
||||
if (aIndex < 0 || aIndex >= _DynosPacks.Count()) {
|
||||
return NULL;
|
||||
}
|
||||
return &_DynosPacks[aIndex];
|
||||
}
|
||||
|
||||
PackData* DynOS_Pack_GetFromPath(const SysPath& aPath) {
|
||||
for (auto& packData : DynosPacks()) {
|
||||
if (packData.mPath == aPath) {
|
||||
return &packData;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PackData* DynOS_Pack_Add(const SysPath& aPath) {
|
||||
PackData* existing = DynOS_Pack_GetFromPath(aPath);
|
||||
if (existing != NULL) { return existing; }
|
||||
|
||||
auto& _DynosPacks = DynosPacks();
|
||||
s32 index = _DynosPacks.Count();
|
||||
_DynosPacks.Add({
|
||||
.mIndex = index,
|
||||
.mPath = aPath,
|
||||
.mGfxData = {},
|
||||
});
|
||||
|
||||
PackData* _Pack = &_DynosPacks[index];
|
||||
|
||||
// extract basename
|
||||
const char* cpath = aPath.c_str();
|
||||
const char* ctoken = cpath;
|
||||
while (*ctoken != '\0') {
|
||||
if (*ctoken == '/' || *ctoken == '\\') {
|
||||
if (*(ctoken + 1) != '\0') {
|
||||
cpath = (ctoken + 1);
|
||||
}
|
||||
}
|
||||
ctoken++;
|
||||
}
|
||||
_Pack->mDisplayName = cpath;
|
||||
|
||||
DynOS_Pack_SetEnabled(_Pack, true);
|
||||
|
||||
return _Pack;
|
||||
}
|
||||
|
||||
Pair<const char *, GfxData *>* DynOS_Pack_GetActor(PackData* aPackData, const char* aActorName) {
|
||||
if (aPackData == NULL || aActorName == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (auto& pair : aPackData->mGfxData) {
|
||||
if (!strcmp(pair.first, aActorName)) {
|
||||
return &pair;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DynOS_Pack_AddActor(PackData* aPackData, const char* aActorName, GfxData* aGfxData) {
|
||||
if (aPackData == NULL || aActorName == NULL || aGfxData == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
s32 index = aPackData->mGfxData.Count();
|
||||
aPackData->mGfxData.Add({ aActorName, aGfxData });
|
||||
|
||||
if (aPackData->mEnabled) {
|
||||
DynOS_Pack_ActivateActor(aPackData->mIndex, aPackData->mGfxData[index]);
|
||||
}
|
||||
}
|
|
@ -4,7 +4,11 @@ extern "C" {
|
|||
#include "pc/gfx/gfx_rendering_api.h"
|
||||
}
|
||||
|
||||
static std::set<DataNode<TexData> *> sDynosValidTextures;
|
||||
// static set
|
||||
static std::set<DataNode<TexData> *>& DynosValidTextures() {
|
||||
static std::set<DataNode<TexData> *> sDynosValidTextures;
|
||||
return sDynosValidTextures;
|
||||
}
|
||||
|
||||
//
|
||||
// Conversion
|
||||
|
@ -251,13 +255,13 @@ static bool DynOS_Tex_Cache(THN **aOutput, DataNode<TexData> *aNode, s32 aTile,
|
|||
|
||||
void DynOS_Tex_Valid(GfxData* aGfxData) {
|
||||
for (auto &_Texture : aGfxData->mTextures) {
|
||||
sDynosValidTextures.insert(_Texture);
|
||||
DynosValidTextures().insert(_Texture);
|
||||
}
|
||||
}
|
||||
|
||||
void DynOS_Tex_Invalid(GfxData* aGfxData) {
|
||||
for (auto &_Texture : aGfxData->mTextures) {
|
||||
sDynosValidTextures.erase(_Texture);
|
||||
DynosValidTextures().erase(_Texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,7 +270,8 @@ void DynOS_Tex_Invalid(GfxData* aGfxData) {
|
|||
//
|
||||
|
||||
static DataNode<TexData> *DynOS_Tex_RetrieveNode(void *aPtr) {
|
||||
if (sDynosValidTextures.find((DataNode<TexData>*)aPtr) != sDynosValidTextures.end()) {
|
||||
auto& _ValidTextures = DynosValidTextures();
|
||||
if (_ValidTextures.find((DataNode<TexData>*)aPtr) != _ValidTextures.end()) {
|
||||
return (DataNode<TexData>*)aPtr;
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
@ -605,7 +605,7 @@ static u32 DynOS_Opt_GetHash(const String& aStr) {
|
|||
}
|
||||
|
||||
static void DynOS_Opt_CreateModelPacksSubMenu() {
|
||||
Array<String> _Packs = DynOS_Gfx_Init();
|
||||
/*Array<String> _Packs = DynOS_Gfx_Init();
|
||||
if (_Packs.Count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -615,7 +615,7 @@ static void DynOS_Opt_CreateModelPacksSubMenu() {
|
|||
DynOS_Opt_CreateToggle(String("dynos_pack_%d", i), String("dynos_pack_%08X", DynOS_Opt_GetHash(_Packs[i])), _Packs[i], false);
|
||||
}
|
||||
DynOS_Opt_CreateButton("dynos_packs_disable_all", "Disable all packs", "DynOS_Opt_DisableAllPacks");
|
||||
DynOS_Opt_EndSubMenu();
|
||||
DynOS_Opt_EndSubMenu();*/
|
||||
}
|
||||
|
||||
void DynOS_Opt_Init() {
|
||||
|
|
|
@ -79,4 +79,13 @@
|
|||
# define LE_TO_HOST32(x) (x)
|
||||
#endif
|
||||
|
||||
// Optimize
|
||||
#ifdef __clang__
|
||||
#define OPTIMIZE_O3
|
||||
#elif __GNUC__
|
||||
#define OPTIMIZE_O3 __attribute__((optimize("O3")))
|
||||
#else
|
||||
#define OPTIMIZE_O3
|
||||
#endif
|
||||
|
||||
#endif // MACROS_H
|
||||
|
|
|
@ -1290,6 +1290,7 @@ void cur_obj_set_model(s32 modelID) {
|
|||
|
||||
void obj_set_model(struct Object* obj, s32 modelID) {
|
||||
obj->header.gfx.sharedChild = gLoadedGraphNodes[modelID];
|
||||
dynos_actor_override((void*)&obj->header.gfx.sharedChild);
|
||||
}
|
||||
|
||||
void mario_set_flag(s32 flag) {
|
||||
|
|
|
@ -265,22 +265,22 @@ static void dynos_pack_read(char** tokens, int numTokens) {
|
|||
}
|
||||
|
||||
bool enabled = !(strcmp(tokens[numTokens-1], "true"));
|
||||
int packCount = dynos_packs_get_count();
|
||||
int packCount = dynos_pack_get_count();
|
||||
|
||||
for (int i = 0; i < packCount; i++) {
|
||||
const char* pack = dynos_packs_get(i);
|
||||
const char* pack = dynos_pack_get_name(i);
|
||||
if (!strcmp(fullPackName, pack)) {
|
||||
dynos_packs_set_enabled(i, enabled);
|
||||
dynos_pack_set_enabled(i, enabled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dynos_pack_write(FILE* file) {
|
||||
int packCount = dynos_packs_get_count();
|
||||
int packCount = dynos_pack_get_count();
|
||||
for (int i = 0; i < packCount; i++) {
|
||||
bool enabled = dynos_packs_get_enabled(i);
|
||||
const char* pack = dynos_packs_get(i);
|
||||
bool enabled = dynos_pack_get_enabled(i);
|
||||
const char* pack = dynos_pack_get_name(i);
|
||||
fprintf(file, "%s %s %s\n", "dynos-pack:", pack, enabled ? "true" : "false");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
#include "data/dynos.c.h"
|
||||
|
||||
static void djui_panel_dynos_apply(struct DjuiBase* caller) {
|
||||
dynos_packs_set_enabled(caller->tag, caller->bTag);
|
||||
dynos_pack_set_enabled(caller->tag, caller->bTag);
|
||||
}
|
||||
|
||||
void djui_panel_dynos_create(struct DjuiBase* caller) {
|
||||
int packCount = dynos_packs_get_count();
|
||||
int packCount = dynos_pack_get_count();
|
||||
f32 bodyHeight = (416) + 64 * 1 + 16 * 1;
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
|
@ -19,8 +19,8 @@ void djui_panel_dynos_create(struct DjuiBase* caller) {
|
|||
struct DjuiPaginated* paginated = djui_paginated_create(&body->base, 8);
|
||||
struct DjuiBase* layoutBase = &paginated->layout->base;
|
||||
for (int i = 0; i < packCount; i++) {
|
||||
bool tmp = dynos_packs_get_enabled(i);
|
||||
const char* pack = dynos_packs_get(i);
|
||||
bool tmp = dynos_pack_get_enabled(i);
|
||||
const char* pack = dynos_pack_get_name(i);
|
||||
|
||||
struct DjuiCheckbox* checkbox1 = djui_checkbox_create(layoutBase, pack, &tmp);
|
||||
checkbox1->base.tag = i;
|
||||
|
|
|
@ -692,7 +692,7 @@ static void calculate_normal_dir(const Light_t *light, float coeffs[3]) {
|
|||
gfx_normalize_vector(coeffs);
|
||||
}
|
||||
|
||||
static void gfx_matrix_mul(float res[4][4], const float a[4][4], const float b[4][4]) {
|
||||
static void OPTIMIZE_O3 gfx_matrix_mul(float res[4][4], const float a[4][4], const float b[4][4]) {
|
||||
float tmp[4][4];
|
||||
for (int32_t i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
|
@ -757,7 +757,7 @@ static float gfx_adjust_x_for_aspect_ratio(float x) {
|
|||
return x * (4.0f / 3.0f) / ((float)gfx_current_dimensions.width / (float)gfx_current_dimensions.height);
|
||||
}
|
||||
|
||||
static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *vertices) {
|
||||
static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *vertices) {
|
||||
for (size_t i = 0; i < n_vertices; i++, dest_index++) {
|
||||
const Vtx_t *v = &vertices[i].v;
|
||||
const Vtx_tn *vn = &vertices[i].n;
|
||||
|
@ -862,7 +862,7 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
}
|
||||
}
|
||||
|
||||
static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
|
||||
static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
|
||||
struct LoadedVertex *v1 = &rsp.loaded_vertices[vtx1_idx];
|
||||
struct LoadedVertex *v2 = &rsp.loaded_vertices[vtx2_idx];
|
||||
struct LoadedVertex *v3 = &rsp.loaded_vertices[vtx3_idx];
|
||||
|
@ -1525,7 +1525,7 @@ static inline void *seg_addr(uintptr_t w1) {
|
|||
#define C0(pos, width) ((cmd->words.w0 >> (pos)) & ((1U << width) - 1))
|
||||
#define C1(pos, width) ((cmd->words.w1 >> (pos)) & ((1U << width) - 1))
|
||||
|
||||
static void gfx_run_dl(Gfx* cmd) {
|
||||
static void OPTIMIZE_O3 gfx_run_dl(Gfx* cmd) {
|
||||
for (;;) {
|
||||
uint32_t opcode = cmd->words.w0 >> 24;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <ultra64.h>
|
||||
#include "macros.h"
|
||||
|
||||
#ifdef __SSE4_1__
|
||||
#include <immintrin.h>
|
||||
|
@ -87,7 +88,7 @@ static int16_t resample_table[64][4] = {
|
|||
{0xffd8, 0x0e5f, 0x6696, 0x0b39}, {0xffdf, 0x0d46, 0x66ad, 0x0c39}
|
||||
};
|
||||
|
||||
static inline int16_t clamp16(int32_t v) {
|
||||
static inline int16_t OPTIMIZE_O3 clamp16(int32_t v) {
|
||||
if (v < -0x8000) {
|
||||
return -0x8000;
|
||||
} else if (v > 0x7fff) {
|
||||
|
@ -206,7 +207,7 @@ void aSetLoopImpl(ADPCM_STATE *adpcm_loop_state) {
|
|||
rspa.adpcm_loop_state = adpcm_loop_state;
|
||||
}
|
||||
|
||||
void aADPCMdecImpl(uint8_t flags, ADPCM_STATE state) {
|
||||
void OPTIMIZE_O3 aADPCMdecImpl(uint8_t flags, ADPCM_STATE state) {
|
||||
#if HAS_SSE41
|
||||
const __m128i tblrev = _mm_setr_epi8(12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1, -1, -1);
|
||||
const __m128i pos0 = _mm_set_epi8(3, -1, 3, -1, 2, -1, 2, -1, 1, -1, 1, -1, 0, -1, 0, -1);
|
||||
|
@ -374,7 +375,7 @@ void aADPCMdecImpl(uint8_t flags, ADPCM_STATE state) {
|
|||
memcpy(state, out - 16, 16 * sizeof(int16_t));
|
||||
}
|
||||
|
||||
void aResampleImpl(uint8_t flags, uint16_t pitch, RESAMPLE_STATE state) {
|
||||
void OPTIMIZE_O3 aResampleImpl(uint8_t flags, uint16_t pitch, RESAMPLE_STATE state) {
|
||||
int16_t tmp[16];
|
||||
int16_t *in_initial = rspa.buf.as_s16 + rspa.in / sizeof(int16_t);
|
||||
int16_t *in = in_initial;
|
||||
|
@ -527,7 +528,7 @@ void aResampleImpl(uint8_t flags, uint16_t pitch, RESAMPLE_STATE state) {
|
|||
}
|
||||
|
||||
|
||||
void aEnvMixerImpl(uint8_t flags, ENVMIX_STATE state) {
|
||||
void OPTIMIZE_O3 aEnvMixerImpl(uint8_t flags, ENVMIX_STATE state) {
|
||||
int16_t *in = rspa.buf.as_s16 + rspa.in / sizeof(int16_t);
|
||||
int16_t *dry[2] = {rspa.buf.as_s16 + rspa.out / sizeof(int16_t), rspa.buf.as_s16 + rspa.dry_right / sizeof(int16_t)};
|
||||
int16_t *wet[2] = {rspa.buf.as_s16 + rspa.wet_left / sizeof(int16_t), rspa.buf.as_s16 + rspa.wet_right / sizeof(int16_t)};
|
||||
|
|
|
@ -188,10 +188,6 @@ void mod_cache_add(struct Mod* mod, struct ModFile* file) {
|
|||
LOG_ERROR("Could not add to cache, mod or file is null");
|
||||
return;
|
||||
}
|
||||
if (mod->basePath == NULL || file->relativePath == NULL) {
|
||||
LOG_ERROR("Could not add to cache, basepath or relativepath is null");
|
||||
return;
|
||||
}
|
||||
|
||||
// if we already have a cached path, don't do anything
|
||||
if (file->cachedPath != NULL) {
|
||||
|
|
Loading…
Reference in New Issue