//------------------------------------------------------------------------- /* Copyright (C) 2010-2019 EDuke32 developers and contributors Copyright (C) 2019 sirlemonhead, Nuke.YKT This file is part of PCExhumed. PCExhumed is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //------------------------------------------------------------------------- #include "ns.h" // Our replacement for the MACT scripting library as the one Exhumed/Powerslave uses is from an older version. This code is based on that older version #include "typedefs.h" #include "exscript.h" #include #include #include BEGIN_PS_NS #if 0 // 16 bytes in size? struct Script { char * _0; Script *_4; Script * _8; Script * _12; }; int ScriptGrabbed = 0; Script *currentsection = 0; int scriptline = 0; Script *script = 0; uint8_t *scriptbuffer = 0; uint8_t *script_p = 0; uint8_t *scriptend_p = 0; int tokenready = 0; char scriptfilename[128]; void FreeScriptSection() { } void FreeScript() { } void Error(const char *fmt, ...) { // TODO exit(-1); } bool TokenAvailable(int nLine) { uint8_t *pOffs = script_p; if (pOffs >= scriptend_p) { return false; } while (1) { char c = *pOffs; if (c > ' ') { if (c != ';') { return true; } while (1) { c = *pOffs; if (c == 0xA) { break; } if (pOffs >= scriptend_p) { return 0; } pOffs++; } } else { if (c == 0x0A && !nLine) { Error("Line %i is incomplete\nin file %s\n", scriptline, scriptfilename); } pOffs++; if (pOffs >= scriptend_p) { return false; } } } } void CheckParseOverflow() { if (script_p >= scriptend_p) { Error("End of script reached prematurely\n"); } } void SkipWhiteSpace(int nLine) { while (1) { CheckParseOverflow(); char c = *script_p; if (c > ' ') { if (c != ';') { return; } while (1) { c = *script_p; if (c == 0xA || script_p >= scriptend_p) { continue; } script_p++; } } else { script_p++; if (c != 0xA) { continue; } if (!nLine) { Error("Line %i is incomplete\nin file %s\n"); } scriptline++; } } } void AddScriptEntry(char *entry, Script *pScript) { Script *eax = 0; if (!currentsection) { Error("No current section adding %s", entry); } if (currentsection->_4->_8 != currentsection->_4) { while (1) { if (stricmp(entry, currentsection->_4->_8->_0) == 0) { eax = currentsection->_4->_8; break; } if (currentsection->_4->_8->_8 == currentsection->_4) { break; } } } if (!eax) { Script *pScript = new Script; Script *ecx = currentsection->_4; pScript->_8 = currentsection->_4; pScript->_12 = ecx->_12; ecx = currentsection->_4; ecx->_12->_8 = pScript; currentsection->_4->_12 = pScript; pScript->_0 = entry; pScript->_4 = pScript; } else { eax = 0; if (currentsection->_4->_8 != currentsection->_4) { while (1) { if (stricmp(entry, currentsection->_4->_8->_0) == 0) { eax = currentsection->_4->_8; break; } if (currentsection->_4->_8->_8 == currentsection->_4) { break; } } } eax->_0 = entry; eax->_4 = pScript; } } void AddScriptSection(char *section) { Script *eax = 0; if (script->_8 != script) { while (1) { if (stricmp(section, script->_8->_0)) { if (script->_8 == script) { eax = 0; break; } } else { eax = script->_8; break; } } } if (!eax) { Script *pNew = new Script; pNew->_8 = script; Script *ebx = script->_12; pNew->_12 = ebx; ebx->_8 = pNew; script->_12 = pNew; pNew->_0 = section; pNew->_4 = new Script; pNew->_4->_12 = pNew->_4; pNew->_4->_8 = pNew->_4; } eax = 0; if (script->_8 != script) { while (1) { if (!stricmp(section, script->_8->_0)) { eax = script->_8; break; } if (script->_8->_8 == script) { break; } } } currentsection = eax; } void DecodeToken() { char c = *script_p; if (c == '[') { char *pSection = (char*)script_p; while (1) { c = *script_p; if (c <= ' ' || c == '=') { break; } script_p++; CheckParseOverflow(); } c = *script_p; if (c != '=') { script_p = '\0'; SkipWhiteSpace(1); c = *script_p; if (c != '=') { Error("No entry separator found for %s\n", pSection); } script_p = '\0'; SkipWhiteSpace(1); AddScriptEntry(pSection, script_p); while (1) { } } } else { script_p++; char *pSection = (char*)script_p; while (1) { c = *script_p; if (c != ']') { if (c == 0xA) { Error("No matching bracket found for section %s", pSection); } script_p++; CheckParseOverflow(); } else { script_p = '\0'; AddScriptSection(pSection); while (1) { c = *script_p; if (c == 0xA) { return; } if (script_p >= scriptend_p) { return; } script_p++; } } } } } void LoadScript(char *filename, int nVal) { if (!ScriptGrabbed) { FreeScript(); } script = new Script; currentsection = 0; script->_12 = script; script->_8 = script; int nScriptSize = 0; // LoadFile(filename); { FILE *fp = fopen(filename, "rb"); if (!fp) { // TODO - do error message return; } fseek(fp, 0, SEEK_END); nScriptSize = ftell(fp); fseek(fp, 0, SEEK_SET); scriptbuffer = new uint8_t[nScriptSize]; if (!scriptbuffer) { // TODO - do error message return; } fread(scriptbuffer, 1, nScriptSize, fp); fclose(fp); } strcpy(scriptfilename, filename); scriptline = 1; script_p = scriptbuffer; tokenready = 0; scriptend_p = scriptbuffer + nScriptSize; int edx = 0; if (nVal) { int nLine = 1; while (1) { if (edx) { return; } if (TokenAvailable(nLine)) { SkipWhiteSpace(nLine); DecodeToken(); } else { edx = nLine; } } } } #endif END_PS_NS