From 02d243c531a5c7886c89024e592a2ccdeab3d3b3 Mon Sep 17 00:00:00 2001 From: fusion32 Date: Wed, 28 May 2025 02:56:09 -0300 Subject: impl all remaining containers --- Makefile | 8 +- reference/game.c | 500 ----------------------------------------------------- reference/types.hh | 173 ------------------ src/common.hh | 5 + src/containers.hh | 207 +++++++++++++++++++++- src/main.cc | 4 +- src/strings.cc | 9 + 7 files changed, 225 insertions(+), 681 deletions(-) create mode 100644 src/strings.cc diff --git a/Makefile b/Makefile index f5bc488..5f40e67 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ BUILDDIR = build OUTPUTEXE = game CC = g++ -CFLAGS = -m64 -fno-strict-aliasing -pedantic -Wall -Wextra -Wno-unused-parameter -Wno-format-truncation -std=c++11 -DOS_LINUX=1 -DARCH_X64=1 -D_CRT_SECURE_NO_WARNINGS=1 +CFLAGS = -m64 -fno-strict-aliasing -pedantic -Wall -Wextra -Wno-unused-parameter -Wno-format-truncation -std=c++11 -DOS_LINUX=1 -DARCH_X64=1 LFLAGS = -Wl,-t DEBUG ?= 0 @@ -15,7 +15,7 @@ endif HEADERS = $(SRCDIR)/common.hh $(SRCDIR)/config.hh $(SRCDIR)/connection.hh $(SRCDIR)/containers.hh $(SRCDIR)/creature.hh $(SRCDIR)/enums.hh $(SRCDIR)/map.hh $(SRCDIR)/monster.hh $(SRCDIR)/objects.hh $(SRCDIR)/player.hh $(SRCDIR)/script.hh $(SRCDIR)/skill.hh $(SRCDIR)/thread.hh -$(BUILDDIR)/$(OUTPUTEXE): $(BUILDDIR)/config.obj $(BUILDDIR)/crcombat.obj $(BUILDDIR)/creature.obj $(BUILDDIR)/main.obj $(BUILDDIR)/map.obj $(BUILDDIR)/objects.obj $(BUILDDIR)/player.obj $(BUILDDIR)/script.obj $(BUILDDIR)/shm.obj $(BUILDDIR)/skill.obj $(BUILDDIR)/thread.obj $(BUILDDIR)/time.obj $(BUILDDIR)/util.obj +$(BUILDDIR)/$(OUTPUTEXE): $(BUILDDIR)/config.obj $(BUILDDIR)/crcombat.obj $(BUILDDIR)/creature.obj $(BUILDDIR)/main.obj $(BUILDDIR)/map.obj $(BUILDDIR)/objects.obj $(BUILDDIR)/player.obj $(BUILDDIR)/script.obj $(BUILDDIR)/shm.obj $(BUILDDIR)/skill.obj $(BUILDDIR)/strings.obj $(BUILDDIR)/thread.obj $(BUILDDIR)/time.obj $(BUILDDIR)/util.obj $(CC) $(CFLAGS) $(LFLAGS) -o $@ $^ $(BUILDDIR)/config.obj: $(SRCDIR)/config.cc $(HEADERS) @@ -58,6 +58,10 @@ $(BUILDDIR)/skill.obj: $(SRCDIR)/skill.cc $(HEADERS) @mkdir -p $(@D) $(CC) -c $(CFLAGS) -o $@ $< +$(BUILDDIR)/strings.obj: $(SRCDIR)/strings.cc $(HEADERS) + @mkdir -p $(@D) + $(CC) -c $(CFLAGS) -o $@ $< + $(BUILDDIR)/thread.obj: $(SRCDIR)/thread.cc $(HEADERS) @mkdir -p $(@D) $(CC) -c $(CFLAGS) -o $@ $< diff --git a/reference/game.c b/reference/game.c index 722a5aa..dff762d 100644 --- a/reference/game.c +++ b/reference/game.c @@ -3914,80 +3914,6 @@ void _GLOBAL__I_StaticStringTable(void) return; } - - -// DWARF original prototype: listnode * -// append(list * this) - -listnode<> * __thiscall list<>::append(list<> *this) - -{ - listnode<> *plVar1; - uint uVar2; - listnode<> *plVar3; - - plVar1 = (listnode<> *)operator_new(0x1000c); - uVar2 = 0x1000c; - plVar3 = plVar1; - if (((uint)plVar1 & 4) != 0) { - plVar1->next = (listnode<> *)0x0; - plVar3 = (listnode<> *)&plVar1->prev; - uVar2 = 0x10008; - } - for (uVar2 = uVar2 >> 2; uVar2 != 0; uVar2 = uVar2 - 1) { - plVar3->next = (listnode<> *)0x0; - plVar3 = (listnode<> *)&plVar3->prev; - } - plVar1->prev = (listnode<> *)0x0; - plVar1->next = (listnode<> *)0x0; - if (this->firstNode == (listnode<> *)0x0) { - this->firstNode = plVar1; - } - else { - this->lastNode->next = plVar1; - plVar1->prev = this->lastNode; - } - this->lastNode = plVar1; - return this->lastNode; -} - - - -// DWARF original prototype: listnode * -// append(list * this) - -listnode<> * __thiscall list<>::append(list<> *this) - -{ - listnode<> *plVar1; - uint uVar2; - listnode<> *plVar3; - - plVar1 = (listnode<> *)operator_new(0x8314); - uVar2 = 0x8314; - plVar3 = plVar1; - if (((uint)plVar1 & 4) != 0) { - plVar1->next = (listnode<> *)0x0; - plVar3 = (listnode<> *)&plVar1->prev; - uVar2 = 0x8310; - } - for (uVar2 = uVar2 >> 2; uVar2 != 0; uVar2 = uVar2 - 1) { - plVar3->next = (listnode<> *)0x0; - plVar3 = (listnode<> *)&plVar3->prev; - } - plVar1->prev = (listnode<> *)0x0; - plVar1->next = (listnode<> *)0x0; - if (this->firstNode == (listnode<> *)0x0) { - this->firstNode = plVar1; - } - else { - this->lastNode->next = plVar1; - plVar1->prev = this->lastNode; - } - this->lastNode = plVar1; - return this->lastNode; -} - void __static_initialization_and_destruction_0(int __initialize_p,int __priority) { @@ -50016,205 +49942,6 @@ void _GLOBAL__I_PlayerList(void) return; } -// WARNING: Variable defined which should be unmapped: i -// DWARF original prototype: TPlayerIndexLeafNode * getFreeItem(store * -// this) - -TPlayerIndexLeafNode * __thiscall store<>::getFreeItem(store<> *this) - -{ - int iVar1; - listnode<> *plVar2; - storeitem<> *psVar3; - storeunit<> *psVar4; - int iVar5; - int local_1c; - storeunit<> *local_18; - int local_14; - int i; - - psVar3 = this->firstFreeItem; - if (psVar3 == (storeitem<> *)0x0) { - plVar2 = list<>::append(this->Units); - local_14 = 0; - local_1c = 0; - iVar5 = 0; - do { - if (plVar2 == (listnode<> *)0x0) { - error("listIterator::operator*: Iterator ist NULL.\n"); - local_18 = (storeunit<> *)0x0; - error("listIterator::operator*: Iterator ist NULL.\n"); - psVar4 = (storeunit<> *)0x0; - } - else { - local_18 = &plVar2->data; - psVar4 = &plVar2->data; - } - iVar1 = local_1c + 0x170; - local_1c = local_1c + 0x170; - *(int *)((int)local_18->item + iVar5) = (int)psVar4->item + iVar1; - local_14 = local_14 + 1; - iVar5 = iVar5 + 0x170; - } while (local_14 < 99); - if (plVar2 == (listnode<> *)0x0) { - error("listIterator::operator*: Iterator ist NULL.\n"); - psVar4 = (storeunit<> *)0x0; - } - else { - psVar4 = &plVar2->data; - } - psVar4->item[99].next = (storeitem<> *)0x0; - if (plVar2 == (listnode<> *)0x0) { - error("listIterator::operator*: Iterator ist NULL.\n"); - psVar3 = (storeitem<> *)0x0; - } - else { - psVar3 = (plVar2->data).item; - } - this->firstFreeItem = psVar3; - } - this->firstFreeItem = psVar3->next; - return (TPlayerIndexLeafNode *)psVar3; -} - - - -// DWARF original prototype: TPlayerIndexInternalNode * -// getFreeItem(store * this) - -TPlayerIndexInternalNode * __thiscall store<>::getFreeItem(store<> *this) - -{ - int iVar1; - listnode<> *plVar2; - storeitem<> *psVar3; - storeunit<> *psVar4; - int i; - int iVar5; - int local_1c; - int local_18; - storeunit<> *local_14; - - psVar3 = this->firstFreeItem; - if (psVar3 == (storeitem<> *)0x0) { - plVar2 = list<>::append(this->Units); - local_18 = 0; - local_1c = 0; - iVar5 = 0x62; - do { - if (plVar2 == (listnode<> *)0x0) { - error("listIterator::operator*: Iterator ist NULL.\n"); - local_14 = (storeunit<> *)0x0; - error("listIterator::operator*: Iterator ist NULL.\n"); - psVar4 = (storeunit<> *)0x0; - } - else { - local_14 = &plVar2->data; - psVar4 = &plVar2->data; - } - iVar1 = local_18 + 0x70; - local_18 = local_18 + 0x70; - *(int *)((int)local_14->item + local_1c) = (int)psVar4->item + iVar1; - local_1c = local_1c + 0x70; - iVar5 = iVar5 + -1; - } while (-1 < iVar5); - if (plVar2 == (listnode<> *)0x0) { - error("listIterator::operator*: Iterator ist NULL.\n"); - psVar4 = (storeunit<> *)0x0; - } - else { - psVar4 = &plVar2->data; - } - psVar4->item[99].next = (storeitem<> *)0x0; - if (plVar2 == (listnode<> *)0x0) { - error("listIterator::operator*: Iterator ist NULL.\n"); - psVar3 = (storeitem<> *)0x0; - } - else { - psVar3 = (plVar2->data).item; - } - this->firstFreeItem = psVar3; - } - this->firstFreeItem = psVar3->next; - return (TPlayerIndexInternalNode *)psVar3; -} - - - -// DWARF original prototype: listnode_> * -// append(list_> * this) - -listnode<> * __thiscall list<>::append(list<> *this) - -{ - listnode<> *plVar1; - uint uVar2; - listnode<> *plVar3; - - plVar1 = (listnode<> *)operator_new(0x8fc8); - uVar2 = 0x8fc8; - plVar3 = plVar1; - if (((uint)plVar1 & 4) != 0) { - plVar1->next = (listnode<> *)0x0; - plVar3 = (listnode<> *)&plVar1->prev; - uVar2 = 0x8fc4; - } - for (uVar2 = uVar2 >> 2; uVar2 != 0; uVar2 = uVar2 - 1) { - plVar3->next = (listnode<> *)0x0; - plVar3 = (listnode<> *)&plVar3->prev; - } - plVar1->prev = (listnode<> *)0x0; - plVar1->next = (listnode<> *)0x0; - if (this->firstNode == (listnode<> *)0x0) { - this->firstNode = plVar1; - } - else { - this->lastNode->next = plVar1; - plVar1->prev = this->lastNode; - } - this->lastNode = plVar1; - return this->lastNode; -} - - - -// DWARF original prototype: listnode_> * -// append(list_> * this) - -listnode<> * __thiscall list<>::append(list<> *this) - -{ - listnode<> *plVar1; - uint uVar2; - listnode<> *plVar3; - - plVar1 = (listnode<> *)operator_new(0x2bc8); - uVar2 = 0x2bc8; - plVar3 = plVar1; - if (((uint)plVar1 & 4) != 0) { - plVar1->next = (listnode<> *)0x0; - plVar3 = (listnode<> *)&plVar1->prev; - uVar2 = 0x2bc4; - } - for (uVar2 = uVar2 >> 2; uVar2 != 0; uVar2 = uVar2 - 1) { - plVar3->next = (listnode<> *)0x0; - plVar3 = (listnode<> *)&plVar3->prev; - } - plVar1->prev = (listnode<> *)0x0; - plVar1->next = (listnode<> *)0x0; - if (this->firstNode == (listnode<> *)0x0) { - this->firstNode = plVar1; - } - else { - this->lastNode->next = plVar1; - plVar1->prev = this->lastNode; - } - this->lastNode = plVar1; - return this->lastNode; -} - - - void __static_initialization_and_destruction_0(int __initialize_p,int __priority) { @@ -58292,133 +58019,6 @@ ulong __thiscall TMonster::GetMaster(TMonster *this) return this->Master; } - - -// DWARF original prototype: TNode * getFreeItem(store * this) - -TNode * __thiscall store::getFreeItem(store *this) - -{ - listnode<> *plVar1; - storeitem *psVar2; - storeunit *psVar3; - int i; - int iVar4; - int iVar5; - storeunit *local_14; - - psVar2 = this->firstFreeItem; - if (psVar2 == (storeitem *)0x0) { - plVar1 = list<>::append(this->Units); - iVar4 = 0; - do { - if (plVar1 == (listnode<> *)0x0) { - error("listIterator::operator*: Iterator ist NULL.\n"); - local_14 = (storeunit *)0x0; - error("listIterator::operator*: Iterator ist NULL.\n"); - psVar3 = (storeunit *)0x0; - } - else { - local_14 = &plVar1->data; - psVar3 = &plVar1->data; - } - iVar5 = iVar4 + 1; - local_14->item[iVar4].next = psVar3->item + iVar4 + 1; - iVar4 = iVar5; - } while (iVar5 < 0xff); - if (plVar1 == (listnode<> *)0x0) { - error("listIterator::operator*: Iterator ist NULL.\n"); - psVar3 = (storeunit *)0x0; - } - else { - psVar3 = &plVar1->data; - } - psVar3->item[0xff].next = (storeitem *)0x0; - if (plVar1 == (listnode<> *)0x0) { - error("listIterator::operator*: Iterator ist NULL.\n"); - psVar2 = (storeitem *)0x0; - } - else { - psVar2 = (plVar1->data).item; - } - this->firstFreeItem = psVar2; - } - this->firstFreeItem = psVar2->next; - return (TNode *)psVar2; -} - -// DWARF original prototype: void remove(list_> * this, -// listnode_> * node) - -int __thiscall list<>::remove(list<> *this,char *__filename) - -{ - int iVar1; - int extraout_EAX; - listnode<> *plVar2; - - if (__filename != (char *)0x0) { - plVar2 = *(listnode<> **)(__filename + 4); - if (plVar2 == (listnode<> *)0x0) { - this->firstNode = *(listnode<> **)__filename; - plVar2 = *(listnode<> **)(__filename + 4); - } - else { - plVar2->next = *(listnode<> **)__filename; - } - iVar1 = *(int *)__filename; - if (iVar1 == 0) { - this->lastNode = plVar2; - } - else { - *(listnode<> **)(iVar1 + 4) = plVar2; - } - operator_delete(__filename); - return iVar1; - } - error("list::remove: node ist NULL.\n"); - return extraout_EAX; -} - - - -// DWARF original prototype: listnode_> * append(list_> -// * this) - -listnode<> * __thiscall list<>::append(list<> *this) - -{ - listnode<> *plVar1; - uint uVar2; - listnode<> *plVar3; - - plVar1 = (listnode<> *)operator_new(0x1008); - uVar2 = 0x1008; - plVar3 = plVar1; - if (((uint)plVar1 & 4) != 0) { - plVar1->next = (listnode<> *)0x0; - plVar3 = (listnode<> *)&plVar1->prev; - uVar2 = 0x1004; - } - for (uVar2 = uVar2 >> 2; uVar2 != 0; uVar2 = uVar2 - 1) { - plVar3->next = (listnode<> *)0x0; - plVar3 = (listnode<> *)&plVar3->prev; - } - plVar1->prev = (listnode<> *)0x0; - plVar1->next = (listnode<> *)0x0; - if (this->firstNode == (listnode<> *)0x0) { - this->firstNode = plVar1; - } - else { - this->lastNode->next = plVar1; - plVar1->prev = this->lastNode; - } - this->lastNode = plVar1; - return this->lastNode; -} - - - void __static_initialization_and_destruction_0(int __initialize_p,int __priority) { @@ -77129,106 +76729,6 @@ void _GLOBAL__I_TCPSocket(void) return; } - - -// DWARF original prototype: TWaitinglistEntry * getFreeItem(store * this) - -TWaitinglistEntry * __thiscall store<>::getFreeItem(store<> *this) - -{ - int iVar1; - listnode<> *plVar2; - storeitem<> *psVar3; - storeunit<> *psVar4; - int i; - int iVar5; - int local_1c; - int local_18; - storeunit<> *local_14; - - psVar3 = this->firstFreeItem; - if (psVar3 == (storeitem<> *)0x0) { - plVar2 = list<>::append(this->Units); - local_18 = 0; - local_1c = 0; - iVar5 = 0x62; - do { - if (plVar2 == (listnode<> *)0x0) { - error("listIterator::operator*: Iterator ist NULL.\n"); - local_14 = (storeunit<> *)0x0; - error("listIterator::operator*: Iterator ist NULL.\n"); - psVar4 = (storeunit<> *)0x0; - } - else { - local_14 = &plVar2->data; - psVar4 = &plVar2->data; - } - iVar1 = local_18 + 0x2c; - local_18 = local_18 + 0x2c; - *(int *)((int)local_14->item + local_1c) = (int)psVar4->item + iVar1; - local_1c = local_1c + 0x2c; - iVar5 = iVar5 + -1; - } while (-1 < iVar5); - if (plVar2 == (listnode<> *)0x0) { - error("listIterator::operator*: Iterator ist NULL.\n"); - psVar4 = (storeunit<> *)0x0; - } - else { - psVar4 = &plVar2->data; - } - psVar4->item[99].next = (storeitem<> *)0x0; - if (plVar2 == (listnode<> *)0x0) { - error("listIterator::operator*: Iterator ist NULL.\n"); - psVar3 = (storeitem<> *)0x0; - } - else { - psVar3 = (plVar2->data).item; - } - this->firstFreeItem = psVar3; - } - this->firstFreeItem = psVar3->next; - return (TWaitinglistEntry *)psVar3; -} - - - -// DWARF original prototype: listnode_> * -// append(list_> * this) - -listnode<> * __thiscall list<>::append(list<> *this) - -{ - listnode<> *plVar1; - uint uVar2; - listnode<> *plVar3; - - plVar1 = (listnode<> *)operator_new(0x1138); - uVar2 = 0x1138; - plVar3 = plVar1; - if (((uint)plVar1 & 4) != 0) { - plVar1->next = (listnode<> *)0x0; - plVar3 = (listnode<> *)&plVar1->prev; - uVar2 = 0x1134; - } - for (uVar2 = uVar2 >> 2; uVar2 != 0; uVar2 = uVar2 - 1) { - plVar3->next = (listnode<> *)0x0; - plVar3 = (listnode<> *)&plVar3->prev; - } - plVar1->prev = (listnode<> *)0x0; - plVar1->next = (listnode<> *)0x0; - if (this->firstNode == (listnode<> *)0x0) { - this->firstNode = plVar1; - } - else { - this->lastNode->next = plVar1; - plVar1->prev = this->lastNode; - } - this->lastNode = plVar1; - return this->lastNode; -} - - - void __static_initialization_and_destruction_0(int __initialize_p,int __priority) { diff --git a/reference/types.hh b/reference/types.hh index b2c0719..2fc67a0 100644 --- a/reference/types.hh +++ b/reference/types.hh @@ -125,21 +125,6 @@ struct TPlayerIndexInternalNode { struct TPlayerIndexNode *Child[27]; }; -union storeitem { - union storeitem *next; - struct TPlayerIndexInternalNode data; -}; - -struct storeunit { - union storeitem item[100]; -}; - -struct listnode_> { // Original name: listnode > - struct listnode_> *next; - struct listnode_> *prev; - struct storeunit data; -}; - struct TPlayerIndexEntry { char Name[30]; ulong CharacterID; @@ -151,15 +136,6 @@ struct TPlayerIndexLeafNode { struct TPlayerIndexEntry Entry[10]; }; -union storeitem { - union storeitem *next; - struct TPlayerIndexLeafNode data; -}; - -struct storeunit { - union storeitem item[100]; -}; - struct TNode { int Type; int Data; @@ -167,21 +143,6 @@ struct TNode { struct TNode *Right; }; -union storeitem { - union storeitem *next; - struct TNode data; -}; - -struct store { - struct list_> *Units; - union storeitem *firstFreeItem; -}; - -struct list_> { // Original name: list > - struct listnode_> *firstNode; - struct listnode_> *lastNode; -}; - struct THouseGuest { char Name[60]; }; @@ -221,21 +182,6 @@ struct TWaitinglistEntry { bool Sleeping; }; -union storeitem { - union storeitem *next; - struct TWaitinglistEntry data; -}; - -struct storeunit { - union storeitem item[100]; -}; - -struct listnode_> { // Original name: listnode > - struct listnode_> *next; - struct listnode_> *prev; - struct storeunit data; -}; - struct TAttackWave { int x; int y; @@ -251,16 +197,6 @@ struct TAttackWave { struct vector ExtraItem; }; -struct store { - struct list_> *Units; - union storeitem *firstFreeItem; -}; - -struct list_> { // Original name: list > - struct listnode_> *firstNode; - struct listnode_> *lastNode; -}; - struct TDynamicStringTableBlock { int FreeEntries; int TotalTextLength; @@ -270,16 +206,6 @@ struct TDynamicStringTableBlock { char Text[32768]; }; -struct listnode { - struct listnode *next; - struct listnode *prev; - struct TDynamicStringTableBlock data; -}; - -struct listIterator { - struct listnode *actNode; -}; - struct TNonplayer { struct TCreature super_TCreature; // INHERITANCE? enum STATE State; @@ -299,13 +225,6 @@ struct TListener { ulong CharacterID; }; -struct fifo { - struct TListener *Entry; - int Size; - int Head; - int Tail; -}; - struct TDelayedMail { ulong CharacterID; int DepotNumber; @@ -313,38 +232,6 @@ struct TDelayedMail { int PacketSize; }; -struct list_> { // Original name: list > - struct listnode_> *firstNode; - struct listnode_> *lastNode; -}; - -struct listnode_> { // Original name: listnode > - struct listnode_> *next; - struct listnode_> *prev; - struct storeunit data; -}; - -struct store { - struct list_> *Units; - union storeitem *firstFreeItem; -}; - -struct listIterator_> { // Original name: listIterator > - struct listnode_> *actNode; -}; - - - -struct storeunit { - union storeitem item[256]; -}; - -struct listnode_> { // Original name: listnode > - struct listnode_> *next; - struct listnode_> *prev; - struct storeunit data; -}; - struct TShortwayPoint { int x; int y; @@ -372,26 +259,6 @@ struct TStaticStringTableBlock { char Text[65536]; }; -struct listnode { - struct listnode *next; - struct listnode *prev; - struct TStaticStringTableBlock data; -}; - -struct list { - struct listnode *firstNode; - struct listnode *lastNode; -}; - -struct listIterator { - struct listnode *actNode; -}; - -struct list_> { // Original name: list > - struct listnode_> *firstNode; - struct listnode_> *lastNode; -}; - struct TCondition { int Type; ulong Text; @@ -415,10 +282,6 @@ struct THelpDepot { int DepotNr; }; -struct listIterator_> { // Original name: listIterator > - struct listnode_> *actNode; -}; - struct TPlayerData { ulong CharacterID; pid_t Locked; @@ -527,25 +390,11 @@ struct TParty { int InvitedPlayers; }; -struct listIterator_> { // Original name: listIterator > - struct listnode_> *actNode; -}; - -struct store { - struct list_> *Units; - union storeitem *firstFreeItem; -}; - struct TMoveUseAction { enum ActionType Action; int Parameters[5]; }; -struct list { - struct listnode *firstNode; - struct listnode *lastNode; -}; - struct TMoveUseRule { int FirstCondition; int LastCondition; @@ -581,23 +430,6 @@ struct THouseArea { int DepotNr; }; -struct listIterator_> { // Original name: listIterator > - struct listnode_> *actNode; -}; - - -struct fifoIterator { - struct fifo *Fifo; - int Position; -}; - -struct fifo { - struct TStatement *Entry; - int Size; - int Head; - int Tail; -}; - struct TStatement { ulong StatementID; ulong TimeStamp; @@ -608,11 +440,6 @@ struct TStatement { bool Reported; }; -struct fifoIterator { - struct fifo *Fifo; - int Position; -}; - struct TDirectReplyData { ulong CharacterID; char Message[100]; diff --git a/src/common.hh b/src/common.hh index bd3ccd7..b981b2b 100644 --- a/src/common.hh +++ b/src/common.hh @@ -115,6 +115,11 @@ void ExitSHM(void); void InitSHMExtern(bool Verbose); void ExitSHMExtern(void); +// strings.cc +// ============================================================================= +void InitStrings(void); +void ExitStrings(void); + // time.cc // ============================================================================= extern uint32 RoundNr; diff --git a/src/containers.hh b/src/containers.hh index d79946c..9cab94e 100644 --- a/src/containers.hh +++ b/src/containers.hh @@ -39,7 +39,9 @@ struct vector{ } } - // TODO(fusion): Probably missing some inlined destructor? + ~vector(void){ + delete[] this->entry; + } T *at(int index){ // TODO(fusion): This is probably not the best way to achieve this. @@ -135,7 +137,9 @@ struct priority_queue{ Entries = 0; } - // TODO(fusion): Probably missing some inlined destructor? + ~priority_queue(void){ + delete Entry; + } void insert(K Key, T *Data){ this->Entries += 1; @@ -241,7 +245,9 @@ struct matrix{ } } - // TODO(fusion): Probably missing some inlined destructor? + ~matrix(void){ + delete[] this->entry; + } T *at(int x, int y){ int xoffset = x - this->xmin; @@ -305,7 +311,9 @@ struct matrix3d{ } } - // TODO(fusion): Probably missing some inlined destructor? + ~matrix3d(void){ + delete[] this->entry; + } T *at(int x, int y, int z){ int xoffset = x - this->xmin; @@ -335,4 +343,195 @@ struct matrix3d{ T *entry; }; +template +struct listnode{ + listnode *next; + listnode *prev; + T data; +}; + +template +struct list{ + // REGULAR FUNCTIONS + // ========================================================================= + list(void){ + firstNode = NULL; + lastNode = NULL; + } + + ~list(void){ + while(this->firstNode != NULL){ + this->remove(this->firstNode); + } + } + + listnode *append(void){ + listnode *node = new listnode; + node->next = NULL; + node->prev = NULL; + if(this->firstNode == NULL){ + ASSERT(this->lastNode == NULL); + this->firstNode = node; + }else{ + ASSERT(this->lastNode != NULL); + this->lastNode->next = node; + node->prev = this->lastNode; + } + this->lastNode = node; + return node; + } + + void remove(listnode *node){ + if(node == NULL){ + error("list::remove: node ist NULL.\n"); + return; + } + + if(node->prev == NULL){ + ASSERT(this->firstNode == node); + this->firstNode = node->next; + }else{ + node->prev->next = node->next; + } + + if(node->next == NULL){ + ASSERT(this->lastNode == node); + this->lastNode = node->prev; + }else{ + node->next->prev = node->prev; + } + + delete node; + } + + // DATA + // ========================================================================= + listnode *firstNode; + listnode *lastNode; +}; + +template +struct fifo{ + // REGULAR FUNCTIONS + // ========================================================================= + fifo(int InitialSize){ + ASSERT(InitialSize > 0); + this->Entry = new T[InitialSize]; + this->Size = InitialSize; + this->Head = -1; + this->Tail = 0; + } + + ~fifo(void){ + delete[] this->Entry; + } + + T *next(void){ + T *Next = NULL; + if(this->Tail <= this->Head){ + Next = &this->Entry[this->Tail % this->Size]; + } + return Next; + } + + T *append(void){ + if((this->Head - this->Tail + 1) == this->Size){ + int NewSize = this->Size * 2; + T *NewEntry = new T[NewSize]; + // TODO(fusion): Is it even possible to have `this->Entry == NULL`? + if(this->Entry != NULL){ + for(int Index = this->Tail; Index <= this->Head; Index += 1){ + NewEntry[Index % NewSize] = this->Entry[Index % this->Size]; + } + delete[] this->Entry; + } + this->Entry = NewEntry; + this->Size = NewSize; + } + + // TODO(fusion): We don't consider integer overflow at all. + this->Head += 1; + return this->Entry[this->Head % this->Size]; + } + + void remove(void){ + if(this->Tail > this->Head){ + error("fifo::remove: Fifo ist leer.\n"); + return; + } + + this->Tail += 1; + } + + // TODO(fusion): There is also a `fifoIterator` used a few times and it is + // essentially iterating from `this->Head` towards `this->Tail`. All its + // functions were inlined so I'm not sure it is needed. + + // DATA + // ========================================================================= + T *Entry; + int Size; + int Head; + int Tail; +}; + +template +union storeitem{ + // IMPORTANT(fusion): This will only work properly with POD structures. We + // could also manually handle `data` construction and destruction but I don't + // think we need it. + STATIC_ASSERT(std::is_pod::value); + storeitem *next; + T data; +}; + +template +struct storeunit{ + STATIC_ASSERT(N > 0); + storeitem item[N]; +}; + +// NOTE(fusion): The `store` container is an allocator that manages a single type. +// It is also known as a slab allocator. +template +struct store{ + // REGULAR FUNCTIONS + // ========================================================================= + store(void){ + this->Units = new list>; + this->firstFreeItem = NULL; + } + + ~store(void){ + delete this->Units; + } + + T *getFreeItem(void){ + if(this->firstFreeItem == NULL){ + storeunit *Unit = &this->Units.append()->data; + for(usize i = 0; i < (N - 1); i += 1){ + Unit->item[i].next = &Unit->item[i + 1]; + } + Unit->item[N - 1].next = NULL; + this->firstFreeItem = &Unit->item[0]; + } + + storeitem *Item = this->firstFreeItem; + this->firstFreeItem = Item->next; + return &Item->data; + } + + void putFreeItem(T *Item){ + // TODO(fusion): Not the safest thing to do. + ASSERT(Item != NULL); + ((storeitem*)Item)->next = this->firstFreeItem; + this->firstfreeItem = (storeitem*)Item; + } + + // DATA + // ========================================================================= + list> *Units; + storeitem *firstFreeItem; +}; + #endif //TIBIA_CONTAINERS_HH_ \ No newline at end of file diff --git a/src/main.cc b/src/main.cc index ecdb333..d3a0cbd 100644 --- a/src/main.cc +++ b/src/main.cc @@ -225,7 +225,7 @@ static void InitAll(void){ InitSignalHandler(); //InitConnections(); //InitCommunication(); - //InitStrings(); + InitStrings(); //InitWriter(); //InitReader(); InitObjects(); @@ -257,7 +257,7 @@ static void ExitAll(void){ ExitObjects(); //ExitReader(); //ExitWriter(); - //ExitStrings(); + ExitStrings(); //ExitCommunication(); //ExitConnections(); ExitSignalHandler(); diff --git a/src/strings.cc b/src/strings.cc new file mode 100644 index 0000000..478ad69 --- /dev/null +++ b/src/strings.cc @@ -0,0 +1,9 @@ +#include "common.hh" + +void InitStrings(void){ + // no-op +} + +void ExitStrings(void){ + // no-op +} -- cgit v1.2.3