Added trajectories to custom DynOS levels
This commit is contained in:
parent
2bd4d4da36
commit
4d59da2500
|
@ -29,6 +29,7 @@ enum {
|
|||
DATA_TYPE_COLLISION,
|
||||
DATA_TYPE_LEVEL_SCRIPT,
|
||||
DATA_TYPE_MACRO_OBJECT,
|
||||
DATA_TYPE_TRAJECTORY,
|
||||
DATA_TYPE_UNUSED,
|
||||
};
|
||||
|
||||
|
@ -426,6 +427,7 @@ struct GfxData : NoCopy {
|
|||
DataNodes<Collision> mCollisions;
|
||||
DataNodes<LevelScript> mLevelScripts;
|
||||
DataNodes<MacroObject> mMacroObjects;
|
||||
DataNodes<Trajectory> mTrajectories;
|
||||
|
||||
// Animation data
|
||||
Array<AnimBuffer<s16> *> mAnimValues;
|
||||
|
@ -753,6 +755,10 @@ DataNode<MacroObject>* DynOS_MacroObject_Parse(GfxData* aGfxData, DataNode<Macro
|
|||
void DynOS_MacroObject_Write(FILE* aFile, GfxData* aGfxData, DataNode<MacroObject> *aNode);
|
||||
DataNode<MacroObject>* DynOS_MacroObject_Load(FILE *aFile, GfxData *aGfxData);
|
||||
|
||||
DataNode<Trajectory>* DynOS_Trajectory_Parse(GfxData* aGfxData, DataNode<Trajectory>* aNode, bool aDisplayPercent);
|
||||
void DynOS_Trajectory_Write(FILE* aFile, GfxData* aGfxData, DataNode<Trajectory> *aNode);
|
||||
DataNode<Trajectory>* DynOS_Trajectory_Load(FILE *aFile, GfxData *aGfxData);
|
||||
|
||||
DataNode<TexData>* DynOS_Tex_Parse(GfxData* aGfxData, DataNode<TexData>* aNode);
|
||||
void DynOS_Tex_Write(FILE* aFile, GfxData* aGfxData, DataNode<TexData> *aNode);
|
||||
void DynOS_Tex_Load(FILE *aFile, GfxData *aGfxData);
|
||||
|
|
|
@ -1207,6 +1207,13 @@ static LevelScript ParseLevelScriptSymbolArg(GfxData* aGfxData, DataNode<LevelSc
|
|||
}
|
||||
}
|
||||
|
||||
// Trajectories
|
||||
for (auto& _Node : aGfxData->mTrajectories) {
|
||||
if (_Arg == _Node->mName) {
|
||||
return (s64) DynOS_Trajectory_Parse(aGfxData, _Node, false)->mData;
|
||||
}
|
||||
}
|
||||
|
||||
// Integers
|
||||
s32 x;
|
||||
if ((_Arg[1] == 'x' && sscanf(_Arg.begin(), "%x", &x) == 1) || (sscanf(_Arg.begin(), "%d", &x) == 1)) {
|
||||
|
@ -1562,6 +1569,11 @@ static bool DynOS_Lvl_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxD
|
|||
DynOS_MacroObject_Write(_File, aGfxData, _Node);
|
||||
}
|
||||
}
|
||||
for (auto &_Node : aGfxData->mTrajectories) {
|
||||
if (_Node->mLoadIndex == i) {
|
||||
DynOS_Trajectory_Write(_File, aGfxData, _Node);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(_File);
|
||||
return true;
|
||||
|
|
|
@ -60,6 +60,13 @@ static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) {
|
|||
}
|
||||
}
|
||||
|
||||
// Trajectories
|
||||
for (auto& _Node : aGfxData->mTrajectories) {
|
||||
if (_Node->mData == aPtr) {
|
||||
return { _Node->mName, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
// Behaviors
|
||||
enum BehaviorId id = get_id_from_vanilla_behavior((const BehaviorScript*) aPtr);
|
||||
if (id >= 0 && id < id_bhv_max_count) {
|
||||
|
@ -181,6 +188,13 @@ static void *GetPointerFromData(GfxData *aGfxData, const String &aPtrName, u32 a
|
|||
}
|
||||
}
|
||||
|
||||
// Trajectories
|
||||
for (auto &_Node : aGfxData->mTrajectories) {
|
||||
if (_Node->mName == aPtrName) {
|
||||
return (void *) _Node->mData;
|
||||
}
|
||||
}
|
||||
|
||||
// Behaviors
|
||||
enum BehaviorId id = get_id_from_behavior_name(aPtrName.begin());
|
||||
if (id >= 0 && id < id_bhv_max_count) {
|
||||
|
|
|
@ -191,6 +191,8 @@ void DynOS_Read_Source(GfxData *aGfxData, const SysPath &aFilename) {
|
|||
_DataType = DATA_TYPE_LEVEL_SCRIPT;
|
||||
} else if (_Buffer == "MacroObject") {
|
||||
_DataType = DATA_TYPE_MACRO_OBJECT;
|
||||
} else if (_Buffer == "Trajectory") {
|
||||
_DataType = DATA_TYPE_TRAJECTORY;
|
||||
} else {
|
||||
PrintError(" ERROR: Unknown type name: %s", _Buffer.begin());
|
||||
}
|
||||
|
@ -217,6 +219,7 @@ void DynOS_Read_Source(GfxData *aGfxData, const SysPath &aFilename) {
|
|||
case DATA_TYPE_COLLISION: AppendNewNode(aGfxData, aGfxData->mCollisions, _Buffer, pDataName, pDataTokens); break;
|
||||
case DATA_TYPE_LEVEL_SCRIPT: AppendNewNode(aGfxData, aGfxData->mLevelScripts, _Buffer, pDataName, pDataTokens); break;
|
||||
case DATA_TYPE_MACRO_OBJECT: AppendNewNode(aGfxData, aGfxData->mMacroObjects, _Buffer, pDataName, pDataTokens); break;
|
||||
case DATA_TYPE_TRAJECTORY: AppendNewNode(aGfxData, aGfxData->mTrajectories, _Buffer, pDataName, pDataTokens); break;
|
||||
case DATA_TYPE_UNUSED: pDataTokens = (Array<String> *) 1; break;
|
||||
}
|
||||
_Buffer.Clear();
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
#include "dynos.cpp.h"
|
||||
|
||||
extern "C" {
|
||||
#include "include/level_misc_macros.h"
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnarrowing"
|
||||
|
||||
/////////////
|
||||
// Parsing //
|
||||
/////////////
|
||||
|
||||
#define TRAJECTORY_SIZE_PER_TOKEN 4
|
||||
|
||||
#define trajectory_constant(x) if (_Arg == #x) { return (s64) (x); }
|
||||
static s64 ParseTrajectorySymbolArg(GfxData* aGfxData, DataNode<Trajectory>* aNode, u64& aTokenIndex) {
|
||||
const String& _Arg = aNode->mTokens[aTokenIndex++];
|
||||
|
||||
// Other constants
|
||||
trajectory_constant(NULL);
|
||||
|
||||
// Integers
|
||||
s32 x;
|
||||
if ((_Arg[1] == 'x' && sscanf(_Arg.begin(), "%x", &x) == 1) || (sscanf(_Arg.begin(), "%d", &x) == 1)) {
|
||||
return (s64) x;
|
||||
}
|
||||
|
||||
// Unknown
|
||||
PrintError(" ERROR: Unknown trajectory arg: %s", _Arg.begin());
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define trajectory_symbol_0(symb) \
|
||||
if (_Symbol == #symb) { \
|
||||
Trajectory _Tr[] = { symb() }; \
|
||||
memcpy(aHead, _Tr, sizeof(_Tr)); \
|
||||
aHead += (sizeof(_Tr) / sizeof(_Tr[0])); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define trajectory_symbol_4(symb) \
|
||||
if (_Symbol == #symb) { \
|
||||
s64 _Arg0 = ParseTrajectorySymbolArg(aGfxData, aNode, aTokenIndex); \
|
||||
s64 _Arg1 = ParseTrajectorySymbolArg(aGfxData, aNode, aTokenIndex); \
|
||||
s64 _Arg2 = ParseTrajectorySymbolArg(aGfxData, aNode, aTokenIndex); \
|
||||
s64 _Arg3 = ParseTrajectorySymbolArg(aGfxData, aNode, aTokenIndex); \
|
||||
Trajectory _Tr[] = { symb(_Arg0, _Arg1, _Arg2, _Arg3) }; \
|
||||
memcpy(aHead, _Tr, sizeof(_Tr)); \
|
||||
aHead += (sizeof(_Tr) / sizeof(_Tr[0])); \
|
||||
return; \
|
||||
}
|
||||
|
||||
static void ParseTrajectorySymbol(GfxData* aGfxData, DataNode<Trajectory>* aNode, Trajectory*& aHead, u64& aTokenIndex, Array<u64>& aSwitchNodes) {
|
||||
const String& _Symbol = aNode->mTokens[aTokenIndex++];
|
||||
|
||||
trajectory_symbol_4(TRAJECTORY_POS);
|
||||
trajectory_symbol_0(TRAJECTORY_END);
|
||||
|
||||
// Unknown
|
||||
PrintError(" ERROR: Unknown trajectory symbol: %s", _Symbol.begin());
|
||||
}
|
||||
|
||||
DataNode<Trajectory>* DynOS_Trajectory_Parse(GfxData* aGfxData, DataNode<Trajectory>* aNode, bool aDisplayPercent) {
|
||||
if (aNode->mData) return aNode;
|
||||
|
||||
// Trajectory data
|
||||
aNode->mData = New<Trajectory>(aNode->mTokens.Count() * TRAJECTORY_SIZE_PER_TOKEN);
|
||||
Trajectory* _Head = aNode->mData;
|
||||
Array<u64> _SwitchNodes;
|
||||
for (u64 _TokenIndex = 0; _TokenIndex < aNode->mTokens.Count();) { // Don't increment _TokenIndex here!
|
||||
ParseTrajectorySymbol(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;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
/////////////
|
||||
// Writing //
|
||||
/////////////
|
||||
|
||||
void DynOS_Trajectory_Write(FILE* aFile, GfxData* aGfxData, DataNode<Trajectory> *aNode) {
|
||||
if (!aNode->mData) return;
|
||||
|
||||
// Name
|
||||
WriteBytes<u8>(aFile, DATA_TYPE_TRAJECTORY);
|
||||
aNode->mName.Write(aFile);
|
||||
|
||||
// Data
|
||||
WriteBytes<u32>(aFile, aNode->mSize);
|
||||
for (u32 i = 0; i != aNode->mSize; ++i) {
|
||||
WriteBytes<Trajectory>(aFile, aNode->mData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////
|
||||
// Reading //
|
||||
/////////////
|
||||
|
||||
DataNode<Trajectory>* DynOS_Trajectory_Load(FILE *aFile, GfxData *aGfxData) {
|
||||
DataNode<Trajectory> *_Node = New<DataNode<Trajectory>>();
|
||||
|
||||
// Name
|
||||
_Node->mName.Read(aFile);
|
||||
|
||||
// Data
|
||||
_Node->mSize = ReadBytes<u32>(aFile);
|
||||
_Node->mData = New<Trajectory>(_Node->mSize);
|
||||
for (u32 i = 0; i != _Node->mSize; ++i) {
|
||||
_Node->mData[i] = ReadBytes<Trajectory>(aFile);
|
||||
}
|
||||
|
||||
// Add it
|
||||
if (aGfxData != NULL) {
|
||||
aGfxData->mTrajectories.Add(_Node);
|
||||
}
|
||||
|
||||
return _Node;
|
||||
}
|
|
@ -42,6 +42,10 @@ void DynOS_Gfx_Free(GfxData* aGfxData) {
|
|||
Delete(_Node->mData);
|
||||
Delete(_Node);
|
||||
}
|
||||
for (auto& _Node : aGfxData->mTrajectories) {
|
||||
Delete(_Node->mData);
|
||||
Delete(_Node);
|
||||
}
|
||||
Delete(aGfxData);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue