From f33993dcb5f1406ceaaa8527d0cb59bda297de5c Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 9 Feb 2016 22:32:01 -0500 Subject: [PATCH 01/15] - Load OpenAL at runtime for all platforms because I can't think of a good reason not to handle them all the same right now. --- src/CMakeLists.txt | 14 ++------------ src/sound/oalload.h | 6 +++++- src/sound/oalsound.cpp | 21 ++++++++++++++++----- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5d20ddf7c..a8e43bcf3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -217,20 +217,10 @@ endif() 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() + set( NO_OPENAL ON ) endif() endif() diff --git a/src/sound/oalload.h b/src/sound/oalload.h index 7d4e62287..986131b2c 100644 --- a/src/sound/oalload.h +++ b/src/sound/oalload.h @@ -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" diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index a5ec97f97..6030c9142 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -36,6 +36,8 @@ #define WIN32_LEAN_AND_MEAN #include #define USE_WINDOWS_DWORD +#else +#include #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; From 65b70dedaa482264b04c1516493b377d40b91d06 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 9 Feb 2016 23:33:31 -0500 Subject: [PATCH 02/15] - Fixed: Heretic powered firemace balls didn't seek their target. --- src/g_heretic/a_hereticweaps.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 636b25a25..619fe7b5a 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -662,7 +662,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) } else { // Seek - self->angle = self->AngleTo(target); + angle = self->AngleTo(target); newAngle = true; } } From bc616dbf0680370dd43fe5a31d7626f44953ca73 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 10:04:52 +0100 Subject: [PATCH 03/15] - fixed: APowerupGiver::PowerupType also needs replacement handling for placeholder classes. --- src/dobject.h | 3 ++- src/dobjtype.cpp | 1 + src/g_shared/a_artifacts.cpp | 12 ++++++++++++ src/g_shared/a_artifacts.h | 12 +++++++++++- src/g_shared/a_weaponpiece.h | 2 +- 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/dobject.h b/src/dobject.h index f478cfc08..254891eb5 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -98,7 +98,8 @@ enum CLASSREG_PClassPlayerPawn, CLASSREG_PClassType, CLASSREG_PClassClass, - CLASSREG_PClassWeaponPiece + CLASSREG_PClassWeaponPiece, + CLASSREG_PClassPowerupGiver }; struct ClassReg diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 1762079fb..b5d758bfc 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -2165,6 +2165,7 @@ PClass *ClassReg::RegisterClass() &PClassType::RegistrationInfo, &PClassClass::RegistrationInfo, &PClassWeaponPiece::RegistrationInfo, + &PClassPowerupGiver::RegistrationInfo, }; // Skip classes that have already been registered diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 58aee16fb..992e97cef 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -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(newclass); + } +} + //=========================================================================== // // APowerupGiver :: Use diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 5881fc52f..a99cf64c5 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -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 diff --git a/src/g_shared/a_weaponpiece.h b/src/g_shared/a_weaponpiece.h index dfa30f5d7..4fa2118cd 100644 --- a/src/g_shared/a_weaponpiece.h +++ b/src/g_shared/a_weaponpiece.h @@ -1,5 +1,5 @@ -// Ammo: Something a weapon needs to operate +// class PClassWeaponPiece : public PClassInventory { DECLARE_CLASS(PClassWeaponPiece, PClassInventory) From dde93362351c08b9eb5f294e366e50b344a3e861 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 11:29:32 +0100 Subject: [PATCH 04/15] - silence floating point conversion warnings in oalsound.cpp --- src/sound/oalsound.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index 6030c9142..1eec34c1b 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -1343,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; @@ -1362,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; @@ -1582,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; } } @@ -1596,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; @@ -1617,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; @@ -1758,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; } From 3e5d1feecdac5ce1818064e66ade1ed955fd61a6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 11:58:54 +0100 Subject: [PATCH 05/15] - fixed: A_CheckProximity could return unmorphed player pawns of currently morphed players. --- src/thingdef/thingdef_codeptr.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index ebc5c0b97..63c7adad7 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -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) { From e2de258498d15a4bc98038dcfc5b61e69ef0b78b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 12:09:14 +0100 Subject: [PATCH 06/15] - remove debug output. --- src/dobjtype.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index b5d758bfc..2c45f483c 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -2414,7 +2414,7 @@ PClass *PClass::FindClassTentative(FName name, bool fatal) return static_cast(found); } PClass *type = static_cast(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; From dd55e0a4c41e2db2fd1ed5d8e12b05204c9f6b60 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 13:34:16 +0100 Subject: [PATCH 07/15] - cleaned up a_painelemental.cpp. No need to expose VM stuff this openly here. --- src/g_doom/a_painelemental.cpp | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/src/g_doom/a_painelemental.cpp b/src/g_doom/a_painelemental.cpp index f96e1cda0..6c02c6517 100644 --- a/src/g_doom/a_painelemental.cpp +++ b/src/g_doom/a_painelemental.cpp @@ -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 ? ¶m[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 ? ¶m[NAP] : NULL); A_Unblock(self, true); A_PainShootSkull (self, self->angle + ANG90, spawntype); A_PainShootSkull (self, self->angle + ANG180, spawntype); From b5029e0976135551032d78ecebbc1b42314aedd8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 13:57:21 +0100 Subject: [PATCH 08/15] - call the native A_BossDeath directly instead of going through the VM-enabled action function. - undo some formatting screwup in a_clericstaff.cpp. --- src/g_hexen/a_clericstaff.cpp | 56 +++++++++++++++---------------- src/g_shared/a_action.cpp | 2 +- src/g_shared/a_morph.cpp | 5 +-- src/g_strife/a_programmer.cpp | 2 +- src/thingdef/thingdef_codeptr.cpp | 2 +- 5 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp index a5a5fdfec..964a78503 100644 --- a/src/g_hexen/a_clericstaff.cpp +++ b/src/g_hexen/a_clericstaff.cpp @@ -65,59 +65,59 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) AWeapon *weapon = self->player->ReadyWeapon; pmo = player->mo; - damage = 20+(pr_staffcheck()&15); + damage = 20 + (pr_staffcheck() & 15); max = pmo->GetMaxHealth(); puff = PClass::FindActor("CStaffPuff"); for (i = 0; i < 3; i++) { - angle = pmo->angle+i*(ANG45/16); - slope = P_AimLineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D); + angle = pmo->angle + i*(ANG45 / 16); + slope = P_AimLineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D); if (linetarget) { - P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &linetarget); + P_LineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &linetarget); if (linetarget != NULL) { pmo->angle = pmo->AngleTo(linetarget); - if (((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0))|| linetarget->flags3&MF3_ISMONSTER) - && (!(linetarget->flags2&(MF2_DORMANT|MF2_INVULNERABLE)))) - { - newLife = player->health+(damage>>3); - newLife = newLife > max ? max : newLife; - if (newLife > player->health) + if (((linetarget->player && (!linetarget->IsTeammate(pmo) || level.teamdamage != 0)) || linetarget->flags3&MF3_ISMONSTER) + && (!(linetarget->flags2&(MF2_DORMANT | MF2_INVULNERABLE)))) { - pmo->health = player->health = newLife; - } + newLife = player->health + (damage >> 3); + newLife = newLife > max ? max : newLife; + if (newLife > player->health) + { + pmo->health = player->health = newLife; + } if (weapon != NULL) { FState * newstate = weapon->FindState("Drain"); if (newstate != NULL) P_SetPsprite(player, ps_weapon, newstate); - } + } + } + if (weapon != NULL) + { + weapon->DepleteAmmo(weapon->bAltFire, false); } - if (weapon != NULL) - { - weapon->DepleteAmmo (weapon->bAltFire, false); - } } break; } - angle = pmo->angle-i*(ANG45/16); - slope = P_AimLineAttack (player->mo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D); + angle = pmo->angle - i*(ANG45 / 16); + slope = P_AimLineAttack(player->mo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D); if (linetarget) { - P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &linetarget); + P_LineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &linetarget); if (linetarget != NULL) { pmo->angle = pmo->AngleTo(linetarget); - if ((linetarget->player && (!linetarget->IsTeammate (pmo) || level.teamdamage != 0)) || linetarget->flags3&MF3_ISMONSTER) - { - newLife = player->health+(damage>>4); - newLife = newLife > max ? max : newLife; - pmo->health = player->health = newLife; - P_SetPsprite (player, ps_weapon, weapon->FindState ("Drain")); - } + if ((linetarget->player && (!linetarget->IsTeammate(pmo) || level.teamdamage != 0)) || linetarget->flags3&MF3_ISMONSTER) + { + newLife = player->health + (damage >> 4); + newLife = newLife > max ? max : newLife; + pmo->health = player->health = newLife; + P_SetPsprite(player, ps_weapon, weapon->FindState("Drain")); + } if (weapon != NULL) { - weapon->DepleteAmmo (weapon->bAltFire, false); + weapon->DepleteAmmo(weapon->bAltFire, false); } } break; diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp index 53acad047..e3d6b7926 100644 --- a/src/g_shared/a_action.cpp +++ b/src/g_shared/a_action.cpp @@ -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); diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 8ec40736a..2aa52ae4f 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -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() diff --git a/src/g_strife/a_programmer.cpp b/src/g_strife/a_programmer.cpp index a0aa24e24..334d12522 100644 --- a/src/g_strife/a_programmer.cpp +++ b/src/g_strife/a_programmer.cpp @@ -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; } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 63c7adad7..a3f7c0887 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -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); From d1b2ef53686d18c6e1a9427df49e194e60dbc806 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 14:38:08 +0100 Subject: [PATCH 09/15] - some refactoring of olddecorations.cpp to move some repeated code into a subfunction. --- src/d_dehacked.cpp | 2 +- src/info.cpp | 5 +++++ src/info.h | 2 ++ src/thingdef/olddecorations.cpp | 18 +++++++++--------- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 82d26d7ab..cceb7c20e 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1715,7 +1715,7 @@ static void SetPointer(FState *state, PFunction *sym, int frame = 0) { if (sym == NULL) { - state->SetAction(NULL); + state->ClearAction(); return; } else diff --git a/src/info.cpp b/src/info.cpp index 3a800e2cf..d827cd7a0 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -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) diff --git a/src/info.h b/src/info.h index 460adb0fb..5d9d36879 100644 --- a/src/info.h +++ b/src/info.h @@ -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); diff --git a/src/thingdef/olddecorations.cpp b/src/thingdef/olddecorations.cpp index fa543e372..b04c589ee 100644 --- a/src/thingdef/olddecorations.cpp +++ b/src/thingdef/olddecorations.cpp @@ -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) From a7254a4af512dd1d2ece095a9e6e40a5a821560c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 14:43:04 +0100 Subject: [PATCH 10/15] - removed the conversion operators from the fixedvec structs (again) They must have been accidentally left in by not properly resolving a merge conflict, I guess. --- src/actor.h | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/actor.h b/src/actor.h index 30e67fa30..7cfee5500 100644 --- a/src/actor.h +++ b/src/actor.h @@ -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() - { - return TVector3(FIXED2DBL(x), FIXED2DBL(y), FIXED2DBL(z)); - } }; struct fixedvec2 { fixed_t x, y; - - operator FVector2() - { - return FVector2(FIXED2FLOAT(x), FIXED2FLOAT(y)); - } - - operator TVector2() - { - return TVector2(FIXED2DBL(x), FIXED2DBL(y)); - } }; class DDropItem : public DObject From 85a3cd984d2a6cc1b793a44a17551a3e934092cc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 17:06:33 +0100 Subject: [PATCH 11/15] - fixed: ParseParameter should not make any assumptions about the necessity of a type cast between int and float. With late resolving it cannot be guaranteed at this point and caused some incorrectly compiled code. Since the cast gets optimized away anyway when not needed there's no point being this selective with applying it. --- src/p_interaction.cpp | 76 ++++++++++++++++----------------- src/thingdef/thingdef_parse.cpp | 10 +---- 2 files changed, 40 insertions(+), 46 deletions(-) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index eb3c6d354..dba66ca9b 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1043,58 +1043,58 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, if ((rawdamage < TELEFRAG_DAMAGE) || (target->flags7 & MF7_LAXTELEFRAGDMG)) // TELEFRAG_DAMAGE may only be reduced with LAXTELEFRAGDMG or it may not guarantee its effect. { if (player && damage > 1) - { - // Take half damage in trainer mode - damage = FixedMul(damage, G_SkillProperty(SKILLP_DamageFactor)); - } - // Special damage types - if (inflictor) - { - if (inflictor->flags4 & MF4_SPECTRAL) { - if (player != NULL) - { - if (!deathmatch && inflictor->FriendPlayer > 0) - return -1; - } - else if (target->flags4 & MF4_SPECTRAL) - { - if (inflictor->FriendPlayer == 0 && !target->IsHostile(inflictor)) - return -1; - } + // Take half damage in trainer mode + damage = FixedMul(damage, G_SkillProperty(SKILLP_DamageFactor)); } + // Special damage types + if (inflictor) + { + if (inflictor->flags4 & MF4_SPECTRAL) + { + if (player != NULL) + { + if (!deathmatch && inflictor->FriendPlayer > 0) + return -1; + } + else if (target->flags4 & MF4_SPECTRAL) + { + if (inflictor->FriendPlayer == 0 && !target->IsHostile(inflictor)) + return -1; + } + } damage = inflictor->DoSpecialDamage(target, damage, mod); if (damage < 0) - { - return -1; + { + return -1; + } } - } int olddam = damage; if (damage > 0 && source != NULL) { - damage = FixedMul(damage, source->DamageMultiply); + damage = FixedMul(damage, source->DamageMultiply); // Handle active damage modifiers (e.g. PowerDamage) if (damage > 0 && source->Inventory != NULL) { source->Inventory->ModifyDamage(damage, mod, damage, false); + } } - } - // Handle passive damage modifiers (e.g. PowerProtection), provided they are not afflicted with protection penetrating powers. + // Handle passive damage modifiers (e.g. PowerProtection), provided they are not afflicted with protection penetrating powers. if (damage > 0 && (target->Inventory != NULL) && !(flags & DMG_NO_PROTECT)) - { + { target->Inventory->ModifyDamage(damage, mod, damage, true); } if (damage > 0 && !(flags & DMG_NO_FACTOR)) - { - damage = FixedMul(damage, target->DamageFactor); - if (damage > 0) { - damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, mod, target->GetClass()->DamageFactors); - } + damage = FixedMul(damage, target->DamageFactor); + if (damage > 0) + { + damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, mod, target->GetClass()->DamageFactors); + } } if (damage >= 0) @@ -1105,23 +1105,23 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, // '<0' is handled below. This only handles the case where damage gets reduced to 0. if (damage == 0 && olddam > 0) { - { // Still allow FORCEPAIN - if (forcedPain) + { // Still allow FORCEPAIN + if (forcedPain) { - goto dopain; + goto dopain; } - else if (fakedPain) + else if (fakedPain) { - goto fakepain; + goto fakepain; } - return -1; + return -1; + } } } - } if (target->flags5 & MF5_NODAMAGE) { damage = 0; - } + } } if (damage < 0) { diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index cf76fb10b..2cd271ad5 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -88,17 +88,11 @@ 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); - } + x = new FxIntCast(x); } else { - if (x->ValueType != VAL_Float) - { - x = new FxFloatCast(x); - } + x = new FxFloatCast(x); } } else if (type == TypeName || type == TypeString) From d18a8398368ed759f7e17529f0952edc4c3a0106 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 17:11:50 +0100 Subject: [PATCH 12/15] - to prevent further occurences of ValueType == 0 being misinterpreted, change it to signify unknown value type and ensure that any real type is non-zero. --- src/thingdef/thingdef_exp.h | 1 + src/thingdef/thingdef_type.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/thingdef/thingdef_exp.h b/src/thingdef/thingdef_exp.h index f81dd2b54..8901e35c3 100644 --- a/src/thingdef/thingdef_exp.h +++ b/src/thingdef/thingdef_exp.h @@ -195,6 +195,7 @@ protected: { isresolved = false; ScriptPosition = pos; + ValueType = VAL_Unresolved; } public: virtual ~FxExpression() {} diff --git a/src/thingdef/thingdef_type.h b/src/thingdef/thingdef_type.h index 706b2ba7a..1707a8939 100644 --- a/src/thingdef/thingdef_type.h +++ b/src/thingdef/thingdef_type.h @@ -8,6 +8,7 @@ enum ExpValType { + VAL_Unresolved, // type not yet known VAL_Int, // integer number VAL_Float, // floating point number VAL_Unknown, // nothing From 1c0cd16d3f4115aca02e679d6c069d08ae2b5fc6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 18:13:20 +0100 Subject: [PATCH 13/15] - fixed: AActor::SetState must restore the 'state' member to the actual calling state after it detected OF_StateChanged. This is needed to decide how the '####' and '----' placeholders should behave. --- src/p_mobj.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index eba7f86fd..dde1c80b8 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -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; } From 91f0a8791cb44a1ce7b67faec6188ac29782cde9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 19:30:17 +0100 Subject: [PATCH 14/15] - fixed type mismatch in A_RadiusGive declaration. --- wadsrc/static/actors/actor.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 8a79dd170..c25c1492b 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -231,7 +231,7 @@ ACTOR Actor native //: Thinker action native A_JumpIfInTargetInventory(class itemtype, int amount, state label, int forward_ptr = AAPTR_DEFAULT); action native A_GiveToTarget(class itemtype, int amount = 0, int forward_ptr = AAPTR_DEFAULT); action native A_TakeFromTarget(class itemtype, int amount = 0, int flags = 0, int forward_ptr = AAPTR_DEFAULT); - action native A_RadiusGive(class itemtype, int distance, int flags, int amount = 0, class filter = "None", name species = "None", int mindist = 0); + action native A_RadiusGive(class itemtype, float distance, int flags, int amount = 0, class 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); From 4428d073d50547a9cf422fe9c37ae975e398b6aa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 10 Feb 2016 20:08:19 +0100 Subject: [PATCH 15/15] - fixed: code generation for floating point negation was wrong. --- src/thingdef/thingdef_expression.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index 8b2c52405..987a9806e 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -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; }