Refactor coop-specific DynOS code

This commit is contained in:
MysterD 2022-03-30 23:04:41 -07:00
parent 784614347b
commit 8a7097b802
22 changed files with 473 additions and 657 deletions

View file

@ -3,13 +3,36 @@
#ifndef __cplusplus
#include "dynos.h"
#include "types.h"
// -- built in -- //
void *dynos_update_cmd (void *cmd);
void dynos_update_gfx ();
void dynos_update_opt (void *pad);
s32 dynos_gfx_import_texture (void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize);
void dynos_gfx_swap_animations(void *ptr);
// -- warps -- //
bool dynos_warp_to_level(s32 aLevel, s32 aArea, s32 aAct);
bool dynos_warp_restart_level(void);
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);
void dynos_generate_packs(const char* directory);
// -- geos -- //
void dynos_add_actor_custom(const char *modPath, const char* geoName);
const void* dynos_geolayout_get(const char *name);
// -- collisions -- //
void dynos_add_collision_custom(const char *modPath, const char* collisionName);
Collision* dynos_collision_get(const char* collisionName);
#endif
#endif

View file

@ -26,9 +26,7 @@ enum {
DATA_TYPE_ANIMATION,
DATA_TYPE_ANIMATION_TABLE,
DATA_TYPE_GFXDYNCMD,
#ifdef COOP
DATA_TYPE_COLLISION,
#endif
DATA_TYPE_UNUSED,
};
@ -423,9 +421,7 @@ struct GfxData : NoCopy {
DataNodes<Vtx> mVertices;
DataNodes<Gfx> mDisplayLists;
DataNodes<GeoLayout> mGeoLayouts;
#ifdef COOP
DataNodes<Collision> mCollisions;
#endif
// Animation data
Array<AnimBuffer<s16> *> mAnimValues;
@ -643,18 +639,12 @@ u8 *DynOS_Gfx_TextureConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat,
bool DynOS_Gfx_ImportTexture(void **aOutput, void *aPtr, s32 aTile, void *aGfxRApi, void **aHashMap, void *aPool, u32 *aPoolPos, u32 aPoolSize);
Array<ActorGfx> &DynOS_Gfx_GetActorList();
Array<PackData *> &DynOS_Gfx_GetPacks();
#ifdef COOP
Array<bool> &DynOS_Gfx_GetPacksEnabled();
void DynOS_Gfx_GeneratePacks(const char* directory);
#endif
Array<String> DynOS_Gfx_Init();
void DynOS_Gfx_Update();
void DynOS_Gfx_SwapAnimations(void *aPtr);
bool DynOS_Gfx_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData);
#ifdef COOP
bool DynOS_Col_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData, DataNode<Collision>* _Node);
DataNode<Collision>* DynOS_Col_LoadFromBinary(const SysPath &aPackFolder, const char *aCollisionName);
#endif
GfxData *DynOS_Gfx_LoadFromBinary(const SysPath &aPackFolder, const char *aActorName);
void DynOS_Gfx_Free(GfxData *aGfxData);
void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder);
@ -673,12 +663,9 @@ s32 DynOS_String_Width(const u8 *aStr64);
// Geo
//
#ifdef COOP
void DynOS_Geo_AddActorCustom(const SysPath &aPackFolder, const char *aActorName);
const void *DynOS_Geo_GetActorLayoutFromName(const char *aActorName);
bool DynOS_Geo_IsCustomActor(s32 aIndex);
#endif
s32 DynOS_Geo_GetActorCount();
const char *DynOS_Geo_GetActorName(s32 aIndex);
const void *DynOS_Geo_GetActorLayout(s32 aIndex);
@ -688,11 +675,6 @@ void *DynOS_Geo_GetFunctionPointerFromIndex(s32 aIndex);
s32 DynOS_Geo_GetFunctionIndex(const void *aPtr);
void *DynOS_Geo_GetGraphNode(const void *aGeoLayout, bool aKeepInMemory);
#ifdef COOP
void DynOS_Col_AddCollisionCustom(const SysPath &aPackFolder, const char *aCollisionName);
Collision* DynOS_Col_GetCollision(const char* collisionName);
#endif
//
// Levels
//
@ -720,5 +702,20 @@ bool DynOS_Warp_ToCastle(s32 aLevel);
void DynOS_Warp_SetParam(s32 aLevel, s32 aIndex);
const char *DynOS_Warp_GetParamName(s32 aLevel, s32 aIndex);
//
// Collisions
//
bool DynOS_Col_GeneratePack(const SysPath &aPackFolder, Array<Pair<u64, String>> _ActorsFolders, GfxData *_GfxData);
bool DynOS_Col_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData, DataNode<Collision>* _Node);
DataNode<Collision>* DynOS_Col_LoadFromBinary(const SysPath &aPackFolder, const char *aCollisionName);
//
// Coop Misc
//
void DynOS_Col_AddCollisionCustom(const SysPath &aPackFolder, const char *aCollisionName);
Collision* DynOS_Col_GetCollision(const char* collisionName);
#endif
#endif

View file

@ -1,6 +1,8 @@
#include "dynos.cpp.h"
extern "C" {
// -- built in -- //
void *dynos_update_cmd(void *cmd) {
return DynOS_UpdateCmd(cmd);
}
@ -21,4 +23,78 @@ void dynos_gfx_swap_animations(void *ptr) {
return DynOS_Gfx_SwapAnimations(ptr);
}
// -- warps -- //
bool dynos_warp_to_level(s32 aLevel, s32 aArea, s32 aAct) {
return DynOS_Warp_ToLevel(aLevel, aArea, aAct);
}
bool dynos_warp_restart_level(void) {
return DynOS_Warp_RestartLevel();
}
bool dynos_warp_exit_level(s32 aDelay) {
return DynOS_Warp_ExitLevel(aDelay);
}
bool dynos_warp_to_castle(s32 aLevel) {
return DynOS_Warp_ToCastle(aLevel);
}
// -- dynos packs -- //
int dynos_packs_get_count(void) {
return DynOS_Gfx_GetPacks().Count();
}
const char* dynos_packs_get(s32 index) {
std::string path = DynOS_Gfx_GetPacks()[index]->mPath;
// extract basename
const char* cpath = path.c_str();
const char* ctoken = cpath;
while (*ctoken != '\0') {
if (*ctoken == '/' || *ctoken == '\\') {
if (*(ctoken + 1) != '\0') {
cpath = (ctoken + 1);
}
}
ctoken++;
}
return cpath;
}
bool dynos_packs_get_enabled(s32 index) {
return DynOS_Gfx_GetPacksEnabled()[index];
}
void dynos_packs_set_enabled(s32 index, bool value) {
DynOS_Gfx_GetPacksEnabled()[index] = value;
}
void dynos_generate_packs(const char* directory) {
DynOS_Gfx_GeneratePacks(directory);
}
// -- geos -- //
void dynos_add_actor_custom(const char *modPath, const char* geoName) {
DynOS_Geo_AddActorCustom(modPath, geoName);
}
const void* dynos_geolayout_get(const char *name) {
return DynOS_Geo_GetActorLayoutFromName(name);
}
// -- collisions -- //
void dynos_add_collision_custom(const char *modPath, const char* collisionName) {
DynOS_Col_AddCollisionCustom(modPath, collisionName);
}
Collision* dynos_collision_get(const char* collisionName) {
return DynOS_Col_GetCollision(collisionName);
}
}

34
data/dynos_col_load.cpp Normal file
View file

@ -0,0 +1,34 @@
#include "dynos.cpp.h"
//
// Load collision from binary
//
static DataNode<Collision>* LoadCollisionData(FILE *aFile) {
DataNode<Collision> *_Node = New<DataNode<Collision>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mData = New<Collision>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
_Node->mData[i] = ReadBytes<Collision>(aFile);
}
return _Node;
}
DataNode<Collision>* DynOS_Col_LoadFromBinary(const SysPath &aPackFolder, const char *aCollisionName) {
// Load data from binary file
DataNode<Collision>* collisionNode = NULL;
SysPath _Filename = fstring("%s/%s.col", aPackFolder.begin(), aCollisionName);
FILE *_File = fopen(_Filename.c_str(), "rb");
if (_File) {
collisionNode = LoadCollisionData(_File);
fclose(_File);
}
return collisionNode;
}

259
data/dynos_col_read.cpp Normal file
View file

@ -0,0 +1,259 @@
#include "dynos.cpp.h"
extern "C" {
#include "include/surface_terrains.h"
}
// Free data pointers, but keep nodes and tokens intact
// Delete nodes generated from GfxDynCmds
template <typename T>
static void ClearColDataNodes(DataNodes<T> &aDataNodes) {
for (s32 i = aDataNodes.Count(); i != 0; --i) {
Delete(aDataNodes[i - 1]->mData);
}
}
//
// Parse collision file
//
#define COLLISION_SIZE_PER_TOKEN 4
#define col_constant(x) if (_Arg == #x) { return (s16) (x); }
static s16 ParseColSymbolArg(GfxData* aGfxData, DataNode<Collision>* aNode, u64& aTokenIndex) {
const String& _Arg = aNode->mTokens[aTokenIndex++];
// Surface constants
col_constant(SURFACE_DEFAULT);
col_constant(SURFACE_BURNING);
col_constant(SURFACE_0004);
col_constant(SURFACE_HANGABLE);
col_constant(SURFACE_SLOW);
col_constant(SURFACE_DEATH_PLANE);
col_constant(SURFACE_CLOSE_CAMERA);
col_constant(SURFACE_WATER);
col_constant(SURFACE_FLOWING_WATER);
col_constant(SURFACE_INTANGIBLE);
col_constant(SURFACE_VERY_SLIPPERY);
col_constant(SURFACE_SLIPPERY);
col_constant(SURFACE_NOT_SLIPPERY);
col_constant(SURFACE_TTM_VINES);
col_constant(SURFACE_MGR_MUSIC);
col_constant(SURFACE_INSTANT_WARP_1B);
col_constant(SURFACE_INSTANT_WARP_1C);
col_constant(SURFACE_INSTANT_WARP_1D);
col_constant(SURFACE_INSTANT_WARP_1E);
col_constant(SURFACE_SHALLOW_QUICKSAND);
col_constant(SURFACE_DEEP_QUICKSAND);
col_constant(SURFACE_INSTANT_QUICKSAND);
col_constant(SURFACE_DEEP_MOVING_QUICKSAND);
col_constant(SURFACE_SHALLOW_MOVING_QUICKSAND);
col_constant(SURFACE_QUICKSAND);
col_constant(SURFACE_MOVING_QUICKSAND);
col_constant(SURFACE_WALL_MISC);
col_constant(SURFACE_NOISE_DEFAULT);
col_constant(SURFACE_NOISE_SLIPPERY);
col_constant(SURFACE_HORIZONTAL_WIND);
col_constant(SURFACE_INSTANT_MOVING_QUICKSAND);
col_constant(SURFACE_ICE);
col_constant(SURFACE_LOOK_UP_WARP);
col_constant(SURFACE_HARD);
col_constant(SURFACE_WARP);
col_constant(SURFACE_TIMER_START);
col_constant(SURFACE_TIMER_END);
col_constant(SURFACE_HARD_SLIPPERY);
col_constant(SURFACE_HARD_VERY_SLIPPERY);
col_constant(SURFACE_HARD_NOT_SLIPPERY);
col_constant(SURFACE_VERTICAL_WIND);
col_constant(SURFACE_BOSS_FIGHT_CAMERA);
col_constant(SURFACE_CAMERA_FREE_ROAM);
col_constant(SURFACE_THI3_WALLKICK);
col_constant(SURFACE_CAMERA_8_DIR);
col_constant(SURFACE_CAMERA_MIDDLE);
col_constant(SURFACE_CAMERA_ROTATE_RIGHT);
col_constant(SURFACE_CAMERA_ROTATE_LEFT);
col_constant(SURFACE_CAMERA_BOUNDARY);
col_constant(SURFACE_NOISE_VERY_SLIPPERY_73);
col_constant(SURFACE_NOISE_VERY_SLIPPERY_74);
col_constant(SURFACE_NOISE_VERY_SLIPPERY);
col_constant(SURFACE_NO_CAM_COLLISION);
col_constant(SURFACE_NO_CAM_COLLISION_77);
col_constant(SURFACE_NO_CAM_COL_VERY_SLIPPERY);
col_constant(SURFACE_NO_CAM_COL_SLIPPERY);
col_constant(SURFACE_SWITCH);
col_constant(SURFACE_VANISH_CAP_WALLS);
col_constant(SURFACE_TRAPDOOR);
// Surface class constants
col_constant(SURFACE_CLASS_DEFAULT);
col_constant(SURFACE_CLASS_VERY_SLIPPERY);
col_constant(SURFACE_CLASS_SLIPPERY);
col_constant(SURFACE_CLASS_NOT_SLIPPERY);
// Surface flag constants
col_constant(SURFACE_FLAG_DYNAMIC);
col_constant(SURFACE_FLAG_NO_CAM_COLLISION);
col_constant(SURFACE_FLAG_X_PROJECTION);
// Other constants
col_constant(NULL);
// Integers
s32 x;
if ((_Arg[1] == 'x' && sscanf(_Arg.begin(), "%x", &x) == 1) || (sscanf(_Arg.begin(), "%d", &x) == 1)) {
return (s16) x;
}
// Unknown
PrintError(" ERROR: Unknown col arg: %s", _Arg.begin());
return 0;
}
#define col_symbol_0(symb) \
if (_Symbol == #symb) { \
Collision _Cl[] = { symb() }; \
memcpy(aHead, _Cl, sizeof(_Cl)); \
aHead += (sizeof(_Cl) / sizeof(_Cl[0])); \
return; \
}
#define col_symbol_1(symb, n) \
if (_Symbol == #symb) { \
s16 _Arg0 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \
Collision _Cl[] = { symb(_Arg0) }; \
memcpy(aHead, _Cl, sizeof(_Cl)); \
aHead += (sizeof(_Cl) / sizeof(_Cl[0])); \
return; \
}
#define col_symbol_2(symb, n) \
if (_Symbol == #symb) { \
s16 _Arg0 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg1 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \
Collision _Cl[] = { symb(_Arg0, _Arg1) }; \
memcpy(aHead, _Cl, sizeof(_Cl)); \
aHead += (sizeof(_Cl) / sizeof(_Cl[0])); \
return; \
}
#define col_symbol_3(symb, n) \
if (_Symbol == #symb) { \
s16 _Arg0 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg1 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg2 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \
Collision _Cl[] = { symb(_Arg0, _Arg1, _Arg2) }; \
memcpy(aHead, _Cl, sizeof(_Cl)); \
aHead += (sizeof(_Cl) / sizeof(_Cl[0])); \
return; \
}
#define col_symbol_4(symb, n) \
if (_Symbol == #symb) { \
s16 _Arg0 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg1 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg2 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg3 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \
Collision _Cl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3) }; \
memcpy(aHead, _Cl, sizeof(_Cl)); \
aHead += (sizeof(_Cl) / sizeof(_Cl[0])); \
return; \
}
#define col_symbol_6(symb, n) \
if (_Symbol == #symb) { \
s16 _Arg0 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg1 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg2 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg3 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg4 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg5 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \
Collision _Cl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5) }; \
memcpy(aHead, _Cl, sizeof(_Cl)); \
aHead += (sizeof(_Cl) / sizeof(_Cl[0])); \
return; \
}
static void ParseCollisionSymbol(GfxData* aGfxData, DataNode<Collision>* aNode, Collision*& aHead, u64& aTokenIndex, Array<u64>& aSwitchNodes) {
const String& _Symbol = aNode->mTokens[aTokenIndex++];
col_symbol_0(COL_INIT);
col_symbol_1(COL_VERTEX_INIT, 0);
col_symbol_3(COL_VERTEX, 0);
col_symbol_2(COL_TRI_INIT, 0);
col_symbol_3(COL_TRI, 0);
col_symbol_4(COL_TRI_SPECIAL, 0);
col_symbol_0(COL_TRI_STOP);
col_symbol_0(COL_END);
col_symbol_1(COL_SPECIAL_INIT, 0);
col_symbol_1(COL_WATER_BOX_INIT, 0);
col_symbol_6(COL_WATER_BOX, 0);
// Unknown
PrintError(" ERROR: Unknown col symbol: %s", _Symbol.begin());
}
static DataNode<Collision>* ParseCollisionData(GfxData* aGfxData, DataNode<Collision>* aNode, bool aDisplayPercent) {
if (aNode->mData) return aNode;
// Collision data
aNode->mData = New<Collision>(aNode->mTokens.Count() * COLLISION_SIZE_PER_TOKEN);
Collision* _Head = aNode->mData;
Array<u64> _SwitchNodes;
for (u64 _TokenIndex = 0; _TokenIndex < aNode->mTokens.Count();) { // Don't increment _TokenIndex here!
ParseCollisionSymbol(aGfxData, aNode, _Head, _TokenIndex, _SwitchNodes);
if (aDisplayPercent && aGfxData->mErrorCount == 0) { PrintNoNewLine("%3d%%\b\b\b\b", (s32) (_TokenIndex * 100) / aNode->mTokens.Count()); }
}
if (aDisplayPercent && aGfxData->mErrorCount == 0) { Print("100%%"); }
aNode->mSize = (u32)(_Head - aNode->mData);
aNode->mLoadIndex = aGfxData->mLoadIndex++;
return aNode;
}
static DataNode<Collision> *GetCollision(GfxData *aGfxData, const String& aGeoRoot) {
for (DataNode<Collision> *_Node : aGfxData->mCollisions) {
if (_Node->mName == aGeoRoot) {
return _Node;
}
}
return NULL;
}
bool DynOS_Col_GeneratePack(const SysPath &aPackFolder, Array<Pair<u64, String>> _ActorsFolders, GfxData *_GfxData) {
bool generated = false;
for (auto &_ColNode : _GfxData->mCollisions) {
String _ColRootName = _ColNode->mName;
DataNode<Collision> *_ColRoot = GetCollision(_GfxData, _ColRootName);
if (_ColRoot != NULL) {
// If there is an existing binary file for this collision, skip and go to the next actor
SysPath _ColFilename = fstring("%s/%s.col", aPackFolder.c_str(), _ColRootName.begin());
if (fs_sys_file_exists(_ColFilename.c_str())) {
continue;
}
// Init
_GfxData->mErrorCount = 0;
_GfxData->mLoadIndex = 0;
// Parse data
PrintNoNewLine("%s.col: Model identifier: %X - Processing... ", _ColRootName.begin(), _GfxData->mModelIdentifier);
ParseCollisionData(_GfxData, _ColRoot, true);
// Write if no error
if (_GfxData->mErrorCount == 0) {
DynOS_Col_WriteBinary(_ColFilename, _GfxData, _ColRoot);
} else {
Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount);
}
// Clear data pointers
ClearColDataNodes(_GfxData->mCollisions);
generated = true;
}
}
return generated;
}

31
data/dynos_col_write.cpp Normal file
View file

@ -0,0 +1,31 @@
#include "dynos.cpp.h"
//
// Collisions
//
static void WriteCollisionData(FILE* aFile, GfxData* aGfxData, DataNode<Collision> *aNode) {
if (!aNode->mData) return;
// Name
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
WriteBytes<Collision>(aFile, aNode->mData[i]);
}
}
bool DynOS_Col_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData, DataNode<Collision>* _Node) {
FILE *_File = fopen(aOutputFilename.c_str(), "wb");
if (!_File) {
PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
return false;
}
WriteCollisionData(_File, aGfxData, _Node);
fclose(_File);
return true;
}

View file

@ -1,28 +0,0 @@
#ifdef COOP
#ifndef DYNOS_COOP_C_H
#define DYNOS_COOP_C_H
#ifndef __cplusplus
#include "types.h"
bool dynos_warp_to_level(s32 aLevel, s32 aArea, s32 aAct);
bool dynos_warp_restart_level(void);
bool dynos_warp_exit_level(s32 aDelay);
bool dynos_warp_to_castle(s32 aLevel);
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);
void dynos_generate_packs(const char* directory);
void dynos_add_actor_custom(const char *modPath, const char* geoName);
const void* dynos_geolayout_get(const char *name);
void dynos_add_collision_custom(const char *modPath, const char* collisionName);
Collision* dynos_collision_get(const char* collisionName);
#endif
#endif
#endif

View file

@ -1,77 +0,0 @@
#ifdef COOP
#include "dynos.cpp.h"
extern "C" {
bool dynos_warp_to_level(s32 aLevel, s32 aArea, s32 aAct) {
return DynOS_Warp_ToLevel(aLevel, aArea, aAct);
}
bool dynos_warp_restart_level(void) {
return DynOS_Warp_RestartLevel();
}
bool dynos_warp_exit_level(s32 aDelay) {
return DynOS_Warp_ExitLevel(aDelay);
}
bool dynos_warp_to_castle(s32 aLevel) {
return DynOS_Warp_ToCastle(aLevel);
}
// -- dynos packs -- //
#define DYNOS_PACK_PATH_SPLIT_LEN 12
int dynos_packs_get_count(void) {
return DynOS_Gfx_GetPacks().Count();
}
const char* dynos_packs_get(s32 index) {
std::string path = DynOS_Gfx_GetPacks()[index]->mPath;
// extract basename
const char* cpath = path.c_str();
const char* ctoken = cpath;
while (*ctoken != '\0') {
if (*ctoken == '/' || *ctoken == '\\') {
if (*(ctoken + 1) != '\0') {
cpath = (ctoken + 1);
}
}
ctoken++;
}
return cpath;
}
bool dynos_packs_get_enabled(s32 index) {
return DynOS_Gfx_GetPacksEnabled()[index];
}
void dynos_packs_set_enabled(s32 index, bool value) {
DynOS_Gfx_GetPacksEnabled()[index] = value;
}
void dynos_generate_packs(const char* directory) {
DynOS_Gfx_GeneratePacks(directory);
}
void dynos_add_actor_custom(const char *modPath, const char* geoName) {
DynOS_Geo_AddActorCustom(modPath, geoName);
}
const void* dynos_geolayout_get(const char *name) {
return DynOS_Geo_GetActorLayoutFromName(name);
}
void dynos_add_collision_custom(const char *modPath, const char* collisionName) {
DynOS_Col_AddCollisionCustom(modPath, collisionName);
}
Collision* dynos_collision_get(const char* collisionName) {
return DynOS_Col_GetCollision(collisionName);
}
}
#endif

View file

@ -10,7 +10,6 @@ Array<PackData *> &DynOS_Gfx_GetPacks() {
return sPacks;
}
#ifdef COOP
Array<bool> &DynOS_Gfx_GetPacksEnabled() {
static Array<bool> sPacksEnabled;
return sPacksEnabled;
@ -35,22 +34,9 @@ void DynOS_Gfx_GeneratePacks(const char* directory) {
closedir(modsDir);
}
#endif
Array<String> DynOS_Gfx_Init() {
// Alloc and init the actors gfx list
Array<ActorGfx> &pActorGfxList = DynOS_Gfx_GetActorList();
pActorGfxList.Resize(DynOS_Geo_GetActorCount());
for (s32 i = 0; i != DynOS_Geo_GetActorCount(); ++i) {
pActorGfxList[i].mPackIndex = -1;
pActorGfxList[i].mGfxData = NULL;
pActorGfxList[i].mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(DynOS_Geo_GetActorLayout(i), false);
}
// Scan the DynOS packs folder
static void ScanPacksFolder(SysPath _DynosPacksFolder) {
Array<PackData *> &pDynosPacks = DynOS_Gfx_GetPacks();
SysPath _DynosPacksFolder = fstring("%s/%s", DYNOS_EXE_FOLDER, DYNOS_PACKS_FOLDER);
DIR *_DynosPacksDir = opendir(_DynosPacksFolder.c_str());
if (_DynosPacksDir) {
struct dirent *_DynosPacksEnt = NULL;
@ -71,16 +57,36 @@ Array<String> DynOS_Gfx_Init() {
// Add pack to pack list
pDynosPacks.Add(_Pack);
#ifdef COOP
// Add enabled flag
DynOS_Gfx_GetPacksEnabled().Add(true);
#endif
}
}
closedir(_DynosPacksDir);
}
}
Array<String> DynOS_Gfx_Init() {
// Alloc and init the actors gfx list
Array<ActorGfx> &pActorGfxList = DynOS_Gfx_GetActorList();
pActorGfxList.Resize(DynOS_Geo_GetActorCount());
for (s32 i = 0; i != DynOS_Geo_GetActorCount(); ++i) {
pActorGfxList[i].mPackIndex = -1;
pActorGfxList[i].mGfxData = NULL;
pActorGfxList[i].mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(DynOS_Geo_GetActorLayout(i), false);
}
// Scan the DynOS packs folder
SysPath _DynosPacksFolder = fstring("%s/%s", DYNOS_EXE_FOLDER, DYNOS_PACKS_FOLDER);
ScanPacksFolder(_DynosPacksFolder);
// 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('\\');
@ -90,46 +96,6 @@ Array<String> DynOS_Gfx_Init() {
SysPath _DirName = _Pack->mPath.substr(MAX(_DirSep1, _DirSep2));
_PackNames.Add(_DirName.c_str());
}
#ifdef COOP
Array<PackData *> &pDynosUserPacks = DynOS_Gfx_GetPacks();
SysPath _DynosPacksUserFolder = fstring("%s/%s", DYNOS_USER_FOLDER, DYNOS_PACKS_FOLDER);
DIR *_DynosPacksUserDir = opendir(_DynosPacksUserFolder.c_str());
if (_DynosPacksUserDir) {
struct dirent *_DynosPacksUserEnt = NULL;
while ((_DynosPacksUserEnt = readdir(_DynosPacksUserDir)) != NULL) {
// Skip . and ..
if (SysPath(_DynosPacksUserEnt->d_name) == ".") continue;
if (SysPath(_DynosPacksUserEnt->d_name) == "..") continue;
// If pack folder exists, add it to the pack list
SysPath _PackFolder = fstring("%s/%s", _DynosPacksUserFolder.c_str(), _DynosPacksUserEnt->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;
DynOS_Gfx_GeneratePack(_PackFolder);
// Add pack to pack list
pDynosPacks.Add(_Pack);
// Add enabled flag
DynOS_Gfx_GetPacksEnabled().Add(true);
}
}
closedir(_DynosPacksUserDir);
}
for (const auto& _Pack : pDynosUserPacks) {
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());
}
#endif
return _PackNames;
}

View file

@ -272,11 +272,7 @@ GfxData *DynOS_Gfx_LoadFromBinary(const SysPath &aPackFolder, const char *aActor
// Look for actor in pack
if (_Pack) {
for (s32 i = 0; i != _Pack->mGfxData.Count(); ++i) {
#ifdef COOP
if (!strcmp(_Pack->mGfxData[i].first, aActorName)) {
#else
if (_Pack->mGfxData[i].first == aActorName) { // Perfectly valid, aActorName comes from static RO data, so its address never changes during execution
#endif
return _Pack->mGfxData[i].second;
}
}
@ -315,40 +311,3 @@ GfxData *DynOS_Gfx_LoadFromBinary(const SysPath &aPackFolder, const char *aActor
}
return _GfxData;
}
#ifdef COOP
//
// Load collision from binary
//
static DataNode<Collision>* LoadCollisionData(FILE *aFile) {
DataNode<Collision> *_Node = New<DataNode<Collision>>();
// Name
_Node->mName.Read(aFile);
// Data
_Node->mSize = ReadBytes<u32>(aFile);
_Node->mData = New<Collision>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
_Node->mData[i] = ReadBytes<Collision>(aFile);
}
return _Node;
}
DataNode<Collision>* DynOS_Col_LoadFromBinary(const SysPath &aPackFolder, const char *aCollisionName) {
// Load data from binary file
DataNode<Collision>* collisionNode = NULL;
SysPath _Filename = fstring("%s/%s.col", aPackFolder.begin(), aCollisionName);
FILE *_File = fopen(_Filename.c_str(), "rb");
if (_File) {
collisionNode = LoadCollisionData(_File);
fclose(_File);
}
return collisionNode;
}
#endif

View file

@ -1,8 +1,5 @@
#include "dynos.cpp.h"
extern "C" {
#ifdef COOP
#include "include/surface_terrains.h"
#endif
#include "geo_commands.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb/stb_image_write.h"
@ -18,9 +15,6 @@ extern "C" {
#define LAYER_TRANSPARENT_INTER 7
#define DISPLAY_LIST_SIZE_PER_TOKEN 4
#define GEO_LAYOUT_SIZE_PER_TOKEN 4
#ifdef COOP
#define COLLISION_SIZE_PER_TOKEN 4
#endif
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnarrowing"
@ -205,10 +199,8 @@ static void ScanModelFile(GfxData *aGfxData, const SysPath &aFilename) {
_DataType = DATA_TYPE_DISPLAY_LIST;
} else if (_Buffer == "GeoLayout") {
_DataType = DATA_TYPE_GEO_LAYOUT;
#ifdef COOP
} else if (_Buffer == "Collision") {
_DataType = DATA_TYPE_COLLISION;
#endif
} else {
PrintError(" ERROR: Unknown type name: %s", _Buffer.begin());
}
@ -232,9 +224,7 @@ static void ScanModelFile(GfxData *aGfxData, const SysPath &aFilename) {
case DATA_TYPE_VERTEX: AppendNewNode(aGfxData, aGfxData->mVertices, _Buffer, pDataName, pDataTokens); break;
case DATA_TYPE_DISPLAY_LIST: AppendNewNode(aGfxData, aGfxData->mDisplayLists, _Buffer, pDataName, pDataTokens); break;
case DATA_TYPE_GEO_LAYOUT: AppendNewNode(aGfxData, aGfxData->mGeoLayouts, _Buffer, pDataName, pDataTokens); break;
#ifdef COOP
case DATA_TYPE_COLLISION: AppendNewNode(aGfxData, aGfxData->mCollisions, _Buffer, pDataName, pDataTokens); break;
#endif
case DATA_TYPE_UNUSED: pDataTokens = (Array<String> *) 1; break;
}
_Buffer.Clear();
@ -1093,9 +1083,7 @@ static void ParseGfxSymbol(GfxData* aGfxData, DataNode<Gfx>* aNode, Gfx*& aHead,
gfx_symbol_4(gsDPSetFogColor);
gfx_symbol_2(gsSPFogPosition, false);
gfx_symbol_1(gsDPSetAlphaCompare, false);
#ifdef COOP
gfx_symbol_2(gsSPCopyLightEXT, false);
#endif
// Special symbols
if (_Symbol == "gsSPTexture") {
@ -1608,208 +1596,6 @@ static DataNode<GeoLayout>* ParseGeoLayoutData(GfxData* aGfxData, DataNode<GeoLa
return aNode;
}
#ifdef COOP
//
// Collision files
//
#define col_constant(x) if (_Arg == #x) { return (s16) (x); }
static s16 ParseColSymbolArg(GfxData* aGfxData, DataNode<Collision>* aNode, u64& aTokenIndex) {
const String& _Arg = aNode->mTokens[aTokenIndex++];
// Surface constants
col_constant(SURFACE_DEFAULT);
col_constant(SURFACE_BURNING);
col_constant(SURFACE_0004);
col_constant(SURFACE_HANGABLE);
col_constant(SURFACE_SLOW);
col_constant(SURFACE_DEATH_PLANE);
col_constant(SURFACE_CLOSE_CAMERA);
col_constant(SURFACE_WATER);
col_constant(SURFACE_FLOWING_WATER);
col_constant(SURFACE_INTANGIBLE);
col_constant(SURFACE_VERY_SLIPPERY);
col_constant(SURFACE_SLIPPERY);
col_constant(SURFACE_NOT_SLIPPERY);
col_constant(SURFACE_TTM_VINES);
col_constant(SURFACE_MGR_MUSIC);
col_constant(SURFACE_INSTANT_WARP_1B);
col_constant(SURFACE_INSTANT_WARP_1C);
col_constant(SURFACE_INSTANT_WARP_1D);
col_constant(SURFACE_INSTANT_WARP_1E);
col_constant(SURFACE_SHALLOW_QUICKSAND);
col_constant(SURFACE_DEEP_QUICKSAND);
col_constant(SURFACE_INSTANT_QUICKSAND);
col_constant(SURFACE_DEEP_MOVING_QUICKSAND);
col_constant(SURFACE_SHALLOW_MOVING_QUICKSAND);
col_constant(SURFACE_QUICKSAND);
col_constant(SURFACE_MOVING_QUICKSAND);
col_constant(SURFACE_WALL_MISC);
col_constant(SURFACE_NOISE_DEFAULT);
col_constant(SURFACE_NOISE_SLIPPERY);
col_constant(SURFACE_HORIZONTAL_WIND);
col_constant(SURFACE_INSTANT_MOVING_QUICKSAND);
col_constant(SURFACE_ICE);
col_constant(SURFACE_LOOK_UP_WARP);
col_constant(SURFACE_HARD);
col_constant(SURFACE_WARP);
col_constant(SURFACE_TIMER_START);
col_constant(SURFACE_TIMER_END);
col_constant(SURFACE_HARD_SLIPPERY);
col_constant(SURFACE_HARD_VERY_SLIPPERY);
col_constant(SURFACE_HARD_NOT_SLIPPERY);
col_constant(SURFACE_VERTICAL_WIND);
col_constant(SURFACE_BOSS_FIGHT_CAMERA);
col_constant(SURFACE_CAMERA_FREE_ROAM);
col_constant(SURFACE_THI3_WALLKICK);
col_constant(SURFACE_CAMERA_8_DIR);
col_constant(SURFACE_CAMERA_MIDDLE);
col_constant(SURFACE_CAMERA_ROTATE_RIGHT);
col_constant(SURFACE_CAMERA_ROTATE_LEFT);
col_constant(SURFACE_CAMERA_BOUNDARY);
col_constant(SURFACE_NOISE_VERY_SLIPPERY_73);
col_constant(SURFACE_NOISE_VERY_SLIPPERY_74);
col_constant(SURFACE_NOISE_VERY_SLIPPERY);
col_constant(SURFACE_NO_CAM_COLLISION);
col_constant(SURFACE_NO_CAM_COLLISION_77);
col_constant(SURFACE_NO_CAM_COL_VERY_SLIPPERY);
col_constant(SURFACE_NO_CAM_COL_SLIPPERY);
col_constant(SURFACE_SWITCH);
col_constant(SURFACE_VANISH_CAP_WALLS);
col_constant(SURFACE_TRAPDOOR);
// Surface class constants
col_constant(SURFACE_CLASS_DEFAULT);
col_constant(SURFACE_CLASS_VERY_SLIPPERY);
col_constant(SURFACE_CLASS_SLIPPERY);
col_constant(SURFACE_CLASS_NOT_SLIPPERY);
// Surface flag constants
col_constant(SURFACE_FLAG_DYNAMIC);
col_constant(SURFACE_FLAG_NO_CAM_COLLISION);
col_constant(SURFACE_FLAG_X_PROJECTION);
// Other constants
col_constant(NULL);
// Integers
s32 x;
if ((_Arg[1] == 'x' && sscanf(_Arg.begin(), "%x", &x) == 1) || (sscanf(_Arg.begin(), "%d", &x) == 1)) {
return (s16) x;
}
// Unknown
PrintError(" ERROR: Unknown col arg: %s", _Arg.begin());
return 0;
}
#define col_symbol_0(symb) \
if (_Symbol == #symb) { \
Collision _Cl[] = { symb() }; \
memcpy(aHead, _Cl, sizeof(_Cl)); \
aHead += (sizeof(_Cl) / sizeof(_Cl[0])); \
return; \
}
#define col_symbol_1(symb, n) \
if (_Symbol == #symb) { \
s16 _Arg0 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \
Collision _Cl[] = { symb(_Arg0) }; \
memcpy(aHead, _Cl, sizeof(_Cl)); \
aHead += (sizeof(_Cl) / sizeof(_Cl[0])); \
return; \
}
#define col_symbol_2(symb, n) \
if (_Symbol == #symb) { \
s16 _Arg0 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg1 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \
Collision _Cl[] = { symb(_Arg0, _Arg1) }; \
memcpy(aHead, _Cl, sizeof(_Cl)); \
aHead += (sizeof(_Cl) / sizeof(_Cl[0])); \
return; \
}
#define col_symbol_3(symb, n) \
if (_Symbol == #symb) { \
s16 _Arg0 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg1 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg2 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \
Collision _Cl[] = { symb(_Arg0, _Arg1, _Arg2) }; \
memcpy(aHead, _Cl, sizeof(_Cl)); \
aHead += (sizeof(_Cl) / sizeof(_Cl[0])); \
return; \
}
#define col_symbol_4(symb, n) \
if (_Symbol == #symb) { \
s16 _Arg0 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg1 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg2 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg3 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \
Collision _Cl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3) }; \
memcpy(aHead, _Cl, sizeof(_Cl)); \
aHead += (sizeof(_Cl) / sizeof(_Cl[0])); \
return; \
}
#define col_symbol_6(symb, n) \
if (_Symbol == #symb) { \
s16 _Arg0 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg1 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg2 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg3 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg4 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
s16 _Arg5 = ParseColSymbolArg(aGfxData, aNode, aTokenIndex); \
if (n != 0) { aGfxData->mPointerList.Add(aHead + n); } \
Collision _Cl[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3, _Arg4, _Arg5) }; \
memcpy(aHead, _Cl, sizeof(_Cl)); \
aHead += (sizeof(_Cl) / sizeof(_Cl[0])); \
return; \
}
static void ParseCollisionSymbol(GfxData* aGfxData, DataNode<Collision>* aNode, Collision*& aHead, u64& aTokenIndex, Array<u64>& aSwitchNodes) {
const String& _Symbol = aNode->mTokens[aTokenIndex++];
col_symbol_0(COL_INIT);
col_symbol_1(COL_VERTEX_INIT, 0);
col_symbol_3(COL_VERTEX, 0);
col_symbol_2(COL_TRI_INIT, 0);
col_symbol_3(COL_TRI, 0);
col_symbol_4(COL_TRI_SPECIAL, 0);
col_symbol_0(COL_TRI_STOP);
col_symbol_0(COL_END);
col_symbol_1(COL_SPECIAL_INIT, 0);
col_symbol_1(COL_WATER_BOX_INIT, 0);
col_symbol_6(COL_WATER_BOX, 0);
// Unknown
PrintError(" ERROR: Unknown col symbol: %s", _Symbol.begin());
}
static DataNode<Collision>* ParseCollisionData(GfxData* aGfxData, DataNode<Collision>* aNode, bool aDisplayPercent) {
if (aNode->mData) return aNode;
// Collision data
aNode->mData = New<Collision>(aNode->mTokens.Count() * COLLISION_SIZE_PER_TOKEN);
Collision* _Head = aNode->mData;
Array<u64> _SwitchNodes;
for (u64 _TokenIndex = 0; _TokenIndex < aNode->mTokens.Count();) { // Don't increment _TokenIndex here!
ParseCollisionSymbol(aGfxData, aNode, _Head, _TokenIndex, _SwitchNodes);
if (aDisplayPercent && aGfxData->mErrorCount == 0) { PrintNoNewLine("%3d%%\b\b\b\b", (s32) (_TokenIndex * 100) / aNode->mTokens.Count()); }
}
if (aDisplayPercent && aGfxData->mErrorCount == 0) { Print("100%%"); }
aNode->mSize = (u32)(_Head - aNode->mData);
aNode->mLoadIndex = aGfxData->mLoadIndex++;
return aNode;
}
#endif
//
// Animation files
//
@ -1997,17 +1783,6 @@ static String GetActorFolder(const Array<Pair<u64, String>> &aActorsFolders, u64
return String();
}
#ifdef COOP
static DataNode<Collision> *GetCollision(GfxData *aGfxData, const String& aGeoRoot) {
for (DataNode<Collision> *_Node : aGfxData->mCollisions) {
if (_Node->mName == aGeoRoot) {
return _Node;
}
}
return NULL;
}
static bool DynOS_Gfx_GeneratePack_Internal(const SysPath &aPackFolder, Array<Pair<u64, String>> _ActorsFolders, GfxData *_GfxData, bool onlyConsiderActors) {
bool generated = false;
for (auto &_GeoNode : _GfxData->mGeoLayouts) {
@ -2085,43 +1860,6 @@ static bool DynOS_Gfx_GeneratePack_Internal(const SysPath &aPackFolder, Array<Pa
return generated;
}
static bool DynOS_Gfx_GeneratePack_Collisions(const SysPath &aPackFolder, Array<Pair<u64, String>> _ActorsFolders, GfxData *_GfxData) {
bool generated = false;
for (auto &_ColNode : _GfxData->mCollisions) {
String _ColRootName = _ColNode->mName;
DataNode<Collision> *_ColRoot = GetCollision(_GfxData, _ColRootName);
if (_ColRoot != NULL) {
// If there is an existing binary file for this collision, skip and go to the next actor
SysPath _ColFilename = fstring("%s/%s.col", aPackFolder.c_str(), _ColRootName.begin());
if (fs_sys_file_exists(_ColFilename.c_str())) {
continue;
}
// Init
_GfxData->mErrorCount = 0;
_GfxData->mLoadIndex = 0;
// Parse data
PrintNoNewLine("%s.col: Model identifier: %X - Processing... ", _ColRootName.begin(), _GfxData->mModelIdentifier);
ParseCollisionData(_GfxData, _ColRoot, true);
// Write if no error
if (_GfxData->mErrorCount == 0) {
DynOS_Col_WriteBinary(_ColFilename, _GfxData, _ColRoot);
} else {
Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount);
}
// Clear data pointers
ClearGfxDataNodes(_GfxData->mCollisions);
generated = true;
}
}
return generated;
}
#endif
void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) {
Print("---------- Pack folder: \"%s\" ----------", aPackFolder.c_str());
Array<Pair<u64, String>> _ActorsFolders;
@ -2144,9 +1882,7 @@ void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) {
_GfxData->mModelIdentifier = 0;
ScanModelFile(_GfxData, fstring("%s/model.inc.c", _Folder.c_str()));
ScanModelFile(_GfxData, fstring("%s/geo.inc.c", _Folder.c_str()));
#ifdef COOP
ScanModelFile(_GfxData, fstring("%s/collision.inc.c", _Folder.c_str()));
#endif
if (_GfxData->mModelIdentifier != 0) {
_ActorsFolders.Add({ _GfxData->mModelIdentifier, String(_PackEnt->d_name) });
}
@ -2156,78 +1892,9 @@ void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) {
}
// Generate a binary file for each actor found in the GfxData
#ifdef COOP
DynOS_Gfx_GeneratePack_Collisions(aPackFolder, _ActorsFolders, _GfxData);
DynOS_Col_GeneratePack(aPackFolder, _ActorsFolders, _GfxData);
bool foundActor = DynOS_Gfx_GeneratePack_Internal(aPackFolder, _ActorsFolders, _GfxData, true);
if (!foundActor) { DynOS_Gfx_GeneratePack_Internal(aPackFolder, _ActorsFolders, _GfxData, false); }
#else
for (s32 i = 0; i != DynOS_Geo_GetActorCount(); ++i) {
String _GeoRootName = DynOS_Geo_GetActorName(i);
DataNode<GeoLayout> *_GeoRoot = GetGeoLayout(_GfxData, _GeoRootName);
if (_GeoRoot != NULL) {
// If there is an existing binary file for this layout, skip and go to the next actor
SysPath _BinFilename = fstring("%s/%s.bin", aPackFolder.c_str(), _GeoRootName.begin());
if (fs_sys_file_exists(_BinFilename.c_str())) {
continue;
}
// Init
_GfxData->mLoadIndex = 0;
_GfxData->mErrorCount = 0;
_GfxData->mModelIdentifier = _GeoRoot->mModelIdentifier;
_GfxData->mPackFolder = aPackFolder;
_GfxData->mPointerList = { NULL }; // The NULL pointer is needed, so we add it here
_GfxData->mGfxContext.mCurrentTexture = NULL;
_GfxData->mGfxContext.mCurrentPalette = NULL;
_GfxData->mGeoNodeStack.Clear();
// Parse data
PrintNoNewLine("%s.bin: Model identifier: %X - Processing... ", _GeoRootName.begin(), _GfxData->mModelIdentifier);
ParseGeoLayoutData(_GfxData, _GeoRoot, true);
// Init animation data
for (auto &_AnimBuffer : _GfxData->mAnimValues) Delete(_AnimBuffer);
for (auto &_AnimBuffer : _GfxData->mAnimIndices) Delete(_AnimBuffer);
for (auto &_AnimNode : _GfxData->mAnimations) Delete(_AnimNode);
_GfxData->mAnimValues.Clear();
_GfxData->mAnimIndices.Clear();
_GfxData->mAnimations.Clear();
_GfxData->mAnimationTable.Clear();
// Scan anims folder for animation data
String _ActorFolder = GetActorFolder(_ActorsFolders, _GfxData->mModelIdentifier);
SysPath _AnimsFolder = fstring("%s/%s/anims", aPackFolder.c_str(), _ActorFolder.begin());
ScanAnimationFolder(_GfxData, _AnimsFolder);
// Create table for mario_geo animations or luigi_geo animations
if ((_GeoRootName == "mario_geo" || _GeoRootName == "luigi_geo") && !_GfxData->mAnimations.Empty()) {
_GfxData->mAnimationTable.Resize(256);
for (s32 i = 0; i != 256; ++i) {
String _AnimName("anim_%02X", i);
if (_GfxData->mAnimations.FindIf([&_AnimName](const DataNode<AnimData> *aNode) { return aNode->mName == _AnimName; }) != -1) {
_GfxData->mAnimationTable[i] = { _AnimName, NULL };
} else {
_GfxData->mAnimationTable[i] = { "NULL", NULL };
}
}
}
// Write if no error
if (_GfxData->mErrorCount == 0) {
DynOS_Gfx_WriteBinary(_BinFilename, _GfxData);
} else {
Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount);
}
// Clear data pointers
ClearGfxDataNodes(_GfxData->mLights);
ClearGfxDataNodes(_GfxData->mTextures);
ClearGfxDataNodes(_GfxData->mVertices);
ClearGfxDataNodes(_GfxData->mDisplayLists);
ClearGfxDataNodes(_GfxData->mGeoLayouts);
}
}
#endif
DynOS_Gfx_Free(_GfxData);
}

View file

@ -3,9 +3,7 @@ extern "C" {
#include "object_fields.h"
#include "game/level_update.h"
#include "game/object_list_processor.h"
#ifdef COOP
#include "pc/configfile.h"
#endif
}
//
@ -106,19 +104,11 @@ void DynOS_Gfx_Update() {
if (gObjectLists) {
// Check packs
#ifdef COOP
Array<bool> &_Enabled = DynOS_Gfx_GetPacksEnabled();
const Array<PackData *> &pDynosPacks = DynOS_Gfx_GetPacks();
while (_Enabled.Count() < pDynosPacks.Count()) {
_Enabled.Add(true);
}
#else
Array<bool> _Enabled;
const Array<PackData *> &pDynosPacks = DynOS_Gfx_GetPacks();
for (s32 i = 0; i != pDynosPacks.Count(); ++i) {
_Enabled.Add(DynOS_Opt_GetValue(String("dynos_pack_%d", i)));
}
#endif
// 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 }) {
@ -132,7 +122,8 @@ void DynOS_Gfx_Update() {
// Replace the object's model and animations
ActorGfx *_ActorGfx = &DynOS_Gfx_GetActorList()[_ActorIndex];
#ifdef COOP
// Check for disabled downloaded models
if (configDisableDownloadedModels && _ActorGfx->mPackIndex == 99) {
extern const GeoLayout error_model_geo[];
s32 actorIndex = DynOS_Geo_IsCustomActor(_ActorIndex) ? DynOS_Geo_GetActorIndex(error_model_geo) : _ActorIndex;
@ -141,7 +132,7 @@ void DynOS_Gfx_Update() {
_ActorGfx->mGfxData = NULL;
_ActorGfx->mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(geoLayout, true);
}
#endif
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

View file

@ -239,27 +239,6 @@ static void WriteAnimationTable(FILE* aFile, GfxData* aGfxData) {
}
}
#ifdef COOP
//
// Collisions
//
static void WriteCollisionData(FILE* aFile, GfxData* aGfxData, DataNode<Collision> *aNode) {
if (!aNode->mData) return;
// Name
aNode->mName.Write(aFile);
// Data
WriteBytes<u32>(aFile, aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
WriteBytes<Collision>(aFile, aNode->mData[i]);
}
}
#endif
//
// Write
//
@ -304,23 +283,6 @@ bool DynOS_Gfx_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData) {
return true;
}
#ifdef COOP
bool DynOS_Col_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData, DataNode<Collision>* _Node) {
FILE *_File = fopen(aOutputFilename.c_str(), "wb");
if (!_File) {
PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
return false;
}
WriteCollisionData(_File, aGfxData, _Node);
fclose(_File);
return true;
}
#endif
//
// Free
//

View file

@ -34,10 +34,8 @@ extern "C" {
#include "actors/group15.h"
#include "actors/group16.h"
#include "actors/group17.h"
#ifdef COOP
#include "actors/custom0.h"
#include "actors/zcustom0.h"
#endif
}
//
@ -313,7 +311,7 @@ define_actor(wooden_signpost_geo),
define_actor(yellow_sphere_geo),
define_actor(yoshi_geo),
define_actor(yoshi_egg_geo),
#ifdef COOP
// coop models
define_actor(error_model_geo),
define_actor(luigi_geo),
define_actor(luigis_cap_geo),
@ -334,10 +332,8 @@ define_actor(warios_cap_geo),
define_actor(warios_metal_cap_geo),
define_actor(warios_wing_cap_geo),
define_actor(warios_winged_metal_cap_geo),
#endif
};
#ifdef COOP
static Array<Pair<const char*, void *>> sDynosCustomActors;
void DynOS_Geo_AddActorCustom(const SysPath &aPackFolder, const char *aActorName) {
@ -425,31 +421,6 @@ bool DynOS_Geo_IsCustomActor(s32 aIndex) {
return aIndex >= arrayCount;
}
#else // NORMAL DYNOS
s32 DynOS_Geo_GetActorCount() {
return (s32) (sizeof(sDynosActors) / (2 * sizeof(sDynosActors[0])));
}
const char *DynOS_Geo_GetActorName(s32 aIndex) {
return (const char *) sDynosActors[2 * aIndex];
}
const void *DynOS_Geo_GetActorLayout(s32 aIndex) {
return (const void *) sDynosActors[2 * aIndex + 1];
}
s32 DynOS_Geo_GetActorIndex(const void *aGeoLayout) {
for (s32 i = 0; i != DynOS_Geo_GetActorCount(); ++i) {
if (sDynosActors[2 * i + 1] == aGeoLayout) {
return i;
}
}
return -1;
}
#endif // NORMAL DYNOS END
//
// Geo Functions
//
@ -506,9 +477,8 @@ static const Array<Pair<const char *, void *>> sGeoFunctions = {
{ "geo_rotate_coin", (void *) geo_rotate_3d_coin },
define_geo_function(geo_offset_klepto_held_object),
define_geo_function(geo_switch_peach_eyes),
#ifdef COOP
// coop-specific
define_geo_function(geo_mario_set_player_colors),
#endif
};
#undef define_geo_function
return sGeoFunctions;
@ -594,8 +564,6 @@ void *DynOS_Geo_GetGraphNode(const void *aGeoLayout, bool aKeepInMemory) {
return NULL;
}
#ifdef COOP
// Collisions
static Array<Pair<const char*, DataNode<Collision>*>> sDynosCustomCollisions;
@ -630,5 +598,3 @@ Collision* DynOS_Col_GetCollision(const char* collisionName) {
}
return NULL;
}
#endif

View file

@ -26,16 +26,12 @@ void DynOS_Opt_LoadConfig(DynosOption *aMenu) {
// Option values
switch (_Opt->mType) {
#ifdef COOP
case DOPT_TOGGLE: {
unsigned char boolValue = 0;
sscanf(_DataBegin, "%hhu\n", &boolValue);
_Opt->mToggle.mTog[0] = boolValue;
break;
}
#else
case DOPT_TOGGLE: sscanf(_DataBegin, "%hhu\n", &_Opt->mToggle.mTog[0]); break;
#endif
case DOPT_CHOICE: sscanf(_DataBegin, "%d\n", &_Opt->mChoice.mIndex[0]); break;
case DOPT_SCROLL: sscanf(_DataBegin, "%d\n", &_Opt->mScroll.mValue[0]); break;
case DOPT_BIND: sscanf(_DataBegin, "%04X;%04X;%04X\n", &_Opt->mBind.mBinds[0], &_Opt->mBind.mBinds[1], &_Opt->mBind.mBinds[2]); break;

View file

@ -62,11 +62,7 @@ static void PrintString(const Label& aLabel, s32 aX, s32 aY, u32 aFrontColorRGBA
}
static void PrintBox(s32 aX, s32 aY, s32 aWidth, s32 aHeight, u32 aColorRGBA, bool aAlignLeft) {
#ifdef COOP
if ((aColorRGBA & 0xFF) != 0) {
#else
if ((aColorRGBA && 0xFF) != 0) {
#endif
Mtx *_Matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
if (!_Matrix) return;
if (aAlignLeft) {

View file

@ -236,9 +236,8 @@ static void *DynOS_Warp_UpdateWarp(void *aCmd, bool aIsLevelInitDone) {
gCurrActNum = MAX(1, sDynosWarpActNum * (gCurrCourseNum <= COURSE_STAGES_MAX));
gDialogCourseActNum = gCurrActNum;
gCurrAreaIndex = sDynosWarpAreaNum;
#ifdef COOP
gCurrActStarNum = sDynosWarpActNum;
#else
#ifndef COOP
DynOS_Warp_SetParam(gCurrLevelNum, DynOS_Opt_GetValue("dynos_warp_param"));
#endif
sDynosWarpTargetArea = gCurrAreaIndex;

View file

@ -6,7 +6,6 @@
#include <ultra64.h>
#include "macros.h"
#include "data/dynos.c.h"
#include "pc/network/version.h"
// Certain functions are marked as having return values, but do not
@ -406,6 +405,6 @@ struct TextureInfo
#define COOP_OBJ_FLAG_NON_SYNC (1 << 2)
#include "src/game/characters.h"
#include "data/dynos_coop.c.h"
#include "data/dynos.c.h"
#endif // _SM64_TYPES_H_

View file

@ -1,7 +1,7 @@
#include "djui.h"
#include "src/pc/utils/misc.h"
#include "src/pc/configfile.h"
#include "data/dynos_coop.c.h"
#include "data/dynos.c.h"
static void djui_panel_dynos_apply(struct DjuiBase* caller) {
dynos_packs_set_enabled(caller->tag, caller->bTag);

View file

@ -1,7 +1,7 @@
#include "sm64.h"
#include "types.h"
#include "data/dynos_coop.c.h"
#include "data/dynos.c.h"
#include "game/hud.h"
#include "pc/lua/smlua.h"
#include "smlua_misc_utils.h"

View file

@ -1,7 +1,7 @@
#include "mod.h"
#include "mods.h"
#include "mods_utils.h"
#include "data/dynos_coop.c.h"
#include "data/dynos.c.h"
#include "pc/utils/misc.h"
#include "pc/debuglog.h"

View file

@ -1,7 +1,7 @@
#include <unistd.h>
#include "mods.h"
#include "mods_utils.h"
#include "data/dynos_coop.c.h"
#include "data/dynos.c.h"
#include "pc/debuglog.h"
#define MOD_DIRECTORY "mods"