Make stringarg application consistent

stringarg[0] and stringarg[1] are now are used as doubles of arg[0] and arg[1]. Specials that use both string args and regular args need to shift their args up to accomedate. This makes the behavior align more closely with the other Doom ports and removes a dumb manual string arg amount thing in callSpecImpl.

I only adjusted the specials that can be called from ACS. I did not mess with level load specials or thing types, since it's not as important. It would be nice to clean them up before release for consistency, though.
This commit is contained in:
Sally Coolatta 2023-03-14 07:52:23 -04:00
parent 62dd76dbcd
commit 181501860f
3 changed files with 101 additions and 126 deletions

View file

@ -286,9 +286,6 @@ ACSVM::Word Environment::callSpecImpl
auto info = &static_cast<Thread *>(thread)->info;
ACSVM::MapScope *const map = thread->scopeMap;
int arg = 0;
int numStringArgs = 0;
INT32 args[NUMLINEARGS] = {0};
char *stringargs[NUMLINESTRINGARGS] = {0};
@ -311,42 +308,20 @@ ACSVM::Word Environment::callSpecImpl
}
);
// This needs manually set, as ACS just uses indicies in the
// compiled string table and not actual strings, and SRB2 has
// separate args and stringargs, so there's no way to
// properly distinguish them.
switch (spec)
int i = 0;
for (i = 0; i < NUMLINESTRINGARGS; i++)
{
case 442:
numStringArgs = 2;
break;
case 413:
case 414:
case 415:
case 423:
case 425:
case 443:
case 459:
case 461:
case 463:
case 469:
numStringArgs = 1;
break;
default:
break;
ACSVM::String *strPtr = map->getString(argV[i]);
stringargs[i] = static_cast<char *>(Z_Malloc(strPtr->len + 1, PU_STATIC, nullptr));
M_Memcpy(stringargs[i], strPtr->str, strPtr->len + 1);
}
for (; arg < numStringArgs; arg++)
for (i = 0; i < NUMLINEARGS; i++)
{
ACSVM::String *strPtr = map->getString(argV[arg]);
stringargs[arg] = static_cast<char *>(Z_Malloc(strPtr->len + 1, PU_STATIC, nullptr));
M_Memcpy(stringargs[arg], strPtr->str, strPtr->len + 1);
}
for (; arg < std::min((signed)argC, NUMLINEARGS); arg++)
{
args[arg - numStringArgs] = argV[arg];
args[i] = argV[i];
}
P_SetTarget(&activator->mo, info->mo);

View file

@ -5158,25 +5158,25 @@ static void P_ConvertBinaryLinedefTypes(void)
break;
case 413: //Change music
if (lines[i].flags & ML_NOCLIMB)
lines[i].args[0] |= TMM_ALLPLAYERS;
lines[i].args[1] |= TMM_ALLPLAYERS;
if (lines[i].flags & ML_SKEWTD)
lines[i].args[0] |= TMM_OFFSET;
lines[i].args[1] |= TMM_OFFSET;
if (lines[i].flags & ML_NOSKEW)
lines[i].args[0] |= TMM_FADE;
lines[i].args[1] |= TMM_FADE;
if (lines[i].flags & ML_BLOCKPLAYERS)
lines[i].args[0] |= TMM_NORELOAD;
lines[i].args[1] |= TMM_NORELOAD;
if (lines[i].flags & ML_NOTBOUNCY)
lines[i].args[0] |= TMM_FORCERESET;
lines[i].args[1] |= TMM_FORCERESET;
if (lines[i].flags & ML_MIDSOLID)
lines[i].args[0] |= TMM_NOLOOP;
lines[i].args[1] |= TMM_NOLOOP;
if (lines[i].flags & ML_MIDPEG)
lines[i].args[0] |= TMM_NOCREDIT;
lines[i].args[1] = sides[lines[i].sidenum[0]].midtexture;
lines[i].args[2] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[3] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
lines[i].args[4] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0;
lines[i].args[5] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].rowoffset >> FRACBITS : -1;
lines[i].args[6] = sides[lines[i].sidenum[0]].bottomtexture;
lines[i].args[1] |= TMM_NOCREDIT;
lines[i].args[2] = sides[lines[i].sidenum[0]].midtexture;
lines[i].args[3] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[4] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
lines[i].args[5] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0;
lines[i].args[6] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].rowoffset >> FRACBITS : -1;
lines[i].args[7] = sides[lines[i].sidenum[0]].bottomtexture;
if (sides[lines[i].sidenum[0]].text)
{
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
@ -5184,41 +5184,41 @@ static void P_ConvertBinaryLinedefTypes(void)
}
break;
case 414: //Play sound effect
lines[i].args[2] = tag;
lines[i].args[3] = tag;
if (tag != 0)
{
if (lines[i].flags & ML_WRAPMIDTEX)
{
lines[i].args[0] = TMSS_TAGGEDSECTOR;
lines[i].args[1] = TMSL_EVERYONE;
lines[i].args[1] = TMSS_TAGGEDSECTOR;
lines[i].args[2] = TMSL_EVERYONE;
}
else
{
lines[i].args[0] = TMSS_NOWHERE;
lines[i].args[1] = TMSL_TAGGEDSECTOR;
lines[i].args[1] = TMSS_NOWHERE;
lines[i].args[2] = TMSL_TAGGEDSECTOR;
}
}
else
{
if (lines[i].flags & ML_NOCLIMB)
{
lines[i].args[0] = TMSS_NOWHERE;
lines[i].args[1] = TMSL_TRIGGERER;
lines[i].args[1] = TMSS_NOWHERE;
lines[i].args[2] = TMSL_TRIGGERER;
}
else if (lines[i].flags & ML_MIDSOLID)
{
lines[i].args[0] = TMSS_NOWHERE;
lines[i].args[1] = TMSL_EVERYONE;
lines[i].args[1] = TMSS_NOWHERE;
lines[i].args[2] = TMSL_EVERYONE;
}
else if (lines[i].flags & ML_BLOCKPLAYERS)
{
lines[i].args[0] = TMSS_TRIGGERSECTOR;
lines[i].args[1] = TMSL_EVERYONE;
lines[i].args[1] = TMSS_TRIGGERSECTOR;
lines[i].args[2] = TMSL_EVERYONE;
}
else
{
lines[i].args[0] = TMSS_TRIGGERMOBJ;
lines[i].args[1] = TMSL_EVERYONE;
lines[i].args[1] = TMSS_TRIGGERMOBJ;
lines[i].args[2] = TMSL_EVERYONE;
}
}
if (sides[lines[i].sidenum[0]].text)
@ -5398,17 +5398,17 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
break;
case 442: //Change object type state
lines[i].args[0] = tag;
lines[i].args[2] = tag;
if (sides[lines[i].sidenum[0]].text)
{
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1);
}
if (lines[i].sidenum[1] == 0xffff)
lines[i].args[1] = 1;
lines[i].args[3] = 1;
else
{
lines[i].args[1] = 0;
lines[i].args[3] = 0;
if (sides[lines[i].sidenum[1]].text)
{
lines[i].stringargs[1] = Z_Malloc(strlen(sides[lines[i].sidenum[1]].text) + 1, PU_LEVEL, NULL);
@ -5558,23 +5558,23 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[4] = !!(lines[i].flags & ML_NOSKEW);
break;
case 459: //Control text prompt
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
if (lines[i].flags & ML_BLOCKPLAYERS)
lines[i].args[2] |= TMP_CLOSE;
lines[i].args[3] |= TMP_CLOSE;
if (lines[i].flags & ML_SKEWTD)
lines[i].args[2] |= TMP_RUNPOSTEXEC;
lines[i].args[3] |= TMP_RUNPOSTEXEC;
if (lines[i].flags & ML_TFERLINE)
lines[i].args[2] |= TMP_CALLBYNAME;
lines[i].args[3] |= TMP_CALLBYNAME;
if (lines[i].flags & ML_NOSKEW)
lines[i].args[2] |= TMP_KEEPCONTROLS;
lines[i].args[3] |= TMP_KEEPCONTROLS;
if (lines[i].flags & ML_MIDPEG)
lines[i].args[2] |= TMP_KEEPREALTIME;
lines[i].args[3] |= TMP_KEEPREALTIME;
/*if (lines[i].flags & ML_NOCLIMB)
lines[i].args[2] |= TMP_ALLPLAYERS;
lines[i].args[3] |= TMP_ALLPLAYERS;
if (lines[i].flags & ML_MIDSOLID)
lines[i].args[2] |= TMP_FREEZETHINKERS;*/
lines[i].args[3] = (lines[i].sidenum[1] != 0xFFFF) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : tag;
lines[i].args[3] |= TMP_FREEZETHINKERS;*/
lines[i].args[4] = (lines[i].sidenum[1] != 0xFFFF) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : tag;
if (sides[lines[i].sidenum[0]].text)
{
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
@ -5587,27 +5587,27 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[2] = !!(lines[i].flags & ML_NOCLIMB);
break;
case 461: //Spawn object
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
lines[i].args[2] = lines[i].frontsector->floorheight >> FRACBITS;
lines[i].args[3] = (lines[i].flags & ML_SKEWTD) ? AngleFixed(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)) >> FRACBITS : 0;
lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
lines[i].args[3] = lines[i].frontsector->floorheight >> FRACBITS;
lines[i].args[4] = (lines[i].flags & ML_SKEWTD) ? AngleFixed(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)) >> FRACBITS : 0;
if (lines[i].flags & ML_NOCLIMB)
{
if (lines[i].sidenum[1] != 0xffff) // Make sure the linedef has a back side
{
lines[i].args[4] = 1;
lines[i].args[5] = sides[lines[i].sidenum[1]].textureoffset >> FRACBITS;
lines[i].args[6] = sides[lines[i].sidenum[1]].rowoffset >> FRACBITS;
lines[i].args[7] = lines[i].frontsector->ceilingheight >> FRACBITS;
lines[i].args[5] = 1;
lines[i].args[6] = sides[lines[i].sidenum[1]].textureoffset >> FRACBITS;
lines[i].args[7] = sides[lines[i].sidenum[1]].rowoffset >> FRACBITS;
lines[i].args[8] = lines[i].frontsector->ceilingheight >> FRACBITS;
}
else
{
CONS_Alert(CONS_WARNING, "Linedef Type %d - Spawn Object: Linedef is set for random range but has no back side.\n", lines[i].special);
lines[i].args[4] = 0;
lines[i].args[5] = 0;
}
}
else
lines[i].args[4] = 0;
lines[i].args[5] = 0;
if (sides[lines[i].sidenum[0]].text)
{
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);

View file

@ -2884,18 +2884,18 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
case 413: // Change music
// console player only unless TMM_ALLPLAYERS is set
if ((args[0] & TMM_ALLPLAYERS) || (mo && mo->player && P_IsLocalPlayer(mo->player)) || titlemapinaction)
if ((args[1] & TMM_ALLPLAYERS) || (mo && mo->player && P_IsLocalPlayer(mo->player)) || titlemapinaction)
{
boolean musicsame = (!stringargs[0] || !stringargs[0][0] || !strnicmp(stringargs[0], S_MusicName(), 7));
UINT16 tracknum = (UINT16)max(args[6], 0);
INT32 position = (INT32)max(args[1], 0);
UINT32 prefadems = (UINT32)max(args[2], 0);
UINT32 postfadems = (UINT32)max(args[3], 0);
UINT8 fadetarget = (UINT8)max(args[4], 0);
INT16 fadesource = (INT16)max(args[5], -1);
UINT16 tracknum = (UINT16)max(args[7], 0);
INT32 position = (INT32)max(args[2], 0);
UINT32 prefadems = (UINT32)max(args[3], 0);
UINT32 postfadems = (UINT32)max(args[4], 0);
UINT8 fadetarget = (UINT8)max(args[5], 0);
INT16 fadesource = (INT16)max(args[6], -1);
// Seek offset from current song position
if (args[0] & TMM_OFFSET)
if (args[1] & TMM_OFFSET)
{
// adjust for loop point if subtracting
if (position < 0 && S_GetMusicLength() &&
@ -2907,7 +2907,7 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
}
// Fade current music to target volume (if music won't be changed)
if ((args[0] & TMM_FADE) && fadetarget && musicsame)
if ((args[1] & TMM_FADE) && fadetarget && musicsame)
{
// 0 fadesource means fade from current volume.
// meaning that we can't specify volume 0 as the source volume -- this starts at 1.
@ -2932,22 +2932,22 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
mapmusname[6] = 0;
mapmusflags = tracknum & MUSIC_TRACKMASK;
if (!(args[0] & TMM_NORELOAD))
if (!(args[1] & TMM_NORELOAD))
mapmusflags |= MUSIC_RELOADRESET;
if (args[0] & TMM_FORCERESET)
if (args[1] & TMM_FORCERESET)
mapmusflags |= MUSIC_FORCERESET;
mapmusposition = position;
mapmusresume = 0;
S_ChangeMusicEx(mapmusname, mapmusflags, !(args[0] & TMM_NOLOOP), position,
!(args[0] & TMM_FADE) ? prefadems : 0,
!(args[0] & TMM_FADE) ? postfadems : 0);
S_ChangeMusicEx(mapmusname, mapmusflags, !(args[1] & TMM_NOLOOP), position,
!(args[1] & TMM_FADE) ? prefadems : 0,
!(args[1] & TMM_FADE) ? postfadems : 0);
if (!(args[0] & TMM_NOCREDIT))
if (!(args[1] & TMM_NOCREDIT))
S_ShowMusicCredit();
if ((args[0] & TMM_FADE) && fadetarget)
if ((args[1] & TMM_FADE) && fadetarget)
{
if (!postfadems)
S_SetInternalMusicVolume(fadetarget);
@ -2962,7 +2962,7 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
break;
case 414: // Play SFX
P_PlaySFX(stringargs[0] ? get_number(stringargs[0]) : sfx_None, mo, callsec, args[2], args[0], args[1]);
P_PlaySFX(stringargs[0] ? get_number(stringargs[0]) : sfx_None, mo, callsec, args[3], args[1], args[2]);
break;
case 415: // Run a script
@ -3459,7 +3459,7 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
if (type < 0 || type >= NUMMOBJTYPES)
break;
if (!args[1])
if (!args[3])
{
state = stringargs[1] ? get_number(stringargs[1]) : S_NULL;
@ -3467,7 +3467,7 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
break;
}
TAG_ITER_SECTORS(args[0], secnum)
TAG_ITER_SECTORS(args[2], secnum)
{
boolean tryagain;
do {
@ -3477,7 +3477,7 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
if (thing->type != type)
continue;
if (!P_SetMobjState(thing, args[1] ? thing->state->nextstate : state))
if (!P_SetMobjState(thing, args[3] ? thing->state->nextstate : state))
{ // mobj was removed
tryagain = true; // snext is corrupt, we'll have to start over.
break;
@ -4130,17 +4130,17 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
// console player only
if (mo && mo->player && P_IsLocalPlayer(mo->player))
{
INT32 promptnum = max(0, args[0] - 1);
INT32 pagenum = max(0, args[1] - 1);
INT32 postexectag = abs(args[3]);
INT32 promptnum = max(0, args[1] - 1);
INT32 pagenum = max(0, args[2] - 1);
INT32 postexectag = abs(args[4]);
boolean closetextprompt = (args[2] & TMP_CLOSE);
//boolean allplayers = (args[2] & TMP_ALLPLAYERS);
boolean runpostexec = (args[2] & TMP_RUNPOSTEXEC);
boolean blockcontrols = !(args[2] & TMP_KEEPCONTROLS);
boolean freezerealtime = !(args[2] & TMP_KEEPREALTIME);
//boolean freezethinkers = (args[2] & TMP_FREEZETHINKERS);
boolean callbynamedtag = (args[2] & TMP_CALLBYNAME);
boolean closetextprompt = (args[3] & TMP_CLOSE);
//boolean allplayers = (args[3] & TMP_ALLPLAYERS);
boolean runpostexec = (args[3] & TMP_RUNPOSTEXEC);
boolean blockcontrols = !(args[3] & TMP_KEEPCONTROLS);
boolean freezerealtime = !(args[3] & TMP_KEEPREALTIME);
//boolean freezethinkers = (args[3] & TMP_FREEZETHINKERS);
boolean callbynamedtag = (args[3] & TMP_CALLBYNAME);
if (closetextprompt)
F_EndTextPrompt(false, false);
@ -4179,23 +4179,23 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
fixed_t x, y, z;
if (args[4]) // If args[4] is set, spawn randomly within a range
if (args[5]) // If args[5] is set, spawn randomly within a range
{
x = P_RandomRange(PR_UNDEFINED, args[0], args[5])<<FRACBITS;
y = P_RandomRange(PR_UNDEFINED, args[1], args[6])<<FRACBITS;
z = P_RandomRange(PR_UNDEFINED, args[2], args[7])<<FRACBITS;
x = P_RandomRange(PR_UNDEFINED, args[1], args[6])<<FRACBITS;
y = P_RandomRange(PR_UNDEFINED, args[2], args[7])<<FRACBITS;
z = P_RandomRange(PR_UNDEFINED, args[3], args[8])<<FRACBITS;
}
else
{
x = args[0] << FRACBITS;
y = args[1] << FRACBITS;
z = args[2] << FRACBITS;
x = args[1] << FRACBITS;
y = args[2] << FRACBITS;
z = args[3] << FRACBITS;
}
mobj = P_SpawnMobj(x, y, z, type);
if (mobj)
{
mobj->angle = FixedAngle(args[3] << FRACBITS);
mobj->angle = FixedAngle(args[4] << FRACBITS);
CONS_Debug(DBG_GAMELOGIC, "Special Type %d - Spawn Object: %d spawned at (%d, %d, %d)\n", special, mobj->type, mobj->x>>FRACBITS, mobj->y>>FRACBITS, mobj->z>>FRACBITS); //TODO: Convert mobj->type to a string somehow.
}
else
@ -4357,16 +4357,16 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
gravityvalue = FloatToFixed(atof(stringargs[0]));
TAG_ITER_SECTORS(args[0], secnum)
TAG_ITER_SECTORS(args[1], secnum)
{
if (args[1])
if (args[2])
sectors[secnum].gravity = FixedMul(sectors[secnum].gravity, gravityvalue);
else
sectors[secnum].gravity = gravityvalue;
if (args[2] == TMF_ADD)
if (args[3] == TMF_ADD)
sectors[secnum].flags |= MSF_GRAVITYFLIP;
else if (args[2] == TMF_REMOVE)
else if (args[3] == TMF_REMOVE)
sectors[secnum].flags &= ~MSF_GRAVITYFLIP;
}
}