diff options
| author | fusion32 <marcopuzziello@gmail.com> | 2025-05-22 11:40:04 -0300 |
|---|---|---|
| committer | fusion32 <marcopuzziello@gmail.com> | 2025-05-22 11:40:04 -0300 |
| commit | 297e8450d80411d81f0aaeee642053354125bd6d (patch) | |
| tree | cba665717e133b288b51a960e0401652ab73019a | |
| parent | de848a4131beb288335b6aaa29c2a6a439c50e0e (diff) | |
| download | game-297e8450d80411d81f0aaeee642053354125bd6d.tar.gz game-297e8450d80411d81f0aaeee642053354125bd6d.zip | |
implement TWriteScriptFile
| -rw-r--r-- | TODO.md | 4 | ||||
| -rw-r--r-- | reference/game.c | 385 | ||||
| -rw-r--r-- | src/script.cc | 185 | ||||
| -rw-r--r-- | src/script.hh | 12 |
4 files changed, 193 insertions, 393 deletions
@@ -1,6 +1,8 @@ ## TODO NEXT -- TReadScript / TWriteScript - THREADS +- TReadStream/TWriteStream +- TReadBuffer/TWriteBuffer +- TReadBinaryFile/TWriteBinaryFile - TCreature - TPlayer - TNonPlayer diff --git a/reference/game.c b/reference/game.c index 1affc5c..975bc84 100644 --- a/reference/game.c +++ b/reference/game.c @@ -3594,391 +3594,6 @@ LAB_0804eb1e: return;
}
-// DWARF original prototype: void TWriteScriptFile(TWriteScriptFile * this)
-
-void __thiscall TWriteScriptFile::TWriteScriptFile(TWriteScriptFile *this)
-
-{
- this->File = (FILE *)0x0;
- return;
-}
-
-
-
-// DWARF original prototype: void TWriteScriptFile(TWriteScriptFile * this)
-
-void __thiscall TWriteScriptFile::TWriteScriptFile(TWriteScriptFile *this)
-
-{
- this->File = (FILE *)0x0;
- return;
-}
-
-
-
-// DWARF original prototype: void ~TWriteScriptFile(TWriteScriptFile * this, int __in_chrg)
-
-void __thiscall TWriteScriptFile::~TWriteScriptFile(TWriteScriptFile *this,int __in_chrg)
-
-{
- char *pcVar1;
- int iVar2;
- int *piVar3;
-
- if (this->File != (FILE *)0x0) {
- pcVar1 = "";
- if (this != (TWriteScriptFile *)0xfffffffc) {
- pcVar1 = this->Filename;
- }
- ::error("TWriteScriptFile::~TWriteScriptFile: Datei %s ist noch offen.\n",pcVar1);
- iVar2 = fclose((FILE *)this->File);
- if (iVar2 != 0) {
- piVar3 = __errno_location();
- ::error(&DAT_080ef6e0,*piVar3);
- }
- }
- return;
-}
-
-
-
-// DWARF original prototype: void ~TWriteScriptFile(TWriteScriptFile * this, int __in_chrg)
-
-void __thiscall TWriteScriptFile::~TWriteScriptFile(TWriteScriptFile *this,int __in_chrg)
-
-{
- char *pcVar1;
- int iVar2;
- int *piVar3;
-
- if (this->File != (FILE *)0x0) {
- pcVar1 = "";
- if (this != (TWriteScriptFile *)0xfffffffc) {
- pcVar1 = this->Filename;
- }
- ::error("TWriteScriptFile::~TWriteScriptFile: Datei %s ist noch offen.\n",pcVar1);
- iVar2 = fclose((FILE *)this->File);
- if (iVar2 != 0) {
- piVar3 = __errno_location();
- ::error(&DAT_080ef6e0,*piVar3);
- }
- }
- return;
-}
-
-
-
-// DWARF original prototype: void open(TWriteScriptFile * this, char * FileName)
-
-int __thiscall TWriteScriptFile::open(TWriteScriptFile *this,char *__file,int __oflag,...)
-
-{
- FILE *pFVar1;
- char *pcVar2;
- int *piVar3;
- undefined4 *puVar4;
- int iVar5;
-
- if (this->File != (FILE *)0x0) {
- ::error("TWriteScriptFile::open: Altes Skript ist noch offen.\n");
- iVar5 = fclose((FILE *)this->File);
- if (iVar5 != 0) {
- piVar3 = __errno_location();
- ::error(&DAT_080ef7c0,*piVar3);
- }
- this->File = (FILE *)0x0;
- }
- pFVar1 = fopen(__file,"wb");
- this->File = (FILE *)pFVar1;
- if (pFVar1 != (FILE *)0x0) {
- this->Line = 0;
- pcVar2 = strcpy(this->Filename,__file);
- return (int)pcVar2;
- }
- piVar3 = __errno_location();
- iVar5 = *piVar3;
- // try { // try from 08050063 to 080500eb has its CatchHandler @ 080500f0
- ::error("TWriteScriptFile: Kann Datei %s nicht anlegen.\n",__file);
- pcVar2 = strerror(iVar5);
- ::error("Fehler %d: %s.\n",iVar5,pcVar2);
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = "Cannot create script-file";
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,char_const*::typeinfo,0);
-}
-
-
-
-// DWARF original prototype: void close(TWriteScriptFile * this)
-
-int __thiscall TWriteScriptFile::close(TWriteScriptFile *this,int __fd)
-
-{
- int iVar1;
- int *piVar2;
- FILE *__stream;
-
- __stream = (FILE *)this->File;
- if (__stream != (FILE *)0x0) {
- iVar1 = fclose(__stream);
- if (iVar1 != 0) {
- piVar2 = __errno_location();
- iVar1 = *piVar2;
- ::error(&DAT_080ef800,iVar1);
- }
- this->File = (FILE *)0x0;
- return iVar1;
- }
- ::error("TWriteScriptFile::close: Kein Skript offen.\n");
- return (int)__stream;
-}
-
-
-
-// DWARF original prototype: void error(TWriteScriptFile * this, char * Text)
-
-void __thiscall TWriteScriptFile::error(TWriteScriptFile *this,char *Text)
-
-{
- int iVar1;
- int *piVar2;
- undefined4 *puVar3;
-
- if ((FILE *)this->File != (FILE *)0x0) {
- iVar1 = fclose((FILE *)this->File);
- if (iVar1 != 0) {
- piVar2 = __errno_location();
- // try { // try from 080501b0 to 08050223 has its CatchHandler @ 08050224
- ::error(&DAT_080ef880,*piVar2);
- }
- }
- this->File = (FILE *)0x0;
- snprintf(ErrorString,100,"error in script-file \"%s\", line %d: %s",this->Filename,this->Line,
- Text);
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = ErrorString;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,char*::typeinfo,0);
-}
-
-
-
-// DWARF original prototype: void writeLn(TWriteScriptFile * this)
-
-void __thiscall TWriteScriptFile::writeLn(TWriteScriptFile *this)
-
-{
- undefined4 *puVar1;
-
- if ((FILE *)this->File != (FILE *)0x0) {
- putc(10,(FILE *)this->File);
- return;
- }
- // try { // try from 0805026a to 08050298 has its CatchHandler @ 08050299
- ::error(&DAT_080ef8c0);
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = "Cannot write linefeed";
- // WARNING: Subroutine does not return
- __cxa_throw(puVar1,char_const*::typeinfo,0);
-}
-
-
-
-// DWARF original prototype: void writeText(TWriteScriptFile * this, char * Text)
-
-void __thiscall TWriteScriptFile::writeText(TWriteScriptFile *this,char *Text)
-
-{
- char cVar1;
- undefined4 *puVar2;
- FILE *__stream;
- char *Text_00;
-
- __stream = (FILE *)this->File;
- if (__stream == (FILE *)0x0) {
- Text_00 = &DAT_080ef940;
- }
- else {
- if (Text != (char *)0x0) {
- cVar1 = *Text;
- if (cVar1 != '\0') {
- while( true ) {
- Text = Text + 1;
- putc((int)cVar1,__stream);
- cVar1 = *Text;
- if (cVar1 == '\0') break;
- __stream = (FILE *)this->File;
- }
- }
- return;
- }
- Text_00 = "TWriteScriptFile::writeText: Text ist NULL.\n";
- }
- // try { // try from 080502fe to 0805032c has its CatchHandler @ 08050336
- ::error(Text_00);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = "Cannot write text";
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,char_const*::typeinfo,0);
-}
-
-
-
-// DWARF original prototype: void writeString(TWriteScriptFile * this, char * Text)
-
-void __thiscall TWriteScriptFile::writeString(TWriteScriptFile *this,char *Text)
-
-{
- undefined4 *puVar1;
- char cVar2;
- char *Text_00;
-
- if ((FILE *)this->File == (FILE *)0x0) {
- Text_00 = &DAT_080ef9e0;
- }
- else {
- if (Text != (char *)0x0) {
- putc(0x22,(FILE *)this->File);
- cVar2 = *Text;
- while (cVar2 != '\0') {
- if ((cVar2 == '\"') || (cVar2 == '\\')) {
- putc(0x5c,(FILE *)this->File);
- cVar2 = *Text;
- }
- if (cVar2 == '\n') {
- putc(0x5c,(FILE *)this->File);
- putc(0x6e,(FILE *)this->File);
- }
- else {
- putc((int)cVar2,(FILE *)this->File);
- }
- Text = Text + 1;
- cVar2 = *Text;
- }
- putc(0x22,(FILE *)this->File);
- return;
- }
- Text_00 = "TWriteScriptFile::writeString: Text ist NULL.\n";
- }
- // try { // try from 08050416 to 08050444 has its CatchHandler @ 0805044e
- ::error(Text_00);
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = "Cannot write string";
- // WARNING: Subroutine does not return
- __cxa_throw(puVar1,char_const*::typeinfo,0);
-}
-
-
-
-// DWARF original prototype: void writeNumber(TWriteScriptFile * this, int Number)
-
-void __thiscall TWriteScriptFile::writeNumber(TWriteScriptFile *this,int Number)
-
-{
- undefined4 *puVar1;
- char local_2c [4];
- char s [20];
-
- if (this->File != (FILE *)0x0) {
- sprintf(local_2c,"%d",Number);
- // try { // try from 080504a6 to 080504ea has its CatchHandler @ 080504f0
- writeText(this,local_2c);
- return;
- }
- ::error(&DAT_080efa40);
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = "Cannot write number";
- // WARNING: Subroutine does not return
- __cxa_throw(puVar1,char_const*::typeinfo,0);
-}
-
-
-
-// DWARF original prototype: void writeBytesequence(TWriteScriptFile * this, uchar * Sequence, int
-// Length)
-
-void __thiscall
-TWriteScriptFile::writeBytesequence(TWriteScriptFile *this,uchar *Sequence,int Length)
-
-{
- undefined4 *puVar1;
- int i;
- int iVar2;
- char *Text;
- char local_3c [4];
- char s [20];
-
- if (this->File == (FILE *)0x0) {
- Text = &DAT_080efb20;
- }
- else if (Sequence == (uchar *)0x0) {
- Text = "TWriteScriptFile::writeBytesequence: Sequence ist NULL.\n";
- }
- else {
- if (0 < Length) {
- iVar2 = 0;
- if (0 < Length) {
- do {
- if (iVar2 != 0) {
- // try { // try from 080505de to 0805061d has its CatchHandler @ 08050648
- writeText(this,"-");
- }
- if (this->File == (FILE *)0x0) {
- ::error(&DAT_080efa40);
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = "Cannot write number";
- // WARNING: Subroutine does not return
- __cxa_throw(puVar1,char_const*::typeinfo,0);
- }
- sprintf(local_3c,"%d",(uint)Sequence[iVar2]);
- // try { // try from 0805057c to 080505d2 has its CatchHandler @ 08050630
- writeText(this,local_3c);
- iVar2 = iVar2 + 1;
- } while (iVar2 < Length);
- }
- return;
- }
- Text = &DAT_080efaa0;
- }
- ::error(Text);
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = "Cannot write bytesequence";
- // WARNING: Subroutine does not return
- __cxa_throw(puVar1,char_const*::typeinfo,0);
-}
-
-
-
-// DWARF original prototype: void writeCoordinate(TWriteScriptFile * this, int x, int y, int z)
-
-void __thiscall TWriteScriptFile::writeCoordinate(TWriteScriptFile *this,int x,int y,int z)
-
-{
- undefined4 *puVar1;
- char local_2c [4];
- char s [20];
-
- if (this->File == (FILE *)0x0) {
- ::error(&DAT_080efbe0);
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = "Cannot write coordinate";
- }
- else {
- if (((-1 < x) && (-1 < y)) && (-1 < z)) {
- sprintf(local_2c,"[%u,%u,%u]",x,y,z);
- // try { // try from 080506b4 to 08050710 has its CatchHandler @ 08050725
- writeText(this,local_2c);
- return;
- }
- ::error(&DAT_080efb80,x,y,z);
- puVar1 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar1 = "Invalid coordinates";
- }
- // WARNING: Subroutine does not return
- __cxa_throw(puVar1,char_const*::typeinfo,0);
-}
-
-
// DWARF original prototype: void TReadBinaryFile(TReadBinaryFile * this)
diff --git a/src/script.cc b/src/script.cc index d3e8134..5c8c7d7 100644 --- a/src/script.cc +++ b/src/script.cc @@ -1,6 +1,15 @@ #include "script.hh" -// ============================================================================= +// NOTE(fusion): Throwing a character array on the stack as an exception won't +// work because it implicitly decays into a character pointer which would then +// point to invalid data when actually parsed. It is the reason `ErrorString` is +// declared statically, or else you'd need to throw some heap allocated string +// which then becomes ambiguous whether you should free it or not. Used in: +// - TReadScriptFile::error +// - TWriteScriptFile::error +static char ErrorString[100]; + +// Helper Functions // ============================================================================= // TODO(fusion): Move to `util.cc`? @@ -104,9 +113,8 @@ static char *findLast(char *s, char c){ return Last; } -// ============================================================================= -// ============================================================================= - +// TWriteScriptFile +//============================================================================== TReadScriptFile::TReadScriptFile(void){ this->RecursionDepth = -1; this->Bytes = (uint8*)this->String; @@ -172,8 +180,6 @@ void TReadScriptFile::close(void){ } void TReadScriptFile::error(const char *Text){ - static char ErrorString[100]; - int Depth = this->RecursionDepth; ASSERT(Depth >= 0 && Depth <= NARRAY(this->File)); @@ -615,3 +621,170 @@ int main(int argc, char **argv){ return EXIT_FAILURE; } + +// TWriteScriptFile +//============================================================================== +TWriteScriptFile::TWriteScriptFile(void){ + this->File = NULL; +} + +TWriteScriptFile::~TWriteScriptFile(void){ + if(this->File != NULL){ + ::error("TWriteScriptFile::~TWriteScriptFile: Datei %s ist noch offen.\n", this->Filename); + if(fclose(this->File) != 0){ + ::error("TWriteScriptFile::~TWriteScriptFile: Fehler %d beim Schließen der Datei.\n", errno); + } + } +} + +void TWriteScriptFile::open(char *FileName){ + if(this->File != NULL){ + ::error("TWriteScriptFile::open: Altes Skript ist noch offen.\n"); + if(fclose(this->File) != 0){ + ::error("TWriteScriptFile::open: Fehler %d beim Schließen der Datei.\n", errno); + } + this->File = NULL; + } + + this->File = fopen(FileName, "wb"); + if(this->File == NULL){ + ::error("TWriteScriptFile: Kann Datei %s nicht anlegen.\n", FileName); + ::error("Fehler %d: %s.\n", errno, strerror(errno)); + throw "Cannot create script-file"; + } + + strcpy(this->Filename, FileName); + this->Line = 0; +} + +void TWriteScriptFile::close(void){ + if(this->File == NULL){ + ::error("TWriteScriptFile::close: Kein Skript offen.\n"); + return; + } + + if(fclose(this->File) != 0){ + ::error("TWriteScriptFile::close: Fehler %d beim Schließen der Datei.\n", errno); + } + this->File = NULL; +} + +void TWriteScriptFile::error(char *Text){ + if(this->File != NULL){ + if(fclose(this->File) != 0){ + ::error("TWriteScriptFile::error: Fehler %d beim Schließen der Datei.\n", errno); + } + this->File = NULL; + } + + snprintf(ErrorString, sizeof(ErrorString), + "error in script-file \"%s\", line %d: %s", + this->Filename, this->Line); + + throw ErrorString; +} + +void TWriteScriptFile::writeLn(void){ + if(this->File == NULL){ + ::error("TWriteScriptFile::writeLn: Kein Skript zum Schreiben geöffnet.\n"); + throw "Cannot write linefeed"; + } + + putc('\n', this->File); +} + +void TWriteScriptFile::writeText(char *Text){ + if(this->File == NULL){ + ::error("TWriteScriptFile::writeText: Kein Skript zum Schreiben geöffnet.\n"); + throw "Cannot write text"; + } + + if(Text == NULL){ + ::error("TWriteScriptFile::writeText: Text ist NULL.\n"); + throw "Cannot write text"; + } + + for(int i = 0; Text[i] != 0; i += 1){ + putc(Text[i], this->File); + } +} + +void TWriteScriptFile::writeNumber(int Number){ + if(this->File == NULL){ + ::error("TWriteScriptFile::writeNumber: Kein Skript zum Schreiben geöffnet.\n"); + throw "Cannot write number"; + } + + char s[32]; + snprintf(s, sizeof(s), "%d", Number); + this->writeText(s); +} + +void TWriteScriptFile::writeString(char *Text){ + if(this->File == NULL){ + ::error(); + throw "Cannot write string"; + } + + if(Text == NULL){ + ::error("TWriteScriptFile::writeString: Text ist NULL.\n"); + throw "Cannot write string"; + } + + putc('"', this->File); + for(int i = 0; Text[i] != 0; i += 1){ + if(Text[i] == '\"' || Text[i] == '\\'){ + putc('\\', this->File); + putc(Text[i], this->File); + }else if(Text[i] == '\n'){ + putc('\\', this->File); + putc('n', this->File); + }else{ + putc(Text[i], this->File); + } + } + putc('"', this->File); +} + +void TWriteScriptFile::writeCoordinate(int x ,int y ,int z){ + if(this->File == NULL){ + ::error("TWriteScriptFile::writeCoordinate: Kein Skript zum Schreiben geöffnet.\n"); + throw "Cannot write coordinate"; + } + + // TODO(fusion): This is weird because we support loading negative coordinates values. + if(x < 0 || y < 0 || z < 0){ + ::error("TWriteScriptFile::writeCoordinate: Ungültige Koordinaten [%d,%d,%d].\n", x, y, z); + throw "Invalid coordinates"; + } + + char s[64]; + snprintf(s, sizeof(s), "[%u,%u,%u]", x, y, z); + this->writeText(s); +} + +void TWriteScriptFile::writeBytesequence(uint8 *Sequence, int Length){ + if(this->File == NULL){ + ::error("TWriteScriptFile::writeBytesequence: Kein Skript zum Schreiben geöffnet.\n"); + throw "Cannot write bytesequence"; + } + + if(Sequence == NULL){ + ::error("TWriteScriptFile::writeBytesequence: Sequence ist NULL.\n"); + throw "Cannot write bytesequence"; + } + + if(Length <= 0){ + ::error("TWriteScriptFile::writeBytesequence: Ungültige Sequenzlänge.\n"); + throw "Cannot write bytesequence"; + } + + for(int i = 0; i < Length; i += 1){ + if(i > 0){ + putc('-', this->File); + } + + snprintf(s, sizeof(s), "%u", Sequence[i]); + this->writeText(s); + } +} diff --git a/src/script.hh b/src/script.hh index 2825d6d..5b63f56 100644 --- a/src/script.hh +++ b/src/script.hh @@ -82,7 +82,17 @@ struct TReadScriptFile { struct TWriteScriptFile { // REGULAR FUNCTIONS // ========================================================================= - //TWriteScriptFile(void); + TWriteScriptFile(void); + ~TWriteScriptFile(void); + void open(char *FileName); + void close(void); + void error(char *Text); + void writeLn(void); + void writeText(char *Text); + void writeNumber(int Number); + void writeString(char *Text); + void writeCoordinate(int x ,int y ,int z); + void writeBytesequence(uint8 *Sequence, int Length); // DATA // ========================================================================= |
