From 57150c8718612e8215df61ebeaff39d6d37c6481 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 1 Aug 2015 11:56:44 +0200 Subject: [PATCH 01/61] - fixed incorrect Strife player death sound. --- wadsrc/static/filter/game-strife/sndinfo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/filter/game-strife/sndinfo.txt b/wadsrc/static/filter/game-strife/sndinfo.txt index 22f9b8356..f602a969b 100644 --- a/wadsrc/static/filter/game-strife/sndinfo.txt +++ b/wadsrc/static/filter/game-strife/sndinfo.txt @@ -8,7 +8,7 @@ $rolloff * 200 1200 $playersound player male *death dspldeth -$playersound player male *xdeath dspdiehi +$playersound player male *xdeath dsplxdth $playersound player male *gibbed dsslop $playersound player male *pain100 dsplpain $playersounddup player male *pain75 *pain100 From 58870d48718a23952ec4aa7be020c86589549f66 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 1 Aug 2015 23:17:06 +0200 Subject: [PATCH 02/61] - fixed: SingleActorFromTid wasn't declared in thingdef_codeptr.cpp --- src/p_acs.cpp | 2 +- src/thingdef/thingdef_codeptr.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 750b8f09d..83a087d8f 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3595,7 +3595,7 @@ int DoGetMasterTID (AActor *self) else return 0; } -static AActor *SingleActorFromTID (int tid, AActor *defactor) +AActor *SingleActorFromTID (int tid, AActor *defactor) { if (tid == 0) { diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index e47f4148f..2ba5fa01a 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -73,6 +73,7 @@ #include "p_setup.h" #include "gstrings.h" +AActor *SingleActorFromTID (int tid, AActor *defactor); static FRandom pr_camissile ("CustomActorfire"); static FRandom pr_camelee ("CustomMelee"); From 3efbf6c74e551551dd28b7430a5e60a2048c661c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 9 Aug 2015 09:03:12 +0200 Subject: [PATCH 03/61] - fixed: am_restorecolors did not work This CCMD tried to access the current menu to decide which colors to reset but that is not available at all when this function gets called. It now uses the automap's own CVAR arrays. --- src/am_map.cpp | 14 ++++++++++++++ src/menu/optionmenuitems.h | 15 --------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index fdbacd34f..045d48589 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -360,6 +360,20 @@ static FColorCVar *cv_overlay[] = { &am_ovsecretsectorcolor }; +CCMD(am_restorecolors) +{ + for (unsigned i = 0; i < countof(cv_standard); i++) + { + cv_standard[i]->ResetToDefault(); + } + for (unsigned i = 0; i < countof(cv_overlay); i++) + { + cv_overlay[i]->ResetToDefault(); + } +} + + + #define NOT_USED 1,0,0 // use almost black as indicator for an unused color static unsigned char DoomColors[]= { diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index 5bc015369..e87e78483 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -1145,18 +1145,3 @@ private: float mMaximum; float mStep; }; -#ifndef NO_IMP -CCMD(am_restorecolors) -{ - if (DMenu::CurrentMenu != NULL && DMenu::CurrentMenu->IsKindOf(RUNTIME_CLASS(DOptionMenu))) - { - DOptionMenu *m = (DOptionMenu*)DMenu::CurrentMenu; - const FOptionMenuDescriptor *desc = m->GetDescriptor(); - // Find the color cvars by scanning the MapColors menu. - for (unsigned i = 0; i < desc->mItems.Size(); ++i) - { - desc->mItems[i]->SetValue(FOptionMenuItemColorPicker::CPF_RESET, 0); - } - } -} -#endif From fcf1d56b1a239700920cd90f3bd431beed03583b Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sun, 9 Aug 2015 14:06:22 -0500 Subject: [PATCH 04/61] - Added SXF_IS. - The spawned actor becomes the calling actor's specified pointers respectively. --- src/thingdef/thingdef_codeptr.cpp | 15 +++++++++++++++ wadsrc/static/actors/constants.txt | 3 +++ 2 files changed, 18 insertions(+) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 2ba5fa01a..69dd89cd0 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1857,6 +1857,9 @@ enum SIX_Flags SIXF_ORIGINATOR = 0x00800000, SIXF_TRANSFERSPRITEFRAME = 0x01000000, SIXF_TRANSFERROLL = 0x02000000, + SIXF_ISTARGET = 0x04000000, + SIXF_ISMASTER = 0x08000000, + SIXF_ISTRACER = 0x10000000, }; static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) @@ -2014,6 +2017,18 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) mo->roll = self->roll; } + if (flags & SIXF_ISTARGET) + { + self->target = mo; + } + if (flags & SIXF_ISMASTER) + { + self->master = mo; + } + if (flags & SIXF_ISTRACER) + { + self->tracer = mo; + } return true; } diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 1ee6c96c9..96877a266 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -74,6 +74,9 @@ const int SXF_NOPOINTERS = 1 << 22; const int SXF_ORIGINATOR = 1 << 23; const int SXF_TRANSFERSPRITEFRAME = 1 << 24; const int SXF_TRANSFERROLL = 1 << 25; +const int SXF_ISTARGET = 1 << 26, +const int SXF_ISMASTER = 1 << 27, +const int SXF_ISTRACER = 1 << 28, // Flags for A_Chase const int CHF_FASTCHASE = 1; From e7aa5c690a4c5c653c363e8a2a6891f953b599f3 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 10 Aug 2015 06:48:24 -0500 Subject: [PATCH 05/61] Minor oversight... --- wadsrc/static/actors/constants.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 96877a266..04ed6f1fc 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -74,9 +74,9 @@ const int SXF_NOPOINTERS = 1 << 22; const int SXF_ORIGINATOR = 1 << 23; const int SXF_TRANSFERSPRITEFRAME = 1 << 24; const int SXF_TRANSFERROLL = 1 << 25; -const int SXF_ISTARGET = 1 << 26, -const int SXF_ISMASTER = 1 << 27, -const int SXF_ISTRACER = 1 << 28, +const int SXF_ISTARGET = 1 << 26; +const int SXF_ISMASTER = 1 << 27; +const int SXF_ISTRACER = 1 << 28; // Flags for A_Chase const int CHF_FASTCHASE = 1; From ad14caa80026a1713377c050d77b1e7ef08dd2d7 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 10 Aug 2015 11:19:54 -0500 Subject: [PATCH 06/61] - Added A_Warp heightoffset property. Only has an effect by two flags. - WARPF_ADDHEIGHT adds the pointed actor's height to heightoffset, and adds to the pointed actor's z position. - WARPF_MULHEIGHT multiplies the pointed actor's height by heightoffset, and adds to the pointed actor's z position. Overridden by ADDHEIGHT. --- src/p_acs.cpp | 3 ++- src/p_local.h | 4 +++- src/p_things.cpp | 18 ++++++++++++------ src/thingdef/thingdef_codeptr.cpp | 5 +++-- wadsrc/static/actors/actor.txt | 2 +- wadsrc/static/actors/constants.txt | 2 ++ 6 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 83a087d8f..b703b87dd 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5862,6 +5862,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) int flags = args[5]; const char *statename = argCount > 6 ? FBehavior::StaticLookupString(args[6]) : ""; bool exact = argCount > 7 ? !!args[7] : false; + fixed_t heightoffset = argCount > 8 ? args[8] : 0; FState *state = argCount > 6 ? activator->GetClass()->ActorInfo->FindStateByString(statename, exact) : 0; @@ -5879,7 +5880,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) if (!reference) return false; - if (P_Thing_Warp(activator, reference, xofs, yofs, zofs, angle, flags)) + if (P_Thing_Warp(activator, reference, xofs, yofs, zofs, angle, flags, heightoffset)) { if (state && argCount > 6) { diff --git a/src/p_local.h b/src/p_local.h index 0b1c9c7a8..6022d8e8e 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -176,7 +176,7 @@ bool P_Thing_Raise(AActor *thing, AActor *raiser); bool P_Thing_CanRaise(AActor *thing); const PClass *P_GetSpawnableType(int spawnnum); void InitSpawnablesFromMapinfo(); -int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags); +int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags, fixed_t heightoffset); enum WARPF { @@ -198,6 +198,8 @@ enum WARPF WARPF_MOVEPTR = 0x1000, WARPF_USEPTR = 0x2000, WARPF_USETID = 0x2000, + WARPF_ADDHEIGHT = 0x4000, + WARPF_MULHEIGHT = 0x8000, }; diff --git a/src/p_things.cpp b/src/p_things.cpp index 799e72893..db80e35ca 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -680,7 +680,7 @@ void InitSpawnablesFromMapinfo() } -int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags) +int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags, fixed_t heightoffset) { if (flags & WARPF_MOVEPTR) { @@ -692,6 +692,12 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t oldx = caller->x; fixed_t oldy = caller->y; fixed_t oldz = caller->z; + fixed_t height = 0; + + if (flags & WARPF_ADDHEIGHT) + height = reference->height + heightoffset; + else if (flags & WARPF_MULHEIGHT) + height = FixedMul(reference->height, heightoffset); if (!(flags & WARPF_ABSOLUTEANGLE)) { @@ -719,7 +725,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, caller->SetOrigin( reference->x + xofs, reference->y + yofs, - reference->z); + reference->z + height); // now the caller's floorz should be appropriate for the assigned xy-position // assigning position again with @@ -730,7 +736,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, caller->SetOrigin( caller->x, caller->y, - caller->floorz + zofs); + caller->floorz + zofs + height); } else { @@ -745,18 +751,18 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, caller->SetOrigin( reference->x + xofs, reference->y + yofs, - reference->z + zofs); + reference->z + zofs + height); } } else // [MC] The idea behind "absolute" is meant to be "absolute". Override everything, just like A_SpawnItemEx's. { if (flags & WARPF_TOFLOOR) { - caller->SetOrigin(xofs, yofs, caller->floorz + zofs); + caller->SetOrigin(xofs, yofs, caller->floorz + zofs + height); } else { - caller->SetOrigin(xofs, yofs, zofs); + caller->SetOrigin(xofs, yofs, zofs + height); } } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 69dd89cd0..5f863e746 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4671,7 +4671,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) { - ACTION_PARAM_START(7); + ACTION_PARAM_START(8); ACTION_PARAM_INT(destination_selector, 0); ACTION_PARAM_FIXED(xofs, 1); @@ -4680,6 +4680,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) ACTION_PARAM_ANGLE(angle, 4); ACTION_PARAM_INT(flags, 5); ACTION_PARAM_STATE(success_state, 6); + ACTION_PARAM_FIXED(heightoffset,7) AActor *reference; @@ -4699,7 +4700,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) return; } - if (P_Thing_Warp(self, reference, xofs, yofs, zofs, angle, flags)) + if (P_Thing_Warp(self, reference, xofs, yofs, zofs, angle, flags, heightoffset)) { if (success_state) { diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 6885ad2d6..00476b502 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -249,7 +249,7 @@ ACTOR Actor native //: Thinker action native A_PlayerSkinCheck(state label); action native A_BasicAttack(int meleedamage, sound meleesound, class missiletype, float missileheight); action native A_Teleport(state teleportstate = "", class targettype = "BossSpot", class fogtype = "TeleportFog", int flags = 0, float mindist = 0, float maxdist = 0, int ptr = AAPTR_DEFAULT); - action native A_Warp(int ptr_destination, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0, int flags = 0, state success_state = ""); + action native A_Warp(int ptr_destination, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0, int flags = 0, state success_state = "", float heightoffset = 0); action native A_ThrowGrenade(class itemtype, float zheight = 0, float xyvel = 0, float zvel = 0, bool useammo = true); action native A_Weave(int xspeed, int yspeed, float xdist, float ydist); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 04ed6f1fc..a0c6f1f98 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -361,6 +361,8 @@ Const Int WARPF_ABSOLUTEPOSITION = 0x400; Const Int WARPF_BOB = 0x800; Const Int WARPF_MOVEPTR = 0x1000; Const Int WARPF_USETID = 0x2000; +Const Int WARPF_ADDHEIGHT = 0x4000; +Const Int WARPF_MULHEIGHT = 0x8000; // flags for A_SetPitch/SetAngle/SetRoll const int SPF_FORCECLAMP = 1; From 9cf8a2a26ca137196874763965dedb9a19584ea4 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 10 Aug 2015 12:20:42 -0500 Subject: [PATCH 07/61] - Missed a spot. --- src/p_things.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_things.cpp b/src/p_things.cpp index db80e35ca..6c8349a72 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -743,7 +743,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, // if there is no offset, there should be no ill effect from moving down to the already defined floor // A_Teleport does the same thing anyway - caller->z = caller->floorz; + caller->z = caller->floorz + height; } } else From 7e661dfe573c6101f7b0d215f12f5cd6d64f5c43 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 10 Aug 2015 12:41:40 -0500 Subject: [PATCH 08/61] - Clean up. --- src/p_things.cpp | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/src/p_things.cpp b/src/p_things.cpp index 6c8349a72..1467935d7 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -692,12 +692,16 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t oldx = caller->x; fixed_t oldy = caller->y; fixed_t oldz = caller->z; - fixed_t height = 0; + if (flags & WARPF_ADDHEIGHT) - height = reference->height + heightoffset; + { + zofs += reference->height + heightoffset; + } else if (flags & WARPF_MULHEIGHT) - height = FixedMul(reference->height, heightoffset); + { + zofs += FixedMul(reference->height, heightoffset); + } if (!(flags & WARPF_ABSOLUTEANGLE)) { @@ -725,44 +729,33 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, caller->SetOrigin( reference->x + xofs, reference->y + yofs, - reference->z + height); + reference->z); // now the caller's floorz should be appropriate for the assigned xy-position - // assigning position again with - - if (zofs) - { - // extra unlink, link and environment calculation - caller->SetOrigin( - caller->x, - caller->y, - caller->floorz + zofs + height); - } - else - { - // if there is no offset, there should be no ill effect from moving down to the already defined floor - - // A_Teleport does the same thing anyway - caller->z = caller->floorz + height; - } + // assigning position again with. + // extra unlink, link and environment calculation + caller->SetOrigin( + caller->x, + caller->y, + caller->floorz + zofs); } else { caller->SetOrigin( reference->x + xofs, reference->y + yofs, - reference->z + zofs + height); + reference->z + zofs); } } else // [MC] The idea behind "absolute" is meant to be "absolute". Override everything, just like A_SpawnItemEx's. { if (flags & WARPF_TOFLOOR) { - caller->SetOrigin(xofs, yofs, caller->floorz + zofs + height); + caller->SetOrigin(xofs, yofs, caller->floorz + zofs); } else { - caller->SetOrigin(xofs, yofs, zofs + height); + caller->SetOrigin(xofs, yofs, zofs); } } From 54af1e379edcc6a2f58034c06d0e406710adb570 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 10 Aug 2015 15:03:29 -0500 Subject: [PATCH 09/61] - Removed WARPF_MULHEIGHT. Enable its ability by default. - WARPF_ADDHEIGHT will simply change HeightOffset from multiplying to adding by default. --- src/p_local.h | 1 - src/p_things.cpp | 2 +- wadsrc/static/actors/constants.txt | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 6022d8e8e..a457cd877 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -199,7 +199,6 @@ enum WARPF WARPF_USEPTR = 0x2000, WARPF_USETID = 0x2000, WARPF_ADDHEIGHT = 0x4000, - WARPF_MULHEIGHT = 0x8000, }; diff --git a/src/p_things.cpp b/src/p_things.cpp index 1467935d7..678608dc6 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -698,7 +698,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, { zofs += reference->height + heightoffset; } - else if (flags & WARPF_MULHEIGHT) + else { zofs += FixedMul(reference->height, heightoffset); } diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index a0c6f1f98..b7baca73a 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -362,7 +362,6 @@ Const Int WARPF_BOB = 0x800; Const Int WARPF_MOVEPTR = 0x1000; Const Int WARPF_USETID = 0x2000; Const Int WARPF_ADDHEIGHT = 0x4000; -Const Int WARPF_MULHEIGHT = 0x8000; // flags for A_SetPitch/SetAngle/SetRoll const int SPF_FORCECLAMP = 1; From 87cc3f77f9c7eccd247448c131b57ad9871bab4f Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 10 Aug 2015 16:05:44 -0500 Subject: [PATCH 10/61] - Removed WARPF_ADDHEIGHT. --- src/p_local.h | 1 - src/p_things.cpp | 9 +-------- wadsrc/static/actors/constants.txt | 1 - 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index a457cd877..a2fa00c71 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -198,7 +198,6 @@ enum WARPF WARPF_MOVEPTR = 0x1000, WARPF_USEPTR = 0x2000, WARPF_USETID = 0x2000, - WARPF_ADDHEIGHT = 0x4000, }; diff --git a/src/p_things.cpp b/src/p_things.cpp index 678608dc6..f9d85c43f 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -693,15 +693,8 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t oldy = caller->y; fixed_t oldz = caller->z; + zofs += FixedMul(reference->height, heightoffset); - if (flags & WARPF_ADDHEIGHT) - { - zofs += reference->height + heightoffset; - } - else - { - zofs += FixedMul(reference->height, heightoffset); - } if (!(flags & WARPF_ABSOLUTEANGLE)) { diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index b7baca73a..04ed6f1fc 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -361,7 +361,6 @@ Const Int WARPF_ABSOLUTEPOSITION = 0x400; Const Int WARPF_BOB = 0x800; Const Int WARPF_MOVEPTR = 0x1000; Const Int WARPF_USETID = 0x2000; -Const Int WARPF_ADDHEIGHT = 0x4000; // flags for A_SetPitch/SetAngle/SetRoll const int SPF_FORCECLAMP = 1; From cac600733f8383c521e78555e79d25c2042de20e Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 10 Aug 2015 20:45:18 -0500 Subject: [PATCH 11/61] - Added Remove console command. --- src/d_net.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++ src/d_protocol.h | 1 + src/p_interaction.cpp | 19 +++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/src/d_net.cpp b/src/d_net.cpp index bc5ccdba9..66b8c5dc3 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2082,6 +2082,33 @@ static int KillAll(const PClass *cls) } return killcount; +} + +static int RemoveClass(const PClass *cls) +{ + AActor *actor; + int removecount = 0; + bool player = false; + TThinkerIterator iterator(cls); + while ((actor = iterator.Next())) + { + if (actor->IsA(cls)) + { + // [MC]Do not remove LIVE players. + if (actor->IsKindOf(RUNTIME_CLASS(APlayerPawn)) && actor->player != NULL) + { + player = true; + continue; + } + removecount++; + actor->ClearCounters(); + actor->Destroy(); + } + } + if (player) + Printf("Cannot remove live players!\n"); + return removecount; + } // [RH] Execute a special "ticcmd". The type byte should // have already been read, and the stream is positioned @@ -2555,6 +2582,27 @@ void Net_DoCommand (int type, BYTE **stream, int player) } break; + case DEM_REMOVE: + { + char *classname = ReadString(stream); + int removecount = 0; + const PClass *cls = PClass::FindClass(classname); + if (cls != NULL && cls->ActorInfo != NULL) + { + removecount = RemoveClass(cls); + const PClass *cls_rep = cls->GetReplacement(); + if (cls != cls_rep) + { + removecount += RemoveClass(cls_rep); + } + Printf("Removed %d actors of type %s.\n", removecount, classname); + } + else + { + Printf("%s is not an actor class.\n", classname); + } + } + break; case DEM_CONVREPLY: case DEM_CONVCLOSE: diff --git a/src/d_protocol.h b/src/d_protocol.h index 8b6e777d5..73b042470 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -164,6 +164,7 @@ enum EDemoCommand DEM_RUNNAMEDSCRIPT, // 65 String: Script name, Byte: Arg count + Always flag; each arg is a 4-byte int DEM_REVERTCAMERA, // 66 DEM_SETSLOTPNUM, // 67 Byte: player number, the rest is the same as DEM_SETSLOT + DEM_REMOVE, // 68 }; // The following are implemented by cht_DoCheat in m_cheat.cpp diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index cbbd87978..276a88c75 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1841,3 +1841,22 @@ CCMD (kill) } C_HideConsole (); } + +CCMD(remove) +{ + if (argv.argc() == 2) + { + if (CheckCheatmode()) + return; + + Net_WriteByte(DEM_REMOVE); + Net_WriteString(argv[1]); + C_HideConsole(); + } + else + { + Printf("Usage: remove \n"); + return; + } + +} \ No newline at end of file From 9c24e9ac71abeb892d5ca47fff9d2093757b5349 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Tue, 11 Aug 2015 06:53:28 -0500 Subject: [PATCH 12/61] - Removed the check for APlayerPawn and just went with player checking alone. - Updated the savever, demogameversion, and mindemoversion. --- src/d_net.cpp | 3 ++- src/version.h | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 66b8c5dc3..e6b5713f2 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2095,7 +2095,7 @@ static int RemoveClass(const PClass *cls) if (actor->IsA(cls)) { // [MC]Do not remove LIVE players. - if (actor->IsKindOf(RUNTIME_CLASS(APlayerPawn)) && actor->player != NULL) + if (actor->player != NULL) { player = true; continue; @@ -2728,6 +2728,7 @@ void Net_SkipCommand (int type, BYTE **stream) case DEM_SUMMONFRIEND: case DEM_SUMMONFOE: case DEM_SUMMONMBF: + case DEM_REMOVE: case DEM_SPRAY: case DEM_MORPHEX: case DEM_KILLCLASSCHEAT: diff --git a/src/version.h b/src/version.h index 3d28dd2ac..913c9bd18 100644 --- a/src/version.h +++ b/src/version.h @@ -61,11 +61,11 @@ const char *GetVersionString(); // Protocol version used in demos. // Bump it if you change existing DEM_ commands or add new ones. // Otherwise, it should be safe to leave it alone. -#define DEMOGAMEVERSION 0x21B +#define DEMOGAMEVERSION 0x21C // Minimum demo version we can play. // Bump it whenever you change or remove existing DEM_ commands. -#define MINDEMOVERSION 0x21B +#define MINDEMOVERSION 0x21C // SAVEVER is the version of the information stored in level snapshots. // Note that SAVEVER is not directly comparable to VERSION. @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4523 +#define SAVEVER 4524 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) From b06770cb92d16c3b7a9cacbeba11c20968e48f1c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 11 Aug 2015 17:12:16 +0200 Subject: [PATCH 13/61] - fixed: A_Respawn did not reset the actor's radius. --- src/thingdef/thingdef_codeptr.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 69dd89cd0..d09ad6d6e 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3017,6 +3017,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn) fixed_t oldz = self->z; self->flags |= MF_SOLID; self->height = self->GetDefault()->height; + self->radius = self->GetDefault()->radius; CALL_ACTION(A_RestoreSpecialPosition, self); if (flags & RSF_TELEFRAG) From 2ed3cec4db39dfb6762830a09d4224aaf9969edc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 11 Aug 2015 22:30:29 +0200 Subject: [PATCH 14/61] - externalized strings from Raven intermission screen. --- src/wi_stuff.cpp | 8 ++++---- wadsrc/static/language.enu | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 02492f272..8119d3802 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -1959,9 +1959,9 @@ void WI_drawStats (void) } else { - screen->DrawText (BigFont, CR_UNTRANSLATED, 50, 65, "KILLS", DTA_Clean, true, DTA_Shadow, true, TAG_DONE); - screen->DrawText (BigFont, CR_UNTRANSLATED, 50, 90, "ITEMS", DTA_Clean, true, DTA_Shadow, true, TAG_DONE); - screen->DrawText (BigFont, CR_UNTRANSLATED, 50, 115, "SECRETS", DTA_Clean, true, DTA_Shadow, true, TAG_DONE); + screen->DrawText (BigFont, CR_UNTRANSLATED, 50, 65, GStrings("TXT_IMKILLS"), DTA_Clean, true, DTA_Shadow, true, TAG_DONE); + screen->DrawText (BigFont, CR_UNTRANSLATED, 50, 90, GStrings("TXT_IMITEMS"), DTA_Clean, true, DTA_Shadow, true, TAG_DONE); + screen->DrawText (BigFont, CR_UNTRANSLATED, 50, 115, GStrings("TXT_IMSECRETS"), DTA_Clean, true, DTA_Shadow, true, TAG_DONE); int countpos = gameinfo.gametype==GAME_Strife? 285:270; if (sp_state >= 2) @@ -1978,7 +1978,7 @@ void WI_drawStats (void) } if (sp_state >= 8) { - screen->DrawText (BigFont, CR_UNTRANSLATED, 85, 160, "TIME", + screen->DrawText (BigFont, CR_UNTRANSLATED, 85, 160, GStrings("TXT_IMTIME"), DTA_Clean, true, DTA_Shadow, true, TAG_DONE); WI_drawTime (249, 160, cnt_time); if (wi_showtotaltime) diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index a01a03559..bdefa1b86 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1281,6 +1281,14 @@ TXT_LEADBOOTSOFF = "LEAD BOOTS OFF"; TXT_LIGHTER = "You feel lighter"; TXT_GRAVITY = "Gravity weighs you down"; +// Raven intermission + +TXT_IMKILLS = "KILLS"; +TXT_IMITEMS = "ITEMS"; +TXT_IMSECRETS = "SECRETS"; +TXT_IMTIME = "TIME"; + + RAVENQUITMSG = "ARE YOU SURE YOU WANT TO QUIT?"; // Hexen strings From 2d58a28cc3feb559b7989698d88144309da7bc6a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Aug 2015 08:50:22 +0200 Subject: [PATCH 15/61] - fixed: In Heretic an active Tome of Power should not freeze a teleporting player. This was implemented by adding a new inventory flag INVENTORY.NOTELEPORTFREEZE so that the effect can both be activated for other items and deactivated for the two that currently have it. --- src/g_shared/a_artifacts.cpp | 14 +++++++++++++- src/g_shared/a_artifacts.h | 1 + src/g_shared/a_pickups.cpp | 19 +++++++++++++++++++ src/g_shared/a_pickups.h | 2 ++ src/p_teleport.cpp | 2 +- src/thingdef/thingdef_data.cpp | 4 +++- wadsrc/static/actors/shared/inventory.txt | 2 ++ 7 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index bc33eb19c..2be2e179d 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -72,7 +72,7 @@ bool APowerupGiver::Use (bool pickup) power->Strength = Strength; } - power->ItemFlags |= ItemFlags & (IF_ALWAYSPICKUP|IF_ADDITIVETIME); + power->ItemFlags |= ItemFlags & (IF_ALWAYSPICKUP|IF_ADDITIVETIME|IF_NOTELEPORTFREEZE); if (power->CallTryPickup (Owner)) { return true; @@ -342,6 +342,18 @@ void APowerup::OwnerDied () Destroy (); } +//=========================================================================== +// +// AInventory :: GetNoTeleportFreeze +// +//=========================================================================== + +bool APowerup::GetNoTeleportFreeze () +{ + if (ItemFlags & IF_NOTELEPORTFREEZE) return true; + return Super::GetNoTeleportFreeze(); +} + // Invulnerability Powerup --------------------------------------------------- IMPLEMENT_CLASS (APowerInvulnerable) diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 4e1823f5a..c16a7a0c1 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -18,6 +18,7 @@ public: virtual AInventory *CreateTossable (); virtual void Serialize (FArchive &arc); virtual void OwnerDied (); + virtual bool GetNoTeleportFreeze(); virtual PalEntry GetBlend (); virtual bool DrawPowerup (int x, int y); diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 038b63029..5d494c935 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -850,6 +850,25 @@ fixed_t AInventory::GetSpeedFactor () } } +//=========================================================================== +// +// AInventory :: GetNoTeleportFreeze +// +//=========================================================================== + +bool AInventory::GetNoTeleportFreeze () +{ + // do not check the flag here because it's only active when used on PowerUps, not on PowerupGivers. + if (Inventory != NULL) + { + return Inventory->GetNoTeleportFreeze(); + } + else + { + return false; + } +} + //=========================================================================== // // AInventory :: AlterWeaponSprite diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 504a26c73..74b10206b 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -137,6 +137,7 @@ enum IF_TOSSED = 1<<22, // Was spawned by P_DropItem (i.e. as a monster drop) IF_ALWAYSRESPAWN = 1<<23, // Always respawn, regardless of dmflag IF_TRANSFER = 1<<24, // All inventory items that the inventory item contains is also transfered to the pickuper + IF_NOTELEPORTFREEZE = 1<<25, // does not 'freeze' the player right after teleporting. }; @@ -201,6 +202,7 @@ public: virtual void AbsorbDamage (int damage, FName damageType, int &newdamage); virtual void ModifyDamage (int damage, FName damageType, int &newdamage, bool passive); virtual fixed_t GetSpeedFactor(); + virtual bool GetNoTeleportFreeze(); virtual int AlterWeaponSprite (visstyle_t *vis); virtual PalEntry GetBlend (); diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 82359f4e0..040aca9f4 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -211,7 +211,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, if (thing->player && (useFog || !keepOrientation) && bHaltVelocity) { // Freeze player for about .5 sec - if (thing->Inventory == NULL || thing->Inventory->GetSpeedFactor() <= FRACUNIT) + if (thing->Inventory == NULL || !thing->Inventory->GetNoTeleportFreeze()) thing->reactiontime = 18; } if (thing->flags & MF_MISSILE) diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index b1387ba52..817afd0fa 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -331,9 +331,11 @@ static FFlagDef InventoryFlagDefs[] = DEFINE_FLAG(IF, TOSSED, AInventory, ItemFlags), DEFINE_FLAG(IF, ALWAYSRESPAWN, AInventory, ItemFlags), DEFINE_FLAG(IF, TRANSFER, AInventory, ItemFlags), + DEFINE_FLAG(IF, NOTELEPORTFREEZE, AInventory, ItemFlags), DEFINE_DEPRECATED_FLAG(PICKUPFLASH), - DEFINE_DEPRECATED_FLAG(INTERHUBSTRIP),}; + DEFINE_DEPRECATED_FLAG(INTERHUBSTRIP), +}; static FFlagDef WeaponFlagDefs[] = { diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 0c106417b..541dd37ac 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -225,6 +225,7 @@ ACTOR PowerWeaponLevel2 : Powerup native { Powerup.Duration -40 Inventory.Icon "SPINBK0" + +INVENTORY.NOTELEPORTFREEZE } ACTOR PowerSpeed : Powerup native @@ -232,6 +233,7 @@ ACTOR PowerSpeed : Powerup native Powerup.Duration -45 Speed 1.5 Inventory.Icon "SPBOOT0" + +INVENTORY.NOTELEPORTFREEZE } // Player Speed Trail (used by the Speed Powerup) ---------------------------- From d786148ccfa7befdccc212fb03665d7fa56b2000 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Aug 2015 20:33:34 +0200 Subject: [PATCH 16/61] - fixed: the 'gameversion' console output was missing a trailing linefeed. --- src/c_cmds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index a40f1f1a2..0a9e4f0e3 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -422,7 +422,7 @@ CCMD (take) CCMD (gameversion) { - Printf ("%s @ %s\nCommit %s", GetVersionString(), GetGitTime(), GetGitHash()); + Printf ("%s @ %s\nCommit %s\n", GetVersionString(), GetGitTime(), GetGitHash()); } CCMD (print) From 86e9504d04eee25fa51dd08e8c195b8de98f66d9 Mon Sep 17 00:00:00 2001 From: Leonard Date: Wed, 19 Aug 2015 15:59:54 +0200 Subject: [PATCH 17/61] Added weapon interpolation. --- src/d_player.h | 1 + src/g_game.cpp | 9 ++ src/p_pspr.cpp | 21 ++++ src/p_pspr.h | 6 ++ src/p_saveg.cpp | 5 + src/p_user.cpp | 15 +++ src/r_data/r_interpolate.cpp | 199 ++++++++++++++++++++++++++++++++++- src/version.h | 2 +- 8 files changed, 254 insertions(+), 4 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index e27bf1087..2ac2ad0d5 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -427,6 +427,7 @@ public: short fixedcolormap; // can be set to REDCOLORMAP, etc. short fixedlightlevel; pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc) + TObjPtr pspinterp[NUMPSPRITES]; // view sprite interpolations int morphTics; // player is a chicken/pig if > 0 const PClass *MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed int MorphStyle; // which effects to apply for this player instance when morphed diff --git a/src/g_game.cpp b/src/g_game.cpp index 8101ca23d..f77949687 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1726,6 +1726,15 @@ void G_DoPlayerPop(int playernum) players[playernum].mo = NULL; players[playernum].camera = NULL; } + // Now's the ideal time to remove his psprite interpolations. + for (int ii = 0; ii < NUMPSPRITES; ii++) + { + if (players[playernum].psprites[ii].interpolation != NULL) + { + players[playernum].psprites[ii].StopInterpolation(); + players[playernum].pspinterp[ii] = NULL; + } + } // [RH] Let the scripts know the player left FBehavior::StaticStartTypedScripts(SCRIPT_Disconnect, NULL, true, playernum); } diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 63f3bc648..d2bf8cc87 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -1104,11 +1104,32 @@ void P_MovePsprites (player_t *player) P_CheckWeaponZoom (player); } } + + psp = &player->psprites[0]; + for (i = 0; i < NUMPSPRITES; i++, psp++) + { + if (psp->state == NULL) + { + if (psp->interpolation != NULL) + { + player->pspinterp[i] = NULL; + psp->StopInterpolation(); + } + } + else if (psp->interpolation == NULL) + { + player->pspinterp[i] = psp->SetInterpolation(player - players, i); + } + } } FArchive &operator<< (FArchive &arc, pspdef_t &def) { arc << def.state << def.tics << def.sx << def.sy << def.sprite << def.frame; + + if (SaveVersion >= 4525) + arc << def.interpolation; + return arc; } diff --git a/src/p_pspr.h b/src/p_pspr.h index ca9b45ee8..62c2a6fe4 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -26,6 +26,7 @@ // Basic data types. // Needs fixed point, and BAM angles. #include "tables.h" +#include "r_data/r_interpolate.h" #include "thingdef/thingdef.h" #define WEAPONBOTTOM 128*FRACUNIT @@ -71,6 +72,11 @@ struct pspdef_t int sprite; int frame; bool processPending; // true: waiting for periodic processing on this tick + + TObjPtr interpolation; + DInterpolation *SetInterpolation(int player, int position); + void UpdateInterpolation(int player); + void StopInterpolation(); }; class FArchive; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 480494320..f16bdb0f9 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -297,6 +297,11 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name) { dst->mo->player = dst; } + // Fix the psprite interpolation pointers too. + for (int i = 0; i < NUMPSPRITES; i++) + { + dst->psprites[i].UpdateInterpolation(dst - players); + } // These 2 variables may not be overwritten. dst->attackdown = attackdown; dst->usedown = usedown; diff --git a/src/p_user.cpp b/src/p_user.cpp index 0617e5d6a..baea731e6 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -316,6 +316,7 @@ player_t::player_t() memset (&cmd, 0, sizeof(cmd)); memset (frags, 0, sizeof(frags)); memset (psprites, 0, sizeof(psprites)); + memset (pspinterp, 0, sizeof(pspinterp)); } player_t &player_t::operator=(const player_t &p) @@ -371,6 +372,7 @@ player_t &player_t::operator=(const player_t &p) fixedcolormap = p.fixedcolormap; fixedlightlevel = p.fixedlightlevel; memcpy(psprites, &p.psprites, sizeof(psprites)); + memcpy(pspinterp, &p.pspinterp, sizeof(pspinterp)); morphTics = p.morphTics; MorphedPlayerClass = p.MorphedPlayerClass; MorphStyle = p.MorphStyle; @@ -435,6 +437,10 @@ size_t player_t::FixPointers (const DObject *old, DObject *rep) if (*&ConversationNPC == old) ConversationNPC = replacement, changed++; if (*&ConversationPC == old) ConversationPC = replacement, changed++; if (*&MUSINFOactor == old) MUSINFOactor = replacement, changed++; + + for (int i = 0; i < NUMPSPRITES; i++) + if (*&pspinterp[i] == old) pspinterp[i] = static_cast(rep), changed++; + return changed; } @@ -454,6 +460,11 @@ size_t player_t::PropagateMark() { GC::Mark(PendingWeapon); } + for (int i = 0; i < NUMPSPRITES; i++) + { + GC::Mark(pspinterp[i]); + } + return sizeof(*this); } @@ -3049,7 +3060,11 @@ void player_t::Serialize (FArchive &arc) for (i = 0; i < MAXPLAYERS; i++) arc << frags[i]; for (i = 0; i < NUMPSPRITES; i++) + { arc << psprites[i]; + if (SaveVersion >= 4525) + arc << pspinterp[i]; + } arc << CurrentPlayerClass; diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp index 3ca3b557c..2acbe2140 100644 --- a/src/r_data/r_interpolate.cpp +++ b/src/r_data/r_interpolate.cpp @@ -151,6 +151,35 @@ public: }; +//========================================================================== +// +// +// +//========================================================================== + +class DPSpriteInterpolation : public DInterpolation +{ + DECLARE_CLASS(DPSpriteInterpolation, DInterpolation) + + pspdef_t *psp; + int player, position; + fixed_t oldx, oldy; + fixed_t bakx, baky; + fixed_t ofsx, ofsy; + fixed_t nfsx, nfsy; + +public: + + DPSpriteInterpolation() {} + DPSpriteInterpolation(pspdef_t *psp, int player, int position); + void UpdatePointer(int player); + void Destroy(); + void UpdateInterpolation(); + void Restore(); + void Interpolate(fixed_t smoothratio); + void Serialize(FArchive &arc); +}; + //========================================================================== // // @@ -162,6 +191,7 @@ IMPLEMENT_CLASS(DSectorPlaneInterpolation) IMPLEMENT_CLASS(DSectorScrollInterpolation) IMPLEMENT_CLASS(DWallScrollInterpolation) IMPLEMENT_CLASS(DPolyobjInterpolation) +IMPLEMENT_CLASS(DPSpriteInterpolation) //========================================================================== // @@ -628,7 +658,6 @@ void DSectorScrollInterpolation::Serialize(FArchive &arc) arc << sector << ceiling << oldx << oldy; } - //========================================================================== // // @@ -824,6 +853,115 @@ void DPolyobjInterpolation::Serialize(FArchive &arc) if (arc.IsLoading()) bakverts.Resize(oldverts.Size()); } +//========================================================================== +// +// +// +//========================================================================== + +//========================================================================== +// +// +// +//========================================================================== + +DPSpriteInterpolation::DPSpriteInterpolation(pspdef_t *_psp, int _player, int _position) +: nfsx(0), nfsy(0), ofsx(0), ofsy(0) +{ + psp = _psp; + player = _player; + position = _position; + UpdateInterpolation (); + interpolator.AddInterpolation(this); +} + +//========================================================================== +// +// +// +//========================================================================== + +void DPSpriteInterpolation::UpdatePointer(int _player) +{ + player = _player; + psp = &players[player].psprites[position]; +} + +//========================================================================== +// +// +// +//========================================================================== + +void DPSpriteInterpolation::Destroy() +{ + psp->interpolation = NULL; + Super::Destroy(); +} + +//========================================================================== +// +// +// +//========================================================================== + +void DPSpriteInterpolation::UpdateInterpolation() +{ + if ( position == ps_weapon ) + P_BobWeapon( &players[player], psp, &ofsx, &ofsy ); + + oldx = psp->sx + ofsx; + oldy = psp->sy + ofsy; +} + +//========================================================================== +// +// +// +//========================================================================== + +void DPSpriteInterpolation::Restore() +{ + psp->sx = bakx - nfsx; + psp->sy = baky - nfsy; +} + +//========================================================================== +// +// +// +//========================================================================== + +void DPSpriteInterpolation::Interpolate(fixed_t smoothratio) +{ + if ( position == ps_weapon ) + P_BobWeapon( &players[player], psp, &nfsx, &nfsy ); + + bakx = psp->sx + nfsx; + baky = psp->sy + nfsy; + + psp->sx = oldx + FixedMul(bakx - oldx, smoothratio) - nfsx; + psp->sy = oldy + FixedMul(baky - oldy, smoothratio) - nfsy; +} + +//========================================================================== +// +// +// +//========================================================================== + +void DPSpriteInterpolation::Serialize(FArchive &arc) +{ + Super::Serialize(arc); + arc << player << position << oldx << oldy << ofsx << ofsy; + UpdatePointer(player); +} + +//========================================================================== +// +// +// +//========================================================================== //========================================================================== // @@ -944,6 +1082,63 @@ void FPolyObj::StopInterpolation() } } +//========================================================================== +// +// +// +//========================================================================== + +DInterpolation *pspdef_t::SetInterpolation(int player, int position) +{ + if (interpolation == NULL) + { + interpolation = new DPSpriteInterpolation(this, player, position); + } + interpolation->AddRef(); + GC::WriteBarrier(interpolation); + return interpolation; +} + +//========================================================================== +// +// +// +//========================================================================== + +void pspdef_t::UpdateInterpolation(int player) +{ + if (interpolation != NULL) + { + DInterpolation *pointer = interpolation; + static_cast(pointer)->UpdatePointer(player); + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void pspdef_t::StopInterpolation() +{ + if (interpolation != NULL) + { + interpolation->DelRef(); + } +} + +//========================================================================== +// +// +// +//========================================================================== + +//========================================================================== +// +// +// +//========================================================================== ADD_STAT (interpolations) { @@ -951,5 +1146,3 @@ ADD_STAT (interpolations) out.Format ("%d interpolations", interpolator.CountInterpolations ()); return out; } - - diff --git a/src/version.h b/src/version.h index 913c9bd18..168cb7519 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4524 +#define SAVEVER 4525 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) From f9e70a82c6216c19075adcd9f3d9826ba52ef5db Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 24 Aug 2015 12:45:10 -0500 Subject: [PATCH 18/61] - Added A_SetSpecies(,). --- src/thingdef/thingdef_codeptr.cpp | 22 ++++++++++++++++++++++ wadsrc/static/actors/actor.txt | 1 + 2 files changed, 23 insertions(+) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index d09ad6d6e..f6b724747 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5764,6 +5764,28 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHigherOrLower) ACTION_JUMP(low); } +//=========================================================================== +// A_SetSpecies(str species, ptr) +// +// Sets the species of the calling actor('s pointer). +//=========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpecies) +{ + ACTION_PARAM_START(2); + ACTION_PARAM_NAME(species, 0); + ACTION_PARAM_INT(ptr, 1); + AActor *mobj = COPY_AAPTR(self, ptr); + if (!mobj) + { + ACTION_SET_RESULT(false); + return; + } + + if (!stricmp(species, "None") || !stricmp(species, "")) + mobj->Species = NAME_None; + else + mobj->Species = species; +} //=========================================================================== // diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 6885ad2d6..5e79d6b82 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -331,6 +331,7 @@ ACTOR Actor native //: Thinker action native A_SetHealth(int health, int ptr = AAPTR_DEFAULT); action native A_ResetHealth(int ptr = AAPTR_DEFAULT); action native A_JumpIfHigherOrLower(state high, state low, float offsethigh = 0, float offsetlow = 0, bool includeHeight = true, int ptr = AAPTR_TARGET); + action native A_SetSpecies(name species, int ptr = AAPTR_DEFAULT); action native A_SetRipperLevel(int level); action native A_SetRipMin(int min); action native A_SetRipMax(int max); From 27316432009ab2a09c494fd4d72287b215caf241 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Tue, 25 Aug 2015 08:15:23 -0500 Subject: [PATCH 19/61] Removed stricmp checks, as they're not needed. --- src/thingdef/thingdef_codeptr.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index f6b724747..377c4915b 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5781,10 +5781,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpecies) return; } - if (!stricmp(species, "None") || !stricmp(species, "")) - mobj->Species = NAME_None; - else - mobj->Species = species; + mobj->Species = species; } //=========================================================================== From ebf515f8c76ca32d2fd5fe9b70783987af5c12ca Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Tue, 25 Aug 2015 20:18:06 -0500 Subject: [PATCH 20/61] - Fixed unneeded dual call to SetOrigin. --- src/p_things.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/p_things.cpp b/src/p_things.cpp index f9d85c43f..b7e3f058b 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -718,19 +718,13 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, if (flags & WARPF_TOFLOOR) { // set correct xy - - caller->SetOrigin( - reference->x + xofs, - reference->y + yofs, - reference->z); - // now the caller's floorz should be appropriate for the assigned xy-position // assigning position again with. // extra unlink, link and environment calculation caller->SetOrigin( - caller->x, - caller->y, - caller->floorz + zofs); + reference->x + xofs, + reference->y + yofs, + reference->floorz + zofs); } else { From 696c6af588a4b1f326a7257ca0cdc1073eaedbb2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 27 Aug 2015 12:48:43 +0200 Subject: [PATCH 21/61] - fixed: FString's 'Strip...' functions could crash on empty strings. --- src/zstring.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/zstring.cpp b/src/zstring.cpp index 510ff19d7..1aa388da9 100644 --- a/src/zstring.cpp +++ b/src/zstring.cpp @@ -583,6 +583,7 @@ void FString::SwapCase () void FString::StripLeft () { size_t max = Len(), i, j; + if (max == 0) return; for (i = 0; i < max; ++i) { if (!isspace(Chars[i])) @@ -613,6 +614,7 @@ void FString::StripLeft (const FString &charset) void FString::StripLeft (const char *charset) { size_t max = Len(), i, j; + if (max == 0) return; for (i = 0; i < max; ++i) { if (!strchr (charset, Chars[i])) @@ -665,6 +667,7 @@ void FString::StripRight (const FString &charset) void FString::StripRight (const char *charset) { size_t max = Len(), i; + if (max == 0) return; for (i = max; i-- > 0; ) { if (!strchr (charset, Chars[i])) @@ -687,6 +690,7 @@ void FString::StripRight (const char *charset) void FString::StripLeftRight () { size_t max = Len(), i, j, k; + if (max == 0) return; for (i = 0; i < max; ++i) { if (!isspace(Chars[i])) @@ -723,6 +727,7 @@ void FString::StripLeftRight (const FString &charset) void FString::StripLeftRight (const char *charset) { size_t max = Len(), i, j, k; + if (max == 0) return; for (i = 0; i < max; ++i) { if (!strchr (charset, Chars[i])) From 98f214ee66fd5223c2d277fb982848e03e0200d2 Mon Sep 17 00:00:00 2001 From: Gaerzi Date: Fri, 28 Aug 2015 19:14:25 +0200 Subject: [PATCH 22/61] Added support for GOG paths This works a bit differently from the Steam version, because each game has its own registry keys and its own independent path. --- src/d_iwad.cpp | 5 ++++ src/win32/i_system.cpp | 63 ++++++++++++++++++++++++++++++++++++++---- src/win32/i_system.h | 3 ++ 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 3fc365e8c..a8d60e1ce 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -435,6 +435,11 @@ int FIWadManager::IdentifyVersion (TArray &wadfiles, const char *iwad, } } } + TArray gog_paths = I_GetGogPaths(); + for (i = 0; i < gog_paths.Size(); ++i) + { + CheckIWAD (gog_paths[i], &wads[0]); + } TArray steam_path = I_GetSteamPath(); for (i = 0; i < steam_path.Size(); ++i) { diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 6d8fb8595..372da8685 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -1504,30 +1504,83 @@ int I_FindClose(void *handle) static bool QueryPathKey(HKEY key, const char *keypath, const char *valname, FString &value) { - HKEY steamkey; + HKEY pathkey; DWORD pathtype; DWORD pathlen; LONG res; - if(ERROR_SUCCESS == RegOpenKeyEx(key, keypath, 0, KEY_QUERY_VALUE, &steamkey)) + if(ERROR_SUCCESS == RegOpenKeyEx(key, keypath, 0, KEY_QUERY_VALUE, &pathkey)) { - if (ERROR_SUCCESS == RegQueryValueEx(steamkey, valname, 0, &pathtype, NULL, &pathlen) && + if (ERROR_SUCCESS == RegQueryValueEx(pathkey, valname, 0, &pathtype, NULL, &pathlen) && pathtype == REG_SZ && pathlen != 0) { // Don't include terminating null in count char *chars = value.LockNewBuffer(pathlen - 1); - res = RegQueryValueEx(steamkey, valname, 0, NULL, (LPBYTE)chars, &pathlen); + res = RegQueryValueEx(pathkey, valname, 0, NULL, (LPBYTE)chars, &pathlen); value.UnlockBuffer(); if (res != ERROR_SUCCESS) { value = ""; } } - RegCloseKey(steamkey); + RegCloseKey(pathkey); } return value.IsNotEmpty(); } +//========================================================================== +// +// I_GetGogPaths +// +// Check the registry for GOG installation paths, so we can search for IWADs +// that were bought from GOG.com. This is a bit different from the Steam +// version because each game has its own independent installation path, no +// such thing as /SteamApps/common/. +// +//========================================================================== + +TArray I_GetGogPaths() +{ + TArray result; + FString path; + FString gamepath; + +#ifdef _WIN64 + FString gogregistrypath = "Software\\Wow6432Node\\GOG.com\\Games"; +#else + // If a 32-bit ZDoom runs on a 64-bit Windows, this will be transparently and + // automatically redirected to the Wow6432Node address instead, so this address + // should be safe to use in all cases. + FString gogregistrypath = "Software\\GOG.com\\Games"; +#endif + + // Look for Ultimate Doom + gamepath = gogregistrypath + "\\1435827232"; + if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.GetChars(), "Path", path)) + { + result.Push(path); // directly in install folder + } + + // Look for Doom II + gamepath = gogregistrypath + "\\1435848814"; + if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.GetChars(), "Path", path)) + { + result.Push(path + "/doom2"); // in a subdirectory + // If direct support for the Master Levels is ever added, they are in path + /master/wads + } + + // Look for Final Doom + gamepath = gogregistrypath + "\\1435848742"; + if (QueryPathKey(HKEY_LOCAL_MACHINE, gamepath.GetChars(), "Path", path)) + { + // in subdirectories + result.Push(path + "/TNT"); + result.Push(path + "/Plutonia"); + } + + return result; +} + //========================================================================== // // I_GetSteamPath diff --git a/src/win32/i_system.h b/src/win32/i_system.h index 566ca1977..03f4f3c0f 100644 --- a/src/win32/i_system.h +++ b/src/win32/i_system.h @@ -168,6 +168,9 @@ void I_SetWndProc(); // directories for IWADs if the user purchased any through Steam. TArray I_GetSteamPath(); +// [GZ] Same deal for GOG paths +TArray I_GetGogPaths(); + // Damn Microsoft for doing Get/SetWindowLongPtr half-assed. Instead of // giving them proper prototypes under Win32, they are just macros for // Get/SetWindowLong, meaning they take LONGs and not LONG_PTRs. From 677dc8893ee53d36361dc40adc5347790b647a2f Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 29 Aug 2015 14:55:10 +0300 Subject: [PATCH 23/61] Fixed compilation on non-Windows OSes --- src/posix/i_system.cpp | 6 ++++++ src/posix/i_system.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/posix/i_system.cpp b/src/posix/i_system.cpp index fd6bb4c0c..84b953717 100644 --- a/src/posix/i_system.cpp +++ b/src/posix/i_system.cpp @@ -758,3 +758,9 @@ unsigned int I_MakeRNGSeed() } return seed; } + +TArray I_GetGogPaths() +{ + // GOG's Doom games are Windows only at the moment + return TArray(); +} diff --git a/src/posix/i_system.h b/src/posix/i_system.h index abda490c4..391503602 100644 --- a/src/posix/i_system.h +++ b/src/posix/i_system.h @@ -124,6 +124,8 @@ int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad); // directories for IWADs if the user purchased any through Steam. TArray I_GetSteamPath(); +TArray I_GetGogPaths(); + // The ini could not be saved at exit bool I_WriteIniFailed (); From 0ed4549683e608422aa1952b01225289e41b2c0b Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 30 Aug 2015 02:47:45 +1200 Subject: [PATCH 24/61] Correct the mastermind's radius --- wadsrc/static/actors/doom/spidermaster.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/actors/doom/spidermaster.txt b/wadsrc/static/actors/doom/spidermaster.txt index 97ebbf143..c2a742f1e 100644 --- a/wadsrc/static/actors/doom/spidermaster.txt +++ b/wadsrc/static/actors/doom/spidermaster.txt @@ -6,7 +6,7 @@ ACTOR SpiderMastermind { Health 3000 - Radius 100 + Radius 128 Height 100 Mass 1000 Speed 12 From 389ff4fc98b6ad354418d9370a97b52dc9f49e0b Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 30 Aug 2015 22:02:36 +1200 Subject: [PATCH 25/61] Shift self-clip to first check for performance --- src/p_map.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index fca43c120..c9b2f14cf 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1013,6 +1013,10 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm) bool solid; int damage; + // don't clip against self + if (thing == tm.thing) + return true; + if (!((thing->flags & (MF_SOLID | MF_SPECIAL | MF_SHOOTABLE)) || thing->flags6 & MF6_TOUCHY)) return true; // can't hit thing @@ -1020,10 +1024,6 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm) if (abs(thing->x - tm.x) >= blockdist || abs(thing->y - tm.y) >= blockdist) return true; - // don't clip against self - if (thing == tm.thing) - return true; - if ((thing->flags2 | tm.thing->flags2) & MF2_THRUACTORS) return true; From b87435ac9d931d3bd053fd9084cb23d7d5457426 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 30 Aug 2015 22:56:34 +1200 Subject: [PATCH 26/61] Remove unnecessary FriendlyFire global --- src/p_interaction.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 276a88c75..2947bf9c0 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -74,7 +74,6 @@ EXTERN_CVAR (Bool, show_obituaries) FName MeansOfDeath; -bool FriendlyFire; // // GET STUFF @@ -198,10 +197,8 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf if (inflictor && inflictor->player && inflictor->player->mo != inflictor) MeansOfDeath = NAME_None; - if (multiplayer && !deathmatch) - FriendlyFire = true; + friendly = (self->player != attacker->player && self->IsTeammate(attacker)); - friendly = FriendlyFire; mod = MeansOfDeath; message = NULL; messagename = NULL; @@ -1024,7 +1021,6 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, } MeansOfDeath = mod; - FriendlyFire = false; // [RH] Andy Baker's Stealth monsters if (target->flags & MF_STEALTH) { @@ -1221,8 +1217,6 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, ((player && player != source->player) || (!player && target != source)) && target->IsTeammate (source)) { - if (player) - FriendlyFire = true; if (rawdamage < TELEFRAG_DAMAGE) //Use the original damage to check for telefrag amount. Don't let the now-amplified damagetypes do it. { // Still allow telefragging :-( damage = (int)((float)damage * level.teamdamage); From 02c562518ddf9657c0a353bd03a4caab424a214e Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 30 Aug 2015 23:36:00 +1200 Subject: [PATCH 27/61] Fixed possible sync issue with frag counts --- src/p_interaction.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 2947bf9c0..a0b1ddbc1 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -268,8 +268,6 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf { if (friendly) { - attacker->player->fragcount -= 2; - attacker->player->frags[attacker->player - players]++; self = attacker; gender = self->player->userinfo.GetGender(); mysnprintf (gendermessage, countof(gendermessage), "OB_FRIENDLY%c", '1' + (pr_obituary() & 3)); @@ -467,12 +465,21 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) if ((dmflags2 & DF2_YES_LOSEFRAG) && deathmatch) player->fragcount--; - ++source->player->fragcount; - ++source->player->spreecount; + if (this->IsTeammate(source)) + { + source->player->fragcount--; + } + else + { + ++source->player->fragcount; + ++source->player->spreecount; + } + if (source->player->morphTics) { // Make a super chicken source->GiveInventoryType (RUNTIME_CLASS(APowerWeaponLevel2)); } + if (deathmatch && cl_showsprees) { const char *spreemsg; From 0fa24ab82d069f5fd44a55d5d307ff36b8642720 Mon Sep 17 00:00:00 2001 From: Leonard Date: Mon, 31 Aug 2015 13:04:40 +0200 Subject: [PATCH 28/61] Use barrier_cast instead of static_cast --- src/r_data/r_interpolate.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp index 2acbe2140..46ac30789 100644 --- a/src/r_data/r_interpolate.cpp +++ b/src/r_data/r_interpolate.cpp @@ -1109,8 +1109,7 @@ void pspdef_t::UpdateInterpolation(int player) { if (interpolation != NULL) { - DInterpolation *pointer = interpolation; - static_cast(pointer)->UpdatePointer(player); + barrier_cast(interpolation)->UpdatePointer(player); } } From 1a275a7e8eb91dfefa341b1745235759fd465cb2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 2 Sep 2015 23:15:41 +0200 Subject: [PATCH 29/61] - removed the initial extra state of Heretic's Mummy's projectile to restore the original sound behavior. --- wadsrc/static/actors/heretic/mummy.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wadsrc/static/actors/heretic/mummy.txt b/wadsrc/static/actors/heretic/mummy.txt index 46e9deaba..c06f519f6 100644 --- a/wadsrc/static/actors/heretic/mummy.txt +++ b/wadsrc/static/actors/heretic/mummy.txt @@ -121,12 +121,11 @@ ACTOR MummyFX1 States { Spawn: - FX15 A 1 Bright FX15 A 5 Bright A_PlaySound("mummy/head") FX15 B 5 Bright A_SeekerMissile(10,20) FX15 C 5 Bright FX15 B 5 Bright A_SeekerMissile(10,20) - Goto Spawn+1 + Loop Death: FX15 DEFG 5 Bright Stop From 8ec4d431cfcba1479d5631613a6c8b4ea20bf2a7 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sat, 5 Sep 2015 14:12:52 +1200 Subject: [PATCH 30/61] Fixed memory leak in joystick menu --- src/menu/joystickmenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/menu/joystickmenu.cpp b/src/menu/joystickmenu.cpp index a7d950ed5..676bc1767 100644 --- a/src/menu/joystickmenu.cpp +++ b/src/menu/joystickmenu.cpp @@ -345,8 +345,8 @@ void UpdateJoystickMenu(IJoystickConfig *selected) for(unsigned i=0;imItems.Size();i++) { delete opt->mItems[i]; - opt->mItems.Clear(); } + opt->mItems.Clear(); int i; int itemnum = -1; From abb033d400eed5a5d3c2577b86764695c6d80cf6 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sat, 5 Sep 2015 14:18:48 +1200 Subject: [PATCH 31/61] Fix deallocation of controllers with no axes --- src/win32/i_dijoy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32/i_dijoy.cpp b/src/win32/i_dijoy.cpp index ccbc7ecdc..439e0fda7 100644 --- a/src/win32/i_dijoy.cpp +++ b/src/win32/i_dijoy.cpp @@ -309,7 +309,7 @@ FDInputJoystick::~FDInputJoystick() { Joy_GenerateButtonEvents(Axes[0].ButtonValue, 0, 2, KEY_JOYAXIS1PLUS); } - else + else if (Axes.Size() > 1) { Joy_GenerateButtonEvents(Axes[1].ButtonValue, 0, 4, KEY_JOYAXIS1PLUS); for (i = 2; i < Axes.Size(); ++i) From 9aabc852816921ed1c95e6bba094961fc8dbcaab Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sat, 5 Sep 2015 17:13:54 +1200 Subject: [PATCH 32/61] Fixed loading default map saves - Just like normal maps, default map stores an FString as a map name. --- src/g_level.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 899f96d4f..15d88ccaf 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1791,8 +1791,14 @@ void G_ReadSnapshots (PNGHandle *png) DWORD snapver; arc << snapver; - arc << namelen; - arc.Read (mapname, namelen); + if (SaveVersion < 4508) + { + arc << namelen; + arc.Read(mapname, namelen); + mapname[namelen] = 0; + MapName = mapname; + } + else arc << MapName; TheDefaultLevelInfo.snapshotVer = snapver; TheDefaultLevelInfo.snapshot = new FCompressedMemFile; TheDefaultLevelInfo.snapshot->Serialize (arc); From e939d6885d293020469840eef43a0ad42f902a8e Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Sat, 5 Sep 2015 23:58:02 +0200 Subject: [PATCH 33/61] - Fixed a crash in ACS strlen parsing with invalid argument. --- src/p_acs.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index b703b87dd..54f9fa658 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -8880,7 +8880,22 @@ scriptwait: break; case PCD_STRLEN: - STACK(1) = SDWORD(strlen(FBehavior::StaticLookupString (STACK(1)))); + { + const char *str = FBehavior::StaticLookupString(STACK(1)); + if (str != NULL) + { + STACK(1) = SDWORD(strlen(str)); + break; + } + + static bool StrlenInvalidPrintedAlready = false; + if (!StrlenInvalidPrintedAlready) + { + Printf(PRINT_BOLD, "Warning: ACS function strlen called with invalid string argument.\n"); + StrlenInvalidPrintedAlready = true; + } + STACK(1) = 0; + } break; case PCD_GETCVAR: From 99120d84420b01e6e03d0379682d966ef7907d9a Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 6 Sep 2015 12:12:57 +0100 Subject: [PATCH 34/61] - Fixed: A_SkullPop did not work with spy mode. --- src/p_user.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/p_user.cpp b/src/p_user.cpp index 0617e5d6a..0d5cdce20 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1562,12 +1562,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullPop) if (player != NULL) { player->mo = mo; - if (player->camera == self) - { - player->camera = mo; - } player->damagecount = 32; } + for (int i = 0; i < MAXPLAYERS; ++i) + { + if (playeringame[i] && players[i].camera == self) + { + players[i].camera = mo; + } + } } //---------------------------------------------------------------------------- From 68ea99016cdf1dfa649008c680924e9139671d87 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 6 Sep 2015 15:45:10 +0300 Subject: [PATCH 35/61] Compatibility fix for Whispers of Satan MAP29 Insta-death pit (sector 1497) is now working as intended independently from compatibility settings --- wadsrc/static/compatibility.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 26f43bb25..6cbe36af4 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -396,3 +396,8 @@ A53AE580A4AF2B5D0B0893F86914781E // TNT: Evilution map31 { setthingflags 470 2016 } + +D0139194F7817BF06F3988DFC47DB38D // Whispers of Satan map29 +{ + nopassover +} From bca50c58b30d3041b8094659ab1f250fdffc0c40 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 6 Sep 2015 16:00:47 +0200 Subject: [PATCH 36/61] - removed A_NoBlocking call from Commander Keen. --- wadsrc/static/actors/doom/keen.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/actors/doom/keen.txt b/wadsrc/static/actors/doom/keen.txt index 2c07e5b32..93d43764f 100644 --- a/wadsrc/static/actors/doom/keen.txt +++ b/wadsrc/static/actors/doom/keen.txt @@ -28,7 +28,7 @@ ACTOR CommanderKeen KEEN AB 6 KEEN C 6 A_Scream KEEN DEFGH 6 - KEEN I 6 A_NoBlocking + KEEN I 6 KEEN J 6 KEEN K 6 A_KeenDie KEEN L -1 From 213216368ab1988a93087827db2b074c7beadec9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 6 Sep 2015 16:36:32 +0200 Subject: [PATCH 37/61] - more DECORATE fixing of Doom monsters, this time the Mancubus. It looks like the definitions that got added on November 4th, 2006 had some issues that mostly went unnoticed over time... --- wadsrc/static/actors/doom/fatso.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wadsrc/static/actors/doom/fatso.txt b/wadsrc/static/actors/doom/fatso.txt index 1ad40fd93..0b3039325 100644 --- a/wadsrc/static/actors/doom/fatso.txt +++ b/wadsrc/static/actors/doom/fatso.txt @@ -30,9 +30,9 @@ ACTOR Fatso Missile: FATT G 20 A_FatRaise FATT H 10 BRIGHT A_FatAttack1 - FATT IG 5 + FATT IG 5 A_FaceTarget FATT H 10 BRIGHT A_FatAttack2 - FATT IG 5 + FATT IG 5 A_FaceTarget FATT H 10 BRIGHT A_FatAttack3 FATT IG 5 Goto See From 143a4c78a9dd630f9d9c2583e56da2b17f31bd21 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sun, 6 Sep 2015 19:57:43 -0500 Subject: [PATCH 38/61] - Added A_SetFloatSpeed. - Sets the FloatSpeed of the actor/pointer. --- src/thingdef/thingdef_codeptr.cpp | 24 +++++++++++++++++++++++- wadsrc/static/actors/actor.txt | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 54b816ebb..62a22532c 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5071,7 +5071,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropItem) // A_SetSpeed // //========================================================================== - DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed) { ACTION_PARAM_START(2); @@ -5089,6 +5088,28 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed) ref->Speed = speed; } +//========================================================================== +// +// A_SetFloatSpeed +// +//========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetFloatSpeed) +{ + ACTION_PARAM_START(2); + ACTION_PARAM_FIXED(speed, 0); + ACTION_PARAM_INT(ptr, 1); + + AActor *ref = COPY_AAPTR(self, ptr); + + if (!ref) + { + ACTION_SET_RESULT(false); + return; + } + + ref->FloatSpeed = speed; +} + //=========================================================================== // // Common A_Damage handler @@ -5823,3 +5844,4 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRipMax) ACTION_PARAM_INT(max, 0); self->RipLevelMax = max; } + diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index f231348d3..5877192ce 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -304,6 +304,7 @@ ACTOR Actor native //: Thinker action native A_SetDamageType(name damagetype); action native A_DropItem(class item, int dropamount = -1, int chance = 256); action native A_SetSpeed(float speed, int ptr = AAPTR_DEFAULT); + action native A_SetFloatSpeed(float speed, int ptr = AAPTR_DEFAULT); action native A_DamageSelf(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); action native A_DamageTarget(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); action native A_DamageMaster(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); From 8948f5dc2bcbcf95a207a5e2e695b0f2c8410e93 Mon Sep 17 00:00:00 2001 From: Xaser Acheron Date: Tue, 8 Sep 2015 10:40:21 -0500 Subject: [PATCH 39/61] Added FPF_NOAUTOAIM to A_FireCustomMissile --- src/p_local.h | 2 +- src/p_mobj.cpp | 4 ++-- src/thingdef/thingdef_codeptr.cpp | 3 ++- wadsrc/static/actors/constants.txt | 1 + wadsrc/static/actors/shared/inventory.txt | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index a2fa00c71..a8aaaeb0d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -153,7 +153,7 @@ AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, const PCl AActor *P_SpawnPlayerMissile (AActor* source, const PClass *type); AActor *P_SpawnPlayerMissile (AActor *source, const PClass *type, angle_t angle); AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, const PClass *type, angle_t angle, - AActor **pLineTarget = NULL, AActor **MissileActor = NULL, bool nofreeaim = false); + AActor **pLineTarget = NULL, AActor **MissileActor = NULL, bool nofreeaim = false, bool noautoaim = false); void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheight=false); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 267e71bb9..901372eef 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5923,7 +5923,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, const PClass *type, angle_t angle) AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, const PClass *type, angle_t angle, AActor **pLineTarget, AActor **pMissileActor, - bool nofreeaim) + bool nofreeaim, bool noautoaim) { static const int angdiff[3] = { -1<<26, 1<<26, 0 }; angle_t an = angle; @@ -5936,7 +5936,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, { return NULL; } - if (source->player && source->player->ReadyWeapon && (source->player->ReadyWeapon->WeaponFlags & WIF_NOAUTOAIM)) + if (source->player && source->player->ReadyWeapon && ((source->player->ReadyWeapon->WeaponFlags & WIF_NOAUTOAIM) || noautoaim)) { // Keep exactly the same angle and pitch as the player's own aim an = angle; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 62a22532c..5cc54a247 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1320,6 +1320,7 @@ enum FP_Flags { FPF_AIMATANGLE = 1, FPF_TRANSFERTRANSLATION = 2, + FPF_NOAUTOAIM = 4, }; DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) { @@ -1358,7 +1359,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) // Temporarily adjusts the pitch fixed_t SavedPlayerPitch = self->pitch; self->pitch -= pitch; - AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &linetarget); + AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &linetarget, NULL, false, Flags & FPF_NOAUTOAIM); self->pitch = SavedPlayerPitch; // automatic handling of seeker missiles diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 04ed6f1fc..b5a8b8cd4 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -188,6 +188,7 @@ const int CPF_STEALARMOR = 32; // Flags for A_CustomMissile const int FPF_AIMATANGLE = 1; const int FPF_TRANSFERTRANSLATION = 2; +const int FPF_NOAUTOAIM = 4; // Flags for A_Teleport enum diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 541dd37ac..13ae00936 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -10,7 +10,7 @@ ACTOR Inventory native action native A_JumpIfNoAmmo(state label); action native A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class armorbonustype = "ArmorBonus"); action native A_FireBullets(float spread_xy, float spread_z, int numbullets, int damageperbullet, class pufftype = "BulletPuff", int flags = 1, float range = 0); - action native A_FireCustomMissile(class missiletype, float angle = 0, bool useammo = true, int spawnofs_xy = 0, float spawnheight = 0, bool aimatangle = false, float pitch = 0); + action native A_FireCustomMissile(class missiletype, float angle = 0, bool useammo = true, int spawnofs_xy = 0, float spawnheight = 0, int flags = 0, float pitch = 0); action native A_RailAttack(int damage, int spawnofs_xy = 0, int useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class pufftype = "BulletPuff", float spread_xy = 0, float spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270); action native A_Light(int extralight); action native A_Light0(); From 19c702a60843c0c2dc41409ae0a9c92b31e30def Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Wed, 9 Sep 2015 21:26:44 +0200 Subject: [PATCH 40/61] - Fixed a crash when a player dies in damage floors. --- src/p_interaction.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index a0b1ddbc1..603535b7c 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -184,7 +184,6 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf const char *message; const char *messagename; char gendermessage[1024]; - bool friendly; int gender; // No obituaries for non-players, voodoo dolls or when not wanted @@ -197,8 +196,6 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf if (inflictor && inflictor->player && inflictor->player->mo != inflictor) MeansOfDeath = NAME_None; - friendly = (self->player != attacker->player && self->IsTeammate(attacker)); - mod = MeansOfDeath; message = NULL; messagename = NULL; @@ -266,7 +263,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf if (message == NULL && attacker != NULL && attacker->player != NULL) { - if (friendly) + if (self->player != attacker->player && self->IsTeammate(attacker)) { self = attacker; gender = self->player->userinfo.GetGender(); From 5afbe8ca007093f7cb6525b5300e4a5436d596ef Mon Sep 17 00:00:00 2001 From: Xaser Acheron Date: Wed, 9 Sep 2015 18:54:49 -0500 Subject: [PATCH 41/61] Fixed compiler warning for FPF_NOAUTOAIM flag check --- src/thingdef/thingdef_codeptr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 5cc54a247..dab68867b 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1359,7 +1359,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) // Temporarily adjusts the pitch fixed_t SavedPlayerPitch = self->pitch; self->pitch -= pitch; - AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &linetarget, NULL, false, Flags & FPF_NOAUTOAIM); + AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &linetarget, NULL, false, (Flags & FPF_NOAUTOAIM) != 0); self->pitch = SavedPlayerPitch; // automatic handling of seeker missiles From 36c7002628cdd73ae09eb0368ab2a9756ebcb529 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 13 Sep 2015 13:46:02 +1200 Subject: [PATCH 42/61] ACS module error was missing newline --- src/p_acs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index b703b87dd..5a25dd5cd 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1417,7 +1417,7 @@ FBehavior *FBehavior::StaticLoadModule (int lumpnum, FileReader *fr, int len) else { delete behavior; - Printf(TEXTCOLOR_RED "%s: invalid ACS module", Wads.GetLumpFullName(lumpnum)); + Printf(TEXTCOLOR_RED "%s: invalid ACS module\n", Wads.GetLumpFullName(lumpnum)); return NULL; } } From f02b52ef28549a4d35adb122384ca873bdda7e64 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sun, 13 Sep 2015 20:56:20 -0400 Subject: [PATCH 43/61] - Fixed: Initialization ordering warning in DPSpriteInterpolation. --- src/r_data/r_interpolate.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp index 46ac30789..6c2221520 100644 --- a/src/r_data/r_interpolate.cpp +++ b/src/r_data/r_interpolate.cpp @@ -866,11 +866,9 @@ void DPolyobjInterpolation::Serialize(FArchive &arc) //========================================================================== DPSpriteInterpolation::DPSpriteInterpolation(pspdef_t *_psp, int _player, int _position) -: nfsx(0), nfsy(0), ofsx(0), ofsy(0) +: psp(_psp), player(_player), position(_position), + ofsx(0), ofsy(0), nfsx(0), nfsy(0) { - psp = _psp; - player = _player; - position = _position; UpdateInterpolation (); interpolator.AddInterpolation(this); } From d7a04b9e98a14f6e10793505cee877ebf080d081 Mon Sep 17 00:00:00 2001 From: Blue-Shadow Date: Mon, 14 Sep 2015 17:22:41 +0300 Subject: [PATCH 44/61] dumpmapthings CCMD: Missing line break after "none". --- src/g_doomedmap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_doomedmap.cpp b/src/g_doomedmap.cpp index 45224329d..08d5aa2e2 100644 --- a/src/g_doomedmap.cpp +++ b/src/g_doomedmap.cpp @@ -135,7 +135,7 @@ CCMD (dumpmapthings) } else { - Printf("%6d none", infos[i]->Key); + Printf("%6d none\n", infos[i]->Key); } } From ee7eb3253a70933098cebc2054caea8c22eb02cb Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 15 Sep 2015 16:45:20 +0300 Subject: [PATCH 45/61] Added compatibility flag for point-on-line algorithm It's possible to use original but buggy implementations of P_PointOnLineSide() and P_PointOnDivlineSide() function See http://forum.zdoom.org/viewtopic.php?f=2&t=49544 --- src/compatibility.cpp | 1 + src/d_main.cpp | 4 +++- src/doomdef.h | 1 + src/g_mapinfo.cpp | 1 + src/p_local.h | 10 ++++++++-- wadsrc/static/menudef.txt | 1 + 6 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index d60677f64..498fefb2a 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -145,6 +145,7 @@ static FCompatOption Options[] = { "badangles", COMPATF2_BADANGLES, SLOT_COMPAT2 }, { "floormove", COMPATF2_FLOORMOVE, SLOT_COMPAT2 }, { "soundcutoff", COMPATF2_SOUNDCUTOFF, SLOT_COMPAT2 }, + { "pointonline", COMPATF2_POINTONLINE, SLOT_COMPAT2 }, { NULL, 0, 0 } }; diff --git a/src/d_main.cpp b/src/d_main.cpp index 98be13e33..3b3cce1f4 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -561,7 +561,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN| COMPATF_DEHHEALTH|COMPATF_INVISIBILITY|COMPATF_CROSSDROPOFF|COMPATF_CORPSEGIBS|COMPATF_HITSCAN| COMPATF_WALLRUN|COMPATF_NOTOSSDROPS|COMPATF_LIGHT|COMPATF_MASKEDMIDTEX; - w = COMPATF2_BADANGLES|COMPATF2_FLOORMOVE; + w = COMPATF2_BADANGLES|COMPATF2_FLOORMOVE|COMPATF2_POINTONLINE; break; case 3: // Boom compat mode @@ -580,6 +580,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) case 6: // Boom with some added settings to reenable some 'broken' behavior v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MISSILECLIP|COMPATF_NO_PASSMOBJ| COMPATF_INVISIBILITY|COMPATF_CORPSEGIBS|COMPATF_HITSCAN|COMPATF_WALLRUN|COMPATF_NOTOSSDROPS; + w = COMPATF2_POINTONLINE; break; } @@ -622,6 +623,7 @@ CVAR (Flag, compat_maskedmidtex, compatflags, COMPATF_MASKEDMIDTEX); CVAR (Flag, compat_badangles, compatflags2, COMPATF2_BADANGLES); CVAR (Flag, compat_floormove, compatflags2, COMPATF2_FLOORMOVE); CVAR (Flag, compat_soundcutoff, compatflags2, COMPATF2_SOUNDCUTOFF); +CVAR (Flag, compat_pointonline, compatflags2, COMPATF2_POINTONLINE); //========================================================================== // diff --git a/src/doomdef.h b/src/doomdef.h index c8aa66c17..802591386 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -340,6 +340,7 @@ enum COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW. COMPATF2_FLOORMOVE = 1 << 1, // Use the same floor motion behavior as Doom. COMPATF2_SOUNDCUTOFF = 1 << 2, // Cut off sounds when an actor vanishes instead of making it owner-less + COMPATF2_POINTONLINE = 1 << 3, // Use original but buggy P_PointOnLineSide() and P_PointOnDivlineSide() }; // Emulate old bugs for select maps. These are not exposed by a cvar diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 49493667e..ac938797d 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1333,6 +1333,7 @@ MapFlagHandlers[] = { "compat_badangles", MITYPE_COMPATFLAG, 0, COMPATF2_BADANGLES }, { "compat_floormove", MITYPE_COMPATFLAG, 0, COMPATF2_FLOORMOVE }, { "compat_soundcutoff", MITYPE_COMPATFLAG, 0, COMPATF2_SOUNDCUTOFF }, + { "compat_pointonline", MITYPE_COMPATFLAG, 0, COMPATF2_POINTONLINE }, { "cd_start_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end1_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end2_track", MITYPE_EATNEXT, 0, 0 }, diff --git a/src/p_local.h b/src/p_local.h index a8aaaeb0d..0e06ad72b 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -240,7 +240,10 @@ fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) { - return DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; + const SDWORD result = DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy); + return (compatflags2 & COMPATF2_POINTONLINE) + ? result >= 0 + : result > 0; } //========================================================================== @@ -254,7 +257,10 @@ inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line) { - return DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0; + const SDWORD result = DMulScale32 (y-line->y, line->dx, line->x-x, line->dy); + return (compatflags2 & COMPATF2_POINTONLINE) + ? result >= 0 + : result > 0; } //========================================================================== diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index f15f91dff..b1ca44de7 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1303,6 +1303,7 @@ OptionMenu "CompatibilityOptions" Option "Find shortest textures like Doom", "compat_SHORTTEX", "YesNo" Option "Use buggier stair building", "compat_stairs", "YesNo" Option "Use Doom's floor motion behavior", "compat_floormove", "YesNo" + Option "Use Doom's point-on-line algorithm", "compat_pointonline", "YesNo" StaticText " " StaticText "Physics Behavior",1 From 39b18a3447c3960c31043dd73ec5f2dbf5e2bcca Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 15 Sep 2015 18:21:05 +0300 Subject: [PATCH 46/61] Improved point-on-line compatibility feature P_PointOnLineSide() and P_PointOnDivlineSide() functions from the initial Doom source code release are used in compatibility mode --- src/p_local.h | 16 +++++---- src/p_maputl.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 7 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 0e06ad72b..cb404eb8c 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -240,10 +240,11 @@ fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) { - const SDWORD result = DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy); - return (compatflags2 & COMPATF2_POINTONLINE) - ? result >= 0 - : result > 0; + extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line); + + return compatflags2 & COMPATF2_POINTONLINE + ? P_VanillaPointOnLineSide(x, y, line) + : DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; } //========================================================================== @@ -257,10 +258,11 @@ inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line) { - const SDWORD result = DMulScale32 (y-line->y, line->dx, line->x-x, line->dy); + extern int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line); + return (compatflags2 & COMPATF2_POINTONLINE) - ? result >= 0 - : result > 0; + ? P_VanillaPointOnDivlineSide(x, y, line) + : (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0); } //========================================================================== diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 3a4a4c6a0..0a39460e7 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -1523,3 +1523,92 @@ static AActor *RoughBlockCheck (AActor *mo, int index, void *param) } return NULL; } + +//=========================================================================== +// +// P_VanillaPointOnLineSide +// P_PointOnLineSide() from the initial Doom source code release +// +//=========================================================================== + +int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line) +{ + fixed_t dx; + fixed_t dy; + fixed_t left; + fixed_t right; + + if (!line->dx) + { + if (x <= line->v1->x) + return line->dy > 0; + + return line->dy < 0; + } + if (!line->dy) + { + if (y <= line->v1->y) + return line->dx < 0; + + return line->dx > 0; + } + + dx = (x - line->v1->x); + dy = (y - line->v1->y); + + left = FixedMul ( line->dy>>FRACBITS , dx ); + right = FixedMul ( dy , line->dx>>FRACBITS ); + + if (right < left) + return 0; // front side + return 1; // back side +} + +//=========================================================================== +// +// P_VanillaPointOnDivlineSide +// P_PointOnDivlineSide() from the initial Doom source code release +// +//=========================================================================== + +int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line) +{ + fixed_t dx; + fixed_t dy; + fixed_t left; + fixed_t right; + + if (!line->dx) + { + if (x <= line->x) + return line->dy > 0; + + return line->dy < 0; + } + if (!line->dy) + { + if (y <= line->y) + return line->dx < 0; + + return line->dx > 0; + } + + dx = (x - line->x); + dy = (y - line->y); + + // try to quickly decide by looking at sign bits + if ( (line->dy ^ line->dx ^ dx ^ dy)&0x80000000 ) + { + if ( (line->dy ^ dx) & 0x80000000 ) + return 1; // (left is negative) + return 0; + } + + left = FixedMul ( line->dy>>8, dx>>8 ); + right = FixedMul ( dy>>8 , line->dx>>8 ); + + if (right < left) + return 0; // front side + return 1; // back side +} + From fea2cb38cc3caf4a71922faf658c3524a19beccc Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 15 Sep 2015 19:27:05 +0300 Subject: [PATCH 47/61] Fixed compatibility flags comparison for point-on-line Now it works in both cases: for compatibility mode set by user and for internal compatibility handler --- src/p_local.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index cb404eb8c..95d7541a8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -242,7 +242,7 @@ inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) { extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line); - return compatflags2 & COMPATF2_POINTONLINE + return i_compatflags2 & COMPATF2_POINTONLINE ? P_VanillaPointOnLineSide(x, y, line) : DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; } @@ -260,7 +260,7 @@ inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line) { extern int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line); - return (compatflags2 & COMPATF2_POINTONLINE) + return (i_compatflags2 & COMPATF2_POINTONLINE) ? P_VanillaPointOnDivlineSide(x, y, line) : (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0); } From 66437e32f6dec75e5692475ed737547d626bf1e4 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 15 Sep 2015 19:29:43 +0300 Subject: [PATCH 48/61] Added compatibility setting for Return to Hadron E1M9 See http://forum.zdoom.org/viewtopic.php?f=2&t=49544 --- wadsrc/static/compatibility.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 6cbe36af4..799168f75 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -401,3 +401,8 @@ D0139194F7817BF06F3988DFC47DB38D // Whispers of Satan map29 { nopassover } + +D7F6E9F08C39A17026349A04F8C0B0BE // Return to Hadron, e1m9 +{ + pointonline +} From f4b637db626412dcc3890689fcedb9b2aaeef490 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 15 Sep 2015 19:30:32 +0300 Subject: [PATCH 49/61] Changed compatibility fix for Nuke Mine E1M2 http://forum.zdoom.org/viewtopic.php?f=7&t=34013 --- wadsrc/static/compatibility.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 799168f75..3c41f871f 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -320,8 +320,7 @@ F481922F4881F74760F3C0437FD5EDD0 // map03 7C1913DEE396BA26CFF22A0E9369B7D2 // Nuke Mine, e1m2 { - clearlinespecial 1107 - clearlinespecial 1108 + pointonline } 5B862477519B21B30059A466F2FF6460 // Khorus, map08 From 6ee0672885b5856899efc6214d3ea203b28f7ac9 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 16 Sep 2015 13:36:18 +0300 Subject: [PATCH 50/61] Fixed missing hit sound for Heretic weapon Dragon Claw See http://forum.zdoom.org/viewtopic.php?f=2&t=49459 --- wadsrc/static/actors/heretic/hereticweaps.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/wadsrc/static/actors/heretic/hereticweaps.txt b/wadsrc/static/actors/heretic/hereticweaps.txt index 711c3fd29..f0db7caf2 100644 --- a/wadsrc/static/actors/heretic/hereticweaps.txt +++ b/wadsrc/static/actors/heretic/hereticweaps.txt @@ -802,6 +802,7 @@ ACTOR BlasterPuff +NOGRAVITY +PUFFONACTORS RenderStyle Add + SeeSound "weapons/blasterhit" States { Crash: From b2fa4970fd57773f5f3353fa64af6a3480177009 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 16 Sep 2015 16:13:56 +0300 Subject: [PATCH 51/61] Fixed potential crash in ACS engine Unknown p-code in compiled script may lead to a crash if the current module was changed during script execution, e.g. by function call See http://forum.zdoom.org/viewtopic.php?f=2&t=48524 --- src/p_acs.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index b85ae28e1..f4d148d09 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6032,6 +6032,7 @@ int DLevelScript::RunScript () int sp = 0; int *pc = this->pc; ACSFormat fmt = activeBehavior->GetFormat(); + FBehavior* const savedActiveBehavior = activeBehavior; unsigned int runaway = 0; // used to prevent infinite loops int pcd; FString work; @@ -6065,6 +6066,7 @@ int DLevelScript::RunScript () { default: Printf ("Unknown P-Code %d in %s\n", pcd, ScriptPresentation(script).GetChars()); + activeBehavior = savedActiveBehavior; // fall through case PCD_TERMINATE: DPrintf ("%s finished\n", ScriptPresentation(script).GetChars()); From 924a2aaaa7e12bf1ddb3fa1991735a4fe1be1e96 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 16 Sep 2015 16:56:43 +0300 Subject: [PATCH 52/61] Added "support" for PCD_CONSOLECOMMAND in ACS Now attempt to execute a console command from a script will not terminate its execution An error message will be issued in the console on every such attempt --- src/p_acs.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index f4d148d09..63ab71717 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -75,6 +75,7 @@ #include "actorptrselect.h" #include "farchive.h" #include "decallib.h" +#include "version.h" #include "g_shared/a_pickups.h" @@ -9357,6 +9358,10 @@ scriptwait: } break; + case PCD_CONSOLECOMMAND: + Printf (TEXTCOLOR_RED GAMENAME " doesn't support execution of console commands from scripts\n"); + sp -= 3; + break; } } From 4de57cd2967236a31b8206aec2a04c026a8c2b87 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Thu, 17 Sep 2015 10:14:54 +0300 Subject: [PATCH 53/61] Fixed compatibility issues on MAP25 of Eternal Doom See http://forum.zdoom.org/viewtopic.php?f=2&t=49577 --- wadsrc/static/compatibility.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 3c41f871f..1bd031ed8 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -55,6 +55,8 @@ A80E7EE40E0D0C76A6FBD242BE29FE27 // map15 { stairs maskedmidtex + corpsegibs + vileghosts } 10E1E2B36302D31AC4AE68C84B5DC457 // Eternal Doom MAP28 @@ -125,7 +127,6 @@ BA530202AF0BA0C6CBAE6A0C7076FB72 // Requiem map04 CBDFEFAC579A62DE8F1B48CA4A09D381 // gather2.wad map05 and darkside.wad map01 C7A2FAFB0AFB2632C50AD625CDB50E51 // Reverie map18 9E5724BC6135AA6F86EE54FD4D91F1E2 // Project X map14 -6DA6FCBA8089161BDEC6A1D3F6C8D60F // Eternal Doom map25 01899825FFEAE016D39C02A7DA4B218F // Archie map01 1D9F3AFDC2517C2E450491ED13896712 // Seej map01 0AE745A3AB86D15FB2FB74489962C421 // 6pack2 map02 From 621116a289d6066889eefd02693b60117795429d Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Fri, 18 Sep 2015 10:53:46 +0300 Subject: [PATCH 54/61] Disabled loading of SDL output plugin for FMOD Ex on OS X Long path to executable file corrupts stack inside FMOD library This plugin is not being built for OS X, output through CoreAudio works just fine --- src/sound/fmodsound.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 8433b301b..33ca0495d 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -771,7 +771,7 @@ bool FMODSoundRenderer::Init() } #endif -#ifndef _WIN32 +#if !defined _WIN32 && !defined __APPLE__ // Try to load SDL output plugin result = Sys->setPluginPath(progdir); // Should we really look for it in the program directory? result = Sys->loadPlugin("liboutput_sdl.so", &OutputPlugin); From b613db4ae5c05655a93792671b50b41d4b4c80d4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 18 Sep 2015 17:41:16 +0200 Subject: [PATCH 55/61] Revert "Merge pull request #359 from Leonard2/master" This reverts commit 364ca11b43d8f4cd736506918f5c1fdb63721235, reversing changes made to dae0e217d1f16260c6e94a3d5db5a8dfcf117ecb. Conflicts: src/r_data/r_interpolate.cpp --- src/d_player.h | 1 - src/g_game.cpp | 9 -- src/p_pspr.cpp | 21 ---- src/p_pspr.h | 6 -- src/p_saveg.cpp | 5 - src/p_user.cpp | 15 --- src/r_data/r_interpolate.cpp | 196 +---------------------------------- src/version.h | 2 +- 8 files changed, 4 insertions(+), 251 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 2ac2ad0d5..e27bf1087 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -427,7 +427,6 @@ public: short fixedcolormap; // can be set to REDCOLORMAP, etc. short fixedlightlevel; pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc) - TObjPtr pspinterp[NUMPSPRITES]; // view sprite interpolations int morphTics; // player is a chicken/pig if > 0 const PClass *MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed int MorphStyle; // which effects to apply for this player instance when morphed diff --git a/src/g_game.cpp b/src/g_game.cpp index f77949687..8101ca23d 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1726,15 +1726,6 @@ void G_DoPlayerPop(int playernum) players[playernum].mo = NULL; players[playernum].camera = NULL; } - // Now's the ideal time to remove his psprite interpolations. - for (int ii = 0; ii < NUMPSPRITES; ii++) - { - if (players[playernum].psprites[ii].interpolation != NULL) - { - players[playernum].psprites[ii].StopInterpolation(); - players[playernum].pspinterp[ii] = NULL; - } - } // [RH] Let the scripts know the player left FBehavior::StaticStartTypedScripts(SCRIPT_Disconnect, NULL, true, playernum); } diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index d2bf8cc87..63f3bc648 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -1104,32 +1104,11 @@ void P_MovePsprites (player_t *player) P_CheckWeaponZoom (player); } } - - psp = &player->psprites[0]; - for (i = 0; i < NUMPSPRITES; i++, psp++) - { - if (psp->state == NULL) - { - if (psp->interpolation != NULL) - { - player->pspinterp[i] = NULL; - psp->StopInterpolation(); - } - } - else if (psp->interpolation == NULL) - { - player->pspinterp[i] = psp->SetInterpolation(player - players, i); - } - } } FArchive &operator<< (FArchive &arc, pspdef_t &def) { arc << def.state << def.tics << def.sx << def.sy << def.sprite << def.frame; - - if (SaveVersion >= 4525) - arc << def.interpolation; - return arc; } diff --git a/src/p_pspr.h b/src/p_pspr.h index 62c2a6fe4..ca9b45ee8 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -26,7 +26,6 @@ // Basic data types. // Needs fixed point, and BAM angles. #include "tables.h" -#include "r_data/r_interpolate.h" #include "thingdef/thingdef.h" #define WEAPONBOTTOM 128*FRACUNIT @@ -72,11 +71,6 @@ struct pspdef_t int sprite; int frame; bool processPending; // true: waiting for periodic processing on this tick - - TObjPtr interpolation; - DInterpolation *SetInterpolation(int player, int position); - void UpdateInterpolation(int player); - void StopInterpolation(); }; class FArchive; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index f16bdb0f9..480494320 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -297,11 +297,6 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name) { dst->mo->player = dst; } - // Fix the psprite interpolation pointers too. - for (int i = 0; i < NUMPSPRITES; i++) - { - dst->psprites[i].UpdateInterpolation(dst - players); - } // These 2 variables may not be overwritten. dst->attackdown = attackdown; dst->usedown = usedown; diff --git a/src/p_user.cpp b/src/p_user.cpp index ced6732a3..0d5cdce20 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -316,7 +316,6 @@ player_t::player_t() memset (&cmd, 0, sizeof(cmd)); memset (frags, 0, sizeof(frags)); memset (psprites, 0, sizeof(psprites)); - memset (pspinterp, 0, sizeof(pspinterp)); } player_t &player_t::operator=(const player_t &p) @@ -372,7 +371,6 @@ player_t &player_t::operator=(const player_t &p) fixedcolormap = p.fixedcolormap; fixedlightlevel = p.fixedlightlevel; memcpy(psprites, &p.psprites, sizeof(psprites)); - memcpy(pspinterp, &p.pspinterp, sizeof(pspinterp)); morphTics = p.morphTics; MorphedPlayerClass = p.MorphedPlayerClass; MorphStyle = p.MorphStyle; @@ -437,10 +435,6 @@ size_t player_t::FixPointers (const DObject *old, DObject *rep) if (*&ConversationNPC == old) ConversationNPC = replacement, changed++; if (*&ConversationPC == old) ConversationPC = replacement, changed++; if (*&MUSINFOactor == old) MUSINFOactor = replacement, changed++; - - for (int i = 0; i < NUMPSPRITES; i++) - if (*&pspinterp[i] == old) pspinterp[i] = static_cast(rep), changed++; - return changed; } @@ -460,11 +454,6 @@ size_t player_t::PropagateMark() { GC::Mark(PendingWeapon); } - for (int i = 0; i < NUMPSPRITES; i++) - { - GC::Mark(pspinterp[i]); - } - return sizeof(*this); } @@ -3063,11 +3052,7 @@ void player_t::Serialize (FArchive &arc) for (i = 0; i < MAXPLAYERS; i++) arc << frags[i]; for (i = 0; i < NUMPSPRITES; i++) - { arc << psprites[i]; - if (SaveVersion >= 4525) - arc << pspinterp[i]; - } arc << CurrentPlayerClass; diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp index 6c2221520..3ca3b557c 100644 --- a/src/r_data/r_interpolate.cpp +++ b/src/r_data/r_interpolate.cpp @@ -151,35 +151,6 @@ public: }; -//========================================================================== -// -// -// -//========================================================================== - -class DPSpriteInterpolation : public DInterpolation -{ - DECLARE_CLASS(DPSpriteInterpolation, DInterpolation) - - pspdef_t *psp; - int player, position; - fixed_t oldx, oldy; - fixed_t bakx, baky; - fixed_t ofsx, ofsy; - fixed_t nfsx, nfsy; - -public: - - DPSpriteInterpolation() {} - DPSpriteInterpolation(pspdef_t *psp, int player, int position); - void UpdatePointer(int player); - void Destroy(); - void UpdateInterpolation(); - void Restore(); - void Interpolate(fixed_t smoothratio); - void Serialize(FArchive &arc); -}; - //========================================================================== // // @@ -191,7 +162,6 @@ IMPLEMENT_CLASS(DSectorPlaneInterpolation) IMPLEMENT_CLASS(DSectorScrollInterpolation) IMPLEMENT_CLASS(DWallScrollInterpolation) IMPLEMENT_CLASS(DPolyobjInterpolation) -IMPLEMENT_CLASS(DPSpriteInterpolation) //========================================================================== // @@ -658,6 +628,7 @@ void DSectorScrollInterpolation::Serialize(FArchive &arc) arc << sector << ceiling << oldx << oldy; } + //========================================================================== // // @@ -853,113 +824,6 @@ void DPolyobjInterpolation::Serialize(FArchive &arc) if (arc.IsLoading()) bakverts.Resize(oldverts.Size()); } -//========================================================================== -// -// -// -//========================================================================== - -//========================================================================== -// -// -// -//========================================================================== - -DPSpriteInterpolation::DPSpriteInterpolation(pspdef_t *_psp, int _player, int _position) -: psp(_psp), player(_player), position(_position), - ofsx(0), ofsy(0), nfsx(0), nfsy(0) -{ - UpdateInterpolation (); - interpolator.AddInterpolation(this); -} - -//========================================================================== -// -// -// -//========================================================================== - -void DPSpriteInterpolation::UpdatePointer(int _player) -{ - player = _player; - psp = &players[player].psprites[position]; -} - -//========================================================================== -// -// -// -//========================================================================== - -void DPSpriteInterpolation::Destroy() -{ - psp->interpolation = NULL; - Super::Destroy(); -} - -//========================================================================== -// -// -// -//========================================================================== - -void DPSpriteInterpolation::UpdateInterpolation() -{ - if ( position == ps_weapon ) - P_BobWeapon( &players[player], psp, &ofsx, &ofsy ); - - oldx = psp->sx + ofsx; - oldy = psp->sy + ofsy; -} - -//========================================================================== -// -// -// -//========================================================================== - -void DPSpriteInterpolation::Restore() -{ - psp->sx = bakx - nfsx; - psp->sy = baky - nfsy; -} - -//========================================================================== -// -// -// -//========================================================================== - -void DPSpriteInterpolation::Interpolate(fixed_t smoothratio) -{ - if ( position == ps_weapon ) - P_BobWeapon( &players[player], psp, &nfsx, &nfsy ); - - bakx = psp->sx + nfsx; - baky = psp->sy + nfsy; - - psp->sx = oldx + FixedMul(bakx - oldx, smoothratio) - nfsx; - psp->sy = oldy + FixedMul(baky - oldy, smoothratio) - nfsy; -} - -//========================================================================== -// -// -// -//========================================================================== - -void DPSpriteInterpolation::Serialize(FArchive &arc) -{ - Super::Serialize(arc); - arc << player << position << oldx << oldy << ofsx << ofsy; - UpdatePointer(player); -} - -//========================================================================== -// -// -// -//========================================================================== //========================================================================== // @@ -1080,62 +944,6 @@ void FPolyObj::StopInterpolation() } } -//========================================================================== -// -// -// -//========================================================================== - -DInterpolation *pspdef_t::SetInterpolation(int player, int position) -{ - if (interpolation == NULL) - { - interpolation = new DPSpriteInterpolation(this, player, position); - } - interpolation->AddRef(); - GC::WriteBarrier(interpolation); - return interpolation; -} - -//========================================================================== -// -// -// -//========================================================================== - -void pspdef_t::UpdateInterpolation(int player) -{ - if (interpolation != NULL) - { - barrier_cast(interpolation)->UpdatePointer(player); - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void pspdef_t::StopInterpolation() -{ - if (interpolation != NULL) - { - interpolation->DelRef(); - } -} - -//========================================================================== -// -// -// -//========================================================================== - -//========================================================================== -// -// -// -//========================================================================== ADD_STAT (interpolations) { @@ -1143,3 +951,5 @@ ADD_STAT (interpolations) out.Format ("%d interpolations", interpolator.CountInterpolations ()); return out; } + + diff --git a/src/version.h b/src/version.h index 168cb7519..913c9bd18 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4525 +#define SAVEVER 4524 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) From 98bdbb1ad8c9d7e06a5a7d2ed2e64779b12c097d Mon Sep 17 00:00:00 2001 From: ZzZombo Date: Sat, 19 Sep 2015 09:40:19 +0800 Subject: [PATCH 56/61] -Fixed PCD_DROP affecting script result value. --- src/p_acs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 63ab71717..4e5875836 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -7274,9 +7274,9 @@ int DLevelScript::RunScript () sp--; break; - case PCD_DROP: case PCD_SETRESULTVALUE: resultValue = STACK(1); + case PCD_DROP: //fall through. sp--; break; From 23577f4be8c3cf4cdd9dbf73043bb3702cb77116 Mon Sep 17 00:00:00 2001 From: khokh2001 Date: Sun, 20 Sep 2015 02:11:03 +0900 Subject: [PATCH 57/61] nuked opl emulator update --- src/oplsynth/nukedopl3.cpp | 427 ++++++++++++++++++++----------------- src/oplsynth/nukedopl3.h | 15 +- 2 files changed, 245 insertions(+), 197 deletions(-) diff --git a/src/oplsynth/nukedopl3.cpp b/src/oplsynth/nukedopl3.cpp index 4d143f4a5..0baa67bda 100644 --- a/src/oplsynth/nukedopl3.cpp +++ b/src/oplsynth/nukedopl3.cpp @@ -1,5 +1,5 @@ /* -* Copyright (C) 2013-2014 Nuke.YKT +* Copyright (C) 2013-2014 Nuke.YKT(Alexey Khokholov) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,53 +27,31 @@ OPL2 ROMs. */ -//version 1.5 +//version 1.6 /* Changelog: v1.1: - Vibrato's sign fix + Vibrato's sign fix. v1.2: - Operator key fix - Corrected 4-operator mode - Corrected rhythm mode - Some small fixes + Operator key fix. + Corrected 4-operator mode. + Corrected rhythm mode. + Some small fixes. v1.2.1: - Small envelope generator fix - Removed EX_Get function(not used) + Small envelope generator fix. v1.3: - Complete rewrite - (Not released) + Complete rewrite. v1.4: - New envelope and waveform generator + New envelope and waveform generator. Some small fixes. - (Not released) v1.4.1: - Envelope generator rate calculation fix - (Not released) + Envelope generator rate calculation fix. v1.4.2: Version for ZDoom. v1.5: - Optimizations -*/ - - -/* Verified: - Noise generator. - Waveform generator. - Envelope generator increase table. - Tremolo. -*/ - -/* TODO: - Verify: - kslrom[15] value(is it 128?). - Sustain level = 15. - Vibrato, Phase generator. - Rhythm part. - Envelope generator state switching(decay->sustain when egt = 1 and decay->release). - Feedback. - Register write. - 4-operator. + Optimizations. + v1.6: + Improved emulation output. */ #include @@ -216,19 +194,17 @@ envelope_sinfunc envelope_sin[8] = { }; void envelope_gen_off(opl_slot *slott); -void envelope_gen_change(opl_slot *slott); void envelope_gen_attack(opl_slot *slott); void envelope_gen_decay(opl_slot *slott); void envelope_gen_sustain(opl_slot *slott); void envelope_gen_release(opl_slot *slott); -envelope_genfunc envelope_gen[6] = { +envelope_genfunc envelope_gen[5] = { envelope_gen_off, envelope_gen_attack, envelope_gen_decay, envelope_gen_sustain, - envelope_gen_release, - envelope_gen_change + envelope_gen_release }; enum envelope_gen_num { @@ -252,7 +228,7 @@ Bit8u envelope_calc_rate(opl_slot *slot, Bit8u reg_rate) { } void envelope_update_ksl(opl_slot *slot) { - Bit16s ksl = (kslrom[slot->channel->f_num >> 6] << 1) - ((slot->channel->block ^ 0x07) << 5) - 0x20; + Bit16s ksl = (kslrom[slot->channel->f_num >> 6] << 2) - ((0x08 - slot->channel->block) << 5); if (ksl < 0) { ksl = 0; } @@ -281,28 +257,25 @@ void envelope_gen_off(opl_slot *slot) { slot->eg_rout = 0x1ff; } -void envelope_gen_change(opl_slot *slot) { - slot->eg_gen = slot->eg_gennext; - envelope_update_rate(slot); -} - void envelope_gen_attack(opl_slot *slot) { + if (slot->eg_rout == 0x00) { + slot->eg_gen = envelope_gen_num_decay; + envelope_update_rate(slot); + return; + } slot->eg_rout += ((~slot->eg_rout) *slot->eg_inc) >> 3; if (slot->eg_rout < 0x00) { slot->eg_rout = 0x00; } - if (!slot->eg_rout) { - slot->eg_gen = envelope_gen_num_change; - slot->eg_gennext = envelope_gen_num_decay; - } } void envelope_gen_decay(opl_slot *slot) { - slot->eg_rout += slot->eg_inc; if (slot->eg_rout >= slot->reg_sl << 4) { - slot->eg_gen = envelope_gen_num_change; - slot->eg_gennext = envelope_gen_num_sustain; + slot->eg_gen = envelope_gen_num_sustain; + envelope_update_rate(slot); + return; } + slot->eg_rout += slot->eg_inc; } void envelope_gen_sustain(opl_slot *slot) { @@ -312,11 +285,13 @@ void envelope_gen_sustain(opl_slot *slot) { } void envelope_gen_release(opl_slot *slot) { - slot->eg_rout += slot->eg_inc; if (slot->eg_rout >= 0x1ff) { - slot->eg_gen = envelope_gen_num_change; - slot->eg_gennext = envelope_gen_num_off; + slot->eg_gen = envelope_gen_num_off; + slot->eg_rout = 0x1ff; + envelope_update_rate(slot); + return; } + slot->eg_rout += slot->eg_inc; } void envelope_calc(opl_slot *slot) { @@ -324,10 +299,7 @@ void envelope_calc(opl_slot *slot) { rate_h = slot->eg_rate >> 2; rate_l = slot->eg_rate & 3; Bit8u inc = 0; - if (slot->eg_gen == envelope_gen_num_attack && rate_h == 0x0f) { - inc = 8; - } - else if (eg_incsh[rate_h] > 0) { + if (eg_incsh[rate_h] > 0) { if ((slot->chip->timer & ((1 << eg_incsh[rate_h]) - 1)) == 0) { inc = eg_incstep[eg_incdesc[rate_h]][rate_l][((slot->chip->timer) >> eg_incsh[rate_h]) & 0x07]; } @@ -336,14 +308,19 @@ void envelope_calc(opl_slot *slot) { inc = eg_incstep[eg_incdesc[rate_h]][rate_l][slot->chip->timer & 0x07] << (-eg_incsh[rate_h]); } slot->eg_inc = inc; - envelope_gen[slot->eg_gen](slot); slot->eg_out = slot->eg_rout + (slot->reg_tl << 2) + (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem; + envelope_gen[slot->eg_gen](slot); } void eg_keyon(opl_slot *slot, Bit8u type) { if (!slot->key) { - slot->eg_gen = envelope_gen_num_change; - slot->eg_gennext = envelope_gen_num_attack; + slot->eg_gen = envelope_gen_num_attack; + envelope_update_rate(slot); + if ((slot->eg_rate >> 2) == 0x0f) { + slot->eg_gen = envelope_gen_num_decay; + envelope_update_rate(slot); + slot->eg_rout = 0x00; + } slot->pg_phase = 0x00; } slot->key |= type; @@ -353,8 +330,8 @@ void eg_keyoff(opl_slot *slot, Bit8u type) { if (slot->key) { slot->key &= (~type); if (!slot->key) { - slot->eg_gen = envelope_gen_num_change; - slot->eg_gennext = envelope_gen_num_release; + slot->eg_gen = envelope_gen_num_release; + envelope_update_rate(slot); } } } @@ -366,7 +343,7 @@ void eg_keyoff(opl_slot *slot, Bit8u type) { void pg_generate(opl_slot *slot) { Bit16u f_num = slot->channel->f_num; if (slot->reg_vib) { - Bit8u f_num_high = f_num >> (7 + vib_table[(slot->chip->timer >> 10)&0x07] + (0x01 - slot->chip->dvb)); + Bit8u f_num_high = f_num >> (7 + vib_table[(slot->chip->timer >> 10) & 0x07] + (0x01 - slot->chip->dvb)); f_num += f_num_high * vibsgn_table[(slot->chip->timer >> 10) & 0x07]; } slot->pg_phase += (((f_num << slot->channel->block) >> 1) * mt[slot->reg_mult]) >> 1; @@ -387,7 +364,7 @@ void n_generate(opl_chip *chip) { // Slot // -void slot_write20(opl_slot *slot,Bit8u data) { +void slot_write20(opl_slot *slot, Bit8u data) { if ((data >> 7) & 0x01) { slot->trem = &slot->chip->tremval; } @@ -434,14 +411,14 @@ void slot_generatephase(opl_slot *slot, Bit16u phase) { } void slot_generate(opl_slot *slot) { - slot->out = envelope_sin[slot->reg_wf]((slot->pg_phase >> 9) + (*slot->mod), slot->eg_out); + slot->out = envelope_sin[slot->reg_wf]((Bit16u)(slot->pg_phase >> 9) + (*slot->mod), slot->eg_out); } void slot_generatezm(opl_slot *slot) { - slot->out = envelope_sin[slot->reg_wf]((slot->pg_phase >> 9), slot->eg_out); + slot->out = envelope_sin[slot->reg_wf]((Bit16u)(slot->pg_phase >> 9), slot->eg_out); } -void slot_calgfb(opl_slot *slot) { +void slot_calcfb(opl_slot *slot) { slot->prout[1] = slot->prout[0]; slot->prout[0] = slot->out; if (slot->channel->fb != 0x00) { @@ -461,57 +438,61 @@ void chan_setupalg(opl_channel *channel); void chan_updaterhythm(opl_chip *chip, Bit8u data) { chip->rhy = data & 0x3f; if (chip->rhy & 0x20) { - chip->channel[6].out[0] = &chip->slot[13].out; - chip->channel[6].out[1] = &chip->slot[13].out; - chip->channel[6].out[2] = &chip->zeromod; - chip->channel[6].out[3] = &chip->zeromod; - chip->channel[7].out[0] = &chip->slot[14].out; - chip->channel[7].out[1] = &chip->slot[14].out; - chip->channel[7].out[2] = &chip->slot[15].out; - chip->channel[7].out[3] = &chip->slot[15].out; - chip->channel[8].out[0] = &chip->slot[16].out; - chip->channel[8].out[1] = &chip->slot[16].out; - chip->channel[8].out[2] = &chip->slot[17].out; - chip->channel[8].out[3] = &chip->slot[17].out; + opl_channel *channel6 = &chip->channel[6]; + opl_channel *channel7 = &chip->channel[7]; + opl_channel *channel8 = &chip->channel[8]; + channel6->out[0] = &channel6->slots[1]->out; + channel6->out[1] = &channel6->slots[1]->out; + channel6->out[2] = &chip->zeromod; + channel6->out[3] = &chip->zeromod; + channel7->out[0] = &channel7->slots[0]->out; + channel7->out[1] = &channel7->slots[0]->out; + channel7->out[2] = &channel7->slots[1]->out; + channel7->out[3] = &channel7->slots[1]->out; + channel8->out[0] = &channel8->slots[0]->out; + channel8->out[1] = &channel8->slots[0]->out; + channel8->out[2] = &channel8->slots[1]->out; + channel8->out[3] = &channel8->slots[1]->out; for (Bit8u chnum = 6; chnum < 9; chnum++) { chip->channel[chnum].chtype = ch_drum; } + chan_setupalg(channel6); //hh if (chip->rhy & 0x01) { - eg_keyon(&chip->slot[14], egk_drum); + eg_keyon(channel7->slots[0], egk_drum); } else { - eg_keyoff(&chip->slot[14], egk_drum); + eg_keyoff(channel7->slots[0], egk_drum); } //tc if (chip->rhy & 0x02) { - eg_keyon(&chip->slot[17], egk_drum); + eg_keyon(channel8->slots[1], egk_drum); } else { - eg_keyoff(&chip->slot[17], egk_drum); + eg_keyoff(channel8->slots[1], egk_drum); } //tom if (chip->rhy & 0x04) { - eg_keyon(&chip->slot[16], egk_drum); + eg_keyon(channel8->slots[0], egk_drum); } else { - eg_keyoff(&chip->slot[16], egk_drum); + eg_keyoff(channel8->slots[0], egk_drum); } //sd if (chip->rhy & 0x08) { - eg_keyon(&chip->slot[15], egk_drum); + eg_keyon(channel7->slots[1], egk_drum); } else { - eg_keyoff(&chip->slot[15], egk_drum); + eg_keyoff(channel7->slots[1], egk_drum); } //bd if (chip->rhy & 0x10) { - eg_keyon(&chip->slot[12], egk_drum); - eg_keyon(&chip->slot[13], egk_drum); + eg_keyon(channel6->slots[0], egk_drum); + eg_keyon(channel6->slots[1], egk_drum); } else { - eg_keyoff(&chip->slot[12], egk_drum); - eg_keyoff(&chip->slot[13], egk_drum); + eg_keyoff(channel6->slots[0], egk_drum); + eg_keyoff(channel6->slots[1], egk_drum); } } else { @@ -566,6 +547,16 @@ void chan_writeb0(opl_channel *channel, Bit8u data) { void chan_setupalg(opl_channel *channel) { if (channel->chtype == ch_drum) { + switch (channel->alg & 0x01) { + case 0x00: + channel->slots[0]->mod = &channel->slots[0]->fbmod; + channel->slots[1]->mod = &channel->slots[0]->out; + break; + case 0x01: + channel->slots[0]->mod = &channel->slots[0]->fbmod; + channel->slots[1]->mod = &channel->chip->zeromod; + break; + } return; } if (channel->alg & 0x08) { @@ -672,49 +663,39 @@ void chan_writec0(opl_channel *channel, Bit8u data) { } } -void chan_generaterhythm(opl_chip *chip) { - if (chip->rhy & 0x20) { - opl_channel *channel6 = &chip->channel[6]; - opl_channel *channel7 = &chip->channel[7]; - opl_channel *channel8 = &chip->channel[8]; - slot_generate(channel6->slots[0]); - slot_generate(channel6->slots[1]); - Bit16u phase14 = channel7->slots[0]->pg_phase & 0x3ff; - Bit16u phase17 = channel8->slots[1]->pg_phase & 0x3ff; - Bit16u phase = 0x00; - //hh tc phase bit - Bit16u phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; - //hh - phase = (phasebit << 9) | (0x34 << ((phasebit ^ (chip->noise & 0x01) << 1))); - slot_generatephase(channel7->slots[0], phase); - //sd - phase = (0x100 << ((phase14 >> 8) & 0x01)) ^ ((chip->noise & 0x01) << 8); - slot_generatephase(channel7->slots[1], phase); - //tt - slot_generatezm(channel8->slots[0]); - //tc - phase = 0x100 | (phasebit << 9); - slot_generatephase(channel8->slots[1], phase); - } +void chan_generaterhythm1(opl_chip *chip) { + opl_channel *channel6 = &chip->channel[6]; + opl_channel *channel7 = &chip->channel[7]; + opl_channel *channel8 = &chip->channel[8]; + slot_generate(channel6->slots[0]); + Bit16u phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; + Bit16u phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; + Bit16u phase = 0x00; + //hh tc phase bit + Bit16u phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; + //hh + phase = (phasebit << 9) | (0x34 << ((phasebit ^ (chip->noise & 0x01) << 1))); + slot_generatephase(channel7->slots[0], phase); + //tt + slot_generatezm(channel8->slots[0]); } -void chan_generate(opl_channel *channel) { - if (channel->chtype == ch_drum) { - return; - } - if (channel->alg & 0x08) { - return; - } - if (channel->alg & 0x04) { - slot_generate(channel->pair->slots[0]); - slot_generate(channel->pair->slots[1]); - slot_generate(channel->slots[0]); - slot_generate(channel->slots[1]); - } - else { - slot_generate(channel->slots[0]); - slot_generate(channel->slots[1]); - } +void chan_generaterhythm2(opl_chip *chip) { + opl_channel *channel6 = &chip->channel[6]; + opl_channel *channel7 = &chip->channel[7]; + opl_channel *channel8 = &chip->channel[8]; + slot_generate(channel6->slots[1]); + Bit16u phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; + Bit16u phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; + Bit16u phase = 0x00; + //hh tc phase bit + Bit16u phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; + //sd + phase = (0x100 << ((phase14 >> 8) & 0x01)) ^ ((chip->noise & 0x01) << 8); + slot_generatephase(channel7->slots[1], phase); + //tc + phase = 0x100 | (phasebit << 9); + slot_generatephase(channel8->slots[1], phase); } void chan_enable(opl_channel *channel) { @@ -782,21 +763,132 @@ Bit16s limshort(Bit32s a) { return (Bit16s)a; } +void chip_generate(opl_chip *chip, Bit16s *buff) { + buff[1] = limshort(chip->mixbuff[1]); + + for (Bit8u ii = 0; ii < 12; ii++) { + slot_calcfb(&chip->slot[ii]); + pg_generate(&chip->slot[ii]); + envelope_calc(&chip->slot[ii]); + slot_generate(&chip->slot[ii]); + } + + for (Bit8u ii = 12; ii < 15; ii++) { + slot_calcfb(&chip->slot[ii]); + pg_generate(&chip->slot[ii]); + envelope_calc(&chip->slot[ii]); + } + + if (chip->rhy & 0x20) { + chan_generaterhythm1(chip); + } + else { + slot_generate(&chip->slot[12]); + slot_generate(&chip->slot[13]); + slot_generate(&chip->slot[14]); + } + + chip->mixbuff[0] = 0; + for (Bit8u ii = 0; ii < 18; ii++) { + Bit16s accm = 0; + for (Bit8u jj = 0; jj < 4; jj++) { + accm += *chip->channel[ii].out[jj]; + } + if (chip->FullPan) { + chip->mixbuff[0] += (Bit16s)(accm * chip->channel[ii].fcha); + } + else { + chip->mixbuff[0] += (Bit16s)(accm & chip->channel[ii].cha); + } + } + + for (Bit8u ii = 15; ii < 18; ii++) { + slot_calcfb(&chip->slot[ii]); + pg_generate(&chip->slot[ii]); + envelope_calc(&chip->slot[ii]); + } + + if (chip->rhy & 0x20) { + chan_generaterhythm2(chip); + } + else { + slot_generate(&chip->slot[15]); + slot_generate(&chip->slot[16]); + slot_generate(&chip->slot[17]); + } + + buff[0] = limshort(chip->mixbuff[0]); + + for (Bit8u ii = 18; ii < 33; ii++) { + slot_calcfb(&chip->slot[ii]); + pg_generate(&chip->slot[ii]); + envelope_calc(&chip->slot[ii]); + slot_generate(&chip->slot[ii]); + } + + chip->mixbuff[1] = 0; + for (Bit8u ii = 0; ii < 18; ii++) { + Bit16s accm = 0; + for (Bit8u jj = 0; jj < 4; jj++) { + accm += *chip->channel[ii].out[jj]; + } + if (chip->FullPan) { + chip->mixbuff[1] += (Bit16s)(accm * chip->channel[ii].fchb); + } + else { + chip->mixbuff[1] += (Bit16s)(accm & chip->channel[ii].chb); + } + } + + for (Bit8u ii = 33; ii < 36; ii++) { + slot_calcfb(&chip->slot[ii]); + pg_generate(&chip->slot[ii]); + envelope_calc(&chip->slot[ii]); + slot_generate(&chip->slot[ii]); + } + + n_generate(chip); + + if ((chip->timer & 0x3f) == 0x3f) { + if (!chip->tremdir) { + if (chip->tremtval == 105) { + chip->tremtval--; + chip->tremdir = 1; + } + else { + chip->tremtval++; + } + } + else { + if (chip->tremtval == 0) { + chip->tremtval++; + chip->tremdir = 0; + } + else { + chip->tremtval--; + } + } + chip->tremval = (chip->tremtval >> 2) >> ((1 - chip->dam) << 1); + } + + chip->timer++; +} + void NukedOPL3::Reset() { memset(&opl3, 0, sizeof(opl_chip)); for (Bit8u slotnum = 0; slotnum < 36; slotnum++) { - opl3.slot[slotnum].channel = &opl3.channel[slotnum / 2]; opl3.slot[slotnum].chip = &opl3; opl3.slot[slotnum].mod = &opl3.zeromod; opl3.slot[slotnum].eg_rout = 0x1ff; opl3.slot[slotnum].eg_out = 0x1ff; opl3.slot[slotnum].eg_gen = envelope_gen_num_off; - opl3.slot[slotnum].eg_gennext = envelope_gen_num_off; opl3.slot[slotnum].trem = (Bit8u*)&opl3.zeromod; } for (Bit8u channum = 0; channum < 18; channum++) { - opl3.channel[channum].slots[0] = &opl3.slot[2 * channum]; - opl3.channel[channum].slots[1] = &opl3.slot[2 * channum + 1]; + opl3.channel[channum].slots[0] = &opl3.slot[ch_slot[channum]]; + opl3.channel[channum].slots[1] = &opl3.slot[ch_slot[channum] + 3]; + opl3.slot[ch_slot[channum]].channel = &opl3.channel[channum]; + opl3.slot[ch_slot[channum] + 3].channel = &opl3.channel[channum]; if ((channum % 9) < 3) { opl3.channel[channum].pair = &opl3.channel[channum + 3]; } @@ -816,6 +908,8 @@ void NukedOPL3::Reset() { chan_setupalg(&opl3.channel[channum]); } opl3.noise = 0x306600; + opl3.timer = 0; + opl3.FullPan = FullPan; } void NukedOPL3::WriteReg(int reg, int v) { @@ -903,58 +997,11 @@ void NukedOPL3::WriteReg(int reg, int v) { } void NukedOPL3::Update(float* sndptr, int numsamples) { - Bit32s outa, outb; + Bit16s buffer[2]; for (Bit32u i = 0; i < (Bit32u)numsamples; i++) { - outa = 0; - outb = 0; - for (Bit8u ii = 0; ii < 36; ii++) { - slot_calgfb(&opl3.slot[ii]); - } - chan_generaterhythm(&opl3); - for (Bit8u ii = 0; ii < 18; ii++) { - chan_generate(&opl3.channel[ii]); - Bit16s accm = 0; - for (Bit8u jj = 0; jj < 4; jj++) { - accm += *opl3.channel[ii].out[jj]; - } - if (FullPan) { - outa += (Bit16s)(accm * opl3.channel[ii].fcha); - outb += (Bit16s)(accm * opl3.channel[ii].fchb); - } - else { - outa += (Bit16s)(accm & opl3.channel[ii].cha); - outb += (Bit16s)(accm & opl3.channel[ii].chb); - } - } - for (Bit8u ii = 0; ii < 36; ii++) { - envelope_calc(&opl3.slot[ii]); - pg_generate(&opl3.slot[ii]); - } - n_generate(&opl3); - opl3.timer++; - if (!(opl3.timer & 0x3f)) { - if (!opl3.tremdir) { - if (opl3.tremtval == 105) { - opl3.tremtval--; - opl3.tremdir = 1; - } - else { - opl3.tremtval++; - } - } - else { - if (opl3.tremtval == 0) { - opl3.tremtval++; - opl3.tremdir = 0; - } - else { - opl3.tremtval--; - } - } - opl3.tremval = (opl3.tremtval >> 2) >> ((1 - opl3.dam) << 1); - } - *sndptr++ += (float)(outa / 10240.0); - *sndptr++ += (float)(outb / 10240.0); + chip_generate(&opl3, buffer); + *sndptr++ += (float)(buffer[0] / 10240.0); + *sndptr++ += (float)(buffer[1] / 10240.0); } } diff --git a/src/oplsynth/nukedopl3.h b/src/oplsynth/nukedopl3.h index ccf37fe14..849646f5f 100644 --- a/src/oplsynth/nukedopl3.h +++ b/src/oplsynth/nukedopl3.h @@ -1,5 +1,5 @@ /* -* Copyright (C) 2013-2014 Nuke.YKT +* Copyright (C) 2013-2015 Nuke.YKT(Alexey Khokholov) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ OPL2 ROMs. */ -//version 1.5 +//version 1.6 #include "opl.h" #include "muslib.h" @@ -116,7 +116,7 @@ static const Bit8u mt[16] = { 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, // ksl table // -static const Bit8u kslrom[16] = { 0, 64, 80, 90, 96, 102, 106, 110, 112, 116, 118, 120, 122, 124, 126, 127 }; +static const Bit8u kslrom[16] = { 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 }; static const Bit8u kslshift[4] = { 8, 1, 2, 0 }; @@ -133,7 +133,7 @@ static const Bit8s vibsgn_table[8] = { 1, 1, 1, 1, -1, -1, -1, -1 }; static const Bit8u eg_incstep[3][4][8] = { { { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 } }, - { { 0, 1, 0, 1, 0, 1, 0, 1 }, { 1, 1, 0, 1, 0, 1, 0, 1 }, { 1, 1, 0, 1, 1, 1, 0, 1 }, { 1, 1, 1, 1, 1, 1, 0, 1 } }, + { { 0, 1, 0, 1, 0, 1, 0, 1 }, { 0, 1, 0, 1, 1, 1, 0, 1 }, { 0, 1, 1, 1, 0, 1, 1, 1 }, { 0, 1, 1, 1, 1, 1, 1, 1 } }, { { 1, 1, 1, 1, 1, 1, 1, 1 }, { 2, 2, 1, 1, 1, 1, 1, 1 }, { 2, 2, 1, 1, 2, 2, 1, 1 }, { 2, 2, 2, 2, 2, 2, 1, 1 } } }; @@ -149,8 +149,8 @@ static const Bit8s eg_incsh[16] = { // address decoding // -static const Bit8s ad_slot[0x20] = { 0, 2, 4, 1, 3, 5, -1, -1, 6, 8, 10, 7, 9, 11, -1, -1, 12, 14, 16, 13, 15, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; - +static const Bit8s ad_slot[0x20] = { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1, 12, 13, 14, 15, 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; +static const Bit8u ch_slot[18] = { 0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32 }; struct opl_chip; struct opl_slot; @@ -167,7 +167,6 @@ struct opl_slot { Bit16s eg_out; Bit8u eg_inc; Bit8u eg_gen; - Bit8u eg_gennext; Bit8u eg_rate; Bit8u eg_ksl; Bit8u *trem; @@ -217,6 +216,8 @@ struct opl_chip { Bit8u tremdir; Bit32u noise; Bit16s zeromod; + Bit32s mixbuff[2]; + Bit8u FullPan; }; From b1b17beaf6b027ef061b3da6683dcf8b351d323a Mon Sep 17 00:00:00 2001 From: khokh2001 Date: Sun, 20 Sep 2015 02:11:03 +0900 Subject: [PATCH 58/61] nuked opl emulator update --- src/oplsynth/nukedopl3.cpp | 427 ++++++++++++++++++++----------------- src/oplsynth/nukedopl3.h | 15 +- 2 files changed, 245 insertions(+), 197 deletions(-) diff --git a/src/oplsynth/nukedopl3.cpp b/src/oplsynth/nukedopl3.cpp index 4d143f4a5..c99c5c55b 100644 --- a/src/oplsynth/nukedopl3.cpp +++ b/src/oplsynth/nukedopl3.cpp @@ -1,5 +1,5 @@ /* -* Copyright (C) 2013-2014 Nuke.YKT +* Copyright (C) 2013-2015 Nuke.YKT(Alexey Khokholov) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,53 +27,31 @@ OPL2 ROMs. */ -//version 1.5 +//version 1.6 /* Changelog: v1.1: - Vibrato's sign fix + Vibrato's sign fix. v1.2: - Operator key fix - Corrected 4-operator mode - Corrected rhythm mode - Some small fixes + Operator key fix. + Corrected 4-operator mode. + Corrected rhythm mode. + Some small fixes. v1.2.1: - Small envelope generator fix - Removed EX_Get function(not used) + Small envelope generator fix. v1.3: - Complete rewrite - (Not released) + Complete rewrite. v1.4: - New envelope and waveform generator + New envelope and waveform generator. Some small fixes. - (Not released) v1.4.1: - Envelope generator rate calculation fix - (Not released) + Envelope generator rate calculation fix. v1.4.2: Version for ZDoom. v1.5: - Optimizations -*/ - - -/* Verified: - Noise generator. - Waveform generator. - Envelope generator increase table. - Tremolo. -*/ - -/* TODO: - Verify: - kslrom[15] value(is it 128?). - Sustain level = 15. - Vibrato, Phase generator. - Rhythm part. - Envelope generator state switching(decay->sustain when egt = 1 and decay->release). - Feedback. - Register write. - 4-operator. + Optimizations. + v1.6: + Improved emulation output. */ #include @@ -216,19 +194,17 @@ envelope_sinfunc envelope_sin[8] = { }; void envelope_gen_off(opl_slot *slott); -void envelope_gen_change(opl_slot *slott); void envelope_gen_attack(opl_slot *slott); void envelope_gen_decay(opl_slot *slott); void envelope_gen_sustain(opl_slot *slott); void envelope_gen_release(opl_slot *slott); -envelope_genfunc envelope_gen[6] = { +envelope_genfunc envelope_gen[5] = { envelope_gen_off, envelope_gen_attack, envelope_gen_decay, envelope_gen_sustain, - envelope_gen_release, - envelope_gen_change + envelope_gen_release }; enum envelope_gen_num { @@ -252,7 +228,7 @@ Bit8u envelope_calc_rate(opl_slot *slot, Bit8u reg_rate) { } void envelope_update_ksl(opl_slot *slot) { - Bit16s ksl = (kslrom[slot->channel->f_num >> 6] << 1) - ((slot->channel->block ^ 0x07) << 5) - 0x20; + Bit16s ksl = (kslrom[slot->channel->f_num >> 6] << 2) - ((0x08 - slot->channel->block) << 5); if (ksl < 0) { ksl = 0; } @@ -281,28 +257,25 @@ void envelope_gen_off(opl_slot *slot) { slot->eg_rout = 0x1ff; } -void envelope_gen_change(opl_slot *slot) { - slot->eg_gen = slot->eg_gennext; - envelope_update_rate(slot); -} - void envelope_gen_attack(opl_slot *slot) { + if (slot->eg_rout == 0x00) { + slot->eg_gen = envelope_gen_num_decay; + envelope_update_rate(slot); + return; + } slot->eg_rout += ((~slot->eg_rout) *slot->eg_inc) >> 3; if (slot->eg_rout < 0x00) { slot->eg_rout = 0x00; } - if (!slot->eg_rout) { - slot->eg_gen = envelope_gen_num_change; - slot->eg_gennext = envelope_gen_num_decay; - } } void envelope_gen_decay(opl_slot *slot) { - slot->eg_rout += slot->eg_inc; if (slot->eg_rout >= slot->reg_sl << 4) { - slot->eg_gen = envelope_gen_num_change; - slot->eg_gennext = envelope_gen_num_sustain; + slot->eg_gen = envelope_gen_num_sustain; + envelope_update_rate(slot); + return; } + slot->eg_rout += slot->eg_inc; } void envelope_gen_sustain(opl_slot *slot) { @@ -312,11 +285,13 @@ void envelope_gen_sustain(opl_slot *slot) { } void envelope_gen_release(opl_slot *slot) { - slot->eg_rout += slot->eg_inc; if (slot->eg_rout >= 0x1ff) { - slot->eg_gen = envelope_gen_num_change; - slot->eg_gennext = envelope_gen_num_off; + slot->eg_gen = envelope_gen_num_off; + slot->eg_rout = 0x1ff; + envelope_update_rate(slot); + return; } + slot->eg_rout += slot->eg_inc; } void envelope_calc(opl_slot *slot) { @@ -324,10 +299,7 @@ void envelope_calc(opl_slot *slot) { rate_h = slot->eg_rate >> 2; rate_l = slot->eg_rate & 3; Bit8u inc = 0; - if (slot->eg_gen == envelope_gen_num_attack && rate_h == 0x0f) { - inc = 8; - } - else if (eg_incsh[rate_h] > 0) { + if (eg_incsh[rate_h] > 0) { if ((slot->chip->timer & ((1 << eg_incsh[rate_h]) - 1)) == 0) { inc = eg_incstep[eg_incdesc[rate_h]][rate_l][((slot->chip->timer) >> eg_incsh[rate_h]) & 0x07]; } @@ -336,14 +308,19 @@ void envelope_calc(opl_slot *slot) { inc = eg_incstep[eg_incdesc[rate_h]][rate_l][slot->chip->timer & 0x07] << (-eg_incsh[rate_h]); } slot->eg_inc = inc; - envelope_gen[slot->eg_gen](slot); slot->eg_out = slot->eg_rout + (slot->reg_tl << 2) + (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem; + envelope_gen[slot->eg_gen](slot); } void eg_keyon(opl_slot *slot, Bit8u type) { if (!slot->key) { - slot->eg_gen = envelope_gen_num_change; - slot->eg_gennext = envelope_gen_num_attack; + slot->eg_gen = envelope_gen_num_attack; + envelope_update_rate(slot); + if ((slot->eg_rate >> 2) == 0x0f) { + slot->eg_gen = envelope_gen_num_decay; + envelope_update_rate(slot); + slot->eg_rout = 0x00; + } slot->pg_phase = 0x00; } slot->key |= type; @@ -353,8 +330,8 @@ void eg_keyoff(opl_slot *slot, Bit8u type) { if (slot->key) { slot->key &= (~type); if (!slot->key) { - slot->eg_gen = envelope_gen_num_change; - slot->eg_gennext = envelope_gen_num_release; + slot->eg_gen = envelope_gen_num_release; + envelope_update_rate(slot); } } } @@ -366,7 +343,7 @@ void eg_keyoff(opl_slot *slot, Bit8u type) { void pg_generate(opl_slot *slot) { Bit16u f_num = slot->channel->f_num; if (slot->reg_vib) { - Bit8u f_num_high = f_num >> (7 + vib_table[(slot->chip->timer >> 10)&0x07] + (0x01 - slot->chip->dvb)); + Bit8u f_num_high = f_num >> (7 + vib_table[(slot->chip->timer >> 10) & 0x07] + (0x01 - slot->chip->dvb)); f_num += f_num_high * vibsgn_table[(slot->chip->timer >> 10) & 0x07]; } slot->pg_phase += (((f_num << slot->channel->block) >> 1) * mt[slot->reg_mult]) >> 1; @@ -387,7 +364,7 @@ void n_generate(opl_chip *chip) { // Slot // -void slot_write20(opl_slot *slot,Bit8u data) { +void slot_write20(opl_slot *slot, Bit8u data) { if ((data >> 7) & 0x01) { slot->trem = &slot->chip->tremval; } @@ -434,14 +411,14 @@ void slot_generatephase(opl_slot *slot, Bit16u phase) { } void slot_generate(opl_slot *slot) { - slot->out = envelope_sin[slot->reg_wf]((slot->pg_phase >> 9) + (*slot->mod), slot->eg_out); + slot->out = envelope_sin[slot->reg_wf]((Bit16u)(slot->pg_phase >> 9) + (*slot->mod), slot->eg_out); } void slot_generatezm(opl_slot *slot) { - slot->out = envelope_sin[slot->reg_wf]((slot->pg_phase >> 9), slot->eg_out); + slot->out = envelope_sin[slot->reg_wf]((Bit16u)(slot->pg_phase >> 9), slot->eg_out); } -void slot_calgfb(opl_slot *slot) { +void slot_calcfb(opl_slot *slot) { slot->prout[1] = slot->prout[0]; slot->prout[0] = slot->out; if (slot->channel->fb != 0x00) { @@ -461,57 +438,61 @@ void chan_setupalg(opl_channel *channel); void chan_updaterhythm(opl_chip *chip, Bit8u data) { chip->rhy = data & 0x3f; if (chip->rhy & 0x20) { - chip->channel[6].out[0] = &chip->slot[13].out; - chip->channel[6].out[1] = &chip->slot[13].out; - chip->channel[6].out[2] = &chip->zeromod; - chip->channel[6].out[3] = &chip->zeromod; - chip->channel[7].out[0] = &chip->slot[14].out; - chip->channel[7].out[1] = &chip->slot[14].out; - chip->channel[7].out[2] = &chip->slot[15].out; - chip->channel[7].out[3] = &chip->slot[15].out; - chip->channel[8].out[0] = &chip->slot[16].out; - chip->channel[8].out[1] = &chip->slot[16].out; - chip->channel[8].out[2] = &chip->slot[17].out; - chip->channel[8].out[3] = &chip->slot[17].out; + opl_channel *channel6 = &chip->channel[6]; + opl_channel *channel7 = &chip->channel[7]; + opl_channel *channel8 = &chip->channel[8]; + channel6->out[0] = &channel6->slots[1]->out; + channel6->out[1] = &channel6->slots[1]->out; + channel6->out[2] = &chip->zeromod; + channel6->out[3] = &chip->zeromod; + channel7->out[0] = &channel7->slots[0]->out; + channel7->out[1] = &channel7->slots[0]->out; + channel7->out[2] = &channel7->slots[1]->out; + channel7->out[3] = &channel7->slots[1]->out; + channel8->out[0] = &channel8->slots[0]->out; + channel8->out[1] = &channel8->slots[0]->out; + channel8->out[2] = &channel8->slots[1]->out; + channel8->out[3] = &channel8->slots[1]->out; for (Bit8u chnum = 6; chnum < 9; chnum++) { chip->channel[chnum].chtype = ch_drum; } + chan_setupalg(channel6); //hh if (chip->rhy & 0x01) { - eg_keyon(&chip->slot[14], egk_drum); + eg_keyon(channel7->slots[0], egk_drum); } else { - eg_keyoff(&chip->slot[14], egk_drum); + eg_keyoff(channel7->slots[0], egk_drum); } //tc if (chip->rhy & 0x02) { - eg_keyon(&chip->slot[17], egk_drum); + eg_keyon(channel8->slots[1], egk_drum); } else { - eg_keyoff(&chip->slot[17], egk_drum); + eg_keyoff(channel8->slots[1], egk_drum); } //tom if (chip->rhy & 0x04) { - eg_keyon(&chip->slot[16], egk_drum); + eg_keyon(channel8->slots[0], egk_drum); } else { - eg_keyoff(&chip->slot[16], egk_drum); + eg_keyoff(channel8->slots[0], egk_drum); } //sd if (chip->rhy & 0x08) { - eg_keyon(&chip->slot[15], egk_drum); + eg_keyon(channel7->slots[1], egk_drum); } else { - eg_keyoff(&chip->slot[15], egk_drum); + eg_keyoff(channel7->slots[1], egk_drum); } //bd if (chip->rhy & 0x10) { - eg_keyon(&chip->slot[12], egk_drum); - eg_keyon(&chip->slot[13], egk_drum); + eg_keyon(channel6->slots[0], egk_drum); + eg_keyon(channel6->slots[1], egk_drum); } else { - eg_keyoff(&chip->slot[12], egk_drum); - eg_keyoff(&chip->slot[13], egk_drum); + eg_keyoff(channel6->slots[0], egk_drum); + eg_keyoff(channel6->slots[1], egk_drum); } } else { @@ -566,6 +547,16 @@ void chan_writeb0(opl_channel *channel, Bit8u data) { void chan_setupalg(opl_channel *channel) { if (channel->chtype == ch_drum) { + switch (channel->alg & 0x01) { + case 0x00: + channel->slots[0]->mod = &channel->slots[0]->fbmod; + channel->slots[1]->mod = &channel->slots[0]->out; + break; + case 0x01: + channel->slots[0]->mod = &channel->slots[0]->fbmod; + channel->slots[1]->mod = &channel->chip->zeromod; + break; + } return; } if (channel->alg & 0x08) { @@ -672,49 +663,39 @@ void chan_writec0(opl_channel *channel, Bit8u data) { } } -void chan_generaterhythm(opl_chip *chip) { - if (chip->rhy & 0x20) { - opl_channel *channel6 = &chip->channel[6]; - opl_channel *channel7 = &chip->channel[7]; - opl_channel *channel8 = &chip->channel[8]; - slot_generate(channel6->slots[0]); - slot_generate(channel6->slots[1]); - Bit16u phase14 = channel7->slots[0]->pg_phase & 0x3ff; - Bit16u phase17 = channel8->slots[1]->pg_phase & 0x3ff; - Bit16u phase = 0x00; - //hh tc phase bit - Bit16u phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; - //hh - phase = (phasebit << 9) | (0x34 << ((phasebit ^ (chip->noise & 0x01) << 1))); - slot_generatephase(channel7->slots[0], phase); - //sd - phase = (0x100 << ((phase14 >> 8) & 0x01)) ^ ((chip->noise & 0x01) << 8); - slot_generatephase(channel7->slots[1], phase); - //tt - slot_generatezm(channel8->slots[0]); - //tc - phase = 0x100 | (phasebit << 9); - slot_generatephase(channel8->slots[1], phase); - } +void chan_generaterhythm1(opl_chip *chip) { + opl_channel *channel6 = &chip->channel[6]; + opl_channel *channel7 = &chip->channel[7]; + opl_channel *channel8 = &chip->channel[8]; + slot_generate(channel6->slots[0]); + Bit16u phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; + Bit16u phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; + Bit16u phase = 0x00; + //hh tc phase bit + Bit16u phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; + //hh + phase = (phasebit << 9) | (0x34 << ((phasebit ^ (chip->noise & 0x01) << 1))); + slot_generatephase(channel7->slots[0], phase); + //tt + slot_generatezm(channel8->slots[0]); } -void chan_generate(opl_channel *channel) { - if (channel->chtype == ch_drum) { - return; - } - if (channel->alg & 0x08) { - return; - } - if (channel->alg & 0x04) { - slot_generate(channel->pair->slots[0]); - slot_generate(channel->pair->slots[1]); - slot_generate(channel->slots[0]); - slot_generate(channel->slots[1]); - } - else { - slot_generate(channel->slots[0]); - slot_generate(channel->slots[1]); - } +void chan_generaterhythm2(opl_chip *chip) { + opl_channel *channel6 = &chip->channel[6]; + opl_channel *channel7 = &chip->channel[7]; + opl_channel *channel8 = &chip->channel[8]; + slot_generate(channel6->slots[1]); + Bit16u phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; + Bit16u phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; + Bit16u phase = 0x00; + //hh tc phase bit + Bit16u phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; + //sd + phase = (0x100 << ((phase14 >> 8) & 0x01)) ^ ((chip->noise & 0x01) << 8); + slot_generatephase(channel7->slots[1], phase); + //tc + phase = 0x100 | (phasebit << 9); + slot_generatephase(channel8->slots[1], phase); } void chan_enable(opl_channel *channel) { @@ -782,21 +763,132 @@ Bit16s limshort(Bit32s a) { return (Bit16s)a; } +void chip_generate(opl_chip *chip, Bit16s *buff) { + buff[1] = limshort(chip->mixbuff[1]); + + for (Bit8u ii = 0; ii < 12; ii++) { + slot_calcfb(&chip->slot[ii]); + pg_generate(&chip->slot[ii]); + envelope_calc(&chip->slot[ii]); + slot_generate(&chip->slot[ii]); + } + + for (Bit8u ii = 12; ii < 15; ii++) { + slot_calcfb(&chip->slot[ii]); + pg_generate(&chip->slot[ii]); + envelope_calc(&chip->slot[ii]); + } + + if (chip->rhy & 0x20) { + chan_generaterhythm1(chip); + } + else { + slot_generate(&chip->slot[12]); + slot_generate(&chip->slot[13]); + slot_generate(&chip->slot[14]); + } + + chip->mixbuff[0] = 0; + for (Bit8u ii = 0; ii < 18; ii++) { + Bit16s accm = 0; + for (Bit8u jj = 0; jj < 4; jj++) { + accm += *chip->channel[ii].out[jj]; + } + if (chip->FullPan) { + chip->mixbuff[0] += (Bit16s)(accm * chip->channel[ii].fcha); + } + else { + chip->mixbuff[0] += (Bit16s)(accm & chip->channel[ii].cha); + } + } + + for (Bit8u ii = 15; ii < 18; ii++) { + slot_calcfb(&chip->slot[ii]); + pg_generate(&chip->slot[ii]); + envelope_calc(&chip->slot[ii]); + } + + if (chip->rhy & 0x20) { + chan_generaterhythm2(chip); + } + else { + slot_generate(&chip->slot[15]); + slot_generate(&chip->slot[16]); + slot_generate(&chip->slot[17]); + } + + buff[0] = limshort(chip->mixbuff[0]); + + for (Bit8u ii = 18; ii < 33; ii++) { + slot_calcfb(&chip->slot[ii]); + pg_generate(&chip->slot[ii]); + envelope_calc(&chip->slot[ii]); + slot_generate(&chip->slot[ii]); + } + + chip->mixbuff[1] = 0; + for (Bit8u ii = 0; ii < 18; ii++) { + Bit16s accm = 0; + for (Bit8u jj = 0; jj < 4; jj++) { + accm += *chip->channel[ii].out[jj]; + } + if (chip->FullPan) { + chip->mixbuff[1] += (Bit16s)(accm * chip->channel[ii].fchb); + } + else { + chip->mixbuff[1] += (Bit16s)(accm & chip->channel[ii].chb); + } + } + + for (Bit8u ii = 33; ii < 36; ii++) { + slot_calcfb(&chip->slot[ii]); + pg_generate(&chip->slot[ii]); + envelope_calc(&chip->slot[ii]); + slot_generate(&chip->slot[ii]); + } + + n_generate(chip); + + if ((chip->timer & 0x3f) == 0x3f) { + if (!chip->tremdir) { + if (chip->tremtval == 105) { + chip->tremtval--; + chip->tremdir = 1; + } + else { + chip->tremtval++; + } + } + else { + if (chip->tremtval == 0) { + chip->tremtval++; + chip->tremdir = 0; + } + else { + chip->tremtval--; + } + } + chip->tremval = (chip->tremtval >> 2) >> ((1 - chip->dam) << 1); + } + + chip->timer++; +} + void NukedOPL3::Reset() { memset(&opl3, 0, sizeof(opl_chip)); for (Bit8u slotnum = 0; slotnum < 36; slotnum++) { - opl3.slot[slotnum].channel = &opl3.channel[slotnum / 2]; opl3.slot[slotnum].chip = &opl3; opl3.slot[slotnum].mod = &opl3.zeromod; opl3.slot[slotnum].eg_rout = 0x1ff; opl3.slot[slotnum].eg_out = 0x1ff; opl3.slot[slotnum].eg_gen = envelope_gen_num_off; - opl3.slot[slotnum].eg_gennext = envelope_gen_num_off; opl3.slot[slotnum].trem = (Bit8u*)&opl3.zeromod; } for (Bit8u channum = 0; channum < 18; channum++) { - opl3.channel[channum].slots[0] = &opl3.slot[2 * channum]; - opl3.channel[channum].slots[1] = &opl3.slot[2 * channum + 1]; + opl3.channel[channum].slots[0] = &opl3.slot[ch_slot[channum]]; + opl3.channel[channum].slots[1] = &opl3.slot[ch_slot[channum] + 3]; + opl3.slot[ch_slot[channum]].channel = &opl3.channel[channum]; + opl3.slot[ch_slot[channum] + 3].channel = &opl3.channel[channum]; if ((channum % 9) < 3) { opl3.channel[channum].pair = &opl3.channel[channum + 3]; } @@ -816,6 +908,8 @@ void NukedOPL3::Reset() { chan_setupalg(&opl3.channel[channum]); } opl3.noise = 0x306600; + opl3.timer = 0; + opl3.FullPan = FullPan; } void NukedOPL3::WriteReg(int reg, int v) { @@ -903,58 +997,11 @@ void NukedOPL3::WriteReg(int reg, int v) { } void NukedOPL3::Update(float* sndptr, int numsamples) { - Bit32s outa, outb; + Bit16s buffer[2]; for (Bit32u i = 0; i < (Bit32u)numsamples; i++) { - outa = 0; - outb = 0; - for (Bit8u ii = 0; ii < 36; ii++) { - slot_calgfb(&opl3.slot[ii]); - } - chan_generaterhythm(&opl3); - for (Bit8u ii = 0; ii < 18; ii++) { - chan_generate(&opl3.channel[ii]); - Bit16s accm = 0; - for (Bit8u jj = 0; jj < 4; jj++) { - accm += *opl3.channel[ii].out[jj]; - } - if (FullPan) { - outa += (Bit16s)(accm * opl3.channel[ii].fcha); - outb += (Bit16s)(accm * opl3.channel[ii].fchb); - } - else { - outa += (Bit16s)(accm & opl3.channel[ii].cha); - outb += (Bit16s)(accm & opl3.channel[ii].chb); - } - } - for (Bit8u ii = 0; ii < 36; ii++) { - envelope_calc(&opl3.slot[ii]); - pg_generate(&opl3.slot[ii]); - } - n_generate(&opl3); - opl3.timer++; - if (!(opl3.timer & 0x3f)) { - if (!opl3.tremdir) { - if (opl3.tremtval == 105) { - opl3.tremtval--; - opl3.tremdir = 1; - } - else { - opl3.tremtval++; - } - } - else { - if (opl3.tremtval == 0) { - opl3.tremtval++; - opl3.tremdir = 0; - } - else { - opl3.tremtval--; - } - } - opl3.tremval = (opl3.tremtval >> 2) >> ((1 - opl3.dam) << 1); - } - *sndptr++ += (float)(outa / 10240.0); - *sndptr++ += (float)(outb / 10240.0); + chip_generate(&opl3, buffer); + *sndptr++ += (float)(buffer[0] / 10240.0); + *sndptr++ += (float)(buffer[1] / 10240.0); } } diff --git a/src/oplsynth/nukedopl3.h b/src/oplsynth/nukedopl3.h index ccf37fe14..849646f5f 100644 --- a/src/oplsynth/nukedopl3.h +++ b/src/oplsynth/nukedopl3.h @@ -1,5 +1,5 @@ /* -* Copyright (C) 2013-2014 Nuke.YKT +* Copyright (C) 2013-2015 Nuke.YKT(Alexey Khokholov) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ OPL2 ROMs. */ -//version 1.5 +//version 1.6 #include "opl.h" #include "muslib.h" @@ -116,7 +116,7 @@ static const Bit8u mt[16] = { 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, // ksl table // -static const Bit8u kslrom[16] = { 0, 64, 80, 90, 96, 102, 106, 110, 112, 116, 118, 120, 122, 124, 126, 127 }; +static const Bit8u kslrom[16] = { 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 }; static const Bit8u kslshift[4] = { 8, 1, 2, 0 }; @@ -133,7 +133,7 @@ static const Bit8s vibsgn_table[8] = { 1, 1, 1, 1, -1, -1, -1, -1 }; static const Bit8u eg_incstep[3][4][8] = { { { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 } }, - { { 0, 1, 0, 1, 0, 1, 0, 1 }, { 1, 1, 0, 1, 0, 1, 0, 1 }, { 1, 1, 0, 1, 1, 1, 0, 1 }, { 1, 1, 1, 1, 1, 1, 0, 1 } }, + { { 0, 1, 0, 1, 0, 1, 0, 1 }, { 0, 1, 0, 1, 1, 1, 0, 1 }, { 0, 1, 1, 1, 0, 1, 1, 1 }, { 0, 1, 1, 1, 1, 1, 1, 1 } }, { { 1, 1, 1, 1, 1, 1, 1, 1 }, { 2, 2, 1, 1, 1, 1, 1, 1 }, { 2, 2, 1, 1, 2, 2, 1, 1 }, { 2, 2, 2, 2, 2, 2, 1, 1 } } }; @@ -149,8 +149,8 @@ static const Bit8s eg_incsh[16] = { // address decoding // -static const Bit8s ad_slot[0x20] = { 0, 2, 4, 1, 3, 5, -1, -1, 6, 8, 10, 7, 9, 11, -1, -1, 12, 14, 16, 13, 15, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; - +static const Bit8s ad_slot[0x20] = { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1, 12, 13, 14, 15, 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; +static const Bit8u ch_slot[18] = { 0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32 }; struct opl_chip; struct opl_slot; @@ -167,7 +167,6 @@ struct opl_slot { Bit16s eg_out; Bit8u eg_inc; Bit8u eg_gen; - Bit8u eg_gennext; Bit8u eg_rate; Bit8u eg_ksl; Bit8u *trem; @@ -217,6 +216,8 @@ struct opl_chip { Bit8u tremdir; Bit32u noise; Bit16s zeromod; + Bit32s mixbuff[2]; + Bit8u FullPan; }; From c743b19e6d784a9cff45c144c643ee072947ee9e Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 22 Sep 2015 15:19:44 +0300 Subject: [PATCH 59/61] Make console text to appear in Windows debug output This works in Debug configuration only Color escape sequences are stripped from text before output --- src/win32/i_system.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 372da8685..c21768f1f 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -1053,6 +1053,30 @@ static TArray bufferedConsoleStuff; void I_PrintStr(const char *cp) { +#ifdef _DEBUG + // Strip out any color escape sequences before writing to debug output + char * copy = new char[strlen(cp)+1]; + const char * srcp = cp; + char * dstp = copy; + + while (*srcp != 0) + { + if (*srcp!=0x1c && *srcp!=0x1d && *srcp!=0x1e && *srcp!=0x1f) + { + *dstp++=*srcp++; + } + else + { + if (srcp[1]!=0) srcp+=2; + else break; + } + } + *dstp=0; + + OutputDebugStringA(copy); + delete [] copy; +#endif // _DEBUG + if (ConWindowHidden) { bufferedConsoleStuff.Push(cp); From 37dde2e77d91bcaf257e8c4f4c64fa6fe2607e5f Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 23 Sep 2015 10:18:57 +0300 Subject: [PATCH 60/61] Make console to Windows debug output controlled by CVAR DebugView can be used to view output without debugger attached --- src/win32/i_system.cpp | 44 ++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index c21768f1f..ef56c7050 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -137,6 +137,7 @@ extern bool ConWindowHidden; // PUBLIC DATA DEFINITIONS ------------------------------------------------- CVAR (String, queryiwad_key, "shift", CVAR_GLOBALCONFIG|CVAR_ARCHIVE); +CVAR (Bool, con_debugoutput, false, 0); double PerfToSec, PerfToMillisec; UINT TimerPeriod; @@ -1053,29 +1054,30 @@ static TArray bufferedConsoleStuff; void I_PrintStr(const char *cp) { -#ifdef _DEBUG - // Strip out any color escape sequences before writing to debug output - char * copy = new char[strlen(cp)+1]; - const char * srcp = cp; - char * dstp = copy; - - while (*srcp != 0) + if (con_debugoutput) { - if (*srcp!=0x1c && *srcp!=0x1d && *srcp!=0x1e && *srcp!=0x1f) - { - *dstp++=*srcp++; - } - else - { - if (srcp[1]!=0) srcp+=2; - else break; - } - } - *dstp=0; + // Strip out any color escape sequences before writing to debug output + char * copy = new char[strlen(cp)+1]; + const char * srcp = cp; + char * dstp = copy; - OutputDebugStringA(copy); - delete [] copy; -#endif // _DEBUG + while (*srcp != 0) + { + if (*srcp!=0x1c && *srcp!=0x1d && *srcp!=0x1e && *srcp!=0x1f) + { + *dstp++=*srcp++; + } + else + { + if (srcp[1]!=0) srcp+=2; + else break; + } + } + *dstp=0; + + OutputDebugStringA(copy); + delete [] copy; + } if (ConWindowHidden) { From f58b67b11db520a982ce56bd5855440bb6769297 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 28 Sep 2015 09:09:52 +0200 Subject: [PATCH 61/61] . added MBF dog sounds to Dehacked sound table. --- wadsrc/static/dehsupp.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/dehsupp.txt b/wadsrc/static/dehsupp.txt index 51db22e91..ae31f6830 100644 --- a/wadsrc/static/dehsupp.txt +++ b/wadsrc/static/dehsupp.txt @@ -534,7 +534,13 @@ SoundMap "skeleton/active", "skeleton/sight", "skeleton/attack", - "misc/chat" + "misc/chat", + "dog/sight", + "dog/attack", + "dog/active", + "dog/death", + "dog/pain", + }; // Names of different actor types, in original Doom 2 order