* Updated to ZDoom r4325:

- Fixed: Don't transform map variable string initializers into global string table entries if they don't really exist in the source string table.
- Fixed: When garbage collecting ACS strings, the active values on the ACS stack also need to be included in the mark phase.
- Added ACS function PlayActorSound. It's functionally equivalent to PlaySound, except instead of taking an actual sound name as its second parameter, it selects the sound to play based on the actor playing the sound and the selector passed as the second parameter.
- fixed: UDMF's Doom namespace needs to retain Boom's sector special flags.
- fixed: UDMF's ZDoomTranslated namespace needs to set the DUMMYSWITCHES flag so that it remains compatible with Doom-format ZDoom maps.


git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1589 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
gez 2013-06-03 16:52:47 +00:00
parent 8fb4b20d86
commit 425ead73ea
5 changed files with 127 additions and 62 deletions

View file

@ -198,6 +198,7 @@ FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
// strings without growing. A string is concidered in use if any value
// in any of these variable blocks contains a valid ID in the global string
// table:
// * The active area of the ACS stack
// * All running scripts' local variables
// * All map variables
// * All world variables
@ -253,7 +254,7 @@ void ACSStringPool::Clear()
//
//============================================================================
int ACSStringPool::AddString(const char *str)
int ACSStringPool::AddString(const char *str, const SDWORD *stack, int stackdepth)
{
size_t len = strlen(str);
unsigned int h = SuperFastHash(str, len);
@ -264,10 +265,10 @@ int ACSStringPool::AddString(const char *str)
return i | STRPOOL_LIBRARYID_OR;
}
FString fstr(str);
return InsertString(fstr, h, bucketnum);
return InsertString(fstr, h, bucketnum, stack, stackdepth);
}
int ACSStringPool::AddString(FString &str)
int ACSStringPool::AddString(FString &str, const SDWORD *stack, int stackdepth)
{
unsigned int h = SuperFastHash(str.GetChars(), str.Len());
unsigned int bucketnum = h % NUM_BUCKETS;
@ -276,7 +277,7 @@ int ACSStringPool::AddString(FString &str)
{
return i | STRPOOL_LIBRARYID_OR;
}
return InsertString(str, h, bucketnum);
return InsertString(str, h, bucketnum, stack, stackdepth);
}
//============================================================================
@ -540,7 +541,7 @@ int ACSStringPool::FindString(const char *str, size_t len, unsigned int h, unsig
//
//============================================================================
int ACSStringPool::InsertString(FString &str, unsigned int h, unsigned int bucketnum)
int ACSStringPool::InsertString(FString &str, unsigned int h, unsigned int bucketnum, const SDWORD *stack, int stackdepth)
{
if (Pool.Size() >= STRPOOL_LIBRARYID)
{
@ -549,7 +550,7 @@ int ACSStringPool::InsertString(FString &str, unsigned int h, unsigned int bucke
unsigned int index = FirstFreeEntry;
if (index >= MIN_GC_SIZE && index == Pool.Max())
{ // We will need to grow the array. Try a garbage collection first.
P_CollectACSGlobalStrings();
P_CollectACSGlobalStrings(stack, stackdepth);
}
if (index == Pool.Size())
{ // There were no free entries; make a new one.
@ -713,8 +714,12 @@ void P_MarkGlobalVarStrings()
//
//============================================================================
void P_CollectACSGlobalStrings()
void P_CollectACSGlobalStrings(const SDWORD *stack, int stackdepth)
{
if (stack != NULL && stackdepth != 0)
{
GlobalACSStrings.MarkStringArray(stack, stackdepth);
}
FBehavior::StaticMarkLevelVarStrings();
P_MarkWorldVarStrings();
P_MarkGlobalVarStrings();
@ -724,7 +729,7 @@ void P_CollectACSGlobalStrings()
#ifdef _DEBUG
CCMD(acsgc)
{
P_CollectACSGlobalStrings();
P_CollectACSGlobalStrings(NULL, 0);
}
CCMD(globstr)
{
@ -1881,7 +1886,11 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
for (DWORD i = 0; i < chunk[1]/4; ++i)
{
// MapVarStore[chunk[i+2]] |= LibraryID;
MapVarStore[chunk[i+2]] = GlobalACSStrings.AddString(LookupString(MapVarStore[chunk[i+2]]));
const char *str = LookupString(MapVarStore[chunk[i+2]]);
if (str != NULL)
{
MapVarStore[chunk[i+2]] = GlobalACSStrings.AddString(str, NULL, 0);
}
}
}
@ -1897,7 +1906,11 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
for (int j = ArrayStore[arraynum].ArraySize; j > 0; --j, ++elems)
{
// *elems |= LibraryID;
*elems = GlobalACSStrings.AddString(LookupString(*elems));
const char *str = LookupString(*elems);
if (str != NULL)
{
*elems = GlobalACSStrings.AddString(str, NULL, 0);
}
}
}
}
@ -1927,7 +1940,11 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
}
else if (*chunkData == 1)
{
*elems = GlobalACSStrings.AddString(LookupString(*elems));
const char *str = LookupString(*elems);
if (str != NULL)
{
*elems = GlobalACSStrings.AddString(str, NULL, 0);
}
}
}
i += 4+ArrayStore[arraynum].ArraySize;
@ -3701,7 +3718,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
}
}
int DLevelScript::GetActorProperty (int tid, int property)
int DLevelScript::GetActorProperty (int tid, int property, const SDWORD *stack, int stackdepth)
{
AActor *actor = SingleActorFromTID (tid, activator);
@ -3768,13 +3785,13 @@ int DLevelScript::GetActorProperty (int tid, int property)
case APROP_ReactionTime:return actor->reactiontime;
case APROP_MeleeRange: return actor->meleerange;
case APROP_SeeSound: return GlobalACSStrings.AddString(actor->SeeSound);
case APROP_AttackSound: return GlobalACSStrings.AddString(actor->AttackSound);
case APROP_PainSound: return GlobalACSStrings.AddString(actor->PainSound);
case APROP_DeathSound: return GlobalACSStrings.AddString(actor->DeathSound);
case APROP_ActiveSound: return GlobalACSStrings.AddString(actor->ActiveSound);
case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies());
case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag());
case APROP_SeeSound: return GlobalACSStrings.AddString(actor->SeeSound, stack, stackdepth);
case APROP_AttackSound: return GlobalACSStrings.AddString(actor->AttackSound, stack, stackdepth);
case APROP_PainSound: return GlobalACSStrings.AddString(actor->PainSound, stack, stackdepth);
case APROP_DeathSound: return GlobalACSStrings.AddString(actor->DeathSound, stack, stackdepth);
case APROP_ActiveSound: return GlobalACSStrings.AddString(actor->ActiveSound, stack, stackdepth);
case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies(), stack, stackdepth);
case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag(), stack, stackdepth);
default: return 0;
}
@ -3819,7 +3836,7 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value)
case APROP_Radius:
case APROP_ReactionTime:
case APROP_MeleeRange:
return (GetActorProperty(tid, property) == value);
return (GetActorProperty(tid, property, NULL, 0) == value);
// Boolean values need to compare to a binary version of value
case APROP_Ambush:
@ -3831,7 +3848,7 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value)
case APROP_Notarget:
case APROP_Notrigger:
case APROP_Dormant:
return (GetActorProperty(tid, property) == (!!value));
return (GetActorProperty(tid, property, NULL, 0) == (!!value));
// Strings are covered by GetActorProperty, but they're fairly
// heavy-duty, so make the check here.
@ -4063,6 +4080,38 @@ int DLevelScript::DoClassifyActor(int tid)
return classify;
}
enum
{
SOUND_See,
SOUND_Attack,
SOUND_Pain,
SOUND_Death,
SOUND_Active,
SOUND_Use,
SOUND_Bounce,
SOUND_WallBounce,
SOUND_CrushPain,
SOUND_Howl,
};
static FSoundID GetActorSound(const AActor *actor, int soundtype)
{
switch (soundtype)
{
case SOUND_See: return actor->SeeSound;
case SOUND_Attack: return actor->AttackSound;
case SOUND_Pain: return actor->PainSound;
case SOUND_Death: return actor->DeathSound;
case SOUND_Active: return actor->ActiveSound;
case SOUND_Use: return actor->UseSound;
case SOUND_Bounce: return actor->BounceSound;
case SOUND_WallBounce: return actor->WallBounceSound;
case SOUND_CrushPain: return actor->CrushPainSound;
case SOUND_Howl: return actor->GetClass()->Meta.GetMetaInt(AMETA_HowlSound);
default: return 0;
}
}
enum EACSFunctions
{
ACSF_GetLineUDMFInt=1,
@ -4135,6 +4184,7 @@ enum EACSFunctions
ACSF_GetActorClass,
ACSF_GetWeapon,
ACSF_SoundVolume,
ACSF_PlayActorSound,
// ZDaemon
ACSF_GetTeamScore = 19620, // (int team)
@ -4273,14 +4323,14 @@ static void DoSetCVar(FBaseCVar *cvar, int value, bool is_string, bool force=fal
}
// Converts floating- to fixed-point as required.
static int DoGetCVar(FBaseCVar *cvar, bool is_string)
static int DoGetCVar(FBaseCVar *cvar, bool is_string, const SDWORD *stack, int stackdepth)
{
UCVarValue val;
if (is_string)
{
val = cvar->GetGenericRep(CVAR_String);
return GlobalACSStrings.AddString(val.String);
return GlobalACSStrings.AddString(val.String, stack, stackdepth);
}
else if (cvar->GetRealType() == CVAR_Float)
{
@ -4294,7 +4344,7 @@ static int DoGetCVar(FBaseCVar *cvar, bool is_string)
}
}
static int GetUserCVar(int playernum, const char *cvarname, bool is_string)
static int GetUserCVar(int playernum, const char *cvarname, bool is_string, const SDWORD *stack, int stackdepth)
{
if ((unsigned)playernum >= MAXPLAYERS || !playeringame[playernum])
{
@ -4306,10 +4356,10 @@ static int GetUserCVar(int playernum, const char *cvarname, bool is_string)
{
return 0;
}
return DoGetCVar(cvar, is_string);
return DoGetCVar(cvar, is_string, stack, stackdepth);
}
static int GetCVar(AActor *activator, const char *cvarname, bool is_string)
static int GetCVar(AActor *activator, const char *cvarname, bool is_string, const SDWORD *stack, int stackdepth)
{
FBaseCVar *cvar = FindCVar(cvarname, NULL);
// Either the cvar doesn't exist, or it's for a mod that isn't loaded, so return 0.
@ -4326,9 +4376,9 @@ static int GetCVar(AActor *activator, const char *cvarname, bool is_string)
{
return 0;
}
return GetUserCVar(int(activator->player - players), cvarname, is_string);
return GetUserCVar(int(activator->player - players), cvarname, is_string, stack, stackdepth);
}
return DoGetCVar(cvar, is_string);
return DoGetCVar(cvar, is_string, stack, stackdepth);
}
}
@ -4383,7 +4433,7 @@ static int SetCVar(AActor *activator, const char *cvarname, int value, bool is_s
return 1;
}
int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const SDWORD *stack, int stackdepth)
{
AActor *actor;
switch(funcIndex)
@ -4659,7 +4709,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
case ACSF_GetActorClass:
{
AActor *a = SingleActorFromTID(args[0], activator);
return GlobalACSStrings.AddString(a == NULL ? "None" : a->GetClass()->TypeName.GetChars());
return GlobalACSStrings.AddString(a == NULL ? "None" : a->GetClass()->TypeName.GetChars(), stack, stackdepth);
}
case ACSF_SoundSequenceOnActor:
@ -4836,7 +4886,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
case ACSF_GetCVarString:
if (argCount == 1)
{
return GetCVar(activator, FBehavior::StaticLookupString(args[0]), true);
return GetCVar(activator, FBehavior::StaticLookupString(args[0]), true, stack, stackdepth);
}
break;
@ -4857,14 +4907,14 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
case ACSF_GetUserCVar:
if (argCount == 2)
{
return GetUserCVar(args[0], FBehavior::StaticLookupString(args[1]), false);
return GetUserCVar(args[0], FBehavior::StaticLookupString(args[1]), false, stack, stackdepth);
}
break;
case ACSF_GetUserCVarString:
if (argCount == 2)
{
return GetUserCVar(args[0], FBehavior::StaticLookupString(args[1]), true);
return GetUserCVar(args[0], FBehavior::StaticLookupString(args[1]), true, stack, stackdepth);
}
break;
@ -4910,15 +4960,24 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
break;
case ACSF_PlaySound:
case ACSF_PlayActorSound:
// PlaySound(tid, "SoundName", channel, volume, looping, attenuation)
{
const char *lookup = FBehavior::StaticLookupString(args[1]);
if (lookup != NULL)
FSoundID sid;
if (funcIndex == ACSF_PlaySound)
{
const char *lookup = FBehavior::StaticLookupString(args[1]);
if (lookup != NULL)
{
sid = lookup;
}
}
if (sid != 0 || funcIndex == ACSF_PlayActorSound)
{
FActorIterator it(args[0]);
AActor *spot;
FSoundID sid(lookup);
int chan = argCount > 2 ? args[2] : CHAN_BODY;
float vol = argCount > 3 ? FIXED2FLOAT(args[3]) : 1.f;
INTBOOL looping = argCount > 4 ? args[4] : false;
@ -4931,13 +4990,20 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
}
while ((spot = it.Next()) != NULL)
{
doplaysound: if (!looping)
doplaysound: if (funcIndex == ACSF_PlayActorSound)
{
S_Sound(spot, chan, sid, vol, atten);
sid = GetActorSound(spot, args[1]);
}
else if (!S_IsActorPlayingSomething(spot, chan, sid))
if (sid != 0)
{
S_Sound(spot, chan | CHAN_LOOP, sid, vol, atten);
if (!looping)
{
S_Sound(spot, chan, sid, vol, atten);
}
else if (!S_IsActorPlayingSomething(spot, chan, sid))
{
S_Sound(spot, chan | CHAN_LOOP, sid, vol, atten);
}
}
}
}
@ -5019,7 +5085,7 @@ doplaysound: if (!looping)
const char *oldstr = FBehavior::StaticLookupString(args[0]);
if (oldstr == NULL || *oldstr == '\0')
{
return GlobalACSStrings.AddString("");
return GlobalACSStrings.AddString("", stack, stackdepth);
}
size_t oldlen = strlen(oldstr);
size_t newlen = args[1];
@ -5029,7 +5095,7 @@ doplaysound: if (!looping)
newlen = oldlen;
}
FString newstr(funcIndex == ACSF_StrLeft ? oldstr : oldstr + oldlen - newlen, newlen);
return GlobalACSStrings.AddString(newstr);
return GlobalACSStrings.AddString(newstr, stack, stackdepth);
}
break;
@ -5039,7 +5105,7 @@ doplaysound: if (!looping)
const char *oldstr = FBehavior::StaticLookupString(args[0]);
if (oldstr == NULL || *oldstr == '\0')
{
return GlobalACSStrings.AddString("");
return GlobalACSStrings.AddString("", stack, stackdepth);
}
size_t oldlen = strlen(oldstr);
size_t pos = args[1];
@ -5047,13 +5113,13 @@ doplaysound: if (!looping)
if (pos >= oldlen)
{
return GlobalACSStrings.AddString("");
return GlobalACSStrings.AddString("", stack, stackdepth);
}
if (pos + newlen > oldlen || pos + newlen < pos)
{
newlen = oldlen - pos;
}
return GlobalACSStrings.AddString(FString(oldstr + pos, newlen));
return GlobalACSStrings.AddString(FString(oldstr + pos, newlen), stack, stackdepth);
}
break;
@ -5061,11 +5127,11 @@ doplaysound: if (!looping)
if (activator == NULL || activator->player == NULL || // Non-players do not have weapons
activator->player->ReadyWeapon == NULL)
{
return GlobalACSStrings.AddString("None");
return GlobalACSStrings.AddString("None", stack, stackdepth);
}
else
{
return GlobalACSStrings.AddString(activator->player->ReadyWeapon->GetClass()->TypeName.GetChars());
return GlobalACSStrings.AddString(activator->player->ReadyWeapon->GetClass()->TypeName.GetChars(), stack, stackdepth);
}
default:
@ -5219,7 +5285,7 @@ int DLevelScript::RunScript ()
case PCD_TAGSTRING:
//Stack[sp-1] |= activeBehavior->GetLibraryID();
Stack[sp-1] = GlobalACSStrings.AddString(activeBehavior->LookupString(Stack[sp-1]));
Stack[sp-1] = GlobalACSStrings.AddString(activeBehavior->LookupString(Stack[sp-1]), Stack, sp);
break;
case PCD_PUSHNUMBER:
@ -5417,7 +5483,7 @@ int DLevelScript::RunScript ()
int argCount = NEXTBYTE;
int funcIndex = NEXTSHORT;
int retval = CallFunction(argCount, funcIndex, &STACK(argCount));
int retval = CallFunction(argCount, funcIndex, &STACK(argCount), Stack, sp);
sp -= argCount-1;
STACK(1) = retval;
}
@ -7853,7 +7919,7 @@ scriptwait:
break;
case PCD_GETACTORPROPERTY:
STACK(2) = GetActorProperty (STACK(2), STACK(1));
STACK(2) = GetActorProperty (STACK(2), STACK(1), Stack, sp);
sp -= 1;
break;
@ -7935,7 +8001,7 @@ scriptwait:
break;
case PCD_GETCVAR:
STACK(1) = GetCVar(activator, FBehavior::StaticLookupString(STACK(1)), false);
STACK(1) = GetCVar(activator, FBehavior::StaticLookupString(STACK(1)), false, Stack, sp);
break;
case PCD_SETHUDSIZE:
@ -8319,7 +8385,7 @@ scriptwait:
case PCD_SAVESTRING:
// Saves the string
{
PushToStack(GlobalACSStrings.AddString(work));
PushToStack(GlobalACSStrings.AddString(work, Stack, sp));
STRINGBUILDER_FINISH(work);
}
break;

View file

@ -80,8 +80,8 @@ class ACSStringPool
{
public:
ACSStringPool();
int AddString(const char *str);
int AddString(FString &str);
int AddString(const char *str, const SDWORD *stack, int stackdepth);
int AddString(FString &str, const SDWORD *stack, int stackdepth);
const char *GetString(int strnum);
void LockString(int strnum);
void UnlockString(int strnum);
@ -99,7 +99,7 @@ public:
private:
int FindString(const char *str, size_t len, unsigned int h, unsigned int bucketnum);
int InsertString(FString &str, unsigned int h, unsigned int bucketnum);
int InsertString(FString &str, unsigned int h, unsigned int bucketnum, const SDWORD *stack, int stackdepth);
enum { NUM_BUCKETS = 251 };
enum { FREE_ENTRY = 0xFFFFFFFE }; // Stored in PoolEntry's Next field
@ -118,7 +118,7 @@ private:
};
extern ACSStringPool GlobalACSStrings;
void P_CollectACSGlobalStrings();
void P_CollectACSGlobalStrings(const SDWORD *stack, int stackdepth);
void P_ReadACSVars(PNGHandle *);
void P_WriteACSVars(FILE*);
void P_ClearACSVars(bool);
@ -833,7 +833,7 @@ protected:
int DoSpawnSpot (int type, int spot, int tid, int angle, bool forced);
int DoSpawnSpotFacing (int type, int spot, int tid, bool forced);
int DoClassifyActor (int tid);
int CallFunction(int argCount, int funcIndex, SDWORD *args);
int CallFunction(int argCount, int funcIndex, SDWORD *args, const SDWORD *stack, int stackdepth);
void DoFadeTo (int r, int g, int b, int a, fixed_t time);
void DoFadeRange (int r1, int g1, int b1, int a1,
@ -841,7 +841,7 @@ protected:
void DoSetFont (int fontnum);
void SetActorProperty (int tid, int property, int value);
void DoSetActorProperty (AActor *actor, int property, int value);
int GetActorProperty (int tid, int property);
int GetActorProperty (int tid, int property, const SDWORD *stack, int stackdepth);
int CheckActorProperty (int tid, int property, int value);
int GetPlayerInput (int playernum, int inputnum);

View file

@ -1542,6 +1542,7 @@ public:
isTranslated = false;
break;
case NAME_ZDoomTranslated:
level.flags2 |= LEVEL2_DUMMYSWITCHES;
namespace_bits = Zdt;
break;
case NAME_Vavoom:

View file

@ -3,5 +3,5 @@
// This file was automatically generated by the
// updaterevision tool. Do not edit by hand.
#define ZD_SVN_REVISION_STRING "4318"
#define ZD_SVN_REVISION_NUMBER 4318
#define ZD_SVN_REVISION_STRING "4325"
#define ZD_SVN_REVISION_NUMBER 4325

View file

@ -3,8 +3,6 @@ include "xlat/doom.txt"
maxlinespecial = 272;
sector bitmask 0xffe0 clear;
sector 15 = 0;
sector 17 = 0;
sector 18 = 0;