This commit is contained in:
Christoph Oelckers 2016-02-10 20:49:32 +01:00
commit 1098093ead
27 changed files with 164 additions and 169 deletions

View file

@ -230,20 +230,10 @@ include_directories( ${OPENGL_INCLUDE_DIR} )
if( NOT NO_OPENAL )
find_package( OpenAL )
mark_as_advanced(CLEAR OPENAL_INCLUDE_DIR)
if( NOT WIN32 )
mark_as_advanced(CLEAR OPENAL_LIBRARY)
endif()
if( OPENAL_FOUND )
if( OPENAL_INCLUDE_DIR )
include_directories( ${OPENAL_INCLUDE_DIR} )
if( NOT WIN32 )
set( ZDOOM_LIBS ${OPENAL_LIBRARY} ${ZDOOM_LIBS} )
endif()
else()
if ( NOT WIN32 )
set( NO_OPENAL ON )
else()
include_directories( ${OPENAL_INCLUDE_DIR} )
endif()
endif()
endif()

View file

@ -572,31 +572,11 @@ struct FStrifeDialogueNode;
struct fixedvec3
{
fixed_t x, y, z;
operator FVector3()
{
return FVector3(FIXED2FLOAT(x), FIXED2FLOAT(y), FIXED2FLOAT(z));
}
operator TVector3<double>()
{
return TVector3<double>(FIXED2DBL(x), FIXED2DBL(y), FIXED2DBL(z));
}
};
struct fixedvec2
{
fixed_t x, y;
operator FVector2()
{
return FVector2(FIXED2FLOAT(x), FIXED2FLOAT(y));
}
operator TVector2<double>()
{
return TVector2<double>(FIXED2DBL(x), FIXED2DBL(y));
}
};
class DDropItem : public DObject

View file

@ -1715,7 +1715,7 @@ static void SetPointer(FState *state, PFunction *sym, int frame = 0)
{
if (sym == NULL)
{
state->SetAction(NULL);
state->ClearAction();
return;
}
else

View file

@ -98,7 +98,8 @@ enum
CLASSREG_PClassPlayerPawn,
CLASSREG_PClassType,
CLASSREG_PClassClass,
CLASSREG_PClassWeaponPiece
CLASSREG_PClassWeaponPiece,
CLASSREG_PClassPowerupGiver
};
struct ClassReg

View file

@ -2165,6 +2165,7 @@ PClass *ClassReg::RegisterClass()
&PClassType::RegistrationInfo,
&PClassClass::RegistrationInfo,
&PClassWeaponPiece::RegistrationInfo,
&PClassPowerupGiver::RegistrationInfo,
};
// Skip classes that have already been registered
@ -2413,7 +2414,7 @@ PClass *PClass::FindClassTentative(FName name, bool fatal)
return static_cast<PClass *>(found);
}
PClass *type = static_cast<PClass *>(GetClass()->CreateNew());
Printf("Creating placeholder class %s : %s\n", name.GetChars(), TypeName.GetChars());
DPrintf("Creating placeholder class %s : %s\n", name.GetChars(), TypeName.GetChars());
type->TypeName = name;
type->ParentClass = this;

View file

@ -12,25 +12,6 @@
DECLARE_ACTION(A_SkullAttack)
static PClassActor *GetSpawnType(VMValue *param)
{
PClassActor *spawntype;
if (param == NULL || param->Type == REGT_NIL)
{
spawntype = NULL;
}
else
{
assert(param->Type == REGT_POINTER);
assert(param->atag == ATAG_OBJECT || param->a == NULL);
spawntype = (PClassActor *)param->a;
}
return (spawntype != NULL) ? spawntype : PClass::FindActor("LostSoul");
}
enum PA_Flags
{
PAF_NOSKULLATTACK = 1,
@ -47,7 +28,8 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int
AActor *other;
int prestep;
if (spawntype == NULL) return;
if (spawntype == NULL) spawntype = PClass::FindActor("LostSoul");
assert(spawntype != NULL);
if (self->DamageType == NAME_Massacre) return;
// [RH] check to make sure it's not too close to the ceiling
@ -182,8 +164,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainAttack)
PARAM_INT_OPT (flags) { flags = 0; }
PARAM_INT_OPT (limit) { limit = -1; }
if (spawntype == NULL) spawntype = PClass::FindActor("LostSoul");
if (!(flags & PAF_AIMFACING))
A_FaceTarget (self);
A_PainShootSkull (self, self->angle+angle, spawntype, flags, limit);
@ -193,11 +173,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainAttack)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
if (!self->target)
return 0;
PClassActor *spawntype = GetSpawnType(numparam > NAP ? &param[NAP] : NULL);
A_FaceTarget (self);
A_PainShootSkull (self, self->angle + ANG45, spawntype);
A_PainShootSkull (self, self->angle - ANG45, spawntype);
@ -207,12 +187,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainDie)
{
PARAM_ACTION_PROLOGUE;
PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; }
if (self->target != NULL && self->IsFriend(self->target))
{ // And I thought you were my friend!
self->flags &= ~MF_FRIENDLY;
}
PClassActor *spawntype = GetSpawnType(numparam > NAP ? &param[NAP] : NULL);
A_Unblock(self, true);
A_PainShootSkull (self, self->angle + ANG90, spawntype);
A_PainShootSkull (self, self->angle + ANG180, spawntype);

View file

@ -662,7 +662,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact)
}
else
{ // Seek
self->angle = self->AngleTo(target);
angle = self->AngleTo(target);
newAngle = true;
}
}

View file

@ -336,7 +336,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
// [RH] Do some stuff to make this more useful outside Hexen
if (self->flags4 & MF4_BOSSDEATH)
{
CALL_ACTION(A_BossDeath, self);
A_BossDeath(self);
}
A_Unblock(self, true);

View file

@ -42,6 +42,18 @@ IMPLEMENT_CLASS (APowerup)
// Powerup-Giver -------------------------------------------------------------
IMPLEMENT_CLASS(PClassPowerupGiver)
void PClassPowerupGiver::ReplaceClassRef(PClass *oldclass, PClass *newclass)
{
Super::ReplaceClassRef(oldclass, newclass);
APowerupGiver *def = (APowerupGiver*)Defaults;
if (def != NULL)
{
if (def->PowerupType == oldclass) def->PowerupType = static_cast<PClassWeapon *>(newclass);
}
}
//===========================================================================
//
// APowerupGiver :: Use

View file

@ -36,14 +36,24 @@ protected:
friend void InitAllPowerupEffects(AInventory *item);
};
class PClassPowerupGiver: public PClassInventory
{
DECLARE_CLASS(PClassPowerupGiver, PClassInventory)
protected:
public:
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
};
// An artifact is an item that gives the player a powerup when activated.
class APowerupGiver : public AInventory
{
DECLARE_CLASS (APowerupGiver, AInventory)
DECLARE_CLASS_WITH_META (APowerupGiver, AInventory, PClassPowerupGiver)
public:
virtual bool Use (bool pickup);
virtual void Serialize (FArchive &arc);
PClassActor *PowerupType;
int EffectTics; // Non-0 to override the powerup's default tics
PalEntry BlendColor; // Non-0 to override the powerup's default blend

View file

@ -550,10 +550,7 @@ bool P_MorphedDeath(AActor *actor, AActor **morphed, int *morphedstyle, int *mor
if (realme->flags4 & MF4_BOSSDEATH)
{
realme->health = 0; // make sure that A_BossDeath considers it dead.
// FIXME: Use the caller's stack once the whole chain is scriptable.
VMFrameStack stack;
VMValue params[3] = { realme, realme, VMValue(NULL, ATAG_STATE) };
stack.Call(A_BossDeath_VMPtr, params, countof(params), NULL, 0, NULL);
A_BossDeath(realme);
}
}
fakeme->flags3 |= MF3_STAYMORPHED; // moved here from AMorphedMonster::Die()

View file

@ -1,5 +1,5 @@
// Ammo: Something a weapon needs to operate
//
class PClassWeaponPiece : public PClassInventory
{
DECLARE_CLASS(PClassWeaponPiece, PClassInventory)

View file

@ -163,6 +163,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_ProgrammerDeath)
}
}
// the sky change scripts are now done as special actions in MAPINFO
CALL_ACTION(A_BossDeath, self);
A_BossDeath(self);
return 0;
}

View file

@ -61,6 +61,11 @@ FRandom FState::pr_statetics("StateTics");
cycle_t ActionCycles;
void FState::SetAction(const char *name)
{
ActionFunc = FindGlobalActionFunction(name)->Variants[0].Implementation;
}
bool FState::CallAction(AActor *self, AActor *stateowner)
{
if (ActionFunc != NULL)

View file

@ -126,6 +126,8 @@ struct FState
Frame = frame - 'A';
}
void SetAction(VMFunction *func) { ActionFunc = func; }
void ClearAction() { ActionFunc = NULL; }
void SetAction(const char *name);
bool CallAction(AActor *self, AActor *stateowner);
static PClassActor *StaticFindStateOwner (const FState *state);
static PClassActor *StaticFindStateOwner (const FState *state, PClassActor *info);

View file

@ -620,7 +620,9 @@ bool AActor::SetState (FState *newstate, bool nofunction)
if (ObjectFlags & OF_StateChanged)
{ // The action was an A_Jump-style function that wants to change the next state.
ObjectFlags &= ~OF_StateChanged;
FState *saved = newstate;
newstate = state;
state = saved; // we need this for comparison of sprites.
tics = 0; // make sure we loop and set the new state properly
continue;
}

View file

@ -1,7 +1,11 @@
#ifndef OALDEF_H
#define OALDEF_H
#if defined _WIN32 && !defined NO_OPENAL
#ifndef NO_OPENAL
#ifndef _WIN32
typedef void* FARPROC;
#endif
#define DEFINE_ENTRY(type, name) static type p_##name;
#include "oaldef.h"

View file

@ -36,6 +36,8 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define USE_WINDOWS_DWORD
#else
#include <dlfcn.h>
#endif
#include "except.h"
@ -61,14 +63,23 @@ CVAR (Bool, snd_efx, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
#ifdef _WIN32
static HMODULE hmodOpenAL;
#define OPENALLIB "openal32.dll"
#else
static void* hmodOpenAL;
#ifdef __APPLE__
#define OPENALLIB "OpenAL.framework/OpenAL"
#else
#define OPENALLIB "libopenal.so"
#endif
#define LoadLibrary(x) dlopen((x), RTLD_LAZY)
#define GetProcAddress(a,b) dlsym((a),(b))
#define FreeLibrary(x) dlclose((x))
#endif
bool IsOpenALPresent()
{
#ifdef NO_OPENAL
return false;
#elif !defined _WIN32
return true;
#else
static bool cached_result = false;
static bool done = false;
@ -78,10 +89,10 @@ bool IsOpenALPresent()
done = true;
if (hmodOpenAL == NULL)
{
hmodOpenAL = LoadLibrary(NicePath("$PROGDIR/openal32.dll"));
hmodOpenAL = LoadLibrary(NicePath("$PROGDIR/" OPENALLIB));
if (hmodOpenAL == NULL)
{
hmodOpenAL = LoadLibrary("openal32.dll");
hmodOpenAL = LoadLibrary(OPENALLIB);
if (hmodOpenAL == NULL)
{
return false;
@ -90,7 +101,7 @@ bool IsOpenALPresent()
for(int i = 0; oalfuncs[i].name != NULL; i++)
{
*oalfuncs[i].funcaddr = GetProcAddress(hmodOpenAL, oalfuncs[i].name);
if (oalfuncs[i].funcaddr == NULL)
if (*oalfuncs[i].funcaddr == NULL)
{
FreeLibrary(hmodOpenAL);
hmodOpenAL = NULL;
@ -1332,13 +1343,13 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
FVector3 dir = pos - listener->position;
if(dir.DoesNotApproximatelyEqual(FVector3(0.f, 0.f, 0.f)))
{
float gain = GetRolloff(rolloff, sqrt(dist_sqr) * distscale);
float gain = GetRolloff(rolloff, sqrtf(dist_sqr) * distscale);
dir.Resize((gain > 0.00001f) ? 1.f/gain : 100000.f);
}
if((chanflags&SNDF_AREA) && dist_sqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
{
FVector3 amb(0.f, !(dir.Y>=0.f) ? -1.f : 1.f, 0.f);
float a = sqrt(dist_sqr) / AREA_SOUND_RADIUS;
float a = sqrtf(dist_sqr) / AREA_SOUND_RADIUS;
dir = amb + (dir-amb)*a;
}
dir += listener->position;
@ -1351,7 +1362,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
float mindist = rolloff->MinDistance/distscale;
FVector3 amb(0.f, !(dir.Y>=0.f) ? -mindist : mindist, 0.f);
float a = sqrt(dist_sqr) / AREA_SOUND_RADIUS;
float a = sqrtf(dist_sqr) / AREA_SOUND_RADIUS;
dir = amb + (dir-amb)*a;
dir += listener->position;
@ -1571,13 +1582,13 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh
{
if(dir.DoesNotApproximatelyEqual(FVector3(0.f, 0.f, 0.f)))
{
float gain = GetRolloff(&chan->Rolloff, sqrt(chan->DistanceSqr) * chan->DistanceScale);
float gain = GetRolloff(&chan->Rolloff, sqrtf(chan->DistanceSqr) * chan->DistanceScale);
dir.Resize((gain > 0.00001f) ? 1.f/gain : 100000.f);
}
if(areasound && chan->DistanceSqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
{
FVector3 amb(0.f, !(dir.Y>=0.f) ? -1.f : 1.f, 0.f);
float a = sqrt(chan->DistanceSqr) / AREA_SOUND_RADIUS;
float a = sqrtf(chan->DistanceSqr) / AREA_SOUND_RADIUS;
dir = amb + (dir-amb)*a;
}
}
@ -1585,7 +1596,7 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh
{
float mindist = chan->Rolloff.MinDistance / chan->DistanceScale;
FVector3 amb(0.f, !(dir.Y>=0.f) ? -mindist : mindist, 0.f);
float a = sqrt(chan->DistanceSqr) / AREA_SOUND_RADIUS;
float a = sqrtf(chan->DistanceSqr) / AREA_SOUND_RADIUS;
dir = amb + (dir-amb)*a;
}
dir += listener->position;
@ -1606,9 +1617,9 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
float angle = listener->angle;
ALfloat orient[6];
// forward
orient[0] = cos(angle);
orient[0] = cosf(angle);
orient[1] = 0.f;
orient[2] = -sin(angle);
orient[2] = -sinf(angle);
// up
orient[3] = 0.f;
orient[4] = 1.f;
@ -1747,7 +1758,7 @@ float OpenALSoundRenderer::GetAudibility(FISoundChannel *chan)
alGetSourcef(source, AL_GAIN, &volume);
getALError();
volume *= GetRolloff(&chan->Rolloff, sqrt(chan->DistanceSqr) * chan->DistanceScale);
volume *= GetRolloff(&chan->Rolloff, sqrtf(chan->DistanceSqr) * chan->DistanceScale);
return volume;
}

View file

@ -234,24 +234,24 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
{
if (extra.bExplosive)
{
type->OwnedStates[extra.DeathStart].SetAction(FindGlobalActionFunction("A_Explode")->Variants[0].Implementation);
type->OwnedStates[extra.DeathStart].SetAction("A_Explode");
}
}
else
{
// The first frame plays the death sound and
// the second frame makes it nonsolid.
type->OwnedStates[extra.DeathStart].SetAction(FindGlobalActionFunction("A_Scream")->Variants[0].Implementation);
type->OwnedStates[extra.DeathStart].SetAction("A_Scream");
if (extra.bSolidOnDeath)
{
}
else if (extra.DeathStart + 1 < extra.DeathEnd)
{
type->OwnedStates[extra.DeathStart+1].SetAction(FindGlobalActionFunction("A_NoBlocking")->Variants[0].Implementation);
type->OwnedStates[extra.DeathStart+1].SetAction("A_NoBlocking");
}
else
{
type->OwnedStates[extra.DeathStart].SetAction(FindGlobalActionFunction("A_ScreamAndUnblock")->Variants[0].Implementation);
type->OwnedStates[extra.DeathStart].SetAction("A_ScreamAndUnblock");
}
if (extra.DeathHeight == 0)
@ -283,17 +283,17 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
// The first frame plays the burn sound and
// the second frame makes it nonsolid.
type->OwnedStates[extra.FireDeathStart].SetAction(FindGlobalActionFunction("A_ActiveSound")->Variants[0].Implementation);
type->OwnedStates[extra.FireDeathStart].SetAction("A_ActiveSound");
if (extra.bSolidOnBurn)
{
}
else if (extra.FireDeathStart + 1 < extra.FireDeathEnd)
{
type->OwnedStates[extra.FireDeathStart+1].SetAction(FindGlobalActionFunction("A_NoBlocking")->Variants[0].Implementation);
type->OwnedStates[extra.FireDeathStart+1].SetAction("A_NoBlocking");
}
else
{
type->OwnedStates[extra.FireDeathStart].SetAction(FindGlobalActionFunction("A_ActiveAndUnblock")->Variants[0].Implementation);
type->OwnedStates[extra.FireDeathStart].SetAction("A_ActiveAndUnblock");
}
if (extra.BurnHeight == 0) extra.BurnHeight = ((AActor*)(type->Defaults))->height;
@ -314,14 +314,14 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
type->OwnedStates[i].Tics = 5;
type->OwnedStates[i].TicRange = 0;
type->OwnedStates[i].Misc1 = 0;
type->OwnedStates[i].SetAction(FindGlobalActionFunction("A_FreezeDeath")->Variants[0].Implementation);
type->OwnedStates[i].SetAction("A_FreezeDeath");
i = type->NumOwnedStates - 1;
type->OwnedStates[i].NextState = &type->OwnedStates[i];
type->OwnedStates[i].Tics = 1;
type->OwnedStates[i].TicRange = 0;
type->OwnedStates[i].Misc1 = 0;
type->OwnedStates[i].SetAction(FindGlobalActionFunction("A_FreezeDeathChunks")->Variants[0].Implementation);
type->OwnedStates[i].SetAction("A_FreezeDeathChunks");
bag.statedef.SetStateLabel("Ice", &type->OwnedStates[extra.IceDeathStart]);
}
else if (extra.bGenericIceDeath)

View file

@ -3310,7 +3310,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Burst)
// [RH] Do some stuff to make this more useful outside Hexen
if (self->flags4 & MF4_BOSSDEATH)
{
CALL_ACTION(A_BossDeath, self);
A_BossDeath(self);
}
A_Unblock(self, true);
@ -6485,6 +6485,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity)
if (mo == ref) //Don't count self.
continue;
// no unmorphed versions of currently morphed players.
if (mo->flags & MF_UNMORPHED)
continue;
//Check inheritance for the classname. Taken partly from CheckClass DECORATE function.
if (flags & CPXF_ANCESTOR)
{

View file

@ -195,6 +195,7 @@ protected:
{
isresolved = false;
ScriptPosition = pos;
ValueType = VAL_Unresolved;
}
public:
virtual ~FxExpression() {}

View file

@ -623,7 +623,7 @@ ExpEmit FxMinusSign::Emit(VMFunctionBuilder *build)
else
{
assert(ValueType == VAL_Float);
build->Emit(OP_NEG, from.RegNum, from.RegNum, 0);
build->Emit(OP_FLOP, from.RegNum, from.RegNum, FLOP_NEG);
}
return from;
}

View file

@ -87,20 +87,14 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool c
}
// Do automatic coercion between ints and floats.
if (type == TypeSInt32)
{
if (x->ValueType != VAL_Int)
{
x = new FxIntCast(x);
}
}
else
{
if (x->ValueType != VAL_Float)
{
x = new FxFloatCast(x);
}
}
}
else if (type == TypeName || type == TypeString)
{
sc.SetEscape(true);

View file

@ -8,6 +8,7 @@
enum ExpValType
{
VAL_Unresolved, // type not yet known
VAL_Int, // integer number
VAL_Float, // floating point number
VAL_Unknown, // nothing

View file

@ -231,7 +231,7 @@ ACTOR Actor native //: Thinker
action native A_JumpIfInTargetInventory(class<Inventory> itemtype, int amount, state label, int forward_ptr = AAPTR_DEFAULT);
action native A_GiveToTarget(class<Inventory> itemtype, int amount = 0, int forward_ptr = AAPTR_DEFAULT);
action native A_TakeFromTarget(class<Inventory> itemtype, int amount = 0, int flags = 0, int forward_ptr = AAPTR_DEFAULT);
action native A_RadiusGive(class<Inventory> itemtype, int distance, int flags, int amount = 0, class<Actor> filter = "None", name species = "None", int mindist = 0);
action native A_RadiusGive(class<Inventory> itemtype, float distance, int flags, int amount = 0, class<Actor> filter = "None", name species = "None", int mindist = 0);
action native A_CheckSpecies(state jump, name species = "", int ptr = AAPTR_DEFAULT);
action native A_CountdownArg(int argnum, state targstate = "");
action native A_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true);