aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfusion32 <marcopuzziello@gmail.com>2025-05-22 11:40:04 -0300
committerfusion32 <marcopuzziello@gmail.com>2025-05-22 11:40:04 -0300
commit297e8450d80411d81f0aaeee642053354125bd6d (patch)
treecba665717e133b288b51a960e0401652ab73019a
parentde848a4131beb288335b6aaa29c2a6a439c50e0e (diff)
downloadgame-297e8450d80411d81f0aaeee642053354125bd6d.tar.gz
game-297e8450d80411d81f0aaeee642053354125bd6d.zip
implement TWriteScriptFile
-rw-r--r--TODO.md4
-rw-r--r--reference/game.c385
-rw-r--r--src/script.cc185
-rw-r--r--src/script.hh12
4 files changed, 193 insertions, 393 deletions
diff --git a/TODO.md b/TODO.md
index 8551046..f9d6da5 100644
--- a/TODO.md
+++ b/TODO.md
@@ -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
// =========================================================================