Massive DynOS refactor for performance/organization

This commit is contained in:
MysterD 2022-04-19 21:06:18 -07:00
parent dd6f6c430e
commit 78bda75e45
22 changed files with 4075 additions and 375 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}
}
}

View file

@ -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);
}
}
}

106
data/dynos_mgr_anim.cpp Normal file
View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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;
}

140
data/dynos_mgr_pack.cpp Normal file
View file

@ -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]);
}
}

View file

@ -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;

View file

@ -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() {

3551
gmon.log Normal file

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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) {

View file

@ -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");
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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)};

View file

@ -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) {