impl strings.cc
This commit is contained in:
parent
565d28e480
commit
e5b60ae075
355
reference/game.c
355
reference/game.c
@ -2667,339 +2667,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// WARNING: Variable defined which should be unmapped: p
|
|
||||||
|
|
||||||
char * AddStaticString(char *String)
|
|
||||||
|
|
||||||
{
|
|
||||||
size_t sVar1;
|
|
||||||
char *__dest;
|
|
||||||
listnode<> *plVar2;
|
|
||||||
TStaticStringTableBlock *pTVar3;
|
|
||||||
listIterator<> iter;
|
|
||||||
TStaticStringTableBlock *local_18;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
sVar1 = strlen(String);
|
|
||||||
if ((int)sVar1 < 0x10000) {
|
|
||||||
__dest = "";
|
|
||||||
if (sVar1 != 0) {
|
|
||||||
for (plVar2 = StaticStringTable.firstNode; plVar2 != (listnode<> *)0x0;
|
|
||||||
plVar2 = plVar2->next) {
|
|
||||||
if ((int)(sVar1 + 1) < 0x10000 - (plVar2->data).TotalTextLength) {
|
|
||||||
if (plVar2 != (listnode<> *)0x0) goto LAB_0805197a;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
plVar2 = list<>::append(&StaticStringTable);
|
|
||||||
if (plVar2 == (listnode<> *)0x0) {
|
|
||||||
error("listIterator::operator*: Iterator ist NULL.\n");
|
|
||||||
pTVar3 = (TStaticStringTableBlock *)0x0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pTVar3 = &plVar2->data;
|
|
||||||
}
|
|
||||||
pTVar3->TotalTextLength = 0;
|
|
||||||
if (plVar2 == (listnode<> *)0x0) {
|
|
||||||
error("listIterator::operator*: Iterator ist NULL.\n");
|
|
||||||
local_18 = (TStaticStringTableBlock *)0x0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LAB_0805197a:
|
|
||||||
local_18 = &plVar2->data;
|
|
||||||
}
|
|
||||||
if (plVar2 == (listnode<> *)0x0) {
|
|
||||||
error("listIterator::operator*: Iterator ist NULL.\n");
|
|
||||||
pTVar3 = (TStaticStringTableBlock *)0x0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pTVar3 = &plVar2->data;
|
|
||||||
}
|
|
||||||
__dest = local_18->Text + pTVar3->TotalTextLength;
|
|
||||||
memcpy(__dest,String,sVar1 + 1);
|
|
||||||
if (plVar2 == (listnode<> *)0x0) {
|
|
||||||
error("listIterator::operator*: Iterator ist NULL.\n");
|
|
||||||
pTVar3 = (TStaticStringTableBlock *)0x0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pTVar3 = &plVar2->data;
|
|
||||||
}
|
|
||||||
pTVar3->TotalTextLength = sVar1 + pTVar3->TotalTextLength + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error("AddStaticString: String zu lang (%d).\n",sVar1);
|
|
||||||
__dest = (char *)0x0;
|
|
||||||
}
|
|
||||||
return __dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// WARNING: Variable defined which should be unmapped: iter
|
|
||||||
|
|
||||||
ulong AddDynamicString(char *String)
|
|
||||||
|
|
||||||
{
|
|
||||||
int iVar1;
|
|
||||||
int i_1;
|
|
||||||
size_t sVar2;
|
|
||||||
int i;
|
|
||||||
int iVar3;
|
|
||||||
TDynamicStringTableBlock *pTVar4;
|
|
||||||
int pos;
|
|
||||||
int iVar5;
|
|
||||||
int local_18;
|
|
||||||
int count;
|
|
||||||
listIterator<> iter;
|
|
||||||
|
|
||||||
sVar2 = strlen(String);
|
|
||||||
if ((int)sVar2 < 0x8000) {
|
|
||||||
if (sVar2 == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
local_18 = 0;
|
|
||||||
count = (int)DynamicStringTable.firstNode;
|
|
||||||
while ((listnode<> *)count != (listnode<> *)0x0) {
|
|
||||||
if (0 < (((listnode<> *)count)->data).FreeEntries) {
|
|
||||||
if ((listnode<> *)count == (listnode<> *)0x0) {
|
|
||||||
error("listIterator::operator*: Iterator ist NULL.\n");
|
|
||||||
pTVar4 = (TDynamicStringTableBlock *)0x0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pTVar4 = &((listnode<> *)count)->data;
|
|
||||||
}
|
|
||||||
if ((int)(sVar2 + 1) < 0x8000 - pTVar4->TotalTextLength) {
|
|
||||||
if ((listnode<> *)count != (listnode<> *)0x0) goto LAB_08051ae9;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((listnode<> *)count == (listnode<> *)0x0) {
|
|
||||||
error("listIterator::operator++: Iterator ist NULL.\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
count = (int)((listnode<> *)count)->next;
|
|
||||||
}
|
|
||||||
local_18 = local_18 + 1;
|
|
||||||
}
|
|
||||||
count = (int)list<>::append(&DynamicStringTable);
|
|
||||||
if ((listnode<> *)count == (listnode<> *)0x0) {
|
|
||||||
error("listIterator::operator*: Iterator ist NULL.\n");
|
|
||||||
pTVar4 = (TDynamicStringTableBlock *)0x0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pTVar4 = &((listnode<> *)count)->data;
|
|
||||||
}
|
|
||||||
pTVar4->FreeEntries = 0x100;
|
|
||||||
iVar3 = 0;
|
|
||||||
pTVar4->TotalTextLength = 0;
|
|
||||||
pTVar4->Dirty = false;
|
|
||||||
do {
|
|
||||||
pTVar4->EntryType[iVar3] = '\0';
|
|
||||||
iVar3 = iVar3 + 1;
|
|
||||||
} while (iVar3 < 0x100);
|
|
||||||
if ((listnode<> *)count == (listnode<> *)0x0) {
|
|
||||||
pTVar4 = (TDynamicStringTableBlock *)0x0;
|
|
||||||
error("listIterator::operator*: Iterator ist NULL.\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LAB_08051ae9:
|
|
||||||
pTVar4 = &((listnode<> *)count)->data;
|
|
||||||
}
|
|
||||||
iVar3 = 0;
|
|
||||||
do {
|
|
||||||
iVar5 = iVar3;
|
|
||||||
if (pTVar4->EntryType[iVar3] == '\0') break;
|
|
||||||
iVar3 = iVar3 + 1;
|
|
||||||
iVar5 = -1;
|
|
||||||
} while (iVar3 < 0x100);
|
|
||||||
if (iVar5 != -1) {
|
|
||||||
iVar1 = pTVar4->TotalTextLength;
|
|
||||||
pTVar4->EntryType[iVar5] = '\x01';
|
|
||||||
iVar3 = pTVar4->TotalTextLength;
|
|
||||||
pTVar4->FreeEntries = pTVar4->FreeEntries + -1;
|
|
||||||
pTVar4->StringOffset[iVar5] = (ushort)iVar1;
|
|
||||||
memcpy(pTVar4->Text + iVar3,String,sVar2 + 1);
|
|
||||||
pTVar4->TotalTextLength = sVar2 + pTVar4->TotalTextLength + 1;
|
|
||||||
return iVar5 + 1 + local_18 * 0x100;
|
|
||||||
}
|
|
||||||
error("AddDynamicString: Keinen freien Platz gefunden.\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error("AddDynamicString: String zu lang (%d)\n",sVar2);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// WARNING: Variable defined which should be unmapped: iter
|
|
||||||
|
|
||||||
char * GetDynamicString(ulong Number)
|
|
||||||
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
int iVar1;
|
|
||||||
int Block;
|
|
||||||
uint uVar2;
|
|
||||||
uint uVar3;
|
|
||||||
char *Text;
|
|
||||||
listnode<> *local_10;
|
|
||||||
listIterator<> iter;
|
|
||||||
|
|
||||||
if (Number == 0) {
|
|
||||||
return (char *)0x0;
|
|
||||||
}
|
|
||||||
uVar2 = Number - 1 >> 8;
|
|
||||||
iVar1 = 0;
|
|
||||||
uVar3 = Number - 1 & 0xff;
|
|
||||||
local_10 = DynamicStringTable.firstNode;
|
|
||||||
if (uVar2 == 0) {
|
|
||||||
LAB_08051c50:
|
|
||||||
if (local_10 != (listnode<> *)0x0) {
|
|
||||||
if ((local_10->data).EntryType[uVar3] == '\x01') {
|
|
||||||
return (local_10->data).Text + (local_10->data).StringOffset[uVar3];
|
|
||||||
}
|
|
||||||
Text = &DAT_080f0540;
|
|
||||||
goto LAB_08051c3a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (DynamicStringTable.firstNode != (listnode<> *)0x0) {
|
|
||||||
do {
|
|
||||||
local_10 = local_10->next;
|
|
||||||
iVar1 = iVar1 + 1;
|
|
||||||
if ((int)uVar2 <= iVar1) goto LAB_08051c50;
|
|
||||||
} while (local_10 != (listnode<> *)0x0);
|
|
||||||
}
|
|
||||||
Text = &DAT_080f0500;
|
|
||||||
LAB_08051c3a:
|
|
||||||
error(Text,Number);
|
|
||||||
return (char *)0x0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// WARNING: Variable defined which should be unmapped: iter
|
|
||||||
|
|
||||||
void DeleteDynamicString(ulong Number)
|
|
||||||
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
int iVar1;
|
|
||||||
int Block;
|
|
||||||
uint uVar2;
|
|
||||||
uint uVar3;
|
|
||||||
char *Text;
|
|
||||||
listnode<> *local_10;
|
|
||||||
listIterator<> iter;
|
|
||||||
|
|
||||||
if (Number == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uVar2 = Number - 1 >> 8;
|
|
||||||
iVar1 = 0;
|
|
||||||
uVar3 = Number - 1 & 0xff;
|
|
||||||
local_10 = DynamicStringTable.firstNode;
|
|
||||||
if (uVar2 == 0) {
|
|
||||||
LAB_08051ce0:
|
|
||||||
if (local_10 != (listnode<> *)0x0) {
|
|
||||||
if ((local_10->data).EntryType[uVar3] == '\x01') {
|
|
||||||
(local_10->data).EntryType[uVar3] = '\x02';
|
|
||||||
(local_10->data).Dirty = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Text = &DAT_080f05c0;
|
|
||||||
goto LAB_08051cca;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (DynamicStringTable.firstNode != (listnode<> *)0x0) {
|
|
||||||
do {
|
|
||||||
local_10 = local_10->next;
|
|
||||||
iVar1 = iVar1 + 1;
|
|
||||||
if ((int)uVar2 <= iVar1) goto LAB_08051ce0;
|
|
||||||
} while (local_10 != (listnode<> *)0x0);
|
|
||||||
}
|
|
||||||
Text = &DAT_080f0580;
|
|
||||||
LAB_08051cca:
|
|
||||||
error(Text,Number);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// WARNING: Variable defined which should be unmapped: iter
|
|
||||||
// WARNING: Unknown calling convention -- yet parameter storage is locked
|
|
||||||
|
|
||||||
void CleanupDynamicStrings(void)
|
|
||||||
|
|
||||||
{
|
|
||||||
int *piVar1;
|
|
||||||
int iVar2;
|
|
||||||
char *__s;
|
|
||||||
ushort uVar3;
|
|
||||||
int Help;
|
|
||||||
size_t sVar4;
|
|
||||||
int j;
|
|
||||||
int iVar5;
|
|
||||||
int Offset;
|
|
||||||
uint uVar6;
|
|
||||||
int Length;
|
|
||||||
int local_18;
|
|
||||||
int i;
|
|
||||||
listIterator<> iter;
|
|
||||||
|
|
||||||
i = (int)DynamicStringTable.firstNode;
|
|
||||||
if (DynamicStringTable.firstNode != (listnode<> *)0x0) {
|
|
||||||
do {
|
|
||||||
piVar1 = (int *)(i + 8);
|
|
||||||
if (*(char *)(i + 0x10) != '\0') {
|
|
||||||
local_18 = 0;
|
|
||||||
do {
|
|
||||||
if (*(char *)(local_18 + 9 + (int)piVar1) == '\x02') {
|
|
||||||
uVar6 = (uint)*(ushort *)(i + 0x112 + local_18 * 2);
|
|
||||||
__s = (char *)(uVar6 + 0x30a + (int)piVar1);
|
|
||||||
sVar4 = strlen(__s);
|
|
||||||
iVar2 = sVar4 + 1;
|
|
||||||
*(int *)(i + 0xc) = *(int *)(i + 0xc) - iVar2;
|
|
||||||
*(undefined1 *)(local_18 + 9 + (int)piVar1) = 0;
|
|
||||||
if ((int)(iVar2 + uVar6) < 0x8001) {
|
|
||||||
sVar4 = (-iVar2 - uVar6) + 0x8000;
|
|
||||||
if (0 < (int)sVar4) {
|
|
||||||
memmove(__s,(void *)(iVar2 + uVar6 + 0x30a + (int)piVar1),sVar4);
|
|
||||||
}
|
|
||||||
*piVar1 = *piVar1 + 1;
|
|
||||||
iVar5 = 0;
|
|
||||||
do {
|
|
||||||
if ((*(char *)(iVar5 + 9 + (int)piVar1) != '\0') &&
|
|
||||||
(uVar3 = *(ushort *)(i + 0x112 + iVar5 * 2), uVar6 < uVar3)) {
|
|
||||||
*(ushort *)(i + 0x112 + iVar5 * 2) = uVar3 - (short)iVar2;
|
|
||||||
}
|
|
||||||
iVar5 = iVar5 + 1;
|
|
||||||
} while (iVar5 < 0x100);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error("CleanupDynamicStrings: Stringende fehlt\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
local_18 = local_18 + 1;
|
|
||||||
} while (local_18 < 0x100);
|
|
||||||
*(undefined1 *)(i + 0x10) = 0;
|
|
||||||
}
|
|
||||||
if (i == 0) {
|
|
||||||
error("listIterator::operator++: Iterator ist NULL.\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
i = *(int *)i;
|
|
||||||
}
|
|
||||||
} while (i != 0);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool IsCountable(char *s)
|
bool IsCountable(char *s)
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -3809,28 +3476,6 @@ char * Capitals(char *Text)
|
|||||||
return Text;
|
return Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// WARNING: Unknown calling convention -- yet parameter storage is locked
|
|
||||||
|
|
||||||
void InitStrings(void)
|
|
||||||
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// WARNING: Unknown calling convention -- yet parameter storage is locked
|
|
||||||
|
|
||||||
void ExitStrings(void)
|
|
||||||
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void __tcf_0(void *param_1)
|
void __tcf_0(void *param_1)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@ -197,15 +197,6 @@ struct TAttackWave {
|
|||||||
struct vector<TItemData> ExtraItem;
|
struct vector<TItemData> ExtraItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TDynamicStringTableBlock {
|
|
||||||
int FreeEntries;
|
|
||||||
int TotalTextLength;
|
|
||||||
bool Dirty;
|
|
||||||
uchar EntryType[256];
|
|
||||||
ushort StringOffset[256];
|
|
||||||
char Text[32768];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TNonplayer {
|
struct TNonplayer {
|
||||||
struct TCreature super_TCreature; // INHERITANCE?
|
struct TCreature super_TCreature; // INHERITANCE?
|
||||||
enum STATE State;
|
enum STATE State;
|
||||||
@ -254,11 +245,6 @@ struct TMonsterhome {
|
|||||||
int Timer;
|
int Timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TStaticStringTableBlock {
|
|
||||||
int TotalTextLength;
|
|
||||||
char Text[65536];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TCondition {
|
struct TCondition {
|
||||||
int Type;
|
int Type;
|
||||||
ulong Text;
|
ulong Text;
|
||||||
|
|||||||
@ -117,6 +117,11 @@ void ExitSHMExtern(void);
|
|||||||
|
|
||||||
// strings.cc
|
// strings.cc
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
const char *AddStaticString(const char *String);
|
||||||
|
uint32 AddDynamicString(const char *String);
|
||||||
|
const char *GetDynamicString(uint32 Number);
|
||||||
|
void DeleteDynamicString(uint32 Number);
|
||||||
|
void CleanupDynamicStrings(void);
|
||||||
void InitStrings(void);
|
void InitStrings(void);
|
||||||
void ExitStrings(void);
|
void ExitStrings(void);
|
||||||
|
|
||||||
|
|||||||
207
src/strings.cc
207
src/strings.cc
@ -1,4 +1,211 @@
|
|||||||
#include "common.hh"
|
#include "common.hh"
|
||||||
|
#include "containers.hh"
|
||||||
|
|
||||||
|
struct TStaticStringTableBlock {
|
||||||
|
int TotalTextLength;
|
||||||
|
char Text[65536];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TDynamicStringTableBlock {
|
||||||
|
int FreeEntries;
|
||||||
|
int TotalTextLength;
|
||||||
|
bool Dirty;
|
||||||
|
uint8 EntryType[256];
|
||||||
|
uint16 StringOffset[256];
|
||||||
|
char Text[32768];
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int StaticBlockSize = NARRAY(TStaticStringTableBlock::Text);
|
||||||
|
constexpr int DynamicBlockSize = NARRAY(TDynamicStringTableBlock::Text);
|
||||||
|
constexpr int DynamicBlockEntries = NARRAY(TDynamicStringTableBlock::EntryType);
|
||||||
|
|
||||||
|
enum : uint8 {
|
||||||
|
DYNAMIC_STRING_FREE = 0,
|
||||||
|
DYNAMIC_STRING_ALLOCATED = 1,
|
||||||
|
DYNAMIC_STRING_DELETED = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
static list<TStaticStringTableBlock> StaticStringTable;
|
||||||
|
static list<TDynamicStringTableBlock> DynamicStringTable;
|
||||||
|
|
||||||
|
const char *AddStaticString(const char *String){
|
||||||
|
int StringLen = (int)strlen(String);
|
||||||
|
if((StringLen + 1) > StaticBlockSize){
|
||||||
|
error("AddStaticString: String zu lang (%d).\n", StringLen);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(StringLen == 0){
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
listnode<TStaticStringTableBlock> *Node = StaticStringTable.firstNode;
|
||||||
|
while(Node != NULL){
|
||||||
|
if((Node->data.TotalTextLength + StringLen + 1) <= StaticBlockSize){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Node = Node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Node == NULL){
|
||||||
|
Node = StaticStringTable.append();
|
||||||
|
memset(&Node->data, 0, sizeof(TStaticStringTableBlock));
|
||||||
|
}
|
||||||
|
|
||||||
|
TStaticStringTableBlock *Block = &Node->data;
|
||||||
|
char *Result = &Block->Text[Block->TotalTextLength];
|
||||||
|
memcpy(Result, String, StringLen + 1);
|
||||||
|
Block->TotalTextLength += StringLen + 1;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 AddDynamicString(const char *String){
|
||||||
|
int StringLen = (int)strlen(String);
|
||||||
|
if((StringLen + 1) > DynamicBlockSize){
|
||||||
|
error("AddDynamicString: String zu lang (%d)\n", StringLen);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(StringLen == 0){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BlockIndex = 0;
|
||||||
|
listnode<TDynamicStringTableBlock> *Node = DynamicStringTable.firstNode;
|
||||||
|
while(Node != NULL){
|
||||||
|
if(Node->data.FreeEntries > 0){
|
||||||
|
if((Node->data.TotalTextLength + StringLen + 1) <= DynamicBlockSize){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Node = Node->next;
|
||||||
|
BlockIndex += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Node == NULL){
|
||||||
|
Node = DynamicStringTable.append();
|
||||||
|
memset(&Node->data, 0, sizeof(TDynamicStringTableBlock));
|
||||||
|
Node->data.FreeEntries = DynamicBlockEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDynamicStringTableBlock *Block = &Node->data;
|
||||||
|
int EntryIndex = -1;
|
||||||
|
for(int i = 0; i < DynamicBlockEntries; i += 1){
|
||||||
|
if(Block->EntryType[i] == DYNAMIC_STRING_FREE){
|
||||||
|
EntryIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(EntryIndex == -1){
|
||||||
|
error("AddDynamicString: Keinen freien Platz gefunden.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StringOffset = Block->TotalTextLength;
|
||||||
|
Block->FreeEntries -= 1;
|
||||||
|
Block->TotalTextLength += StringLen + 1;
|
||||||
|
Block->EntryType[EntryIndex] = DYNAMIC_STRING_ALLOCATED;
|
||||||
|
Block->StringOffset[EntryIndex] = (uint16)StringOffset;
|
||||||
|
memcpy(&Block->Text[StringOffset], String, StringLen + 1);
|
||||||
|
|
||||||
|
return (uint32)(1 + BlockIndex * DynamicBlockEntries + EntryIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *GetDynamicString(uint32 Number){
|
||||||
|
if(Number == 0){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BlockIndex = (int)(Number - 1) / DynamicBlockEntries;
|
||||||
|
int EntryIndex = (int)(Number - 1) % DynamicBlockEntries;
|
||||||
|
listnode<TDynamicStringTableBlock> *Node = DynamicStringTable.firstNode;
|
||||||
|
while(BlockIndex > 0 && Node != NULL){
|
||||||
|
Node = Node->next;
|
||||||
|
BlockIndex -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Node == NULL){
|
||||||
|
error("GetDynamicString: Block für String %u existiert nicht\n", Number);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDynamicStringTableBlock *Block = &Node->data;
|
||||||
|
if(Block->EntryType[EntryIndex] != DYNAMIC_STRING_ALLOCATED){
|
||||||
|
error("GetDynamicString: Eintrag für String %u existiert nicht\n", Number);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StringOffset = (int)Block->StringOffset[EntryIndex];
|
||||||
|
return &Block->Text[StringOffset];
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteDynamicString(uint32 Number){
|
||||||
|
if(Number == 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BlockIndex = (int)(Number - 1) / DynamicBlockEntries;
|
||||||
|
int EntryIndex = (int)(Number - 1) % DynamicBlockEntries;
|
||||||
|
listnode<TDynamicStringTableBlock> *Node = DynamicStringTable.firstNode;
|
||||||
|
while(BlockIndex > 0 && Node != NULL){
|
||||||
|
Node = Node->next;
|
||||||
|
BlockIndex -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Node == NULL){
|
||||||
|
error("DeleteDynamicString: Block für String %u existiert nicht\n", Number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDynamicStringTableBlock *Block = &Node->data;
|
||||||
|
if(Block->EntryType[EntryIndex] != DYNAMIC_STRING_ALLOCATED){
|
||||||
|
error("DeleteDynamicString: Eintrag für String %u existiert nicht\n", Number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block->EntryType[EntryIndex] = DYNAMIC_STRING_DELETED;
|
||||||
|
Block->Dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CleanupDynamicStrings(void){
|
||||||
|
// IMPORTANT(fusion): The way we manage dynamic strings also mean pointers
|
||||||
|
// returned from `GetDynamicString` aren't stable.
|
||||||
|
for(listnode<TDynamicStringTableBlock> *Node = DynamicStringTable.firstNode;
|
||||||
|
Node != NULL;
|
||||||
|
Node = Node->next){
|
||||||
|
TDynamicStringTableBlock *Block = &Node->data;
|
||||||
|
if(!Block->Dirty){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < DynamicBlockEntries; i += 1){
|
||||||
|
if(Block->EntryType[i] == DYNAMIC_STRING_DELETED){
|
||||||
|
int StringOffset = Block->StringOffset[i];
|
||||||
|
char *String = &Block->Text[StringOffset];
|
||||||
|
int StringLen = (int)strlen(String);
|
||||||
|
int StringEnd = StringOffset + StringLen + 1;
|
||||||
|
Block->EntryType[i] = DYNAMIC_STRING_FREE;
|
||||||
|
|
||||||
|
if(StringEnd > DynamicBlockSize){
|
||||||
|
error("CleanupDynamicStrings: Stringende fehlt\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(StringEnd < DynamicBlockSize){
|
||||||
|
memmove(String, String + StringEnd, DynamicBlockSize - StringEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int j = 0; j < DynamicBlockEntries; j += 1){
|
||||||
|
if(Block->EntryType[j] != DYNAMIC_STRING_FREE
|
||||||
|
&& Block->StringOffset[j] > StringOffset){
|
||||||
|
Block->StringOffset[j] -= StringLen + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InitStrings(void){
|
void InitStrings(void){
|
||||||
// no-op
|
// no-op
|
||||||
|
|||||||
@ -15,18 +15,13 @@ typedef void TRefreshSectorFunction(int SectorX, int SectorY, int SectorZ, const
|
|||||||
typedef void TSendMailsFunction(TPlayerData *PlayerData);
|
typedef void TSendMailsFunction(TPlayerData *PlayerData);
|
||||||
|
|
||||||
extern void AbortWriter(void);
|
extern void AbortWriter(void);
|
||||||
extern uint32 AddDynamicString(const char *String);
|
|
||||||
extern const char *AddStaticString(const char *String);
|
|
||||||
extern void AnnounceChangedCreature(uint32 CreatureID, int Type);
|
extern void AnnounceChangedCreature(uint32 CreatureID, int Type);
|
||||||
extern void BroadcastMessage(int Mode, const char *Text, ...) ATTR_PRINTF(2, 3);
|
extern void BroadcastMessage(int Mode, const char *Text, ...) ATTR_PRINTF(2, 3);
|
||||||
extern void Change(Object Obj, ObjectType NewType, uint32 Value);
|
extern void Change(Object Obj, ObjectType NewType, uint32 Value);
|
||||||
extern bool CheckRight(uint32 CreatureID, RIGHT Right);
|
extern bool CheckRight(uint32 CreatureID, RIGHT Right);
|
||||||
extern void CleanHouseField(int x, int y, int z);
|
extern void CleanHouseField(int x, int y, int z);
|
||||||
extern void CleanupDynamicStrings(void);
|
|
||||||
extern void CreatePlayerList(bool Online);
|
extern void CreatePlayerList(bool Online);
|
||||||
extern void DeleteDynamicString(uint32 Number);
|
|
||||||
extern TCreature *GetCreature(uint32 CreatureID);
|
extern TCreature *GetCreature(uint32 CreatureID);
|
||||||
extern const char *GetDynamicString(uint32 Number);
|
|
||||||
extern TConnection *GetFirstConnection(void);
|
extern TConnection *GetFirstConnection(void);
|
||||||
extern TConnection *GetNextConnection(void);
|
extern TConnection *GetNextConnection(void);
|
||||||
extern void Log(const char *ProtocolName, const char *Text, ...) ATTR_PRINTF(2, 3);
|
extern void Log(const char *ProtocolName, const char *Text, ...) ATTR_PRINTF(2, 3);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user