mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- ZDoom implementation of strcpy, submitted by FDARI.
SVN r3227 (trunk)
This commit is contained in:
parent
e6de6fed3c
commit
74ad869e62
2 changed files with 174 additions and 11 deletions
173
src/p_acs.cpp
173
src/p_acs.cpp
|
@ -1721,6 +1721,25 @@ void FBehavior::SetArrayVal (int arraynum, int index, int value)
|
|||
array->Elements[index] = value;
|
||||
}
|
||||
|
||||
inline bool FBehavior::CopyStringToArray(int arraynum, int index, int maxLength, const char *string)
|
||||
{
|
||||
// false if the operation was incomplete or unsuccessful
|
||||
|
||||
if ((unsigned)arraynum >= (unsigned)NumTotalArrays || index < 0)
|
||||
return false;
|
||||
const ArrayInfo *array = Arrays[arraynum];
|
||||
|
||||
if ((signed)array->ArraySize - index < maxLength) maxLength = (signed)array->ArraySize - index;
|
||||
|
||||
while (maxLength-- > 0)
|
||||
{
|
||||
array->Elements[index++] = *string;
|
||||
if (!(*string)) return true; // written terminating 0
|
||||
string++;
|
||||
}
|
||||
return !(*string); // return true if only terminating 0 was not written
|
||||
}
|
||||
|
||||
BYTE *FBehavior::FindChunk (DWORD id) const
|
||||
{
|
||||
BYTE *chunk = Chunks;
|
||||
|
@ -5112,43 +5131,101 @@ int DLevelScript::RunScript ()
|
|||
|
||||
// [JB] Print map character array
|
||||
case PCD_PRINTMAPCHARARRAY:
|
||||
case PCD_PRINTMAPCHRANGE:
|
||||
{
|
||||
int capacity, offset;
|
||||
|
||||
if (pcd == PCD_PRINTMAPCHRANGE)
|
||||
{
|
||||
capacity = STACK(1);
|
||||
offset = STACK(2);
|
||||
if (capacity < 1 || offset < 0)
|
||||
{
|
||||
sp -= 4;
|
||||
break;
|
||||
}
|
||||
sp -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
capacity = 0x7FFFFFFF;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
int a = *(activeBehavior->MapVars[STACK(1)]);
|
||||
int offset = STACK(2);
|
||||
offset += STACK(2);
|
||||
int c;
|
||||
while((c = activeBehavior->GetArrayVal (a, offset)) != '\0') {
|
||||
while(capacity-- && (c = activeBehavior->GetArrayVal (a, offset)) != '\0') {
|
||||
work += (char)c;
|
||||
offset++;
|
||||
}
|
||||
sp-=2;
|
||||
sp-= 2;
|
||||
}
|
||||
break;
|
||||
|
||||
// [JB] Print world character array
|
||||
case PCD_PRINTWORLDCHARARRAY:
|
||||
case PCD_PRINTWORLDCHRANGE:
|
||||
{
|
||||
int capacity, offset;
|
||||
if (pcd == PCD_PRINTWORLDCHRANGE)
|
||||
{
|
||||
capacity = STACK(1);
|
||||
offset = STACK(2);
|
||||
if (capacity < 1 || offset < 0)
|
||||
{
|
||||
sp -= 4;
|
||||
break;
|
||||
}
|
||||
sp -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
capacity = 0x7FFFFFFF;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
int a = STACK(1);
|
||||
int offset = STACK(2);
|
||||
offset += STACK(2);
|
||||
int c;
|
||||
while((c = ACS_WorldArrays[a][offset]) != '\0') {
|
||||
while(capacity-- && (c = ACS_WorldArrays[a][offset]) != '\0') {
|
||||
work += (char)c;
|
||||
offset++;
|
||||
}
|
||||
sp-=2;
|
||||
sp-= 2;
|
||||
}
|
||||
break;
|
||||
|
||||
// [JB] Print global character array
|
||||
case PCD_PRINTGLOBALCHARARRAY:
|
||||
case PCD_PRINTGLOBALCHRANGE:
|
||||
{
|
||||
int capacity, offset;
|
||||
if (pcd == PCD_PRINTGLOBALCHRANGE)
|
||||
{
|
||||
capacity = STACK(1);
|
||||
offset = STACK(2);
|
||||
if (capacity < 1 || offset < 0)
|
||||
{
|
||||
sp -= 4;
|
||||
break;
|
||||
}
|
||||
sp -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
capacity = 0x7FFFFFFF;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
int a = STACK(1);
|
||||
int offset = STACK(2);
|
||||
offset += STACK(2);
|
||||
int c;
|
||||
while((c = ACS_GlobalArrays[a][offset]) != '\0') {
|
||||
while(capacity-- && (c = ACS_GlobalArrays[a][offset]) != '\0') {
|
||||
work += (char)c;
|
||||
offset++;
|
||||
}
|
||||
sp-=2;
|
||||
sp-= 2;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -6731,6 +6808,84 @@ int DLevelScript::RunScript ()
|
|||
}
|
||||
break;
|
||||
|
||||
case PCD_STRCPYTOMAPCHRANGE:
|
||||
case PCD_STRCPYTOWORLDCHRANGE:
|
||||
case PCD_STRCPYTOGLOBALCHRANGE:
|
||||
// source: stringid(2); stringoffset(1)
|
||||
// destination: capacity (3); stringoffset(4); arrayid (5); offset(6)
|
||||
|
||||
{
|
||||
int index = STACK(4);
|
||||
int capacity = STACK(3);
|
||||
|
||||
if (index < 0 || STACK(1) < 0)
|
||||
{
|
||||
// no writable destination, or negative offset to source string
|
||||
sp -= 5;
|
||||
Stack[sp-1] = 0; // false
|
||||
break;
|
||||
}
|
||||
|
||||
index += STACK(6);
|
||||
|
||||
lookup = FBehavior::StaticLookupString (STACK(2));
|
||||
|
||||
if (!lookup) {
|
||||
// no data, operation complete
|
||||
STRCPYTORANGECOMPLETE:
|
||||
sp -= 5;
|
||||
Stack[sp-1] = 1; // true
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0;i < STACK(1); i++)
|
||||
{
|
||||
if (! (*(lookup++)))
|
||||
{
|
||||
// no data, operation complete
|
||||
goto STRCPYTORANGECOMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
switch (pcd)
|
||||
{
|
||||
case PCD_STRCPYTOMAPCHRANGE:
|
||||
{
|
||||
Stack[sp-6] = activeBehavior->CopyStringToArray(STACK(5), index, capacity, lookup);
|
||||
}
|
||||
break;
|
||||
case PCD_STRCPYTOWORLDCHRANGE:
|
||||
{
|
||||
int a = STACK(5);
|
||||
|
||||
while (capacity-- > 0)
|
||||
{
|
||||
ACS_WorldArrays[a][index++] = *lookup;
|
||||
if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0
|
||||
}
|
||||
|
||||
Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied
|
||||
}
|
||||
break;
|
||||
case PCD_STRCPYTOGLOBALCHRANGE:
|
||||
{
|
||||
int a = STACK(5);
|
||||
|
||||
while (capacity-- > 0)
|
||||
{
|
||||
ACS_GlobalArrays[a][index++] = *lookup;
|
||||
if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0
|
||||
}
|
||||
|
||||
Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
sp -= 5;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
src/p_acs.h
12
src/p_acs.h
|
@ -168,6 +168,8 @@ public:
|
|||
ScriptFunction *GetFunction (int funcnum, FBehavior *&module) const;
|
||||
int GetArrayVal (int arraynum, int index) const;
|
||||
void SetArrayVal (int arraynum, int index, int value);
|
||||
inline bool CopyStringToArray(int arraynum, int index, int maxLength, const char * string);
|
||||
|
||||
int FindFunctionName (const char *funcname) const;
|
||||
int FindMapVarName (const char *varname) const;
|
||||
int FindMapArray (const char *arrayname) const;
|
||||
|
@ -587,9 +589,15 @@ public:
|
|||
PCD_PRINTBINARY,
|
||||
/*350*/ PCD_PRINTHEX,
|
||||
PCD_CALLFUNC,
|
||||
PCD_SAVESTRING, // [FDARI]
|
||||
PCD_SAVESTRING, // [FDARI] create string (temporary)
|
||||
PCD_PRINTMAPCHRANGE, // [FDARI] output range (print part of array)
|
||||
PCD_PRINTWORLDCHRANGE,
|
||||
PCD_PRINTGLOBALCHRANGE,
|
||||
PCD_STRCPYTOMAPCHRANGE, // [FDARI] input range (copy string to all/part of array)
|
||||
PCD_STRCPYTOWORLDCHRANGE,
|
||||
PCD_STRCPYTOGLOBALCHRANGE,
|
||||
|
||||
/*353*/ PCODE_COMMAND_COUNT
|
||||
/*359*/ PCODE_COMMAND_COUNT
|
||||
};
|
||||
|
||||
// Some constants used by ACS scripts
|
||||
|
|
Loading…
Reference in a new issue