mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2026-02-19 03:51:25 +00:00
Some checks failed
Build coop / build-linux (push) Has been cancelled
Build coop / build-steamos (push) Has been cancelled
Build coop / build-windows-opengl (push) Has been cancelled
Build coop / build-windows-directx (push) Has been cancelled
Build coop / build-macos-arm (push) Has been cancelled
Build coop / build-macos-intel (push) Has been cancelled
234 lines
6.6 KiB
C++
234 lines
6.6 KiB
C++
#include <deque>
|
|
#include "dynos.cpp.h"
|
|
extern "C" {
|
|
#include "engine/graph_node.h"
|
|
}
|
|
|
|
static std::deque<PackData>& DynosPacks() {
|
|
static std::deque<PackData> sDynosPacks;
|
|
return sDynosPacks;
|
|
}
|
|
|
|
static void ScanPackBins(struct PackData* aPack) {
|
|
DIR *_PackDir = opendir(aPack->mPath.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;
|
|
|
|
SysPath _FileName = fstring("%s/%s", aPack->mPath.c_str(), _PackEnt->d_name);
|
|
s32 length = strlen(_PackEnt->d_name);
|
|
|
|
// check for actors
|
|
if (length > 4 && !strncmp(&_PackEnt->d_name[length - 4], ".bin", 4)) {
|
|
String _ActorName = _PackEnt->d_name;
|
|
_ActorName[length - 4] = '\0';
|
|
DynOS_Actor_LoadFromBinary(aPack->mPath, _ActorName.begin(), _FileName, true);
|
|
}
|
|
|
|
// check for textures
|
|
if (length > 4 && !strncmp(&_PackEnt->d_name[length - 4], ".tex", 4)) {
|
|
String _TexName = _PackEnt->d_name;
|
|
_TexName[length - 4] = '\0';
|
|
DynOS_Tex_LoadFromBinary(aPack->mPath, _FileName, _TexName.begin(), true);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void DynOS_Pack_ActivateActor(s32 aPackIndex, std::pair<std::string, GfxData *> &pair) {
|
|
const char* aActorName = pair.first.c_str();
|
|
GfxData* aGfxData = pair.second;
|
|
|
|
auto& geoNode = *(aGfxData->mGeoLayouts.end() - 1);
|
|
u32 id = 0;
|
|
GraphNode* graphNode = DynOS_Model_LoadGeo(&id, MODEL_POOL_PERMANENT, geoNode->mData, true);
|
|
if (graphNode == NULL) { return; }
|
|
|
|
const void* georef = DynOS_Builtin_Actor_GetFromName(aActorName);
|
|
graphNode->georef = georef;
|
|
|
|
ActorGfx actorGfx;
|
|
actorGfx.mGfxData = aGfxData;
|
|
actorGfx.mGraphNode = graphNode;
|
|
actorGfx.mPackIndex = aPackIndex;
|
|
|
|
for (const auto &vtxNode : aGfxData->mVertices) {
|
|
if (vtxNode->mFlags & GRAPH_EXTRA_FORCE_3D) {
|
|
actorGfx.mGraphNode->extraFlags |= GRAPH_EXTRA_FORCE_3D;
|
|
break;
|
|
}
|
|
}
|
|
|
|
DynOS_Actor_Valid(georef, actorGfx);
|
|
}
|
|
|
|
static void DynOS_Pack_DeactivateActor(s32 aPackIndex, std::pair<std::string, GfxData *> &pair) {
|
|
const char* aActorName = pair.first.c_str();
|
|
const void* georef = DynOS_Builtin_Actor_GetFromName(aActorName);
|
|
DynOS_Actor_Invalid(georef, aPackIndex);
|
|
|
|
// figure out which actor to replace it with
|
|
std::pair<std::string, 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().size();
|
|
}
|
|
|
|
void DynOS_Pack_SetEnabled(PackData* aPack, bool aEnabled) {
|
|
if (aPack == NULL) { return; }
|
|
aPack->mEnabled = aEnabled;
|
|
|
|
if (aEnabled && !aPack->mLoaded) {
|
|
ScanPackBins(aPack);
|
|
aPack->mLoaded = true;
|
|
}
|
|
|
|
if (aEnabled) {
|
|
for (auto& pair : aPack->mGfxData) {
|
|
DynOS_Pack_ActivateActor(aPack->mIndex, pair);
|
|
}
|
|
for (auto& _Tex : aPack->mTextures) {
|
|
DynOS_Tex_Activate(_Tex, false);
|
|
}
|
|
} else {
|
|
for (auto& pair : aPack->mGfxData) {
|
|
DynOS_Pack_DeactivateActor(aPack->mIndex, pair);
|
|
}
|
|
for (auto& _Tex : aPack->mTextures) {
|
|
DynOS_Tex_Deactivate(_Tex);
|
|
}
|
|
}
|
|
DynOS_Actor_Override_All();
|
|
}
|
|
|
|
PackData* DynOS_Pack_GetFromIndex(s32 aIndex) {
|
|
auto& _DynosPacks = DynosPacks();
|
|
if (aIndex < 0 || aIndex >= _DynosPacks.size()) {
|
|
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_GetFromDisplayName(const char* aDisplayName) {
|
|
for (auto& packData : DynosPacks()) {
|
|
if (!strcmp(packData.mDisplayName.begin(), aDisplayName)) {
|
|
return &packData;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
PackData* DynOS_Pack_Add(const SysPath& aPath) {
|
|
PackData* existing = DynOS_Pack_GetFromPath(aPath);
|
|
if (existing != NULL) { return existing; }
|
|
|
|
// extract basename
|
|
const char* displayName = aPath.c_str();
|
|
const char* ctoken = displayName;
|
|
while (*ctoken != '\0') {
|
|
if (*ctoken == '/' || *ctoken == '\\') {
|
|
if (*(ctoken + 1) != '\0') {
|
|
displayName = (ctoken + 1);
|
|
}
|
|
}
|
|
ctoken++;
|
|
}
|
|
|
|
existing = DynOS_Pack_GetFromDisplayName(displayName);
|
|
if (existing != NULL) { return existing; }
|
|
|
|
|
|
auto& _DynosPacks = DynosPacks();
|
|
s32 index = _DynosPacks.size();
|
|
const PackData packData = {
|
|
.mIndex = index,
|
|
.mEnabled = false,
|
|
.mPath = aPath,
|
|
.mDisplayName = "",
|
|
.mGfxData = {},
|
|
.mTextures = {},
|
|
.mLoaded = false,
|
|
};
|
|
_DynosPacks.push_back(packData);
|
|
|
|
PackData* _Pack = &_DynosPacks.back();
|
|
|
|
_Pack->mDisplayName = displayName;
|
|
|
|
return _Pack;
|
|
}
|
|
|
|
std::pair<std::string, GfxData *>* DynOS_Pack_GetActor(PackData* aPackData, const char* aActorName) {
|
|
if (aPackData == NULL || aActorName == NULL) {
|
|
return NULL;
|
|
}
|
|
for (auto& pair : aPackData->mGfxData) {
|
|
if (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.size();
|
|
aPackData->mGfxData.emplace_back(aActorName, aGfxData);
|
|
|
|
if (aPackData->mEnabled) {
|
|
DynOS_Pack_ActivateActor(aPackData->mIndex, aPackData->mGfxData[index]);
|
|
}
|
|
}
|
|
|
|
DataNode<TexData>* DynOS_Pack_GetTex(PackData* aPackData, const char* aTexName) {
|
|
if (aPackData == NULL || aTexName == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
for (auto& _Tex : aPackData->mTextures) {
|
|
if (!strcmp(_Tex->mName.begin(), aTexName)) {
|
|
return _Tex;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void DynOS_Pack_AddTex(PackData* aPackData, DataNode<TexData>* aTexData) {
|
|
if (aPackData == NULL || aTexData == NULL) {
|
|
return;
|
|
}
|
|
|
|
aPackData->mTextures.push_back(aTexData);
|
|
|
|
if (aPackData->mEnabled) {
|
|
DynOS_Tex_Activate(aTexData, false);
|
|
}
|
|
}
|