mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-28 15:03:01 +00:00
b2bdf8859c
Moved dynos parsing for bhvs and models to a common file Fixed recursive descent to correctly parse the entire expression Adjusted bhv generation to use recursive descent Switched all known behavior comparisons to the overridden versions Fixed issue with Chain Chomp in star road
375 lines
8.9 KiB
C++
375 lines
8.9 KiB
C++
#include "dynos.cpp.h"
|
|
|
|
//////////
|
|
// Misc //
|
|
//////////
|
|
|
|
s64 DynOS_Misc_ParseInteger(const String& _Arg, bool* found) {
|
|
const char* argStr = _Arg.begin();
|
|
if (argStr[0] == '0' && argStr[1] == 'x') {
|
|
// is a hex number
|
|
argStr += 2;
|
|
while(*argStr != '\0') {
|
|
if (*argStr >= '0' && *argStr <= '9') {
|
|
// good
|
|
} else if (*argStr >= 'a' && *argStr <= 'f') {
|
|
// good
|
|
} else if (*argStr >= 'A' && *argStr <= 'F') {
|
|
// good
|
|
} else {
|
|
// bad character
|
|
*found = false;
|
|
return 0;
|
|
}
|
|
argStr++;
|
|
}
|
|
} else {
|
|
// is a decimal number
|
|
if (*argStr == '-' || *argStr == '+') {
|
|
// good
|
|
argStr++;
|
|
}
|
|
while(*argStr != '\0') {
|
|
if (*argStr >= '0' && *argStr <= '9') {
|
|
// good
|
|
} else if (*argStr == '.') {
|
|
// good
|
|
} else {
|
|
// bad character
|
|
*found = false;
|
|
return 0;
|
|
}
|
|
argStr++;
|
|
}
|
|
}
|
|
|
|
*found = true;
|
|
return _Arg.ParseInt();
|
|
}
|
|
|
|
void DynOS_Gfx_Free(GfxData* aGfxData) {
|
|
if (aGfxData) {
|
|
for (auto& _Node : aGfxData->mLights) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mLightTs) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mAmbientTs) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mTextures) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mTextureLists) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mVertices) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mDisplayLists) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mGeoLayouts) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mAnimations) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mCollisions) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mBehaviorScripts) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mLevelScripts) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mMacroObjects) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mTrajectories) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mMovtexs) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mMovtexQCs) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
for (auto& _Node : aGfxData->mRooms) {
|
|
Delete(_Node->mData);
|
|
Delete(_Node);
|
|
}
|
|
Delete(aGfxData);
|
|
}
|
|
}
|
|
|
|
u32 DynOS_Lua_RememberVariable(GfxData* aGfxData, void* aPtr, String& token) {
|
|
// remember as lua pointer
|
|
aGfxData->mLuaPointerList.Add(aPtr);
|
|
|
|
// find existing token
|
|
for (u32 i = 0; i < aGfxData->mLuaTokenList.Count(); i++) {
|
|
if (aGfxData->mLuaTokenList[i] == token) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
// add token
|
|
aGfxData->mLuaTokenList.Add(token);
|
|
return aGfxData->mLuaTokenList.Count() - 1;
|
|
}
|
|
|
|
///////////////////////
|
|
// Recursive Descent //
|
|
///////////////////////
|
|
|
|
static char* sRdString = NULL;
|
|
static bool sRdError = false;
|
|
static RDConstantFunc sRdConstantFunc = NULL;
|
|
|
|
static s64 ParseExpression();
|
|
|
|
static void ParseWhitespace() {
|
|
while (*sRdString == ' ' || *sRdString == '\t' || *sRdString == '\r' || *sRdString == '\n') {
|
|
sRdString++;
|
|
}
|
|
}
|
|
|
|
static bool IsAlphabetical(char c) {
|
|
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
|
}
|
|
|
|
static bool IsAlphaNumeric(char c) {
|
|
return IsAlphabetical(c) || (c >= '0' && c <= '9');
|
|
}
|
|
|
|
static bool IsIdentifierBeginning(char c) {
|
|
return IsAlphabetical(c) || (c == '_');
|
|
}
|
|
|
|
static bool IsIdentifierCharacter(char c) {
|
|
return IsAlphaNumeric(c) || (c == '_');
|
|
}
|
|
|
|
static bool ParseOperator(const char* op) {
|
|
size_t opLen = strlen(op);
|
|
if (!strncmp(sRdString, op, opLen)) {
|
|
sRdString += opLen;
|
|
ParseWhitespace();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool PeekOperator(const char* op) {
|
|
size_t opLen = strlen(op);
|
|
return (!strncmp(sRdString, op, opLen));
|
|
}
|
|
|
|
static s64 ParseNumeric() {
|
|
String numeric = "";
|
|
char* c = sRdString;
|
|
|
|
if (*c == '0' && *(c+1) == 'x') {
|
|
// is hex
|
|
numeric.Add(*c);
|
|
c++;
|
|
numeric.Add(*c);
|
|
c++;
|
|
while (true) {
|
|
if (*c >= '0' && *c <= '9') {
|
|
// good
|
|
} else if (*c >= 'a' && *c <= 'f') {
|
|
// good
|
|
} else if (*c >= 'A' && *c <= 'F') {
|
|
// good
|
|
} else {
|
|
// bad
|
|
break;
|
|
}
|
|
numeric.Add(*c);
|
|
c++;
|
|
}
|
|
} else {
|
|
// is decimal
|
|
while (*c >= '0' && *c <= '9') {
|
|
numeric.Add(*c);
|
|
c++;
|
|
}
|
|
}
|
|
|
|
// advance parsing
|
|
sRdString = c;
|
|
ParseWhitespace();
|
|
|
|
// parse
|
|
return numeric.ParseInt();
|
|
}
|
|
|
|
static s64 ParseFactor() {
|
|
char* c = sRdString;
|
|
|
|
// check for unary op
|
|
if (ParseOperator("-")) {
|
|
return -ParseFactor();
|
|
} else if (ParseOperator("+")) {
|
|
return +ParseFactor();
|
|
} else if (ParseOperator("!")) {
|
|
return !ParseFactor();
|
|
} else if (ParseOperator("~")) {
|
|
return ~ParseFactor();
|
|
}
|
|
|
|
// check for numeric
|
|
if (*c >= '0' && *c <= '9') {
|
|
return ParseNumeric();
|
|
}
|
|
|
|
// check for sub expression
|
|
if (ParseOperator("(")) {
|
|
s64 e1 = ParseExpression();
|
|
if (ParseOperator(")")) {
|
|
return e1;
|
|
} else {
|
|
sRdError = true;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// check for known identifier
|
|
if (IsIdentifierBeginning(*c)) {
|
|
String identifier = "";
|
|
char* cTmp = c;
|
|
while (IsIdentifierCharacter(*cTmp)) {
|
|
identifier.Add(*cTmp);
|
|
cTmp++;
|
|
}
|
|
|
|
if (sRdConstantFunc != NULL) {
|
|
bool constantFound = false;
|
|
s64 constantValue = sRdConstantFunc(identifier, &constantFound);
|
|
if (constantFound) {
|
|
sRdString = cTmp;
|
|
return constantValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
sRdError = true;
|
|
return 0;
|
|
}
|
|
|
|
static s64 ParseTerm() {
|
|
s64 f1 = ParseFactor();
|
|
|
|
while (PeekOperator("*") || PeekOperator("/") || PeekOperator("%")) {
|
|
if (ParseOperator("*")) {
|
|
f1 *= ParseFactor();
|
|
} else if (ParseOperator("/")) {
|
|
f1 /= ParseFactor();
|
|
} else if (ParseOperator("%")) {
|
|
f1 %= ParseFactor();
|
|
}
|
|
}
|
|
|
|
return f1;
|
|
}
|
|
|
|
static s64 ParseAddSubExpression() {
|
|
s64 t1 = ParseTerm();
|
|
|
|
while (PeekOperator("+") || PeekOperator("-")) {
|
|
if (ParseOperator("+")) {
|
|
t1 += ParseTerm();
|
|
} else if (ParseOperator("-")) {
|
|
t1 -= ParseTerm();
|
|
}
|
|
}
|
|
|
|
return t1;
|
|
}
|
|
|
|
static s64 ParseShiftExpression() {
|
|
s64 e1 = ParseAddSubExpression();
|
|
|
|
while (PeekOperator("<<") || PeekOperator(">>")) {
|
|
if (ParseOperator("<<")) {
|
|
e1 = e1 << ParseAddSubExpression();
|
|
} else if (ParseOperator(">>")) {
|
|
e1 = e1 >> ParseAddSubExpression();
|
|
}
|
|
}
|
|
|
|
return e1;
|
|
}
|
|
|
|
static s64 ParseBitAndExpression() {
|
|
s64 e1 = ParseShiftExpression();
|
|
|
|
while (PeekOperator("&")) {
|
|
if (ParseOperator("&")) {
|
|
e1 &= ParseShiftExpression();
|
|
}
|
|
}
|
|
|
|
return e1;
|
|
}
|
|
|
|
static s64 ParseBitXorExpression() {
|
|
s64 e1 = ParseBitAndExpression();
|
|
|
|
while (PeekOperator("^")) {
|
|
if (ParseOperator("^")) {
|
|
e1 ^= ParseBitAndExpression();
|
|
}
|
|
}
|
|
|
|
return e1;
|
|
}
|
|
|
|
static s64 ParseBitOrExpression() {
|
|
s64 e1 = ParseBitXorExpression();
|
|
|
|
while (PeekOperator("|")) {
|
|
if (ParseOperator("|")) {
|
|
e1 |= ParseBitXorExpression();
|
|
}
|
|
}
|
|
|
|
return e1;
|
|
}
|
|
|
|
static s64 ParseExpression() {
|
|
return ParseBitOrExpression();
|
|
}
|
|
|
|
s64 DynOS_RecursiveDescent_Parse(const char* expr, bool* success, RDConstantFunc func) {
|
|
sRdString = (char*)expr;
|
|
sRdError = false;
|
|
sRdConstantFunc = func;
|
|
s64 value = ParseExpression();
|
|
if (strlen(sRdString) > 0) {
|
|
sRdError = true;
|
|
}
|
|
sRdString = NULL;
|
|
*success = !sRdError;
|
|
return value;
|
|
}
|