From 36d676ca2088b2bd4583937f0dd60d272da75a04 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 26 Aug 2020 22:39:15 +0200 Subject: [PATCH 01/43] - renamed ESyncBits so that the replacement can take that name later. --- source/core/packet.h | 6 +++--- source/games/duke/src/funct.h | 8 ++++---- source/games/duke/src/inlines.h | 8 ++++---- source/games/duke/src/input.cpp | 4 ++-- source/games/duke/src/player.cpp | 8 ++++---- source/games/duke/src/player_d.cpp | 18 +++++++++--------- source/games/duke/src/player_r.cpp | 18 +++++++++--------- source/games/duke/src/player_w.cpp | 2 +- source/games/duke/src/prediction.cpp | 2 +- 9 files changed, 37 insertions(+), 37 deletions(-) diff --git a/source/core/packet.h b/source/core/packet.h index 2727a960b..9ec2768c8 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -56,8 +56,8 @@ enum ESyncBits_ : uint32_t }; // enforce type safe operations on the input bits. -using ESyncBits = TFlags; -DEFINE_TFLAGS_OPERATORS(ESyncBits) +using EDukeSyncBits = TFlags; +DEFINE_TFLAGS_OPERATORS(EDukeSyncBits) union SYNCFLAGS { @@ -178,7 +178,7 @@ struct InputPacket // Making this a union lets some constructs fail. Since these names are transitional only the added memory use doesn't really matter. // for Duke - ESyncBits sbits; + EDukeSyncBits sbits; // for SW int32_t bits; diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 5621a1127..3e396f62f 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -112,10 +112,10 @@ void playerJump(int snum, int fz, int cz); void applylook(int snum, double factor, fixed_t adjustment); void checklook(int snum, int sb_snum); void playerCenterView(int snum); -void playerLookUp(int snum, ESyncBits sb_snum); -void playerLookDown(int snum, ESyncBits sb_snum); -void playerAimUp(int snum, ESyncBits sb_snum); -void playerAimDown(int snum, ESyncBits sb_snum); +void playerLookUp(int snum, EDukeSyncBits sb_snum); +void playerLookDown(int snum, EDukeSyncBits sb_snum); +void playerAimUp(int snum, EDukeSyncBits sb_snum); +void playerAimDown(int snum, EDukeSyncBits sb_snum); bool view(struct player_struct* pp, int* vx, int* vy, int* vz, short* vsectnum, int ang, int horiz); void tracers(int x1, int y1, int z1, int x2, int y2, int z2, int n); int hits(int i); diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index b8907cc08..69841ba76 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -116,22 +116,22 @@ inline bool isIn(int value, const std::initializer_list& list) // these are mainly here to avoid directly accessing the input data so that it can be more easily refactored later. -inline bool PlayerInput(int pl, ESyncBits bit) +inline bool PlayerInput(int pl, EDukeSyncBits bit) { return (!!((sync[pl].sbits) & bit)); } -inline void PlayerSetInput(int pl, ESyncBits bit) +inline void PlayerSetInput(int pl, EDukeSyncBits bit) { sync[pl].sbits |= bit; } -inline void PlayerClearInput(int pl, ESyncBits bit) +inline void PlayerClearInput(int pl, EDukeSyncBits bit) { sync[pl].sbits &= ~bit; } -inline ESyncBits PlayerInputBits(int pl, ESyncBits bits) +inline EDukeSyncBits PlayerInputBits(int pl, EDukeSyncBits bits) { return (sync[pl].sbits & bits); } diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 9bad5c595..f5b3ce3d8 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -40,7 +40,7 @@ source as it is released. BEGIN_DUKE_NS static int WeaponToSend; -static ESyncBits BitsToSend; +static EDukeSyncBits BitsToSend; // State timer counters. static int nonsharedtimer; @@ -665,7 +665,7 @@ static void processInputBits(player_struct *p, ControlInfo &info) if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info.dz < 0) j = 12; if (j && (loc.sbits & SKB_WEAPONMASK_BITS) == 0) - loc.sbits |= ESyncBits::FromInt(j * SKB_FIRST_WEAPON_BIT); + loc.sbits |= EDukeSyncBits::FromInt(j * SKB_FIRST_WEAPON_BIT); } diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index 701d92123..41ce74954 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -1050,7 +1050,7 @@ void playerCenterView(int snum) } } -void playerLookUp(int snum, ESyncBits sb_snum) +void playerLookUp(int snum, EDukeSyncBits sb_snum) { auto p = &ps[snum]; SetGameVarID(g_iReturnVarID, 0, p->i, snum); @@ -1062,7 +1062,7 @@ void playerLookUp(int snum, ESyncBits sb_snum) } } -void playerLookDown(int snum, ESyncBits sb_snum) +void playerLookDown(int snum, EDukeSyncBits sb_snum) { auto p = &ps[snum]; SetGameVarID(g_iReturnVarID, 0, p->i, snum); @@ -1074,7 +1074,7 @@ void playerLookDown(int snum, ESyncBits sb_snum) } } -void playerAimUp(int snum, ESyncBits sb_snum) +void playerAimUp(int snum, EDukeSyncBits sb_snum) { auto p = &ps[snum]; SetGameVarID(g_iReturnVarID, 0, p->i, snum); @@ -1085,7 +1085,7 @@ void playerAimUp(int snum, ESyncBits sb_snum) } } -void playerAimDown(int snum, ESyncBits sb_snum) +void playerAimDown(int snum, EDukeSyncBits sb_snum) { auto p = &ps[snum]; SetGameVarID(g_iReturnVarID, 0, p->i, snum); diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index d3b8a5d1c..06cf66eb6 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -41,7 +41,7 @@ source as it is released. BEGIN_DUKE_NS void fireweapon_ww(int snum); -void operateweapon_ww(int snum, ESyncBits sb_snum, int psect); +void operateweapon_ww(int snum, EDukeSyncBits sb_snum, int psect); //--------------------------------------------------------------------------- // @@ -1548,7 +1548,7 @@ void checkweapons_d(struct player_struct* p) // //--------------------------------------------------------------------------- -static void operateJetpack(int snum, ESyncBits sb_snum, int psectlotag, int fz, int cz, int shrunk) +static void operateJetpack(int snum, EDukeSyncBits sb_snum, int psectlotag, int fz, int cz, int shrunk) { int j; auto p = &ps[snum]; @@ -1622,7 +1622,7 @@ static void operateJetpack(int snum, ESyncBits sb_snum, int psectlotag, int fz, // //--------------------------------------------------------------------------- -static void movement(int snum, ESyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist, int psectlotag) +static void movement(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist, int psectlotag) { int j; auto p = &ps[snum]; @@ -1809,7 +1809,7 @@ static void movement(int snum, ESyncBits sb_snum, int psect, int fz, int cz, int // //--------------------------------------------------------------------------- -static void underwater(int snum, ESyncBits sb_snum, int psect, int fz, int cz) +static void underwater(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz) { int j; auto p = &ps[snum]; @@ -2058,7 +2058,7 @@ static void fireweapon(int snum) // //--------------------------------------------------------------------------- -static void operateweapon(int snum, ESyncBits sb_snum, int psect) +static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) { auto p = &ps[snum]; int pi = p->i; @@ -2514,7 +2514,7 @@ static void operateweapon(int snum, ESyncBits sb_snum, int psect) // //--------------------------------------------------------------------------- -static void processweapon(int snum, ESyncBits sb_snum, int psect) +static void processweapon(int snum, EDukeSyncBits sb_snum, int psect) { auto p = &ps[snum]; int pi = p->i; @@ -2599,7 +2599,7 @@ void processinput_d(int snum) { int j, i, k, doubvel, fz, cz, hz, lz, truefdist; char shrunk; - ESyncBits sb_snum; + EDukeSyncBits sb_snum; short psect, psectlotag, pi; struct player_struct* p; spritetype* s; @@ -3065,12 +3065,12 @@ HORIZONLY: processweapon(snum, sb_snum, psect); } -void processweapon_d(int s, ESyncBits ss, int p) +void processweapon_d(int s, EDukeSyncBits ss, int p) { processweapon(s, ss, p); } -void processmove_d(int snum, ESyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist) +void processmove_d(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist) { int psectlotag = sector[psect].lotag; auto p = &ps[snum]; diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 882a935fc..abd1ba1bc 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -1509,7 +1509,7 @@ void checkweapons_r(struct player_struct* p) // //--------------------------------------------------------------------------- -static void onMotorcycle(int snum, ESyncBits &sb_snum) +static void onMotorcycle(int snum, EDukeSyncBits &sb_snum) { auto p = &ps[snum]; auto pi = p->i; @@ -1802,7 +1802,7 @@ static void onMotorcycle(int snum, ESyncBits &sb_snum) // //--------------------------------------------------------------------------- -static void onBoat(int snum, ESyncBits& sb_snum) +static void onBoat(int snum, EDukeSyncBits& sb_snum) { auto p = &ps[snum]; auto pi = p->i; @@ -2086,7 +2086,7 @@ static void onBoat(int snum, ESyncBits& sb_snum) // //--------------------------------------------------------------------------- -static void movement(int snum, ESyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist, int psectlotag) +static void movement(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist, int psectlotag) { auto p = &ps[snum]; auto pi = p->i; @@ -2316,7 +2316,7 @@ static void movement(int snum, ESyncBits sb_snum, int psect, int fz, int cz, int // //--------------------------------------------------------------------------- -static void underwater(int snum, ESyncBits sb_snum, int psect, int fz, int cz) +static void underwater(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz) { int j; auto p = &ps[snum]; @@ -2740,7 +2740,7 @@ static void fireweapon(int snum) // //--------------------------------------------------------------------------- -static void operateweapon(int snum, ESyncBits sb_snum, int psect) +static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) { auto p = &ps[snum]; int pi = p->i; @@ -3332,7 +3332,7 @@ static void operateweapon(int snum, ESyncBits sb_snum, int psect) // //--------------------------------------------------------------------------- -static void processweapon(int snum, ESyncBits sb_snum, int psect) +static void processweapon(int snum, EDukeSyncBits sb_snum, int psect) { auto p = &ps[snum]; int pi = p->i; @@ -3397,7 +3397,7 @@ void processinput_r(int snum) { int j, i, k, doubvel, fz, cz, hz, lz, truefdist, var60; char shrunk; - ESyncBits sb_snum; + EDukeSyncBits sb_snum; short psect, psectlotag, pi; struct player_struct* p; spritetype* s; @@ -4099,12 +4099,12 @@ HORIZONLY: // //--------------------------------------------------------------------------- -void processweapon_r(int s, ESyncBits ss, int p) +void processweapon_r(int s, EDukeSyncBits ss, int p) { processweapon(s, ss, p); } -void processmove_r(int snum, ESyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist) +void processmove_r(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist) { int psectlotag = sector[psect].lotag; auto p = &ps[snum]; diff --git a/source/games/duke/src/player_w.cpp b/source/games/duke/src/player_w.cpp index cc23579be..29466ea0b 100644 --- a/source/games/duke/src/player_w.cpp +++ b/source/games/duke/src/player_w.cpp @@ -306,7 +306,7 @@ void fireweapon_ww(int snum) // //--------------------------------------------------------------------------- -void operateweapon_ww(int snum, ESyncBits sb_snum, int psect) +void operateweapon_ww(int snum, EDukeSyncBits sb_snum, int psect) { auto p = &ps[snum]; int pi = p->i; diff --git a/source/games/duke/src/prediction.cpp b/source/games/duke/src/prediction.cpp index da408e7f0..0e6052be2 100644 --- a/source/games/duke/src/prediction.cpp +++ b/source/games/duke/src/prediction.cpp @@ -104,7 +104,7 @@ void fakedomovethings(void) input *syn; struct player_struct *p; int i, j, k, doubvel, fz, cz, hz, lz, x, y; - ESyncBits sb_snum; + EDukeSyncBits sb_snum; short psect, psectlotag, tempsect, backcstat; uint8_t shrunk, spritebridge; From e768a2bf24f5ebd93e2199eefe28c3775c5393ba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 26 Aug 2020 23:02:55 +0200 Subject: [PATCH 02/43] - use new bitmask for weapon selection in Duke. --- source/core/packet.h | 48 ++++++++++++++++++++++++--------- source/games/duke/src/inlines.h | 10 +++++++ source/games/duke/src/input.cpp | 8 +++--- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/source/core/packet.h b/source/core/packet.h index 9ec2768c8..6960e80cf 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -5,6 +5,20 @@ #include "tflags.h" +enum ESyncBits_ : uint32_t +{ + SB_FIRST_WEAPON_BIT = 1 << 0, + + SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits + + SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS) +}; + +// enforce type safe operations on the input bits. +using ESyncBits = TFlags; +DEFINE_TFLAGS_OPERATORS(ESyncBits) + + // Blood flags enum { @@ -13,7 +27,7 @@ enum }; -enum ESyncBits_ : uint32_t +enum EDukeSyncBits_ : uint32_t { SKB_JUMP = 1 << 0, SKB_CROUCH = 1 << 1, @@ -45,8 +59,7 @@ enum ESyncBits_ : uint32_t SKB_INVENTORY = 1 << 30, SKB_ESCAPE = 1u << 31, - SKB_WEAPONMASK_BITS = (15u * SKB_FIRST_WEAPON_BIT), - SKB_INTERFACE_BITS = (SKB_WEAPONMASK_BITS | SKB_STEROIDS | SKB_NIGHTVISION | SKB_MEDKIT | SKB_QUICK_KICK | \ + SKB_INTERFACE_BITS = (SKB_STEROIDS | SKB_NIGHTVISION | SKB_MEDKIT | SKB_QUICK_KICK | \ SKB_HOLSTER | SKB_INV_LEFT | SKB_PAUSE | SKB_HOLODUKE | SKB_JETPACK | SKB_INV_RIGHT | \ SKB_TURNAROUND | SKB_OPEN | SKB_INVENTORY | SKB_ESCAPE), @@ -56,7 +69,7 @@ enum ESyncBits_ : uint32_t }; // enforce type safe operations on the input bits. -using EDukeSyncBits = TFlags; +using EDukeSyncBits = TFlags; DEFINE_TFLAGS_OPERATORS(EDukeSyncBits) union SYNCFLAGS @@ -175,17 +188,28 @@ struct InputPacket fix16_t q16horz; fix16_t q16aimvel; // only used by SW fix16_t q16ang; // only used by SW + ESyncBits actions; // Making this a union lets some constructs fail. Since these names are transitional only the added memory use doesn't really matter. - // for Duke - EDukeSyncBits sbits; + // for Duke + EDukeSyncBits sbits; - // for SW - int32_t bits; + // for SW + int32_t bits; - // for Blood - SYNCFLAGS syncFlags; + // for Blood + SYNCFLAGS syncFlags; - // For Exhumed - uint16_t buttons; + // For Exhumed + uint16_t buttons; + + int getNewWeapon() const + { + return (actions & SB_WEAPONMASK_BITS).GetValue(); + } + + void SetNewWeapon(int weap) + { + actions = (actions & ~SB_WEAPONMASK_BITS) | (ESyncBits::FromInt(weap) & SB_WEAPONMASK_BITS); + } }; diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index 69841ba76..4d9075237 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -136,6 +136,16 @@ inline EDukeSyncBits PlayerInputBits(int pl, EDukeSyncBits bits) return (sync[pl].sbits & bits); } +inline ESyncBits PlayerInputBits(int pl, ESyncBits bits) +{ + return (sync[pl].actions & bits); +} + +inline int PlayerNewWeapon(int pl) +{ + return sync[pl].getNewWeapon(); +} + inline int PlayerInputSideVel(int pl) { return sync[pl].svel; diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index f5b3ce3d8..2fe35fbec 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -195,7 +195,7 @@ void hud_input(int snum) } if (!PlayerInput(snum, SKB_QUICK_KICK)) p->quick_kick_msg = false; - if (!PlayerInputBits(snum, SKB_INTERFACE_BITS)) + if (!PlayerInputBits(snum, SKB_INTERFACE_BITS) && ! PlayerInputBits(snum, SB_INTERFACE_BITS)) p->interface_toggle_flag = 0; else if (p->interface_toggle_flag == 0) { @@ -339,7 +339,7 @@ void hud_input(int snum) if (dainv >= 1 && dainv < 8) FTA(invquotes[dainv - 1], p); } - j = (PlayerInputBits(snum, SKB_WEAPONMASK_BITS) / SKB_FIRST_WEAPON_BIT) - 1; + j = PlayerNewWeapon(snum) - 1; if (j >= 0) { int a = 0; @@ -664,8 +664,8 @@ static void processInputBits(player_struct *p, ControlInfo &info) if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info.dz > 0) j = 11; if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info.dz < 0) j = 12; - if (j && (loc.sbits & SKB_WEAPONMASK_BITS) == 0) - loc.sbits |= EDukeSyncBits::FromInt(j * SKB_FIRST_WEAPON_BIT); + if (j && (loc.actions & SB_WEAPONMASK_BITS) == 0) + loc.SetNewWeapon(j); } From c7e667a17aec28902cd417bd1cab919df830aa34 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 27 Aug 2020 00:06:59 +0200 Subject: [PATCH 03/43] - transition weapon selection in SW. Thanks to the macro insanity for trivial operations in this code base this turned out to be a lot more troublesome than Duke... --- source/core/packet.h | 10 ---------- source/games/duke/src/input.cpp | 3 +-- source/sw/src/game.h | 1 + source/sw/src/input.cpp | 3 +-- source/sw/src/network.cpp | 8 +++++++- source/sw/src/panel.cpp | 17 +++++------------ source/sw/src/player.cpp | 1 + source/sw/src/predict.cpp | 4 ++-- 8 files changed, 18 insertions(+), 29 deletions(-) diff --git a/source/core/packet.h b/source/core/packet.h index 6960e80cf..4c8156d19 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -113,16 +113,6 @@ union SYNCFLAGS // NETWORK - REDEFINABLE SHARED (SYNC) KEYS BIT POSITIONS // -// weapons takes up 4 bits -#define SK_WEAPON_BIT0 0 -#define SK_WEAPON_BIT1 1 -#define SK_WEAPON_BIT2 2 -#define SK_WEAPON_BIT3 3 -#define SK_WEAPON_MASK (BIT(SK_WEAPON_BIT0)| \ - BIT(SK_WEAPON_BIT1)| \ - BIT(SK_WEAPON_BIT2)| \ - BIT(SK_WEAPON_BIT3)) // 16 possible numbers 0-15 - #define SK_INV_HOTKEY_BIT0 4 #define SK_INV_HOTKEY_BIT1 5 #define SK_INV_HOTKEY_BIT2 6 diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 2fe35fbec..4343e7e05 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -664,8 +664,7 @@ static void processInputBits(player_struct *p, ControlInfo &info) if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info.dz > 0) j = 11; if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info.dz < 0) j = 12; - if (j && (loc.actions & SB_WEAPONMASK_BITS) == 0) - loc.SetNewWeapon(j); + if (j) loc.SetNewWeapon(j); } diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 33e268378..2f21873bc 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -1002,6 +1002,7 @@ struct PLAYERstruct PLAYER_ACTION_FUNCp DoPlayerAction; int Flags, Flags2; + ESyncBits KeyPressBits; int KeyPressFlags; SECTOR_OBJECTp sop_control; // sector object pointer diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index 06e386318..0fff211b7 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -343,8 +343,7 @@ getinput(InputPacket *loc, SWBOOL tied) if (WeaponToSend > 0) { - loc->bits &= ~SK_WEAPON_MASK; - loc->bits |= WeaponToSend; + loc->SetNewWeapon(WeaponToSend); WeaponToSend = 0; } else if (WeaponToSend == -1) diff --git a/source/sw/src/network.cpp b/source/sw/src/network.cpp index e1fa0c5f9..a101554ab 100644 --- a/source/sw/src/network.cpp +++ b/source/sw/src/network.cpp @@ -84,6 +84,7 @@ typedef struct fix16_t q16ang; fix16_t q16horz; int32_t bits; + ESyncBits actions; } SW_AVERAGE_PACKET; int MovesPerPacket = 1; @@ -204,8 +205,12 @@ UpdateInputs(void) AveragePacket.q16ang = Player[myconnectindex].camq16ang; AveragePacket.q16horz = Player[myconnectindex].camq16horiz; SET(AveragePacket.bits, loc.bits); + SET(AveragePacket.actions, loc.actions); + // The above would or the weapon numbers together. Undo that now. The last one should win. + AveragePacket.actions &= ~SB_WEAPONMASK_BITS; + AveragePacket.actions |= ESyncBits::FromInt(loc.getNewWeapon()) & SB_WEAPONMASK_BITS; - Bmemset(&loc, 0, sizeof(loc)); + memset(&loc, 0, sizeof(loc)); pp = Player + myconnectindex; @@ -226,6 +231,7 @@ UpdateInputs(void) loc.q16ang = AveragePacket.q16ang; loc.q16horz = AveragePacket.q16horz; loc.bits = AveragePacket.bits; + loc.actions = AveragePacket.actions; memset(&AveragePacket, 0, sizeof(AveragePacket)); diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index 9d4eabd42..e10e2d9b7 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -191,15 +191,8 @@ void pToggleCrosshair(void) void DoPlayerChooseYell(PLAYERp pp) { int choose_snd = 0; - short weapon; - weapon = TEST(pp->input.bits, SK_WEAPON_MASK); - - if (weapon == WPN_FIST) - { - if (RANDOM_RANGE(1000) < 900) return; - } - else if (RANDOM_RANGE(1000) < 990) return; + if (RANDOM_RANGE(1000) < 990) return; choose_snd = STD_RANDOM_RANGE(MAX_YELLSOUNDS); @@ -487,13 +480,13 @@ int WeaponOperate(PLAYERp pp) } } - weapon = TEST(pp->input.bits, SK_WEAPON_MASK); + weapon = pp->input.getNewWeapon(); if (weapon) { - if (FLAG_KEY_PRESSED(pp, SK_WEAPON_BIT0)) + if (pp->KeyPressBits & SB_FIRST_WEAPON_BIT) { - FLAG_KEY_RELEASE(pp, SK_WEAPON_BIT0); + pp->KeyPressBits &= ~SB_FIRST_WEAPON_BIT; weapon -= 1; @@ -640,7 +633,7 @@ int WeaponOperate(PLAYERp pp) } else { - FLAG_KEY_RESET(pp, SK_WEAPON_BIT0); + pp->KeyPressBits |= SB_FIRST_WEAPON_BIT; } // Shut that computer chick up if weapon has changed! diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index bfe7944e6..21ad39895 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -7806,6 +7806,7 @@ InitAllPlayers(void) pp->WpnGotOnceFlags = 0; pp->DoPlayerAction = DoPlayerBeginRun; + pp->KeyPressBits = ESyncBits::FromInt(0xFFFFFFFF); pp->KeyPressFlags = 0xFFFFFFFF; memset(pp->KilledPlayer,0,sizeof(pp->KilledPlayer)); diff --git a/source/sw/src/predict.cpp b/source/sw/src/predict.cpp index 1e1c3d2fc..84b7687a3 100644 --- a/source/sw/src/predict.cpp +++ b/source/sw/src/predict.cpp @@ -83,12 +83,13 @@ DoPrediction(PLAYERp ppp) // get rid of input bits so it doesn't go into other code branches that would // get it out of sync + ppp->input.actions &= ~(SB_WEAPONMASK_BITS); + ppp->KeyPressBits |= (SB_WEAPONMASK_BITS); RESET(ppp->input.bits, BIT(SK_SHOOT)|BIT(SK_OPERATE)|BIT(SK_INV_LEFT)|BIT(SK_INV_RIGHT)| BIT(SK_INV_USE)|BIT(SK_HIDE_WEAPON)| BIT(SK_AUTO_AIM)| BIT(SK_CENTER_VIEW)| - SK_WEAPON_MASK| SK_INV_HOTKEY_MASK ); @@ -97,7 +98,6 @@ DoPrediction(PLAYERp ppp) BIT(SK_INV_USE)|BIT(SK_HIDE_WEAPON)| BIT(SK_AUTO_AIM)| BIT(SK_CENTER_VIEW)| - SK_WEAPON_MASK| SK_INV_HOTKEY_MASK ); From 99486cba7e7d802ee4f7df9e69c6ac17edb48630 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 27 Aug 2020 00:21:11 +0200 Subject: [PATCH 04/43] - gave Blood the same treatment. --- source/blood/src/blood.cpp | 4 ++-- source/blood/src/controls.cpp | 2 +- source/blood/src/player.cpp | 2 +- source/core/packet.h | 2 -- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 35aa17956..0261066bb 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -527,8 +527,8 @@ void ProcessFrame(void) { gPlayer[i].input.syncFlags.value &= ~flag_buttonmask; gPlayer[i].input.syncFlags.value |= gFifoInput[gNetFifoTail & 255][i].syncFlags.value; - if (gFifoInput[gNetFifoTail&255][i].syncFlags.newWeapon) - gPlayer[i].newWeapon = gFifoInput[gNetFifoTail&255][i].syncFlags.newWeapon; + int newweap = gFifoInput[gNetFifoTail & 255][i].getNewWeapon(); + if (newweap) gPlayer[i].newWeapon = newweap; gPlayer[i].input.fvel = gFifoInput[gNetFifoTail&255][i].fvel; gPlayer[i].input.q16avel = gFifoInput[gNetFifoTail&255][i].q16avel; gPlayer[i].input.svel = gFifoInput[gNetFifoTail&255][i].svel; diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 384c515ef..ca622d62c 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -151,7 +151,7 @@ void ctrlGetInput(void) gInput.syncFlags.value |= BitsToSend.value; if (WeaponToSend != 0) - gInput.syncFlags.newWeapon = WeaponToSend; + gInput.SetNewWeapon(WeaponToSend); BitsToSend.value = 0; WeaponToSend = 0; diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index fc88c07d7..d277249a8 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -1331,7 +1331,7 @@ void ProcessInput(PLAYER *pPlayer) pPlayer->q16horiz = mulscale16(0x8000-(Cos(ClipHigh(pPlayer->deathTime*8, 1024))>>15), fix16_from_int(120)); } if (pPlayer->curWeapon) - pInput->syncFlags.newWeapon = pPlayer->curWeapon; + pInput->SetNewWeapon(pPlayer->curWeapon); if (pInput->syncFlags.action) { if (bSeqStat) diff --git a/source/core/packet.h b/source/core/packet.h index 4c8156d19..431434c6b 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -37,7 +37,6 @@ enum EDukeSyncBits_ : uint32_t SKB_RUN = 1 << 5, SKB_LOOK_LEFT = 1 << 6, SKB_LOOK_RIGHT = 1 << 7, - SKB_FIRST_WEAPON_BIT = 1 << 8, SKB_STEROIDS = 1 << 12, SKB_LOOK_UP = 1 << 13, SKB_LOOK_DOWN = 1 << 14, @@ -103,7 +102,6 @@ union SYNCFLAGS unsigned int useCrystalBall : 1; unsigned int useJumpBoots : 1; unsigned int useMedKit : 1; - unsigned int newWeapon : 4; }; }; From 4b299fa41293d01ce70d37310b236cfc1a6a18a1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 27 Aug 2020 00:58:21 +0200 Subject: [PATCH 05/43] - Exhumed also handled. --- source/core/packet.h | 3 - source/exhumed/src/exhumed.cpp | 7 +- source/exhumed/src/gameloop.cpp | 2 +- source/exhumed/src/input.cpp | 221 ++++++++++++++++++++++++++++++- source/exhumed/src/player.cpp | 222 +------------------------------- source/exhumed/src/player.h | 2 +- source/exhumed/src/ps_input.h | 12 ++ 7 files changed, 239 insertions(+), 230 deletions(-) diff --git a/source/core/packet.h b/source/core/packet.h index 431434c6b..0ffbc6fb1 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -158,9 +158,6 @@ enum { kButtonCheatGodMode = 0x40, kButtonCheatKeys = 0x80, kButtonCheatItems = 0x100, - - kButtonWeaponShift = 13, - kButtonWeaponBits = 7 << kButtonWeaponShift, // upper 3 bits. }; diff --git a/source/exhumed/src/exhumed.cpp b/source/exhumed/src/exhumed.cpp index 9881842b1..12c09a06b 100644 --- a/source/exhumed/src/exhumed.cpp +++ b/source/exhumed/src/exhumed.cpp @@ -483,7 +483,7 @@ void GameTicker() lastTic = currentTic; int lLocalButtons = GetLocalInput(); // shouldn't this be placed in localInput? - PlayerInterruptKeys(); + PlayerInterruptKeys(false); nPlayerDAng = fix16_sadd(nPlayerDAng, localInput.q16avel); inita &= kAngleMask; @@ -500,8 +500,11 @@ void GameTicker() sPlayerInput[nLocalPlayer].xVel = lPlayerXVel; sPlayerInput[nLocalPlayer].yVel = lPlayerYVel; // make weapon selection persist until it gets used up. - if ((lLocalButtons & kButtonWeaponBits) == 0) lLocalButtons |= sPlayerInput[nLocalPlayer].buttons & kButtonWeaponBits; sPlayerInput[nLocalPlayer].buttons = lLocalButtons | lLocalCodes; + int weap = sPlayerInput[nLocalPlayer].getNewWeapon(); + sPlayerInput[nLocalPlayer].actions = localInput.actions; + int weap2 = localInput.getNewWeapon(); + if (weap2 <= 0 || weap2 > 7) sPlayerInput[nLocalPlayer].SetNewWeapon(weap); sPlayerInput[nLocalPlayer].nTarget = besttarget; Ra[nLocalPlayer].nTarget = besttarget; diff --git a/source/exhumed/src/gameloop.cpp b/source/exhumed/src/gameloop.cpp index 1668218d0..087969cbd 100644 --- a/source/exhumed/src/gameloop.cpp +++ b/source/exhumed/src/gameloop.cpp @@ -257,7 +257,7 @@ void GameLoop() { CheckKeys(); GameTicker(); - PlayerInterruptKeys(); + PlayerInterruptKeys(true); UpdateSounds(); CheckKeys2(); } diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index f51c828dd..eb1d6fff9 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -28,7 +28,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS +extern short bPlayerPan; +extern short bLockPan; + int WeaponToSend, BitsToSend; +bool g_MyAimMode; short nInputStack = 0; @@ -82,8 +86,6 @@ int GetLocalInput() { lLocalButtons = (buttonMap.ButtonDown(gamefunc_Crouch) << 4) | (buttonMap.ButtonDown(gamefunc_Fire) << 3) | (buttonMap.ButtonDown(gamefunc_Jump) << 0); - lLocalButtons |= (WeaponToSend << 13); - WeaponToSend = 0; } else { @@ -156,6 +158,221 @@ void CheckKeys2() } +void PlayerInterruptKeys(bool after) +{ + ControlInfo info; + memset(&info, 0, sizeof(ControlInfo)); // this is done within CONTROL_GetInput() anyway + CONTROL_GetInput(&info); + + static double lastInputTicks; + auto const currentHiTicks = I_msTimeF(); + double const elapsedInputTicks = currentHiTicks - lastInputTicks; + + lastInputTicks = currentHiTicks; + + auto scaleAdjustmentToInterval = [=](double x) { return x * (120 / 4) / (1000.0 / elapsedInputTicks); }; + + if (paused) + return; + + localInput = {}; + InputPacket input{}; + fix16_t input_angle = 0; + + if (PlayerList[nLocalPlayer].nHealth == 0) + { + lPlayerYVel = 0; + lPlayerXVel = 0; + nPlayerDAng = 0; + return; + } + + // JBF: Run key behaviour is selectable + int const playerRunning = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)); + int const turnAmount = playerRunning ? 12 : 8; + int const keyMove = playerRunning ? 12 : 6; + + if (buttonMap.ButtonDown(gamefunc_Strafe)) + { + input.svel -= info.mousex * 4.f; + input.svel -= info.dyaw * keyMove; + } + else + { + input_angle = fix16_sadd(input_angle, fix16_from_float(info.mousex)); + input_angle = fix16_sadd(input_angle, fix16_from_dbl(scaleAdjustmentToInterval(info.dyaw))); + } + + g_MyAimMode = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); + + if (g_MyAimMode) + input.q16horz = fix16_sadd(input.q16horz, fix16_from_float(info.mousey)); + else + input.fvel -= info.mousey * 8.f; + + if (!in_mouseflip) input.q16horz = -input.q16horz; + + input.q16horz = fix16_ssub(input.q16horz, fix16_from_dbl(scaleAdjustmentToInterval(info.dpitch))); + input.svel -= info.dx * keyMove; + input.fvel -= info.dz * keyMove; + + if (buttonMap.ButtonDown(gamefunc_Strafe)) + { + if (buttonMap.ButtonDown(gamefunc_Turn_Left)) + input.svel -= -keyMove; + + if (buttonMap.ButtonDown(gamefunc_Turn_Right)) + input.svel -= keyMove; + } + else + { + static int turn = 0; + static int counter = 0; + // normal, non strafing movement + if (buttonMap.ButtonDown(gamefunc_Turn_Left)) + { + turn -= 2; + + if (turn < -turnAmount) + turn = -turnAmount; + } + else if (buttonMap.ButtonDown(gamefunc_Turn_Right)) + { + turn += 2; + + if (turn > turnAmount) + turn = turnAmount; + } + + if (turn < 0) + { + turn++; + if (turn > 0) + turn = 0; + } + + if (turn > 0) + { + turn--; + if (turn < 0) + turn = 0; + } + + //if ((counter++) % 4 == 0) // what was this for??? + input_angle = fix16_sadd(input_angle, fix16_from_dbl(scaleAdjustmentToInterval(turn * 2))); + + } + + if (buttonMap.ButtonDown(gamefunc_Strafe_Left)) + input.svel += keyMove; + + if (buttonMap.ButtonDown(gamefunc_Strafe_Right)) + input.svel += -keyMove; + + if (buttonMap.ButtonDown(gamefunc_Move_Forward)) + input.fvel += keyMove; + + if (buttonMap.ButtonDown(gamefunc_Move_Backward)) + input.fvel += -keyMove; + + localInput.fvel = clamp(localInput.fvel + input.fvel, -12, 12); + localInput.svel = clamp(localInput.svel + input.svel, -12, 12); + + localInput.q16avel = fix16_sadd(localInput.q16avel, input_angle); + + if (!after) + { + if (WeaponToSend > 0) + localInput.SetNewWeapon(WeaponToSend); + WeaponToSend = 0; + } + + if (!nFreeze) + { + PlayerList[nLocalPlayer].q16angle = fix16_sadd(PlayerList[nLocalPlayer].q16angle, input_angle) & 0x7FFFFFF; + + // A horiz diff of 128 equal 45 degrees, + // so we convert horiz to 1024 angle units + + float const horizAngle = clamp(atan2f(PlayerList[nLocalPlayer].q16horiz - fix16_from_int(92), fix16_from_int(128)) * (512.f / fPI) + fix16_to_float(input.q16horz), -255.f, 255.f); + PlayerList[nLocalPlayer].q16horiz = fix16_from_int(92) + Blrintf(fix16_from_int(128) * tanf(horizAngle * (fPI / 512.f))); + + // Look/aim up/down functions. + if (buttonMap.ButtonDown(gamefunc_Look_Up) || buttonMap.ButtonDown(gamefunc_Aim_Up)) + { + bLockPan = false; + if (PlayerList[nLocalPlayer].q16horiz < fix16_from_int(180)) { + PlayerList[nLocalPlayer].q16horiz = fix16_sadd(PlayerList[nLocalPlayer].q16horiz, fix16_from_dbl(scaleAdjustmentToInterval(4))); + } + + bPlayerPan = true; + nDestVertPan[nLocalPlayer] = PlayerList[nLocalPlayer].q16horiz; + } + else if (buttonMap.ButtonDown(gamefunc_Look_Down) || buttonMap.ButtonDown(gamefunc_Aim_Down)) + { + bLockPan = false; + if (PlayerList[nLocalPlayer].q16horiz > fix16_from_int(4)) { + PlayerList[nLocalPlayer].q16horiz = fix16_ssub(PlayerList[nLocalPlayer].q16horiz, fix16_from_dbl(scaleAdjustmentToInterval(4))); + } + + bPlayerPan = true; + nDestVertPan[nLocalPlayer] = PlayerList[nLocalPlayer].q16horiz; + } + } + + // loc_1C048: + if (totalvel[nLocalPlayer] > 20) { + bPlayerPan = false; + } + + if (g_MyAimMode) + bLockPan = true; + + // loc_1C05E + fix16_t ecx = nDestVertPan[nLocalPlayer] - PlayerList[nLocalPlayer].q16horiz; + + if (g_MyAimMode) + { + ecx = 0; + } + + if (!nFreeze) + { + if (ecx) + { + if (ecx / 4 == 0) + { + if (ecx >= 0) { + ecx = 1; + } + else + { + ecx = -1; + } + } + else + { + ecx /= 4; + + if (ecx > fix16_from_int(4)) + { + ecx = fix16_from_int(4); + } + else if (ecx < -fix16_from_int(4)) + { + ecx = -fix16_from_int(4); + } + } + + PlayerList[nLocalPlayer].q16horiz = fix16_sadd(PlayerList[nLocalPlayer].q16horiz, ecx); + } + + PlayerList[nLocalPlayer].q16horiz = fix16_clamp(PlayerList[nLocalPlayer].q16horiz, fix16_from_int(0), fix16_from_int(184)); + } +} + + + //--------------------------------------------------------------------------- // // CCMD based input. The basics are from Randi's ZDuke but this uses dynamic diff --git a/source/exhumed/src/player.cpp b/source/exhumed/src/player.cpp index 9ae4f53fd..5b8fecc45 100644 --- a/source/exhumed/src/player.cpp +++ b/source/exhumed/src/player.cpp @@ -53,7 +53,6 @@ fix16_t nPlayerDAng = 0; short obobangle = 0, bobangle = 0; short bPlayerPan = 0; short bLockPan = 0; -bool g_MyAimMode; static actionSeq ActionSeq[] = { {18, 0}, {0, 0}, {9, 0}, {27, 0}, {63, 0}, @@ -130,224 +129,6 @@ short PlayerCount; short nNetStartSprites; short nCurStartSprite; -/* -typedef struct -{ -fixed dx; -fixed dy; -fixed dz; -fixed dyaw; -fixed dpitch; -fixed droll; -} ControlInfo; -*/ - -void PlayerInterruptKeys() -{ - ControlInfo info; - memset(&info, 0, sizeof(ControlInfo)); // this is done within CONTROL_GetInput() anyway - CONTROL_GetInput(&info); - - static double lastInputTicks; - auto const currentHiTicks = I_msTimeF(); - double const elapsedInputTicks = currentHiTicks - lastInputTicks; - - lastInputTicks = currentHiTicks; - - auto scaleAdjustmentToInterval = [=](double x) { return x * (120 / 4) / (1000.0 / elapsedInputTicks); }; - - if (paused) - return; - - localInput = {}; - InputPacket input {}; - fix16_t input_angle = 0; - - if (PlayerList[nLocalPlayer].nHealth == 0) - { - lPlayerYVel = 0; - lPlayerXVel = 0; - nPlayerDAng = 0; - return; - } - - // JBF: Run key behaviour is selectable - int const playerRunning = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)); - int const turnAmount = playerRunning ? 12 : 8; - int const keyMove = playerRunning ? 12 : 6; - - if (buttonMap.ButtonDown(gamefunc_Strafe)) - { - input.svel -= info.mousex * 4.f; - input.svel -= info.dyaw * keyMove; - } - else - { - input_angle = fix16_sadd(input_angle, fix16_from_float(info.mousex)); - input_angle = fix16_sadd(input_angle, fix16_from_dbl(scaleAdjustmentToInterval(info.dyaw))); - } - - g_MyAimMode = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - - if (g_MyAimMode) - input.q16horz = fix16_sadd(input.q16horz, fix16_from_float(info.mousey)); - else - input.fvel -= info.mousey * 8.f; - - if (!in_mouseflip) input.q16horz = -input.q16horz; - - input.q16horz = fix16_ssub(input.q16horz, fix16_from_dbl(scaleAdjustmentToInterval(info.dpitch))); - input.svel -= info.dx * keyMove; - input.fvel -= info.dz * keyMove; - - if (buttonMap.ButtonDown(gamefunc_Strafe)) - { - if (buttonMap.ButtonDown(gamefunc_Turn_Left)) - input.svel -= -keyMove; - - if (buttonMap.ButtonDown(gamefunc_Turn_Right)) - input.svel -= keyMove; - } - else - { - static int turn = 0; - static int counter = 0; - // normal, non strafing movement - if (buttonMap.ButtonDown(gamefunc_Turn_Left)) - { - turn -= 2; - - if (turn < -turnAmount) - turn = -turnAmount; - } - else if (buttonMap.ButtonDown(gamefunc_Turn_Right)) - { - turn += 2; - - if (turn > turnAmount) - turn = turnAmount; - } - - if (turn < 0) - { - turn++; - if (turn > 0) - turn = 0; - } - - if (turn > 0) - { - turn--; - if (turn < 0) - turn = 0; - } - - //if ((counter++) % 4 == 0) // what was this for??? - input_angle = fix16_sadd(input_angle, fix16_from_dbl(scaleAdjustmentToInterval(turn * 2))); - - } - - if (buttonMap.ButtonDown(gamefunc_Strafe_Left)) - input.svel += keyMove; - - if (buttonMap.ButtonDown(gamefunc_Strafe_Right)) - input.svel += -keyMove; - - if (buttonMap.ButtonDown(gamefunc_Move_Forward)) - input.fvel += keyMove; - - if (buttonMap.ButtonDown(gamefunc_Move_Backward)) - input.fvel += -keyMove; - - localInput.fvel = clamp(localInput.fvel + input.fvel, -12, 12); - localInput.svel = clamp(localInput.svel + input.svel, -12, 12); - - localInput.q16avel = fix16_sadd(localInput.q16avel, input_angle); - - if (!nFreeze) - { - PlayerList[nLocalPlayer].q16angle = fix16_sadd(PlayerList[nLocalPlayer].q16angle, input_angle) & 0x7FFFFFF; - - // A horiz diff of 128 equal 45 degrees, - // so we convert horiz to 1024 angle units - - float const horizAngle = clamp(atan2f(PlayerList[nLocalPlayer].q16horiz - fix16_from_int(92), fix16_from_int(128)) * (512.f / fPI) + fix16_to_float(input.q16horz), -255.f, 255.f); - PlayerList[nLocalPlayer].q16horiz = fix16_from_int(92) + Blrintf(fix16_from_int(128) * tanf(horizAngle * (fPI / 512.f))); - - // Look/aim up/down functions. - if (buttonMap.ButtonDown(gamefunc_Look_Up) || buttonMap.ButtonDown(gamefunc_Aim_Up)) - { - bLockPan = false; - if (PlayerList[nLocalPlayer].q16horiz < fix16_from_int(180)) { - PlayerList[nLocalPlayer].q16horiz = fix16_sadd(PlayerList[nLocalPlayer].q16horiz, fix16_from_dbl(scaleAdjustmentToInterval(4))); - } - - bPlayerPan = true; - nDestVertPan[nLocalPlayer] = PlayerList[nLocalPlayer].q16horiz; - } - else if (buttonMap.ButtonDown(gamefunc_Look_Down) || buttonMap.ButtonDown(gamefunc_Aim_Down)) - { - bLockPan = false; - if (PlayerList[nLocalPlayer].q16horiz > fix16_from_int(4)) { - PlayerList[nLocalPlayer].q16horiz = fix16_ssub(PlayerList[nLocalPlayer].q16horiz, fix16_from_dbl(scaleAdjustmentToInterval(4))); - } - - bPlayerPan = true; - nDestVertPan[nLocalPlayer] = PlayerList[nLocalPlayer].q16horiz; - } - } - - // loc_1C048: - if (totalvel[nLocalPlayer] > 20) { - bPlayerPan = false; - } - - if (g_MyAimMode) - bLockPan = true; - - // loc_1C05E - fix16_t ecx = nDestVertPan[nLocalPlayer] - PlayerList[nLocalPlayer].q16horiz; - - if (g_MyAimMode) - { - ecx = 0; - } - - if (!nFreeze) - { - if (ecx) - { - if (ecx / 4 == 0) - { - if (ecx >= 0) { - ecx = 1; - } - else - { - ecx = -1; - } - } - else - { - ecx /= 4; - - if (ecx > fix16_from_int(4)) - { - ecx = fix16_from_int(4); - } - else if (ecx < -fix16_from_int(4)) - { - ecx = -fix16_from_int(4); - } - } - - PlayerList[nLocalPlayer].q16horiz = fix16_sadd(PlayerList[nLocalPlayer].q16horiz, ecx); - } - - PlayerList[nLocalPlayer].q16horiz = fix16_clamp(PlayerList[nLocalPlayer].q16horiz, fix16_from_int(0), fix16_from_int(184)); - } -} - void RestoreSavePoint(int nPlayer, int *x, int *y, int *z, short *nSector, short *nAngle) { *x = sPlayerSave[nPlayer].x; @@ -2884,7 +2665,7 @@ loc_1BD2E: // loc_1BE70: // Handle player pressing number keys to change weapon - uint8_t var_90 = (buttons >> 13) & 0xF; + uint8_t var_90 = sPlayerInput[nPlayer].getNewWeapon(); if (var_90) { @@ -3108,7 +2889,6 @@ static SavegameHelper sgh("player", SV(bobangle), SV(bPlayerPan), SV(bLockPan), - SV(g_MyAimMode), SV(nStandHeight), SV(PlayerCount), SV(nNetStartSprites), diff --git a/source/exhumed/src/player.h b/source/exhumed/src/player.h index 49321f55e..3c1dc8c40 100644 --- a/source/exhumed/src/player.h +++ b/source/exhumed/src/player.h @@ -23,7 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS -void PlayerInterruptKeys(); +void PlayerInterruptKeys(bool after); void RestoreSavePoint(int nPlayer, int *x, int *y, int *z, short *nSector, short *nAngle); void SetSavePoint(int nPlayer, int x, int y, int z, short nSector, short nAngle); void InitPlayer(); diff --git a/source/exhumed/src/ps_input.h b/source/exhumed/src/ps_input.h index 966313223..23ae1e3fb 100644 --- a/source/exhumed/src/ps_input.h +++ b/source/exhumed/src/ps_input.h @@ -33,6 +33,18 @@ struct PlayerInput short nTarget; fix16_t horizon; int8_t nItem; + ESyncBits actions; + + int getNewWeapon() const + { + return (actions & SB_WEAPONMASK_BITS).GetValue(); + } + + void SetNewWeapon(int weap) + { + actions = (actions & ~SB_WEAPONMASK_BITS) | (ESyncBits::FromInt(weap) & SB_WEAPONMASK_BITS); + } + }; void InitInput(); From f597f7c265f68c078c59e9fa63ccdf3e22b33422 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 27 Aug 2020 00:25:59 +0200 Subject: [PATCH 06/43] - made the GameFunc constants global again. With most of the more specific features being migrated to CCMDs the list is relatively clean now, with merely 2 buttons that are game specific. --- source/blood/src/blood.cpp | 33 ----------------------- source/blood/src/blood.h | 35 ------------------------ source/core/gamecontrol.cpp | 1 + source/core/inputstate.cpp | 45 +++++++++++++++++++++++++++++++ source/core/inputstate.h | 36 +++++++++++++++++++++++++ source/exhumed/src/exhumed.h | 37 ------------------------- source/games/duke/src/constants.h | 35 ------------------------ source/games/duke/src/game.cpp | 41 ---------------------------- source/sw/src/game.cpp | 36 ------------------------- source/sw/src/game.h | 36 ------------------------- source/sw/src/input.cpp | 4 +-- 11 files changed, 84 insertions(+), 255 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 0261066bb..7d8c42e27 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -665,42 +665,9 @@ void ParseOptions(void) void ReadAllRFS(); -static const char* actions[] = { - "Move_Forward", - "Move_Backward", - "Turn_Left", - "Turn_Right", - "Strafe", - "Fire", - "Open", - "Run", - "Alt_Fire", // Duke3D", Blood - "Jump", - "Crouch", - "Look_Up", - "Look_Down", - "Look_Left", - "Look_Right", - "Strafe_Left", - "Strafe_Right", - "Aim_Up", - "Aim_Down", - "SendMessage", - "Shrink_Screen", - "Enlarge_Screen", - "Show_Opponents_Weapon", - "See_Coop_View", - "Mouse_Aiming", - "Dpad_Select", - "Dpad_Aiming", - "Third_Person_View", - "Toggle_Crouch", -}; - void GameInterface::app_init() { InitCheats(); - buttonMap.SetButtons(actions, NUM_ACTIONS); memcpy(&gGameOptions, &gSingleGameOptions, sizeof(GAMEOPTIONS)); gGameOptions.nMonsterSettings = !userConfig.nomonsters; ReadAllRFS(); diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index b447e4692..71b77fc59 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -29,41 +29,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS -// Order is that of EDuke32 by necessity because it exposes the key binds to scripting by index instead of by name. -enum GameFunction_t -{ - gamefunc_Move_Forward, - gamefunc_Move_Backward, - gamefunc_Turn_Left, - gamefunc_Turn_Right, - gamefunc_Strafe, - gamefunc_Fire, - gamefunc_Open, - gamefunc_Run, - gamefunc_Alt_Fire, // Duke3D, Blood - gamefunc_Jump, - gamefunc_Crouch, - gamefunc_Look_Up, - gamefunc_Look_Down, - gamefunc_Look_Left, - gamefunc_Look_Right, - gamefunc_Strafe_Left, - gamefunc_Strafe_Right, - gamefunc_Aim_Up, - gamefunc_Aim_Down, - gamefunc_SendMessage, - gamefunc_Shrink_Screen, - gamefunc_Enlarge_Screen, - gamefunc_Show_Opponents_Weapon, - gamefunc_See_Coop_View, - gamefunc_Mouse_Aiming, - gamefunc_Dpad_Select, - gamefunc_Dpad_Aiming, - gamefunc_Third_Person_View, - gamefunc_Toggle_Crouch, - NUM_ACTIONS -}; - struct INIDESCRIPTION { const char *pzName; const char *pzFilename; diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 2f53733b4..07fafdd0e 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -871,6 +871,7 @@ int RunGame() if (exec) exec->ExecCommands(); gamestate = GS_LEVEL; + SetupGameButtons(); gi->app_init(); app_loop(); return 0; // this is never reached. app_loop only exits via exception. diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index d24afb35a..b437ba160 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -38,6 +38,8 @@ #include "gamecvars.h" #include "v_video.h" #include "statusbar.h" +#include"packet.h" +#include "gamecontrol.h" //========================================================================== // @@ -175,3 +177,46 @@ void CONTROL_GetInput(ControlInfo* info) info->dpitch += -joyaxes[JOYAXIS_Pitch] * 22.5f; } } + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void SetupGameButtons() +{ + static const char* actions[] = { + "Move_Forward", + "Move_Backward", + "Turn_Left", + "Turn_Right", + "Strafe", + "Fire", + "Open", + "Run", + "Alt_Fire", + "Jump", + "Crouch", + "Look_Up", + "Look_Down", + "Look_Left", + "Look_Right", + "Strafe_Left", + "Strafe_Right", + "Aim_Up", + "Aim_Down", + "Shrink_Screen", + "Enlarge_Screen", + "Show_Opponents_Weapon", + "See_Coop_View", + "Mouse_Aiming", + "Dpad_Select", + "Dpad_Aiming", + "Third_Person_View", + "Toggle_Crouch", + "Quick_Kick", + }; + buttonMap.SetButtons(actions, NUM_ACTIONS); +} + diff --git a/source/core/inputstate.h b/source/core/inputstate.h index 22f0d5c24..161fa31b8 100644 --- a/source/core/inputstate.h +++ b/source/core/inputstate.h @@ -62,3 +62,39 @@ extern InputState inputState; void CONTROL_GetInput(ControlInfo* info); int32_t handleevents(void); + +enum GameFunction_t +{ + gamefunc_Move_Forward, + gamefunc_Move_Backward, + gamefunc_Turn_Left, + gamefunc_Turn_Right, + gamefunc_Strafe, + gamefunc_Fire, + gamefunc_Open, + gamefunc_Run, + gamefunc_Alt_Fire, + gamefunc_Jump, + gamefunc_Crouch, + gamefunc_Look_Up, + gamefunc_Look_Down, + gamefunc_Look_Left, + gamefunc_Look_Right, + gamefunc_Strafe_Left, + gamefunc_Strafe_Right, + gamefunc_Aim_Up, + gamefunc_Aim_Down, + gamefunc_Shrink_Screen, // Automap only + gamefunc_Enlarge_Screen, // Automap only + gamefunc_Show_Opponents_Weapon, // CCMD + gamefunc_See_Coop_View, // CCMD + gamefunc_Mouse_Aiming, + gamefunc_Dpad_Select, + gamefunc_Dpad_Aiming, + gamefunc_Third_Person_View, // CCMD + gamefunc_Toggle_Crouch, + gamefunc_Quick_Kick, + NUM_ACTIONS +}; + +void SetupGameButtons(); diff --git a/source/exhumed/src/exhumed.h b/source/exhumed/src/exhumed.h index 47bfa58db..a68d9b27a 100644 --- a/source/exhumed/src/exhumed.h +++ b/source/exhumed/src/exhumed.h @@ -36,43 +36,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS -// Order is that of EDuke32 by necessity because it exposes the key binds to scripting by index instead of by name. -enum GameFunction_t -{ - gamefunc_Move_Forward, - gamefunc_Move_Backward, - gamefunc_Turn_Left, - gamefunc_Turn_Right, - gamefunc_Strafe, - gamefunc_Fire, - gamefunc_Open, - gamefunc_Run, - gamefunc_Alt_Fire, // Duke3D, Blood - gamefunc_Jump, - gamefunc_Crouch, - gamefunc_Look_Up, - gamefunc_Look_Down, - gamefunc_Look_Left, - gamefunc_Look_Right, - gamefunc_Strafe_Left, - gamefunc_Strafe_Right, - gamefunc_Aim_Up, - gamefunc_Aim_Down, - gamefunc_SendMessage, - gamefunc_Shrink_Screen, - gamefunc_Enlarge_Screen, - gamefunc_Show_Opponents_Weapon, - gamefunc_See_Coop_View, - gamefunc_Mouse_Aiming, - gamefunc_Dpad_Select, - gamefunc_Dpad_Aiming, - gamefunc_Last_Weapon, - gamefunc_Alt_Weapon, - gamefunc_Third_Person_View, - gamefunc_Toggle_Crouch, // This is the last one used by EDuke32. - NUM_ACTIONS, - -}; #define kTimerTicks 120 diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h index 64822083a..3d441fe0c 100644 --- a/source/games/duke/src/constants.h +++ b/source/games/duke/src/constants.h @@ -3,41 +3,6 @@ // all game constants got collected here. -// Most of these should be replaced by CCMDs eventually -enum GameFunction_t -{ - gamefunc_Move_Forward, - gamefunc_Move_Backward, - gamefunc_Turn_Left, - gamefunc_Turn_Right, - gamefunc_Strafe, - gamefunc_Fire, - gamefunc_Open, - gamefunc_Run, - gamefunc_Jump, - gamefunc_Crouch, - gamefunc_Look_Up, - gamefunc_Look_Down, - gamefunc_Look_Left, - gamefunc_Look_Right, - gamefunc_Strafe_Left, - gamefunc_Strafe_Right, - gamefunc_Aim_Up, - gamefunc_Aim_Down, - gamefunc_Shrink_Screen, // CCMD - gamefunc_Enlarge_Screen, // CCMD - gamefunc_Show_Opponents_Weapon, // CCMD - gamefunc_See_Coop_View, // CCMD - gamefunc_Mouse_Aiming, // CCMD - gamefunc_Quick_Kick, - gamefunc_Dpad_Select, - gamefunc_Dpad_Aiming, - gamefunc_Third_Person_View, // CCMD - gamefunc_Toggle_Crouch, - NUM_ACTIONS -}; - - enum { TICRATE = 120, diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index 7fc48316f..caa264c8f 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -234,47 +234,6 @@ static void setupbackdrop() // //--------------------------------------------------------------------------- -static void SetupGameButtons() -{ - static const char* actions[] = { - "Move_Forward", - "Move_Backward", - "Turn_Left", - "Turn_Right", - "Strafe", - "Fire", - "Open", - "Run", - "Jump", - "Crouch", - "Look_Up", - "Look_Down", - "Look_Left", - "Look_Right", - "Strafe_Left", - "Strafe_Right", - "Aim_Up", - "Aim_Down", - "Shrink_Screen", - "Enlarge_Screen", - "Show_Opponents_Weapon", - "See_Coop_View", - "Mouse_Aiming", - "Quick_Kick", - "Dpad_Select", - "Dpad_Aiming", - "Third_Person_View", - "Toggle_Crouch", - }; - buttonMap.SetButtons(actions, NUM_ACTIONS); -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - static void loaddefs() { const char* defsfile = G_DefFile(); diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index edf851112..e67c1283d 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -175,46 +175,10 @@ void SybexScreen(void); // //--------------------------------------------------------------------------- -static const char* actions[] = { - "Move_Forward", - "Move_Backward", - "Turn_Left", - "Turn_Right", - "Strafe", - "Fire", - "Open", - "Run", - "Alt_Fire", // Duke3D", Blood - "Jump", - "Crouch", - "Look_Up", - "Look_Down", - "Look_Left", - "Look_Right", - "Strafe_Left", - "Strafe_Right", - "Aim_Up", - "Aim_Down", - "SendMessage", - "Shrink_Screen", - "Enlarge_Screen", - "Show_Opponents_Weapon", - "See_Coop_View", - "Mouse_Aiming", - "Dpad_Select", - "Dpad_Aiming", - "Last_Weapon", - "Alt_Weapon", - "Third_Person_View", - "Toggle_Crouch", // This is the last one used by EDuke32"", - -}; - void GameInterface::app_init() { GameTicRate = 40; InitCheats(); - buttonMap.SetButtons(actions, NUM_ACTIONS); automapping = 1; gs = gs_defaults; diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 2f21873bc..b1b4244a0 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -73,42 +73,6 @@ typedef struct extern const GAME_SET gs_defaults; extern GAME_SET gs; -enum GameFunction_t -{ - gamefunc_Move_Forward, - gamefunc_Move_Backward, - gamefunc_Turn_Left, - gamefunc_Turn_Right, - gamefunc_Strafe, - gamefunc_Fire, - gamefunc_Open, - gamefunc_Run, - gamefunc_Alt_Fire, // Duke3D, Blood - gamefunc_Jump, - gamefunc_Crouch, - gamefunc_Look_Up, - gamefunc_Look_Down, - gamefunc_Look_Left, - gamefunc_Look_Right, - gamefunc_Strafe_Left, - gamefunc_Strafe_Right, - gamefunc_Aim_Up, - gamefunc_Aim_Down, - gamefunc_SendMessage, - gamefunc_Shrink_Screen, - gamefunc_Enlarge_Screen, - gamefunc_Show_Opponents_Weapon, - gamefunc_See_Coop_View, - gamefunc_Mouse_Aiming, - gamefunc_Dpad_Select, - gamefunc_Dpad_Aiming, - gamefunc_Last_Weapon, - gamefunc_Alt_Weapon, - gamefunc_Third_Person_View, - gamefunc_Toggle_Crouch, // This is the last one used by EDuke32. - NUM_ACTIONS -}; - enum { DREALMSPAL = 1, diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index 0fff211b7..b92554978 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -420,9 +420,9 @@ getinput(InputPacket *loc, SWBOOL tied) SET(loc->bits, prev_weapon + 1); } - if (buttonMap.ButtonDown(gamefunc_Alt_Weapon)) + if (false)//buttonMap.ButtonDown(gamefunc_Alt_Weapon)) will be renabled in an upcoming commit. { - buttonMap.ClearButton(gamefunc_Alt_Weapon); + //buttonMap.ClearButton(gamefunc_Alt_Weapon); USERp u = User[pp->PlayerSprite]; short const which_weapon = u->WeaponNum + 1; SET(loc->bits, which_weapon); From 89f5b2698846caa97a53ab2f1beb36784af5d807 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 27 Aug 2020 00:27:10 +0200 Subject: [PATCH 07/43] - fixed badly placed include. --- source/blood/src/controls.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blood/src/controls.h b/source/blood/src/controls.h index 82ab79bf8..59865a03e 100644 --- a/source/blood/src/controls.h +++ b/source/blood/src/controls.h @@ -22,10 +22,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //------------------------------------------------------------------------- #pragma once -BEGIN_BLD_NS - #include "packet.h" +BEGIN_BLD_NS + extern InputPacket gInput, gNetInput; extern bool bSilentAim; From 10df3e094a25eac1f04fdd8c8c3dd2cb41af27d1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 27 Aug 2020 00:53:35 +0200 Subject: [PATCH 08/43] - rework of weapon input to use common features in shared code. This also adds stubs for all unimplemented features in the games for easier addition. --- source/blood/src/blood.cpp | 18 +++++----- source/blood/src/controls.cpp | 21 +---------- source/blood/src/player.cpp | 2 +- source/blood/src/player.h | 4 +-- source/blood/src/weapon.cpp | 12 ++++--- source/core/inputstate.cpp | 57 ++++++++++++++++++++++++++++++ source/core/inputstate.h | 3 ++ source/core/packet.h | 25 ++++++++++--- source/exhumed/src/exhumed.cpp | 32 ++++++++++++++++- source/exhumed/src/input.cpp | 33 ++++------------- source/games/duke/src/input.cpp | 55 +++++----------------------- source/games/duke/src/player_d.cpp | 18 ++++++---- source/games/duke/src/player_r.cpp | 14 +++++--- source/sw/src/input.cpp | 45 +++++------------------ 14 files changed, 177 insertions(+), 162 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 7d8c42e27..44c2fe282 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -525,14 +525,16 @@ void ProcessFrame(void) char buffer[128]; for (int i = connecthead; i >= 0; i = connectpoint2[i]) { - gPlayer[i].input.syncFlags.value &= ~flag_buttonmask; - gPlayer[i].input.syncFlags.value |= gFifoInput[gNetFifoTail & 255][i].syncFlags.value; - int newweap = gFifoInput[gNetFifoTail & 255][i].getNewWeapon(); - if (newweap) gPlayer[i].newWeapon = newweap; - gPlayer[i].input.fvel = gFifoInput[gNetFifoTail&255][i].fvel; - gPlayer[i].input.q16avel = gFifoInput[gNetFifoTail&255][i].q16avel; - gPlayer[i].input.svel = gFifoInput[gNetFifoTail&255][i].svel; - gPlayer[i].input.q16horz = gFifoInput[gNetFifoTail&255][i].q16horz; + auto& inp = gPlayer[i].input; + auto oldactions = inp.actions; + auto oldflags = inp.syncFlags.value; + + inp = gFifoInput[gNetFifoTail & 255][i]; + inp.actions |= oldactions & SB_INTERFACE_MASK; // should be everything non-button and non-weapon + inp.syncFlags.value |= oldflags & ~flag_buttonmask; + + int newweap = inp.getNewWeapon(); + if (newweap > 0 && newweap < WeaponSel_MaxBlood) gPlayer[i].newWeapon = newweap; } gNetFifoTail++; diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index ca622d62c..c0571cea4 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -150,8 +150,7 @@ void ctrlGetInput(void) gInput.syncFlags.quit = 1; gInput.syncFlags.value |= BitsToSend.value; - if (WeaponToSend != 0) - gInput.SetNewWeapon(WeaponToSend); + ApplyGlobalInput(gInput, &info); BitsToSend.value = 0; WeaponToSend = 0; @@ -345,27 +344,9 @@ void ctrlGetInput(void) // //--------------------------------------------------------------------------- -static int ccmd_slot(CCmdFuncPtr parm) -{ - if (parm->numparms != 1) return CCMD_SHOWHELP; - - auto slot = atoi(parm->parms[0]); - if (slot >= 1 && slot <= 10) - { - WeaponToSend = slot; - return CCMD_OK; - } - return CCMD_SHOWHELP; -} - void registerinputcommands() { - C_RegisterFunction("slot", "slot : select a weapon from the given slot (1-10)", ccmd_slot); - C_RegisterFunction("weapprev", nullptr, [](CCmdFuncPtr)->int { if (gPlayer[myconnectindex].nextWeapon == 0) BitsToSend.prevWeapon = 1; return CCMD_OK; }); - C_RegisterFunction("weapnext", nullptr, [](CCmdFuncPtr)->int { if (gPlayer[myconnectindex].nextWeapon == 0) BitsToSend.nextWeapon = 1; return CCMD_OK; }); C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend.pause = 1; sendPause = true; return CCMD_OK; }); - C_RegisterFunction("proximitybombs", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = 11; return CCMD_OK; }); - C_RegisterFunction("remotebombs", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = 12; return CCMD_OK; }); C_RegisterFunction("jumpboots", nullptr, [](CCmdFuncPtr)->int { BitsToSend.useJumpBoots = 1; return CCMD_OK; }); C_RegisterFunction("medkit", nullptr, [](CCmdFuncPtr)->int { BitsToSend.useMedKit = 1; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend.lookCenter = 1; return CCMD_OK; }); diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index d277249a8..f9a692621 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -1331,7 +1331,7 @@ void ProcessInput(PLAYER *pPlayer) pPlayer->q16horiz = mulscale16(0x8000-(Cos(ClipHigh(pPlayer->deathTime*8, 1024))>>15), fix16_from_int(120)); } if (pPlayer->curWeapon) - pInput->SetNewWeapon(pPlayer->curWeapon); + pInput->setNewWeapon(pPlayer->curWeapon); if (pInput->syncFlags.action) { if (bSeqStat) diff --git a/source/blood/src/player.h b/source/blood/src/player.h index f90fe6900..5fe05a22d 100644 --- a/source/blood/src/player.h +++ b/source/blood/src/player.h @@ -119,8 +119,8 @@ struct PLAYER char hasFlag; short used2[8]; // ?? int damageControl[7]; - char curWeapon; - char nextWeapon; + int8_t curWeapon; + int8_t nextWeapon; int weaponTimer; int weaponState; int weaponAmmo; //rename diff --git a/source/blood/src/weapon.cpp b/source/blood/src/weapon.cpp index 76cd93f5a..581486447 100644 --- a/source/blood/src/weapon.cpp +++ b/source/blood/src/weapon.cpp @@ -2026,9 +2026,9 @@ void WeaponProcess(PLAYER *pPlayer) { pPlayer->newWeapon = pPlayer->nextWeapon; pPlayer->nextWeapon = 0; } - if (pPlayer->input.syncFlags.nextWeapon) + if (pPlayer->input.getNewWeapon() == WeaponSel_Next) { - pPlayer->input.syncFlags.nextWeapon = 0; + pPlayer->input.setNewWeapon(0); pPlayer->weaponState = 0; pPlayer->nextWeapon = 0; int t; @@ -2042,9 +2042,9 @@ void WeaponProcess(PLAYER *pPlayer) { } pPlayer->newWeapon = weapon; } - if (pPlayer->input.syncFlags.prevWeapon) + else if (pPlayer->input.getNewWeapon() == WeaponSel_Prev) { - pPlayer->input.syncFlags.prevWeapon = 0; + pPlayer->input.setNewWeapon(0); pPlayer->weaponState = 0; pPlayer->nextWeapon = 0; int t; @@ -2058,6 +2058,10 @@ void WeaponProcess(PLAYER *pPlayer) { } pPlayer->newWeapon = weapon; } + else if (pPlayer->input.getNewWeapon() == WeaponSel_Alt) + { + // todo + } if (pPlayer->weaponState == -1) { pPlayer->weaponState = 0; diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index b437ba160..e9921e54a 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -41,6 +41,8 @@ #include"packet.h" #include "gamecontrol.h" +static int WeaponToSend = 0; + //========================================================================== // // @@ -220,3 +222,58 @@ void SetupGameButtons() buttonMap.SetButtons(actions, NUM_ACTIONS); } +//========================================================================== +// +// +// +//========================================================================== + +CCMD(slot) +{ + // The max differs between games so we have to handle this here. + int max = (g_gameType & GAMEFLAG_PSEXHUMED) || (g_gameType & (GAMEFLAG_DUKE | GAMEFLAG_SHAREWARE)) == (GAMEFLAG_DUKE | GAMEFLAG_SHAREWARE) ? 7 : (g_gameType & GAMEFLAG_BLOOD) ? 12 : 10; + if (argv.argc() != 2) + { + Printf("slot : select a weapon from the given slot (1-%d)", max); + } + + auto slot = atoi(argv[1]); + if (slot >= 1 && slot <= max) + { + WeaponToSend = slot; + } +} + +CCMD(weapprev) +{ + WeaponToSend = WeaponSel_Prev; +} + +CCMD(weapnext) +{ + WeaponToSend = WeaponSel_Next; +} + +CCMD(weapalt) +{ + WeaponToSend = WeaponSel_Alt; // Only used by SW - should also be made usable by Blood ans Duke which put multiple weapons in the same slot. +} + +void ApplyGlobalInput(InputPacket& input, ControlInfo *info) +{ + if (WeaponToSend != 0) input.setNewWeapon(WeaponToSend); + WeaponToSend = 0; + if (info) + { + if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info->dz > 0) input.setNewWeapon(WeaponSel_Prev); + if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info->dz < 0) input.setNewWeapon(WeaponSel_Next); + } + if (buttonMap.ButtonDown(gamefunc_Dpad_Select)) + { + // This eats the controller input for regular use + info->dx = 0; + info->dz = 0; + info->dyaw = 0; + } + +} \ No newline at end of file diff --git a/source/core/inputstate.h b/source/core/inputstate.h index 161fa31b8..221b48204 100644 --- a/source/core/inputstate.h +++ b/source/core/inputstate.h @@ -11,6 +11,7 @@ #include "d_event.h" #include "m_joy.h" #include "gamecvars.h" +#include "packet.h" struct ControlInfo @@ -98,3 +99,5 @@ enum GameFunction_t }; void SetupGameButtons(); +void ApplyGlobalInput(InputPacket& input, ControlInfo *info); + diff --git a/source/core/packet.h b/source/core/packet.h index 0ffbc6fb1..7942aa965 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -4,14 +4,15 @@ #include "fix16.h" #include "tflags.h" - enum ESyncBits_ : uint32_t { SB_FIRST_WEAPON_BIT = 1 << 0, SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits - SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS) + SB_BUTTON_MASK = 0, // all input from buttons (i.e. active while held) + SB_INTERFACE_MASK = 0, // all input from CCMDs + SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS | SB_INTERFACE_MASK) }; // enforce type safe operations on the input bits. @@ -27,6 +28,20 @@ enum }; +enum +{ + // The maximum valid weapons for the respective games. + WeaponSel_Max = 10, + WeaponSel_MaxExhumed = 7, + WeaponSel_MaxBlood = 12, + + // Use named constants instead of magic values for these. The maximum of the supported games is 12 weapons for Blood so these 3 are free. + // Should there ever be need for more weapons to select, the bit field needs to be expanded. + WeaponSel_Next = 13, + WeaponSel_Prev = 14, + WeaponSel_Alt = 15 +}; + enum EDukeSyncBits_ : uint32_t { SKB_JUMP = 1 << 0, @@ -88,8 +103,6 @@ union SYNCFLAGS unsigned int prevItem : 1; unsigned int nextItem : 1; unsigned int useItem : 1; - unsigned int prevWeapon : 1; - unsigned int nextWeapon : 1; unsigned int holsterWeapon : 1; unsigned int lookCenter : 1; unsigned int lookLeft : 1; @@ -193,8 +206,10 @@ struct InputPacket return (actions & SB_WEAPONMASK_BITS).GetValue(); } - void SetNewWeapon(int weap) + void setNewWeapon(int weap) { actions = (actions & ~SB_WEAPONMASK_BITS) | (ESyncBits::FromInt(weap) & SB_WEAPONMASK_BITS); } }; + + diff --git a/source/exhumed/src/exhumed.cpp b/source/exhumed/src/exhumed.cpp index 12c09a06b..78d7e0f17 100644 --- a/source/exhumed/src/exhumed.cpp +++ b/source/exhumed/src/exhumed.cpp @@ -46,6 +46,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "screenjob.h" #include "c_console.h" #include "cheathandler.h" +#include "inputstate.h" #include "core/menu/menu.h" BEGIN_PS_NS @@ -466,6 +467,23 @@ void GameMove(void) totalmoves++; } +static int SelectNextWeapon(int weap2) +{ + // todo + return 0; +} + +static int SelectPrevWeapon(int weap2) +{ + // todo + return 0; +} + +static int SelectAltWeapon(int weap2) +{ + // todo + return 0; +} void GameTicker() { @@ -496,6 +514,19 @@ void GameTicker() lPlayerXVel -= (lPlayerXVel >> 5) + (lPlayerXVel >> 6); lPlayerYVel -= (lPlayerYVel >> 5) + (lPlayerYVel >> 6); } + int weap2 = localInput.getNewWeapon(); + if (weap2 == WeaponSel_Next) + { + weap2 = SelectNextWeapon(weap2); + } + else if (weap2 == WeaponSel_Prev) + { + weap2 = SelectPrevWeapon(weap2); + } + else if (weap2 == WeaponSel_Alt) + { + weap2 = SelectAltWeapon(weap2); + } sPlayerInput[nLocalPlayer].xVel = lPlayerXVel; sPlayerInput[nLocalPlayer].yVel = lPlayerYVel; @@ -503,7 +534,6 @@ void GameTicker() sPlayerInput[nLocalPlayer].buttons = lLocalButtons | lLocalCodes; int weap = sPlayerInput[nLocalPlayer].getNewWeapon(); sPlayerInput[nLocalPlayer].actions = localInput.actions; - int weap2 = localInput.getNewWeapon(); if (weap2 <= 0 || weap2 > 7) sPlayerInput[nLocalPlayer].SetNewWeapon(weap); sPlayerInput[nLocalPlayer].nTarget = besttarget; diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index eb1d6fff9..fe48d7f34 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -31,7 +31,7 @@ BEGIN_PS_NS extern short bPlayerPan; extern short bLockPan; -int WeaponToSend, BitsToSend; +int BitsToSend; bool g_MyAimMode; short nInputStack = 0; @@ -187,6 +187,12 @@ void PlayerInterruptKeys(bool after) return; } + if (!after) + { + ApplyGlobalInput(localInput, &info); + } + + // JBF: Run key behaviour is selectable int const playerRunning = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)); int const turnAmount = playerRunning ? 12 : 8; @@ -280,13 +286,6 @@ void PlayerInterruptKeys(bool after) localInput.q16avel = fix16_sadd(localInput.q16avel, input_angle); - if (!after) - { - if (WeaponToSend > 0) - localInput.SetNewWeapon(WeaponToSend); - WeaponToSend = 0; - } - if (!nFreeze) { PlayerList[nLocalPlayer].q16angle = fix16_sadd(PlayerList[nLocalPlayer].q16angle, input_angle) & 0x7FFFFFF; @@ -380,33 +379,16 @@ void PlayerInterruptKeys(bool after) // //--------------------------------------------------------------------------- -static int ccmd_slot(CCmdFuncPtr parm) -{ - if (parm->numparms != 1) return CCMD_SHOWHELP; - - auto slot = atoi(parm->parms[0]); - if (slot >= 1 && slot <= 7) - { - WeaponToSend = slot; - return CCMD_OK; - } - return CCMD_SHOWHELP; -} - int ccmd_centerview(CCmdFuncPtr parm); void registerinputcommands() { - C_RegisterFunction("slot", "slot : select a weapon from the given slot (1-10)", ccmd_slot); C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { /*BitsToSend |= SKB_PAUSE;*/ sendPause = true; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, ccmd_centerview); C_RegisterFunction("invprev", nullptr, [](CCmdFuncPtr)->int { if (PlayerList[nLocalPlayer].nHealth > 0) SetPrevItem(nLocalPlayer); return CCMD_OK; }); C_RegisterFunction("invnext", nullptr, [](CCmdFuncPtr)->int { if (PlayerList[nLocalPlayer].nHealth > 0) SetNextItem(nLocalPlayer); return CCMD_OK; }); C_RegisterFunction("invuse", nullptr, [](CCmdFuncPtr)->int { if (PlayerList[nLocalPlayer].nHealth > 0) UseCurItem(nLocalPlayer); return CCMD_OK; }); - // todo: These still need to be implemented. - C_RegisterFunction("weapprev", nullptr, [](CCmdFuncPtr)->int { /*WeaponToSend = 11;*/ return CCMD_OK; }); - C_RegisterFunction("weapnext", nullptr, [](CCmdFuncPtr)->int { /*WeaponToSend = 12;*/ return CCMD_OK; }); // These are only here to silence the engine when the keys bound to them are pressed. The functions do not exist. C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { return CCMD_OK; }); @@ -417,7 +399,6 @@ void registerinputcommands() // This is called from ImputState::ClearAllInput and resets all static state being used here. void GameInterface::clearlocalinputstate() { - WeaponToSend = 0; BitsToSend = 0; } diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 4343e7e05..4fa868bc2 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -39,7 +39,6 @@ source as it is released. BEGIN_DUKE_NS -static int WeaponToSend; static EDukeSyncBits BitsToSend; // State timer counters. @@ -146,7 +145,6 @@ void hud_input(int snum) { int i, k; uint8_t dainv; - unsigned int j; struct player_struct* p; short unk; @@ -339,16 +337,12 @@ void hud_input(int snum) if (dainv >= 1 && dainv < 8) FTA(invquotes[dainv - 1], p); } - j = PlayerNewWeapon(snum) - 1; - if (j >= 0) - { - int a = 0; - } - if (j > 0 && p->kickback_pic > 0) - p->wantweaponfire = j; + int weap = PlayerNewWeapon(snum); + if (weap > 1 && p->kickback_pic > 0) + p->wantweaponfire = weap - 1; // Here we have to be extra careful that the weapons do not get mixed up, so let's keep the code for Duke and RR completely separate. - fi.selectweapon(snum, j); + fi.selectweapon(snum, weap); if (PlayerInput(snum, SKB_HOLSTER)) { @@ -467,7 +461,7 @@ void hud_input(int snum) { if (!isRR()) { - j = max_player_health - sprite[p->i].extra; + int j = max_player_health - sprite[p->i].extra; if ((unsigned int)p->firstaid_amount > j) { @@ -485,7 +479,7 @@ void hud_input(int snum) } else { - j = 10; + int j = 10; if (p->firstaid_amount > j) { p->firstaid_amount -= j; @@ -631,7 +625,7 @@ static void processInputBits(player_struct *p, ControlInfo &info) loc.sbits |= BitsToSend; BitsToSend = 0; - if (buttonMap.ButtonDown(gamefunc_Dpad_Select)) + if (buttonMap.ButtonDown(gamefunc_Dpad_Select)) // todo: This must go to global code. { if (info.dx < 0 || info.dyaw < 0) loc.sbits |= SKB_INV_LEFT; if (info.dx > 0 || info.dyaw < 0) loc.sbits |= SKB_INV_RIGHT; @@ -657,23 +651,7 @@ static void processInputBits(player_struct *p, ControlInfo &info) if (buttonMap.ButtonDown(gamefunc_Quick_Kick)) loc.sbits |= SKB_QUICK_KICK; if (in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming)) loc.sbits |= SKB_AIMMODE; - int j = WeaponToSend; - WeaponToSend = 0; - if (VOLUMEONE && (j >= 7 && j <= 10)) j = 0; - - if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info.dz > 0) j = 11; - if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info.dz < 0) j = 12; - - if (j) loc.SetNewWeapon(j); - - } - - if (buttonMap.ButtonDown(gamefunc_Dpad_Select)) - { - // This eats the controller input for regular use - info.dx = 0; - info.dz = 0; - info.dyaw = 0; + ApplyGlobalInput(loc, &info); } if (buttonMap.ButtonDown(gamefunc_Dpad_Aiming)) @@ -1188,24 +1166,8 @@ void GetInput() // //--------------------------------------------------------------------------- -static int ccmd_slot(CCmdFuncPtr parm) -{ - if (parm->numparms != 1) return CCMD_SHOWHELP; - - auto slot = atoi(parm->parms[0]); - if (slot >= 1 && slot <= 10) - { - WeaponToSend = slot; - return CCMD_OK; - } - return CCMD_SHOWHELP; -} - void registerinputcommands() { - C_RegisterFunction("slot", "slot : select a weapon from the given slot (1-10)", ccmd_slot); - C_RegisterFunction("weapprev", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = 11; return CCMD_OK; }); - C_RegisterFunction("weapnext", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = 12; return CCMD_OK; }); C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_PAUSE; sendPause = true; return CCMD_OK; }); C_RegisterFunction("steroids", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_STEROIDS; return CCMD_OK; }); C_RegisterFunction("nightvision", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_NIGHTVISION; return CCMD_OK; }); @@ -1224,7 +1186,6 @@ void registerinputcommands() // This is called from ImputState::ClearAllInput and resets all static state being used here. void GameInterface::clearlocalinputstate() { - WeaponToSend = 0; BitsToSend = 0; nonsharedtimer = 0; turnheldtime = 0; diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 06cf66eb6..521f1540b 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -1099,18 +1099,22 @@ void shoot_d(int i, int atwith) // //--------------------------------------------------------------------------- -void selectweapon_d(int snum, int j) // playernum, weaponnum +void selectweapon_d(int snum, int weap) // playernum, weaponnum { - int i, k; + int i, j, k; auto p = &ps[snum]; if (p->last_pissed_time <= (26 * 218) && p->show_empty_weapon == 0 && p->kickback_pic == 0 && p->quick_kick == 0 && sprite[p->i].xrepeat > 32 && p->access_incs == 0 && p->knee_incs == 0) { if ((p->weapon_pos == 0 || (p->holster_weapon && p->weapon_pos == -9))) { - if (j == 10 || j == 11) + if (weap == WeaponSel_Alt) + { + // todo + } + else if (weap == WeaponSel_Next || weap == WeaponSel_Prev) { k = p->curr_weapon; - j = (j == 10 ? -1 : 1); // JBF: prev (-1) or next (1) weapon choice + j = (weap == WeaponSel_Prev ? -1 : 1); // JBF: prev (-1) or next (1) weapon choice i = 0; while ((k >= 0 && k < 10) || (PLUTOPAK && k == GROW_WEAPON && (p->subweapon & (1 << GROW_WEAPON)) != 0) @@ -1146,8 +1150,8 @@ void selectweapon_d(int snum, int j) // playernum, weaponnum if (PLUTOPAK) // JBF 20040116: so we don't select grower with v1.3d if (k == SHRINKER_WEAPON && (p->subweapon & (1 << GROW_WEAPON))) k = GROW_WEAPON; - if (isWorldTour() && k == FREEZE_WEAPON && (p->subweapon & (1 << FLAMETHROWER_WEAPON)) != 0) - k = FLAMETHROWER_WEAPON; + if (isWorldTour() && k == FREEZE_WEAPON && (p->subweapon & (1 << FLAMETHROWER_WEAPON)) != 0) + k = FLAMETHROWER_WEAPON; j = k; break; @@ -1186,10 +1190,10 @@ void selectweapon_d(int snum, int j) // playernum, weaponnum } } } + else j = weap - 1; k = -1; - if (j == HANDBOMB_WEAPON && p->ammo_amount[HANDBOMB_WEAPON] == 0) { k = headspritestat[1]; diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index abd1ba1bc..e176dab8f 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -947,15 +947,19 @@ void shoot_r(int i, int atwith) // //--------------------------------------------------------------------------- -void selectweapon_r(int snum, int j) +void selectweapon_r(int snum, int weap) { - int i, k; + int i, j, k; auto p = &ps[snum]; if (p->last_pissed_time <= (26 * 218) && p->show_empty_weapon == 0 && p->kickback_pic == 0 && p->quick_kick == 0 && sprite[p->i].xrepeat > 8 && p->access_incs == 0 && p->knee_incs == 0) { if ((p->weapon_pos == 0 || (p->holster_weapon && p->weapon_pos == -9))) { - if (j == 10 || j == 11) + if (weap == WeaponSel_Alt) + { + // todo + } + else if (weap == WeaponSel_Next || weap == WeaponSel_Prev) { k = p->curr_weapon; if (isRRRA()) @@ -964,7 +968,7 @@ void selectweapon_r(int snum, int j) else if (k == BUZZSAW_WEAPON) k = THROWSAW_WEAPON; else if (k == SLINGBLADE_WEAPON) k = KNEE_WEAPON; } - j = (j == 10 ? -1 : 1); + j = (weap == WeaponSel_Prev ? -1 : 1); // JBF: prev (-1) or next (1) weapon choice i = 0; while (k >= 0 && k < 10) @@ -987,10 +991,10 @@ void selectweapon_r(int snum, int j) } } } + else j = weap - 1; k = -1; - if (j == DYNAMITE_WEAPON && p->ammo_amount[DYNAMITE_WEAPON] == 0) { k = headspritestat[1]; diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index b92554978..bb922ee02 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -36,7 +36,6 @@ BEGIN_SW_NS SWBOOL MultiPlayQuitFlag = FALSE; -int WeaponToSend = 0; int BitsToSend = 0; int inv_hotkey = 0; @@ -172,6 +171,9 @@ getinput(InputPacket *loc, SWBOOL tied) // for dividing controller input to match speed input speed of other games. float const ticrateScale = 0.75f; + ApplyGlobalInput(*loc, &info); + + if (running) { if (pp->sop_control) @@ -341,18 +343,12 @@ getinput(InputPacket *loc, SWBOOL tied) SET_LOC_KEY(loc->bits, SK_LOOK_UP, buttonMap.ButtonDown(gamefunc_Look_Up)); SET_LOC_KEY(loc->bits, SK_LOOK_DOWN, buttonMap.ButtonDown(gamefunc_Look_Down)); - if (WeaponToSend > 0) - { - loc->SetNewWeapon(WeaponToSend); - WeaponToSend = 0; - } - else if (WeaponToSend == -1) + if (loc->getNewWeapon() == WeaponSel_Next) { USERp u = User[pp->PlayerSprite]; short next_weapon = u->WeaponNum + 1; short start_weapon; - WeaponToSend = 0; start_weapon = u->WeaponNum + 1; if (u->WeaponNum == WPN_SWORD) @@ -381,16 +377,14 @@ getinput(InputPacket *loc, SWBOOL tied) } } - SET(loc->bits, next_weapon + 1); + loc->setNewWeapon(next_weapon + 1); } - else if (WeaponToSend == -2) + else if (loc->getNewWeapon() == WeaponSel_Prev) { USERp u = User[pp->PlayerSprite]; short prev_weapon = u->WeaponNum - 1; short start_weapon; - WeaponToSend = 0; - start_weapon = u->WeaponNum - 1; if (u->WeaponNum == WPN_SWORD) @@ -416,16 +410,13 @@ getinput(InputPacket *loc, SWBOOL tied) } } } - - SET(loc->bits, prev_weapon + 1); + loc->setNewWeapon(prev_weapon + 1); } - - if (false)//buttonMap.ButtonDown(gamefunc_Alt_Weapon)) will be renabled in an upcoming commit. + else if (loc->getNewWeapon() == WeaponSel_Alt) { - //buttonMap.ClearButton(gamefunc_Alt_Weapon); USERp u = User[pp->PlayerSprite]; short const which_weapon = u->WeaponNum + 1; - SET(loc->bits, which_weapon); + loc->setNewWeapon(which_weapon); } @@ -480,25 +471,8 @@ getinput(InputPacket *loc, SWBOOL tied) // //--------------------------------------------------------------------------- -static int ccmd_slot(CCmdFuncPtr parm) -{ - if (parm->numparms != 1) return CCMD_SHOWHELP; - - auto slot = atoi(parm->parms[0]); - if (slot >= 1 && slot <= 10) - { - WeaponToSend = slot; - return CCMD_OK; - } - return CCMD_SHOWHELP; -} - - void registerinputcommands() { - C_RegisterFunction("slot", "slot : select a weapon from the given slot (1-10)", ccmd_slot); - C_RegisterFunction("weapprev", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = -2; return CCMD_OK; }); - C_RegisterFunction("weapnext", nullptr, [](CCmdFuncPtr)->int { WeaponToSend = -1; return CCMD_OK; }); C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_PAUSE); sendPause = true; return CCMD_OK; }); C_RegisterFunction("smoke_bomb", nullptr, [](CCmdFuncPtr)->int { inv_hotkey = INVENTORY_CLOAK + 1; return CCMD_OK; }); C_RegisterFunction("nightvision", nullptr, [](CCmdFuncPtr)->int { inv_hotkey = INVENTORY_NIGHT_VISION + 1; return CCMD_OK; }); @@ -517,7 +491,6 @@ void registerinputcommands() // This is called from ImputState::ClearAllInput and resets all static state being used here. void GameInterface::clearlocalinputstate() { - WeaponToSend = 0; BitsToSend = 0; inv_hotkey = 0; From 43de0d831221acffee14e7d69e1d881a42ff95ac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 27 Aug 2020 21:25:09 +0200 Subject: [PATCH 09/43] - consolidation of inventory item activation through hotkeys. This also adds hotkeys for Exhumed which never implemented them. --- source/blood/src/controls.cpp | 4 - source/blood/src/player.cpp | 24 ++++-- source/core/inputstate.cpp | 22 +++++- source/core/inputstate.h | 2 +- source/core/packet.h | 50 ++++++++----- source/exhumed/src/exhumed.cpp | 19 +++++ source/exhumed/src/input.cpp | 2 +- source/exhumed/src/items.cpp | 16 ---- source/games/duke/src/inlines.h | 10 +++ source/games/duke/src/input.cpp | 27 ++----- source/sw/src/input.cpp | 9 --- source/sw/src/inv.cpp | 46 ++++++------ source/sw/src/predict.cpp | 10 +-- source/sw/src/weapon.cpp | 2 +- wadsrc/static/engine/commonbinds.txt | 2 +- wadsrc/static/engine/menudef.txt | 73 +++++++++++-------- .../static/filter/blood/engine/defbinds.txt | 12 +-- .../static/filter/blood/engine/leftbinds.txt | 12 +-- .../static/filter/blood/engine/origbinds.txt | 14 ++-- wadsrc/static/filter/duke/engine/defbinds.txt | 14 ++-- .../static/filter/duke/engine/leftbinds.txt | 10 +-- .../static/filter/duke/engine/origbinds.txt | 12 +-- wadsrc/static/filter/nam/engine/defbinds.txt | 14 ++-- wadsrc/static/filter/nam/engine/leftbinds.txt | 10 +-- wadsrc/static/filter/nam/engine/origbinds.txt | 14 ++-- .../static/filter/redneck/engine/defbinds.txt | 14 ++-- .../filter/redneck/engine/leftbinds.txt | 10 +-- .../filter/redneck/engine/origbinds.txt | 10 +-- .../filter/shadowwarrior/engine/defbinds.txt | 14 ++-- .../filter/shadowwarrior/engine/leftbinds.txt | 12 +-- .../filter/shadowwarrior/engine/origbinds.txt | 14 ++-- .../static/filter/ww2gi/engine/defbinds.txt | 14 ++-- .../static/filter/ww2gi/engine/leftbinds.txt | 10 +-- .../static/filter/ww2gi/engine/origbinds.txt | 14 ++-- 34 files changed, 288 insertions(+), 254 deletions(-) diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index c0571cea4..57b699121 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -347,14 +347,10 @@ void ctrlGetInput(void) void registerinputcommands() { C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend.pause = 1; sendPause = true; return CCMD_OK; }); - C_RegisterFunction("jumpboots", nullptr, [](CCmdFuncPtr)->int { BitsToSend.useJumpBoots = 1; return CCMD_OK; }); - C_RegisterFunction("medkit", nullptr, [](CCmdFuncPtr)->int { BitsToSend.useMedKit = 1; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend.lookCenter = 1; return CCMD_OK; }); C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend.holsterWeapon = 1; return CCMD_OK; }); C_RegisterFunction("invprev", nullptr, [](CCmdFuncPtr)->int { BitsToSend.prevItem = 1; return CCMD_OK; }); C_RegisterFunction("invnext", nullptr, [](CCmdFuncPtr)->int { BitsToSend.nextItem = 1; return CCMD_OK; }); - C_RegisterFunction("crystalball", nullptr, [](CCmdFuncPtr)->int { BitsToSend.useCrystalBall = 1; return CCMD_OK; }); - C_RegisterFunction("beastvision", nullptr, [](CCmdFuncPtr)->int { BitsToSend.useBeastVision = 1; return CCMD_OK; }); C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend.spin180 = 1; return CCMD_OK; }); C_RegisterFunction("invuse", nullptr, [](CCmdFuncPtr)->int { BitsToSend.useItem = 1; return CCMD_OK; }); } diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index f9a692621..b7c962f2c 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -1295,6 +1295,14 @@ int ActionScan(PLAYER *pPlayer, int *a2, int *a3) void ProcessInput(PLAYER *pPlayer) { + enum + { + Item_MedKit = 0, + Item_CrystalBall = 1, + Item_BeastVision = 2, + Item_JumpBoots = 3 + }; + spritetype *pSprite = pPlayer->pSprite; XSPRITE *pXSprite = pPlayer->pXSprite; int nSprite = pPlayer->nSprite; @@ -1643,27 +1651,27 @@ void ProcessInput(PLAYER *pPlayer) if (pPlayer->packSlots[pPlayer->packItemId].curAmount > 0) packUseItem(pPlayer, pPlayer->packItemId); } - if (pInput->syncFlags.useBeastVision) + if (pInput->isItemUsed(Item_BeastVision)) { - pInput->syncFlags.useBeastVision = 0; + pInput->clearItemUsed(Item_BeastVision); if (pPlayer->packSlots[3].curAmount > 0) packUseItem(pPlayer, 3); } - if (pInput->syncFlags.useCrystalBall) + if (pInput->isItemUsed(Item_CrystalBall)) { - pInput->syncFlags.useCrystalBall = 0; + pInput->clearItemUsed(Item_CrystalBall); if (pPlayer->packSlots[2].curAmount > 0) packUseItem(pPlayer, 2); } - if (pInput->syncFlags.useJumpBoots) + if (pInput->isItemUsed(Item_JumpBoots)) { - pInput->syncFlags.useJumpBoots = 0; + pInput->clearItemUsed(Item_JumpBoots); if (pPlayer->packSlots[4].curAmount > 0) packUseItem(pPlayer, 4); } - if (pInput->syncFlags.useMedKit) + if (pInput->isItemUsed(Item_MedKit)) { - pInput->syncFlags.useMedKit = 0; + pInput->clearItemUsed(Item_MedKit); if (pPlayer->packSlots[0].curAmount > 0) packUseItem(pPlayer, 0); } diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index e9921e54a..04465d81e 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -42,7 +42,7 @@ #include "gamecontrol.h" static int WeaponToSend = 0; - +ESyncBits ActionsToSend = 0; //========================================================================== // // @@ -259,6 +259,24 @@ CCMD(weapalt) WeaponToSend = WeaponSel_Alt; // Only used by SW - should also be made usable by Blood ans Duke which put multiple weapons in the same slot. } +CCMD(useitem) +{ + int max = (g_gameType & GAMEFLAG_PSEXHUMED)? 6 : (g_gameType & GAMEFLAG_SW)? 7 : (g_gameType & GAMEFLAG_BLOOD) ? 4 : 5; + if (argv.argc() != 2) + { + Printf("useitem : activates an inventory item (1-%d)", max); + } + + auto slot = atoi(argv[1]); + if (slot >= 1 && slot <= max) + { + ActionsToSend |= ESyncBits::FromInt(SB_ITEM_BIT_1 << (slot - 1)); + } +} + + + + void ApplyGlobalInput(InputPacket& input, ControlInfo *info) { if (WeaponToSend != 0) input.setNewWeapon(WeaponToSend); @@ -275,5 +293,7 @@ void ApplyGlobalInput(InputPacket& input, ControlInfo *info) info->dz = 0; info->dyaw = 0; } + input.actions |= ActionsToSend; + ActionsToSend = 0; } \ No newline at end of file diff --git a/source/core/inputstate.h b/source/core/inputstate.h index 221b48204..1c28311d8 100644 --- a/source/core/inputstate.h +++ b/source/core/inputstate.h @@ -100,4 +100,4 @@ enum GameFunction_t void SetupGameButtons(); void ApplyGlobalInput(InputPacket& input, ControlInfo *info); - +extern ESyncBits ActionsToSend; \ No newline at end of file diff --git a/source/core/packet.h b/source/core/packet.h index 7942aa965..668b2d96e 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -6,13 +6,24 @@ enum ESyncBits_ : uint32_t { - SB_FIRST_WEAPON_BIT = 1 << 0, + SB_FIRST_WEAPON_BIT = 1 << 0, + SB_ITEM_BIT_1 = 1 << 4, + SB_ITEM_BIT_2 = 1 << 5, + SB_ITEM_BIT_3 = 1 << 6, + SB_ITEM_BIT_4 = 1 << 7, + SB_ITEM_BIT_5 = 1 << 8, + SB_ITEM_BIT_6 = 1 << 9, + SB_ITEM_BIT_7 = 1 << 10, + + // Exhumed has 6 items but doesn't use the network packet to activate them. Need to change + SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits + SB_ITEMUSE_BITS = (127u * SB_ITEM_BIT_1), SB_BUTTON_MASK = 0, // all input from buttons (i.e. active while held) SB_INTERFACE_MASK = 0, // all input from CCMDs - SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS | SB_INTERFACE_MASK) + SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS | SB_ITEMUSE_BITS | SB_INTERFACE_MASK) }; // enforce type safe operations on the input bits. @@ -52,11 +63,8 @@ enum EDukeSyncBits_ : uint32_t SKB_RUN = 1 << 5, SKB_LOOK_LEFT = 1 << 6, SKB_LOOK_RIGHT = 1 << 7, - SKB_STEROIDS = 1 << 12, SKB_LOOK_UP = 1 << 13, SKB_LOOK_DOWN = 1 << 14, - SKB_NIGHTVISION = 1 << 15, - SKB_MEDKIT = 1 << 16, SKB_MULTIFLAG = 1 << 17, SKB_CENTER_VIEW = 1 << 18, SKB_HOLSTER = 1 << 19, @@ -64,8 +72,6 @@ enum EDukeSyncBits_ : uint32_t SKB_PAUSE = 1 << 21, SKB_QUICK_KICK = 1 << 22, SKB_AIMMODE = 1 << 23, - SKB_HOLODUKE = 1 << 24, - SKB_JETPACK = 1 << 25, SKB_GAMEQUIT = 1 << 26, SKB_INV_RIGHT = 1 << 27, SKB_TURNAROUND = 1 << 28, @@ -73,8 +79,8 @@ enum EDukeSyncBits_ : uint32_t SKB_INVENTORY = 1 << 30, SKB_ESCAPE = 1u << 31, - SKB_INTERFACE_BITS = (SKB_STEROIDS | SKB_NIGHTVISION | SKB_MEDKIT | SKB_QUICK_KICK | \ - SKB_HOLSTER | SKB_INV_LEFT | SKB_PAUSE | SKB_HOLODUKE | SKB_JETPACK | SKB_INV_RIGHT | \ + SKB_INTERFACE_BITS = (SKB_QUICK_KICK | \ + SKB_HOLSTER | SKB_INV_LEFT | SKB_PAUSE | SKB_INV_RIGHT | \ SKB_TURNAROUND | SKB_OPEN | SKB_INVENTORY | SKB_ESCAPE), SKB_NONE = 0, @@ -111,10 +117,6 @@ union SYNCFLAGS unsigned int pause : 1; unsigned int quit : 1; unsigned int restart : 1; - unsigned int useBeastVision : 1; - unsigned int useCrystalBall : 1; - unsigned int useJumpBoots : 1; - unsigned int useMedKit : 1; }; }; @@ -124,10 +126,6 @@ union SYNCFLAGS // NETWORK - REDEFINABLE SHARED (SYNC) KEYS BIT POSITIONS // -#define SK_INV_HOTKEY_BIT0 4 -#define SK_INV_HOTKEY_BIT1 5 -#define SK_INV_HOTKEY_BIT2 6 -#define SK_INV_HOTKEY_MASK (BIT(SK_INV_HOTKEY_BIT0)|BIT(SK_INV_HOTKEY_BIT1)|BIT(SK_INV_HOTKEY_BIT2)) #define SK_AUTO_AIM 7 #define SK_CENTER_VIEW 8 @@ -148,8 +146,6 @@ union SYNCFLAGS #define SK_SNAP_DOWN 22 #define SK_QUIT_GAME 23 -#define SK_MULTI_VIEW 24 - #define SK_TURN_180 25 #define SK_INV_LEFT 26 @@ -210,6 +206,22 @@ struct InputPacket { actions = (actions & ~SB_WEAPONMASK_BITS) | (ESyncBits::FromInt(weap) & SB_WEAPONMASK_BITS); } + + bool isItemUsed(int num) + { + return !!(actions & ESyncBits::FromInt(SB_ITEM_BIT_1 << num)); + } + + void setItemUsed(int num) + { + actions |= ESyncBits::FromInt(SB_ITEM_BIT_1 << num); + } + + void clearItemUsed(int num) + { + actions &= ~ESyncBits::FromInt(SB_ITEM_BIT_1 << num); + } + }; diff --git a/source/exhumed/src/exhumed.cpp b/source/exhumed/src/exhumed.cpp index 78d7e0f17..559912a10 100644 --- a/source/exhumed/src/exhumed.cpp +++ b/source/exhumed/src/exhumed.cpp @@ -528,6 +528,25 @@ void GameTicker() weap2 = SelectAltWeapon(weap2); } + for (int i = 0; i < 6; i++) + { + if (localInput.isItemUsed(i)) + { + localInput.clearItemUsed(i); + if (PlayerList[nLocalPlayer].items[i] > 0) + { + if (nItemMagic[i] <= PlayerList[nLocalPlayer].nMagic) + { + sPlayerInput[nLocalPlayer].nItem = i; + break; + } + } + } + } + + + + sPlayerInput[nLocalPlayer].xVel = lPlayerXVel; sPlayerInput[nLocalPlayer].yVel = lPlayerYVel; // make weapon selection persist until it gets used up. diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index fe48d7f34..22866714c 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -388,7 +388,7 @@ void registerinputcommands() C_RegisterFunction("centerview", nullptr, ccmd_centerview); C_RegisterFunction("invprev", nullptr, [](CCmdFuncPtr)->int { if (PlayerList[nLocalPlayer].nHealth > 0) SetPrevItem(nLocalPlayer); return CCMD_OK; }); C_RegisterFunction("invnext", nullptr, [](CCmdFuncPtr)->int { if (PlayerList[nLocalPlayer].nHealth > 0) SetNextItem(nLocalPlayer); return CCMD_OK; }); - C_RegisterFunction("invuse", nullptr, [](CCmdFuncPtr)->int { if (PlayerList[nLocalPlayer].nHealth > 0) UseCurItem(nLocalPlayer); return CCMD_OK; }); + //C_RegisterFunction("invuse", nullptr, [](CCmdFuncPtr)->int { if (PlayerList[nLocalPlayer].nHealth > 0) UseCurItem(nLocalPlayer); return CCMD_OK; }); // These are only here to silence the engine when the keys bound to them are pressed. The functions do not exist. C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { return CCMD_OK; }); diff --git a/source/exhumed/src/items.cpp b/source/exhumed/src/items.cpp index 35d1a57c0..4956ab5aa 100644 --- a/source/exhumed/src/items.cpp +++ b/source/exhumed/src/items.cpp @@ -316,22 +316,6 @@ void UseItem(short nPlayer, short nItem) } } -void UseCurItem(short nPlayer) -{ - int nItem = nPlayerItem[nPlayer]; - - if (nItem >= 0) - { - if (PlayerList[nPlayer].items[nItem] > 0) - { - if (nItemMagic[nItem] <= PlayerList[nPlayer].nMagic) - { - sPlayerInput[nPlayer].nItem = nItem; - } - } - } -} - // TODO - bool return type? int GrabItem(short nPlayer, short nItem) { diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index 4d9075237..710b4abe9 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -146,6 +146,16 @@ inline int PlayerNewWeapon(int pl) return sync[pl].getNewWeapon(); } +inline void PlayerSetItemUsed(int pl, int num) +{ + sync[pl].setItemUsed(num - 1); +} + +inline bool PlayerUseItem(int pl, int num) +{ + return sync[pl].isItemUsed(num - 1); +} + inline int PlayerInputSideVel(int pl) { return sync[pl].svel; diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 4fa868bc2..6b1592630 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -210,19 +210,11 @@ void hud_input(int snum) OnEvent(EVENT_INVENTORY, -1, snum, -1); if (GetGameVarID(g_iReturnVarID, -1, snum) == 0) { - switch (p->inven_icon) - { - // Yet another place where no symbolic constants were used. :( - case ICON_JETPACK: PlayerSetInput(snum, SKB_JETPACK); break; - case ICON_HOLODUKE: PlayerSetInput(snum, SKB_HOLODUKE); break; - case ICON_HEATS: PlayerSetInput(snum, SKB_NIGHTVISION); break; - case ICON_FIRSTAID: PlayerSetInput(snum, SKB_MEDKIT); break; - case ICON_STEROIDS: PlayerSetInput(snum, SKB_STEROIDS); break; - } + if (p->inven_icon > ICON_NONE && p->inven_icon <= ICON_HEATS) PlayerSetItemUsed(snum, p->inven_icon); } } - if (!isRR() && PlayerInput(snum, SKB_NIGHTVISION)) + if (!isRR() && PlayerUseItem(snum, ICON_HEATS)) { SetGameVarID(g_iReturnVarID, 0, -1, snum); OnEvent(EVENT_USENIGHTVISION, -1, snum, -1); @@ -236,7 +228,7 @@ void hud_input(int snum) } } - if (PlayerInput(snum, SKB_STEROIDS)) + if (PlayerUseItem(snum, ICON_STEROIDS)) { SetGameVarID(g_iReturnVarID, 0, -1, snum); OnEvent(EVENT_USESTEROIDS, -1, snum, -1); @@ -363,7 +355,7 @@ void hud_input(int snum) } } - if (PlayerInput(snum, SKB_HOLODUKE) && (isRR() || p->newowner == -1)) + if (PlayerUseItem(snum, ICON_HOLODUKE) && (isRR() || p->newowner == -1)) { SetGameVarID(g_iReturnVarID, 0, -1, snum); OnEvent(EVENT_HOLODUKEON, -1, snum, -1); @@ -419,7 +411,7 @@ void hud_input(int snum) } } - if (isRR() && PlayerInput(snum, SKB_NIGHTVISION) && p->newowner == -1) + if (isRR() && PlayerUseItem(snum, ICON_HEATS) && p->newowner == -1) { SetGameVarID(g_iReturnVarID, 0, -1, snum); OnEvent(EVENT_USENIGHTVISION, -1, snum, -1); @@ -451,7 +443,7 @@ void hud_input(int snum) } } - if (PlayerInput(snum, SKB_MEDKIT)) + if (PlayerUseItem(snum, ICON_FIRSTAID)) { SetGameVarID(g_iReturnVarID, 0, -1, snum); OnEvent(EVENT_USEMEDKIT, -1, snum, -1); @@ -504,7 +496,7 @@ void hud_input(int snum) } } - if (PlayerInput(snum, SKB_JETPACK) && (isRR() || p->newowner == -1)) + if (PlayerUseItem(snum, ICON_JETPACK) && (isRR() || p->newowner == -1)) { SetGameVarID(g_iReturnVarID, 0, -1, snum); OnEvent(EVENT_USEJETPACK, -1, snum, -1); @@ -1169,15 +1161,10 @@ void GetInput() void registerinputcommands() { C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_PAUSE; sendPause = true; return CCMD_OK; }); - C_RegisterFunction("steroids", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_STEROIDS; return CCMD_OK; }); - C_RegisterFunction("nightvision", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_NIGHTVISION; return CCMD_OK; }); - C_RegisterFunction("medkit", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_MEDKIT; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_CENTER_VIEW; return CCMD_OK; }); C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_HOLSTER; return CCMD_OK; }); C_RegisterFunction("invprev", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_INV_LEFT; return CCMD_OK; }); C_RegisterFunction("invnext", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_INV_RIGHT; return CCMD_OK; }); - C_RegisterFunction("holoduke", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_HOLODUKE; return CCMD_OK; }); - C_RegisterFunction("jetpack", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_JETPACK; return CCMD_OK; }); C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_TURNAROUND; return CCMD_OK; }); C_RegisterFunction("invuse", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_INVENTORY; return CCMD_OK; }); C_RegisterFunction("backoff", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_ESCAPE; return CCMD_OK; }); diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index bb922ee02..579b22b12 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -423,9 +423,6 @@ getinput(InputPacket *loc, SWBOOL tied) loc->bits |= BitsToSend; BitsToSend = 0; - SET(loc->bits, inv_hotkey<bits, SK_OPERATE, buttonMap.ButtonDown(gamefunc_Open)); SET_LOC_KEY(loc->bits, SK_JUMP, buttonMap.ButtonDown(gamefunc_Jump)); SET_LOC_KEY(loc->bits, SK_CRAWL, buttonMap.ButtonDown(gamefunc_Crouch)); @@ -474,16 +471,10 @@ getinput(InputPacket *loc, SWBOOL tied) void registerinputcommands() { C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_PAUSE); sendPause = true; return CCMD_OK; }); - C_RegisterFunction("smoke_bomb", nullptr, [](CCmdFuncPtr)->int { inv_hotkey = INVENTORY_CLOAK + 1; return CCMD_OK; }); - C_RegisterFunction("nightvision", nullptr, [](CCmdFuncPtr)->int { inv_hotkey = INVENTORY_NIGHT_VISION + 1; return CCMD_OK; }); - C_RegisterFunction("medkit", nullptr, [](CCmdFuncPtr)->int { inv_hotkey = INVENTORY_MEDKIT + 1; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_CENTER_VIEW); return CCMD_OK; }); C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_HIDE_WEAPON); return CCMD_OK; }); C_RegisterFunction("invprev", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_INV_LEFT); return CCMD_OK; }); C_RegisterFunction("invnext", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_INV_RIGHT); return CCMD_OK; }); - C_RegisterFunction("gas_bomb", nullptr, [](CCmdFuncPtr)->int { inv_hotkey = INVENTORY_CHEMBOMB + 1; return CCMD_OK; }); - C_RegisterFunction("flash_bomb", nullptr, [](CCmdFuncPtr)->int { inv_hotkey = INVENTORY_FLASHBOMB + 1; return CCMD_OK; }); - C_RegisterFunction("caltrops", nullptr, [](CCmdFuncPtr)->int { inv_hotkey = INVENTORY_CALTROPS + 1; return CCMD_OK; }); C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_TURN_180); return CCMD_OK; }); C_RegisterFunction("invuse", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_INV_USE); return CCMD_OK; }); } diff --git a/source/sw/src/inv.cpp b/source/sw/src/inv.cpp index 7f60f702a..d4b07c58b 100644 --- a/source/sw/src/inv.cpp +++ b/source/sw/src/inv.cpp @@ -367,8 +367,6 @@ DoPlayerNightVisionPalette(PLAYERp pp) void UseInventoryNightVision(PLAYERp pp) { -#define NIGHT_INVENTORY_TIME 30 - if (pp->InventoryActive[pp->InventoryNum]) { StopInventoryNightVision(pp, pp->InventoryNum); @@ -473,33 +471,33 @@ void InventoryKeys(PLAYERp pp) FLAG_KEY_RESET(pp, SK_INV_USE); } - // get hotkey number out of input bits - inv_hotkey = TEST(pp->input.bits, SK_INV_HOTKEY_MASK) >> SK_INV_HOTKEY_BIT0; - - if (inv_hotkey) + // test all 7 items + for (int i = 0; i <= 7; i++) { - if (FLAG_KEY_PRESSED(pp, SK_INV_HOTKEY_BIT0)) + ESyncBits bit = ESyncBits::FromInt(SB_ITEM_BIT_1 << i); + if (pp->input.isItemUsed(i)) { - FLAG_KEY_RELEASE(pp, SK_INV_HOTKEY_BIT0); - - inv_hotkey -= 1; - - // switches you to this inventory item - pp->InventoryNum = inv_hotkey; - - if (InventoryData[pp->InventoryNum].Init && !TEST(pp->Flags, PF_CLIMBING)) + if (pp->KeyPressBits & bit) { - if (pp->InventoryAmount[pp->InventoryNum]) - { - InventoryUse(pp); - } - } + pp->KeyPressBits &= ~bit; + + // switches you to this inventory item + pp->InventoryNum = i; + + if (InventoryData[pp->InventoryNum].Init && !TEST(pp->Flags, PF_CLIMBING)) + { + if (pp->InventoryAmount[pp->InventoryNum]) + { + InventoryUse(pp); + } + } + } + } + else + { + pp->KeyPressBits |= bit; } } - else - { - FLAG_KEY_RESET(pp, SK_INV_HOTKEY_BIT0); - } } void InventoryTimer(PLAYERp pp) diff --git a/source/sw/src/predict.cpp b/source/sw/src/predict.cpp index 84b7687a3..6aaaa24ac 100644 --- a/source/sw/src/predict.cpp +++ b/source/sw/src/predict.cpp @@ -83,22 +83,20 @@ DoPrediction(PLAYERp ppp) // get rid of input bits so it doesn't go into other code branches that would // get it out of sync - ppp->input.actions &= ~(SB_WEAPONMASK_BITS); - ppp->KeyPressBits |= (SB_WEAPONMASK_BITS); + ppp->input.actions &= ~(SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS); + ppp->KeyPressBits |= (SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS); RESET(ppp->input.bits, BIT(SK_SHOOT)|BIT(SK_OPERATE)|BIT(SK_INV_LEFT)|BIT(SK_INV_RIGHT)| BIT(SK_INV_USE)|BIT(SK_HIDE_WEAPON)| BIT(SK_AUTO_AIM)| - BIT(SK_CENTER_VIEW)| - SK_INV_HOTKEY_MASK + BIT(SK_CENTER_VIEW) ); SET(ppp->KeyPressFlags, BIT(SK_SHOOT)|BIT(SK_OPERATE)|BIT(SK_INV_LEFT)|BIT(SK_INV_RIGHT)| BIT(SK_INV_USE)|BIT(SK_HIDE_WEAPON)| BIT(SK_AUTO_AIM)| - BIT(SK_CENTER_VIEW)| - SK_INV_HOTKEY_MASK + BIT(SK_CENTER_VIEW) ); // back up things so they won't get stepped on diff --git a/source/sw/src/weapon.cpp b/source/sw/src/weapon.cpp index 839f415ee..f31cbb28a 100644 --- a/source/sw/src/weapon.cpp +++ b/source/sw/src/weapon.cpp @@ -7518,7 +7518,7 @@ const char *DeathString(short SpriteNum) case RADIATION_CLOUD: return GStrings("radiation"); case CALTROPS: - return GStrings("caltrops"); + return GStrings("useitem 7"); } return ""; } diff --git a/wadsrc/static/engine/commonbinds.txt b/wadsrc/static/engine/commonbinds.txt index a9da9dc9e..d38e6e8a9 100644 --- a/wadsrc/static/engine/commonbinds.txt +++ b/wadsrc/static/engine/commonbinds.txt @@ -34,7 +34,7 @@ RCtrl "+Fire" Pause "pause" ` "toggleconsole" -T "+Send_Message" +T "messagemode" Tab "togglemap" mapbind F "togglefollow" mapbind - "+Shrink_Screen" diff --git a/wadsrc/static/engine/menudef.txt b/wadsrc/static/engine/menudef.txt index c471e8e08..14af5aa80 100644 --- a/wadsrc/static/engine/menudef.txt +++ b/wadsrc/static/engine/menudef.txt @@ -584,15 +584,15 @@ OptionMenu "WeaponsControlMenu"// protected } ifgame(Blood) { - Control "$CNTRLMNU_PROXIMITYBOMBS","proximitybombs" - Control "$CNTRLMNU_REMOTEBOMBS" ,"remotebombs" + Control "$CNTRLMNU_PROXIMITYBOMBS","slot 11" + Control "$CNTRLMNU_REMOTEBOMBS" ,"slot 12" } ifgame(ShadowWarrior) { - Control "$CNTRLMNU_SMOKEBOMB","smoke_bomb" - Control "$CNTRLMNU_GASBOMB" ,"gas_bomb" - Control "$CNTRLMNU_FLASHBOMB","flash_bomb" - Control "$CNTRLMNU_CALTROPS" ,"caltrops" + Control "$CNTRLMNU_SMOKEBOMB","useitem 3" + Control "$CNTRLMNU_GASBOMB" ,"useitem 5" + Control "$CNTRLMNU_FLASHBOMB","useitem 6" + Control "$CNTRLMNU_CALTROPS" ,"useitem 7" } } @@ -610,54 +610,65 @@ OptionMenu "InventoryControlsMenu"// protected Control "$CNTRLMNU_NEXTITEM" , "invnext" Control "$CNTRLMNU_PREVIOUSITEM" , "invprev" + // Item numbers here are are defined by the games' internal order. ifgame(Duke) { StaticText "" - Control "$CNTRLMNU_HOLODUKE" , "holoduke" - Control "$CNTRLMNU_JETPACK" , "jetpack" - Control "$CNTRLMNU_NIGHTVISION" , "nightvision" - Control "$CNTRLMNU_MEDKIT" , "medkit" - Control "$CNTRLMNU_STEROIDS" , "steroids" + Control "$CNTRLMNU_HOLODUKE" , "useitem 3" + Control "$CNTRLMNU_JETPACK" , "useitem 4" + Control "$CNTRLMNU_NIGHTVISION" , "useitem 5" + Control "$CNTRLMNU_MEDKIT" , "useitem 1" + Control "$CNTRLMNU_STEROIDS" , "useitem 2" } ifgame(Nam) { StaticText "" - Control "$CNTRLMNU_HOLOSOLDIER" , "holoduke" - Control "$CNTRLMNU_HUEY" , "jetpack" - Control "$CNTRLMNU_NIGHTVISION" , "nightvision" - Control "$CNTRLMNU_MEDKIT" , "medkit" - Control "$CNTRLMNU_TANKMODE" , "steroids" + Control "$CNTRLMNU_HOLOSOLDIER" , "useitem 3" + Control "$CNTRLMNU_HUEY" , "useitem 4" + Control "$CNTRLMNU_NIGHTVISION" , "useitem 5" + Control "$CNTRLMNU_MEDKIT" , "useitem 1" + Control "$CNTRLMNU_TANKMODE" , "useitem 2" } ifgame(WW2GI) { StaticText "" - Control "$CNTRLMNU_FIRE MISSION" , "holoduke" - Control "$CNTRLMNU_NIGHTVISION" , "nightvision" - Control "$CNTRLMNU_MEDKIT" , "medkit" - Control "$CNTRLMNU_SMOKES" , "steroids" + Control "$CNTRLMNU_FIRE MISSION" , "useitem 3" + Control "$CNTRLMNU_NIGHTVISION" , "useitem 5" + Control "$CNTRLMNU_MEDKIT" , "useitem 1" + Control "$CNTRLMNU_SMOKES" , "useitem 2" } ifgame(Redneck, RedneckRides) { StaticText "" - Control "$CNTRLMNU_BEER" , "holoduke" - Control "$CNTRLMNU_COWPIE" , "jetpack" - Control "$CNTRLMNU_YEEHAA" , "nightvision" - Control "$CNTRLMNU_WHISKEY" , "medkit" - Control "$CNTRLMNU_MOONSHINE" , "steroids" + Control "$CNTRLMNU_BEER" , "useitem 3" + Control "$CNTRLMNU_COWPIE" , "useitem 4" + Control "$CNTRLMNU_YEEHAA" , "useitem 5" + Control "$CNTRLMNU_WHISKEY" , "useitem 1" + Control "$CNTRLMNU_MOONSHINE" , "useitem 2" } ifgame(Blood) { StaticText "" - Control "$CNTRLMNU_CRYSTALBALL" , "crystalball" - Control "$CNTRLMNU_JUMPBOOTS" , "jumpboots" - Control "$CNTRLMNU_BEASTVISION" , "beastvision" - Control "$CNTRLMNU_MEDKIT" , "medkit" + Control "$CNTRLMNU_CRYSTALBALL" , "useitem 2" + Control "$CNTRLMNU_JUMPBOOTS" , "useitem 4" + Control "$CNTRLMNU_BEASTVISION" , "useitem 3" + Control "$CNTRLMNU_MEDKIT" , "useitem 1" } ifgame(ShadowWarrior) { StaticText "" - Control "$CNTRLMNU_NIGHTVISION" , "nightvision" - Control "$CNTRLMNU_MEDKIT" , "medkit" + Control "$CNTRLMNU_NIGHTVISION" , "useitem 4" + Control "$CNTRLMNU_MEDKIT" , "useitem 1" + } + ifgame(Exhumed) + { + StaticText "" + Control "$TXT_USEINV1" , "useitem 1" + Control "$TXT_USEINV2" , "useitem 2" + Control "$TXT_USEINV3" , "useitem 3" + Control "$TXT_USEINV4" , "useitem 4" + Control "$TXT_USEINV5" , "useitem 5" + Control "$TXT_USEINV6" , "useitem 6" } } diff --git a/wadsrc/static/filter/blood/engine/defbinds.txt b/wadsrc/static/filter/blood/engine/defbinds.txt index 3e57e634e..027ece43e 100644 --- a/wadsrc/static/filter/blood/engine/defbinds.txt +++ b/wadsrc/static/filter/blood/engine/defbinds.txt @@ -1,11 +1,11 @@ U "+Mouse_Aiming" I "toggle cl_crosshair" Scroll "+Holster_Weapon" -B "BeastVision" -C "CrystalBall" -P "ProximityBombs" -R "RemoteBombs" +B "useitem 3" +C "useitem 2" +P "slot 11" +R "slot 12" X "+Alt_Fire" -J "jumpboots" -M "MedKit" +J "useitem 4" +M "useitem 1" Mouse2 "+Alt_Fire" diff --git a/wadsrc/static/filter/blood/engine/leftbinds.txt b/wadsrc/static/filter/blood/engine/leftbinds.txt index bc13285ed..9fed4e5be 100644 --- a/wadsrc/static/filter/blood/engine/leftbinds.txt +++ b/wadsrc/static/filter/blood/engine/leftbinds.txt @@ -1,9 +1,9 @@ // W "+Show_Opponents_Weapon" -B "BeastVision" -C "CrystalBall" -P "ProximityBombs" -R "RemoteBombs" +B "useitem 3" +C "useitem 2" +P "slot 11" +R "slot 12" X "+Alt_Fire" -J "jumpboots" -M "MedKit" +J "useitem 4" +M "useitem 1" diff --git a/wadsrc/static/filter/blood/engine/origbinds.txt b/wadsrc/static/filter/blood/engine/origbinds.txt index ef059205f..c8e4e65da 100644 --- a/wadsrc/static/filter/blood/engine/origbinds.txt +++ b/wadsrc/static/filter/blood/engine/origbinds.txt @@ -1,10 +1,10 @@ // -X "+Alt_Fire" W "+Show_Opponents_Weapon" -B "BeastVision" -C "CrystalBall" -J "jumpboots" -M "MedKit" -P "ProximityBombs" -R "RemoteBombs" +B "useitem 3" +C "useitem 2" +P "slot 11" +R "slot 12" +X "+Alt_Fire" +J "useitem 4" +M "useitem 1" Mouse2 "+Alt_Fire" diff --git a/wadsrc/static/filter/duke/engine/defbinds.txt b/wadsrc/static/filter/duke/engine/defbinds.txt index 5bcd053fb..2abe049a8 100644 --- a/wadsrc/static/filter/duke/engine/defbinds.txt +++ b/wadsrc/static/filter/duke/engine/defbinds.txt @@ -1,10 +1,10 @@ // -R "Steroids" +R "useitem 2" Q "+Quick_Kick" -H "HoloDuke" -J "Jetpack" -N "NightVision" -M "MedKit" +H "useitem 3" +J "useitem 4" +N "useitem 5" +M "useitem 1" C "+Toggle_Crouch" -Mouse2 "Jetpack" -Mouse3 "MediKit" +Mouse2 "useitem 4" +Mouse3 "useitem 1" diff --git a/wadsrc/static/filter/duke/engine/leftbinds.txt b/wadsrc/static/filter/duke/engine/leftbinds.txt index ce00aa0c8..d04297d13 100644 --- a/wadsrc/static/filter/duke/engine/leftbinds.txt +++ b/wadsrc/static/filter/duke/engine/leftbinds.txt @@ -1,7 +1,7 @@ -H "HoloDuke" -R "Steroids" +H "useitem 3" +R "useitem 2" Q "+Quick_Kick" -J "Jetpack" -N "NightVision" -M "MedKit" +J "useitem 4" +N "useitem 5" +M "useitem 1" W "+Show_Opponents_Weapon" diff --git a/wadsrc/static/filter/duke/engine/origbinds.txt b/wadsrc/static/filter/duke/engine/origbinds.txt index 4da1d5fb4..8c12f9162 100644 --- a/wadsrc/static/filter/duke/engine/origbinds.txt +++ b/wadsrc/static/filter/duke/engine/origbinds.txt @@ -1,13 +1,13 @@ // -R "Steroids" +R "useitem 2" ` "+Quick_Kick" W "+Show_Opponents_Weapon" H "Holo_Duke" -J "Jetpack" -N "NightVision" -M "MedKit" +J "useitem 4" +N "useitem 5" +M "useitem 1" C "toggleconsole" -Mouse2 "Jetpack" -Mouse3 "MediKit" +Mouse2 "useitem 4" +Mouse3 "useitem 1" \ No newline at end of file diff --git a/wadsrc/static/filter/nam/engine/defbinds.txt b/wadsrc/static/filter/nam/engine/defbinds.txt index 5bcd053fb..2abe049a8 100644 --- a/wadsrc/static/filter/nam/engine/defbinds.txt +++ b/wadsrc/static/filter/nam/engine/defbinds.txt @@ -1,10 +1,10 @@ // -R "Steroids" +R "useitem 2" Q "+Quick_Kick" -H "HoloDuke" -J "Jetpack" -N "NightVision" -M "MedKit" +H "useitem 3" +J "useitem 4" +N "useitem 5" +M "useitem 1" C "+Toggle_Crouch" -Mouse2 "Jetpack" -Mouse3 "MediKit" +Mouse2 "useitem 4" +Mouse3 "useitem 1" diff --git a/wadsrc/static/filter/nam/engine/leftbinds.txt b/wadsrc/static/filter/nam/engine/leftbinds.txt index ce00aa0c8..d04297d13 100644 --- a/wadsrc/static/filter/nam/engine/leftbinds.txt +++ b/wadsrc/static/filter/nam/engine/leftbinds.txt @@ -1,7 +1,7 @@ -H "HoloDuke" -R "Steroids" +H "useitem 3" +R "useitem 2" Q "+Quick_Kick" -J "Jetpack" -N "NightVision" -M "MedKit" +J "useitem 4" +N "useitem 5" +M "useitem 1" W "+Show_Opponents_Weapon" diff --git a/wadsrc/static/filter/nam/engine/origbinds.txt b/wadsrc/static/filter/nam/engine/origbinds.txt index 52014371c..253985daa 100644 --- a/wadsrc/static/filter/nam/engine/origbinds.txt +++ b/wadsrc/static/filter/nam/engine/origbinds.txt @@ -1,13 +1,13 @@ // -R "Steroids" +R "useitem 2" ` "+Quick_Kick" W "+Show_Opponents_Weapon" -H "HoloDuke" -J "Jetpack" -N "NightVision" -M "MedKit" +H "useitem 3" +J "useitem 4" +N "useitem 5" +M "useitem 1" C "toggleconsole" -Mouse2 "Jetpack" -Mouse3 "MediKit" +Mouse2 "useitem 4" +Mouse3 "useitem 1" \ No newline at end of file diff --git a/wadsrc/static/filter/redneck/engine/defbinds.txt b/wadsrc/static/filter/redneck/engine/defbinds.txt index 44ff76647..2ac4d63ac 100644 --- a/wadsrc/static/filter/redneck/engine/defbinds.txt +++ b/wadsrc/static/filter/redneck/engine/defbinds.txt @@ -1,10 +1,10 @@ // V "+Show_Opponents_Weapon" -B "HoloDuke" -C "Jetpack" -Y "NightVision" -R "MedKit" -M "Steroids" +B "useitem 3" +C "useitem 4" +Y "useitem 5" +R "useitem 1" +M "useitem 2" Q "+Quick_Kick" -Mouse2 "Jetpack" -Mouse3 "MediKit" +Mouse2 "useitem 4" +Mouse3 "useitem 1" diff --git a/wadsrc/static/filter/redneck/engine/leftbinds.txt b/wadsrc/static/filter/redneck/engine/leftbinds.txt index 52bd1cf24..83ffb9f72 100644 --- a/wadsrc/static/filter/redneck/engine/leftbinds.txt +++ b/wadsrc/static/filter/redneck/engine/leftbinds.txt @@ -1,7 +1,7 @@ E "+Show_Opponents_Weapon" -M "Steroids" +M "useitem 2" Q "+Quick_Kick" -B "HoloDuke" -C "Jetpack" -Y "NightVision" -W "MedKit" +B "useitem 3" +C "useitem 4" +Y "useitem 5" +W "useitem 1" diff --git a/wadsrc/static/filter/redneck/engine/origbinds.txt b/wadsrc/static/filter/redneck/engine/origbinds.txt index 6aa9210bb..ac76b35e8 100644 --- a/wadsrc/static/filter/redneck/engine/origbinds.txt +++ b/wadsrc/static/filter/redneck/engine/origbinds.txt @@ -1,8 +1,8 @@ V "toggleconsole" E "+Show_Opponents_Weapon" -M "Steroids" +M "useitem 2" ` "+Quick_Kick" -B "HoloDuke" -C "Jetpack" -Y "NightVision" -W "MedKit" +B "useitem 3" +C "useitem 4" +Y "useitem 5" +W "useitem 1" diff --git a/wadsrc/static/filter/shadowwarrior/engine/defbinds.txt b/wadsrc/static/filter/shadowwarrior/engine/defbinds.txt index e9d6d2d71..78f8097d5 100644 --- a/wadsrc/static/filter/shadowwarrior/engine/defbinds.txt +++ b/wadsrc/static/filter/shadowwarrior/engine/defbinds.txt @@ -1,9 +1,9 @@ // I "toggle cl_crosshair" -Mouse2 "MedKit" -M "MedKit" -B "Smoke_Bomb" -N "Nightvision" -G "Gas_Bomb" -F "Flash_Bomb" -C "Caltrops" +Mouse2 "useitem 1" +M "useitem 1" +B "useitem 3" +N "useitem 4" +G "useitem 5" +F "useitem 6" +C "useitem 7" diff --git a/wadsrc/static/filter/shadowwarrior/engine/leftbinds.txt b/wadsrc/static/filter/shadowwarrior/engine/leftbinds.txt index e45842f26..a51ed08dc 100644 --- a/wadsrc/static/filter/shadowwarrior/engine/leftbinds.txt +++ b/wadsrc/static/filter/shadowwarrior/engine/leftbinds.txt @@ -1,6 +1,6 @@ -M "MedKit" -B "Smoke_Bomb" -N "Nightvision" -G "Gas_Bomb" -F "Flash_Bomb" -C "Caltrops" +M "useitem 1" +B "useitem 3" +N "useitem 4" +G "useitem 5" +F "useitem 6" +C "useitem 7" diff --git a/wadsrc/static/filter/shadowwarrior/engine/origbinds.txt b/wadsrc/static/filter/shadowwarrior/engine/origbinds.txt index 1eaf623ab..5d349cb28 100644 --- a/wadsrc/static/filter/shadowwarrior/engine/origbinds.txt +++ b/wadsrc/static/filter/shadowwarrior/engine/origbinds.txt @@ -1,7 +1,7 @@ -M "MedKit" -S "Smoke_Bomb" -N "Nightvision" -G "Gas_Bomb" -F "Flash_Bomb" -C "Caltrops" -Mouse2 "MedKit" +M "useitem 1" +S "useitem 3" +N "useitem 4" +G "useitem 5" +F "useitem 6" +C "useitem 7" +Mouse2 "useitem 1" diff --git a/wadsrc/static/filter/ww2gi/engine/defbinds.txt b/wadsrc/static/filter/ww2gi/engine/defbinds.txt index 5bcd053fb..2abe049a8 100644 --- a/wadsrc/static/filter/ww2gi/engine/defbinds.txt +++ b/wadsrc/static/filter/ww2gi/engine/defbinds.txt @@ -1,10 +1,10 @@ // -R "Steroids" +R "useitem 2" Q "+Quick_Kick" -H "HoloDuke" -J "Jetpack" -N "NightVision" -M "MedKit" +H "useitem 3" +J "useitem 4" +N "useitem 5" +M "useitem 1" C "+Toggle_Crouch" -Mouse2 "Jetpack" -Mouse3 "MediKit" +Mouse2 "useitem 4" +Mouse3 "useitem 1" diff --git a/wadsrc/static/filter/ww2gi/engine/leftbinds.txt b/wadsrc/static/filter/ww2gi/engine/leftbinds.txt index ce00aa0c8..d04297d13 100644 --- a/wadsrc/static/filter/ww2gi/engine/leftbinds.txt +++ b/wadsrc/static/filter/ww2gi/engine/leftbinds.txt @@ -1,7 +1,7 @@ -H "HoloDuke" -R "Steroids" +H "useitem 3" +R "useitem 2" Q "+Quick_Kick" -J "Jetpack" -N "NightVision" -M "MedKit" +J "useitem 4" +N "useitem 5" +M "useitem 1" W "+Show_Opponents_Weapon" diff --git a/wadsrc/static/filter/ww2gi/engine/origbinds.txt b/wadsrc/static/filter/ww2gi/engine/origbinds.txt index 52014371c..253985daa 100644 --- a/wadsrc/static/filter/ww2gi/engine/origbinds.txt +++ b/wadsrc/static/filter/ww2gi/engine/origbinds.txt @@ -1,13 +1,13 @@ // -R "Steroids" +R "useitem 2" ` "+Quick_Kick" W "+Show_Opponents_Weapon" -H "HoloDuke" -J "Jetpack" -N "NightVision" -M "MedKit" +H "useitem 3" +J "useitem 4" +N "useitem 5" +M "useitem 1" C "toggleconsole" -Mouse2 "Jetpack" -Mouse3 "MediKit" +Mouse2 "useitem 4" +Mouse3 "useitem 1" \ No newline at end of file From 447573aa36fd31e6d8fb65bc76b955394426a013 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 27 Aug 2020 22:19:24 +0200 Subject: [PATCH 10/43] - consolidation of invprev, invnext and invuse. --- source/blood/src/controls.cpp | 3 --- source/blood/src/player.cpp | 12 ++++----- source/core/inputstate.cpp | 38 +++++++++++++++++++++++----- source/core/packet.h | 20 +++++---------- source/exhumed/src/exhumed.cpp | 40 +++++++++++++++++++++++++++++ source/exhumed/src/input.cpp | 3 --- source/exhumed/src/status.cpp | 45 --------------------------------- source/exhumed/src/status.h | 2 -- source/games/duke/src/inlines.h | 5 ++++ source/games/duke/src/input.cpp | 20 +++++---------- source/sw/src/input.cpp | 6 +---- source/sw/src/inv.cpp | 27 +++++++++----------- source/sw/src/predict.cpp | 8 +++--- 13 files changed, 111 insertions(+), 118 deletions(-) diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 57b699121..0240efb89 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -349,10 +349,7 @@ void registerinputcommands() C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend.pause = 1; sendPause = true; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend.lookCenter = 1; return CCMD_OK; }); C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend.holsterWeapon = 1; return CCMD_OK; }); - C_RegisterFunction("invprev", nullptr, [](CCmdFuncPtr)->int { BitsToSend.prevItem = 1; return CCMD_OK; }); - C_RegisterFunction("invnext", nullptr, [](CCmdFuncPtr)->int { BitsToSend.nextItem = 1; return CCMD_OK; }); C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend.spin180 = 1; return CCMD_OK; }); - C_RegisterFunction("invuse", nullptr, [](CCmdFuncPtr)->int { BitsToSend.useItem = 1; return CCMD_OK; }); } // This is called from ImputState::ClearAllInput and resets all static state being used here. diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index b7c962f2c..e65348fc3 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -1635,19 +1635,19 @@ void ProcessInput(PLAYER *pPlayer) pPlayer->q16slopehoriz = 0; } pPlayer->slope = (-fix16_to_int(pPlayer->q16horiz))<<7; - if (pInput->syncFlags.prevItem) + if (pInput->actions & SB_INVPREV) { - pInput->syncFlags.prevItem = 0; + pInput->actions&= ~SB_INVPREV; packPrevItem(pPlayer); } - if (pInput->syncFlags.nextItem) + if (pInput->actions & SB_INVNEXT) { - pInput->syncFlags.nextItem = 0; + pInput->actions &= ~SB_INVNEXT; packNextItem(pPlayer); } - if (pInput->syncFlags.useItem) + if (pInput->actions & SB_INVUSE) { - pInput->syncFlags.useItem = 0; + pInput->actions &= ~SB_INVUSE; if (pPlayer->packSlots[pPlayer->packItemId].curAmount > 0) packUseItem(pPlayer, pPlayer->packItemId); } diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index 04465d81e..b92f9658e 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -43,6 +43,8 @@ static int WeaponToSend = 0; ESyncBits ActionsToSend = 0; +static int dpad_lock = 0; + //========================================================================== // // @@ -112,6 +114,9 @@ void InputState::ClearAllInput() { memset(KeyStatus, 0, sizeof(KeyStatus)); AnyKeyStatus = false; + ActionsToSend = 0; + WeaponToSend = 0; + dpad_lock = 0; buttonMap.ResetButtonStates(); // this is important. If all input is cleared, the buttons must be cleared as well. gi->clearlocalinputstate(); // also clear game local input state. } @@ -274,6 +279,20 @@ CCMD(useitem) } } +CCMD(invprev) +{ + ActionsToSend |= SB_INVPREV; +} + +CCMD(invnext) +{ + ActionsToSend |= SB_INVNEXT; +} + +CCMD(invuse) +{ + ActionsToSend |= SB_INVUSE; +} @@ -281,18 +300,25 @@ void ApplyGlobalInput(InputPacket& input, ControlInfo *info) { if (WeaponToSend != 0) input.setNewWeapon(WeaponToSend); WeaponToSend = 0; - if (info) - { - if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info->dz > 0) input.setNewWeapon(WeaponSel_Prev); - if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info->dz < 0) input.setNewWeapon(WeaponSel_Next); - } - if (buttonMap.ButtonDown(gamefunc_Dpad_Select)) + if (info && buttonMap.ButtonDown(gamefunc_Dpad_Select)) { + // These buttons should not autorepeat. The game handlers are not really equipped for that. + if (info->dz > 0 && !(dpad_lock & 1)) { dpad_lock |= 1; input.setNewWeapon(WeaponSel_Prev); } + else dpad_lock &= ~1; + if (info->dz < 0 && !(dpad_lock & 2)) { dpad_lock |= 2; input.setNewWeapon(WeaponSel_Next); } + else dpad_lock &= ~2; + if ((info->dx < 0 || info->dyaw < 0) && !(dpad_lock & 4)) { dpad_lock |= 4; input.actions |= SB_INVPREV; } + else dpad_lock &= ~4; + if ((info->dx > 0 || info->dyaw > 0) && !(dpad_lock & 8)) { dpad_lock |= 8; input.actions |= SB_INVNEXT; } + else dpad_lock &= ~8; + // This eats the controller input for regular use info->dx = 0; info->dz = 0; info->dyaw = 0; } + else dpad_lock = 0; + input.actions |= ActionsToSend; ActionsToSend = 0; diff --git a/source/core/packet.h b/source/core/packet.h index 668b2d96e..6018ae106 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -15,14 +15,16 @@ enum ESyncBits_ : uint32_t SB_ITEM_BIT_6 = 1 << 9, SB_ITEM_BIT_7 = 1 << 10, - // Exhumed has 6 items but doesn't use the network packet to activate them. Need to change + SB_INVPREV = 1 << 11, + SB_INVNEXT = 1 << 12, + SB_INVUSE = 1 << 13, SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits SB_ITEMUSE_BITS = (127u * SB_ITEM_BIT_1), SB_BUTTON_MASK = 0, // all input from buttons (i.e. active while held) - SB_INTERFACE_MASK = 0, // all input from CCMDs + SB_INTERFACE_MASK = (SB_INVPREV|SB_INVNEXT|SB_INVUSE), // all input from CCMDs SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS | SB_ITEMUSE_BITS | SB_INTERFACE_MASK) }; @@ -68,20 +70,17 @@ enum EDukeSyncBits_ : uint32_t SKB_MULTIFLAG = 1 << 17, SKB_CENTER_VIEW = 1 << 18, SKB_HOLSTER = 1 << 19, - SKB_INV_LEFT = 1 << 20, SKB_PAUSE = 1 << 21, SKB_QUICK_KICK = 1 << 22, SKB_AIMMODE = 1 << 23, SKB_GAMEQUIT = 1 << 26, - SKB_INV_RIGHT = 1 << 27, SKB_TURNAROUND = 1 << 28, SKB_OPEN = 1 << 29, - SKB_INVENTORY = 1 << 30, SKB_ESCAPE = 1u << 31, SKB_INTERFACE_BITS = (SKB_QUICK_KICK | \ - SKB_HOLSTER | SKB_INV_LEFT | SKB_PAUSE | SKB_INV_RIGHT | \ - SKB_TURNAROUND | SKB_OPEN | SKB_INVENTORY | SKB_ESCAPE), + SKB_HOLSTER | SKB_PAUSE | \ + SKB_TURNAROUND | SKB_OPEN | SKB_ESCAPE), SKB_NONE = 0, SKB_ALL = ~0u @@ -106,9 +105,6 @@ union SYNCFLAGS unsigned int lookDown : 1; unsigned int action : 1; unsigned int jab : 1; - unsigned int prevItem : 1; - unsigned int nextItem : 1; - unsigned int useItem : 1; unsigned int holsterWeapon : 1; unsigned int lookCenter : 1; unsigned int lookLeft : 1; @@ -148,10 +144,6 @@ union SYNCFLAGS #define SK_TURN_180 25 -#define SK_INV_LEFT 26 -#define SK_INV_RIGHT 27 - -#define SK_INV_USE 29 #define SK_HIDE_WEAPON 30 #define SK_SPACE_BAR 31 diff --git a/source/exhumed/src/exhumed.cpp b/source/exhumed/src/exhumed.cpp index 559912a10..099eca5cc 100644 --- a/source/exhumed/src/exhumed.cpp +++ b/source/exhumed/src/exhumed.cpp @@ -528,6 +528,46 @@ void GameTicker() weap2 = SelectAltWeapon(weap2); } + if (localInput.actions & SB_INVPREV) + { + int nItem = nPlayerItem[nLocalPlayer]; + + for (int i = 6; i > 0; i--) + { + nItem--; + if (nItem < 0) nItem = 5; + + if (PlayerList[nLocalPlayer].items[nItem] != 0) + break; + } + + if (i > 0) SetPlayerItem(nLocalPlayer, nItem); + } + + if (localInput.actions & SB_INVNEXT) + { + int nItem = nPlayerItem[nLocalPlayer]; + + for (int i = 6; i > 0; i--) + { + nItem++; + if (nItem == 6) nItem = 0; + + if (PlayerList[nLocalPlayer].items[nItem] != 0) + break; + } + + if (i > 0) SetPlayerItem(nLocalPlayer, nItem); + } + + if (localInput.actions & SB_INVUSE) + { + if (nPlayerItem[nLocalPlayer] != -1) + { + localInput.setItemUsed(nPlayerItem[nLocalPlayer]); + } + } + for (int i = 0; i < 6; i++) { if (localInput.isItemUsed(i)) diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index 22866714c..332b86585 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -386,9 +386,6 @@ void registerinputcommands() { C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { /*BitsToSend |= SKB_PAUSE;*/ sendPause = true; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, ccmd_centerview); - C_RegisterFunction("invprev", nullptr, [](CCmdFuncPtr)->int { if (PlayerList[nLocalPlayer].nHealth > 0) SetPrevItem(nLocalPlayer); return CCMD_OK; }); - C_RegisterFunction("invnext", nullptr, [](CCmdFuncPtr)->int { if (PlayerList[nLocalPlayer].nHealth > 0) SetNextItem(nLocalPlayer); return CCMD_OK; }); - //C_RegisterFunction("invuse", nullptr, [](CCmdFuncPtr)->int { if (PlayerList[nLocalPlayer].nHealth > 0) UseCurItem(nLocalPlayer); return CCMD_OK; }); // These are only here to silence the engine when the keys bound to them are pressed. The functions do not exist. C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { return CCMD_OK; }); diff --git a/source/exhumed/src/status.cpp b/source/exhumed/src/status.cpp index 1886a4237..94cda6d60 100644 --- a/source/exhumed/src/status.cpp +++ b/source/exhumed/src/status.cpp @@ -384,51 +384,6 @@ void SetPlayerItem(short nPlayer, short nItem) } } -void SetNextItem(int nPlayer) -{ - short nItem = nPlayerItem[nPlayer]; - - int i; - - for (i = 6; i > 0; i--) - { - nItem++; - if (nItem == 6) - nItem = 0; - - if (PlayerList[nPlayer].items[nItem] != 0) - break; - } - - if (i > 0) { - SetPlayerItem(nPlayer, nItem); - } -} - -void SetPrevItem(int nPlayer) -{ - if (nPlayerItem[nPlayer] == -1) - return; - - int nItem = nPlayerItem[nPlayer]; - - int i; - - for (i = 6; i > 0; i--) - { - nItem--; - if (nItem < 0) - nItem = 5; - - if (PlayerList[nPlayer].items[nItem] != 0) - break; - } - - if (i > 0) { - SetPlayerItem(nPlayer, nItem); - } -} - void MoveStatus() { if (nItemSeq >= 0) diff --git a/source/exhumed/src/status.h b/source/exhumed/src/status.h index 06fe1385a..3f5c92c3f 100644 --- a/source/exhumed/src/status.h +++ b/source/exhumed/src/status.h @@ -36,8 +36,6 @@ void MoveStatus(); void DrawSnakeCamStatus(); void DrawStatus(); int BuildStatusAnim(int val, int nFlags); -void SetNextItem(int nPlayer); -void SetPrevItem(int nPlayer); void SetCounter(short nVal); void SetCounterImmediate(short nVal); diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index 710b4abe9..93b4d0f14 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -136,6 +136,11 @@ inline EDukeSyncBits PlayerInputBits(int pl, EDukeSyncBits bits) return (sync[pl].sbits & bits); } +inline bool PlayerInput(int pl, ESyncBits bit) +{ + return (!!((sync[pl].actions) & bit)); +} + inline ESyncBits PlayerInputBits(int pl, ESyncBits bits) { return (sync[pl].actions & bits); diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 6b1592630..9e46ea6cf 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -204,7 +204,7 @@ void hud_input(int snum) if (sprite[p->i].extra <= 0) return; // Activate an inventory item. This just forwards to the other inventory bits. If the inventory selector was taken out of the playsim this could be removed. - if (PlayerInput(snum, SKB_INVENTORY) && p->newowner == -1) + if (PlayerInput(snum, SB_INVUSE) && p->newowner == -1) { SetGameVarID(g_iReturnVarID, 0, -1, snum); OnEvent(EVENT_INVENTORY, -1, snum, -1); @@ -245,11 +245,11 @@ void hud_input(int snum) return; } - if (PlayerInput(snum, SKB_INV_LEFT) || PlayerInput(snum, SKB_INV_RIGHT)) + if (PlayerInput(snum, SB_INVPREV) || PlayerInput(snum, SB_INVNEXT)) { p->invdisptime = 26 * 2; - if (PlayerInput(snum, SKB_INV_RIGHT)) k = 1; + if (PlayerInput(snum, SB_INVNEXT)) k = 1; else k = 0; dainv = p->inven_icon; @@ -311,13 +311,13 @@ void hud_input(int snum) else dainv = 0; // These events force us to keep the inventory selector in the playsim as opposed to the UI where it really belongs. - if (PlayerInput(snum, SKB_INV_LEFT)) + if (PlayerInput(snum, SB_INVPREV)) { SetGameVarID(g_iReturnVarID, dainv, -1, snum); OnEvent(EVENT_INVENTORYLEFT, -1, snum, -1); dainv = GetGameVarID(g_iReturnVarID, -1, snum); } - if (PlayerInput(snum, SKB_INV_RIGHT)) + if (PlayerInput(snum, SB_INVNEXT)) { SetGameVarID(g_iReturnVarID, dainv, -1, snum); OnEvent(EVENT_INVENTORYRIGHT, -1, snum, -1); @@ -617,12 +617,6 @@ static void processInputBits(player_struct *p, ControlInfo &info) loc.sbits |= BitsToSend; BitsToSend = 0; - if (buttonMap.ButtonDown(gamefunc_Dpad_Select)) // todo: This must go to global code. - { - if (info.dx < 0 || info.dyaw < 0) loc.sbits |= SKB_INV_LEFT; - if (info.dx > 0 || info.dyaw < 0) loc.sbits |= SKB_INV_RIGHT; - } - if (gamequit) loc.sbits |= SKB_GAMEQUIT; if (!onVehicle) @@ -1163,10 +1157,8 @@ void registerinputcommands() C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_PAUSE; sendPause = true; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_CENTER_VIEW; return CCMD_OK; }); C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_HOLSTER; return CCMD_OK; }); - C_RegisterFunction("invprev", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_INV_LEFT; return CCMD_OK; }); - C_RegisterFunction("invnext", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_INV_RIGHT; return CCMD_OK; }); + C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_TURNAROUND; return CCMD_OK; }); - C_RegisterFunction("invuse", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_INVENTORY; return CCMD_OK; }); C_RegisterFunction("backoff", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_ESCAPE; return CCMD_OK; }); } diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index 579b22b12..f3ec56ed2 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -37,7 +37,6 @@ BEGIN_SW_NS SWBOOL MultiPlayQuitFlag = FALSE; int BitsToSend = 0; -int inv_hotkey = 0; void @@ -473,17 +472,14 @@ void registerinputcommands() C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_PAUSE); sendPause = true; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_CENTER_VIEW); return CCMD_OK; }); C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_HIDE_WEAPON); return CCMD_OK; }); - C_RegisterFunction("invprev", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_INV_LEFT); return CCMD_OK; }); - C_RegisterFunction("invnext", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_INV_RIGHT); return CCMD_OK; }); + C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_TURN_180); return CCMD_OK; }); - C_RegisterFunction("invuse", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_INV_USE); return CCMD_OK; }); } // This is called from ImputState::ClearAllInput and resets all static state being used here. void GameInterface::clearlocalinputstate() { BitsToSend = 0; - inv_hotkey = 0; } diff --git a/source/sw/src/inv.cpp b/source/sw/src/inv.cpp index d4b07c58b..cf83b02bd 100644 --- a/source/sw/src/inv.cpp +++ b/source/sw/src/inv.cpp @@ -412,14 +412,12 @@ StopInventoryNightVision(PLAYERp pp, short InventoryNum) void InventoryKeys(PLAYERp pp) { - short inv_hotkey; - // scroll SPELLs left - if (TEST_SYNC_KEY(pp, SK_INV_LEFT)) + if (pp->input.actions & SB_INVPREV) { - if (FLAG_KEY_PRESSED(pp, SK_INV_LEFT)) + if (pp->KeyPressBits & SB_INVPREV) { - FLAG_KEY_RELEASE(pp, SK_INV_LEFT); + pp->KeyPressBits &= ~SB_INVPREV; pp->InventoryBarTics = SEC(2); PlayerUpdateInventory(pp, pp->InventoryNum - 1); PutStringInfo(pp, InventoryData[pp->InventoryNum].Name); @@ -427,15 +425,15 @@ void InventoryKeys(PLAYERp pp) } else { - FLAG_KEY_RESET(pp, SK_INV_LEFT); + pp->KeyPressBits |= SB_INVPREV; } // scroll SPELLs right - if (TEST_SYNC_KEY(pp, SK_INV_RIGHT)) + if (pp->input.actions & SB_INVNEXT) { - if (FLAG_KEY_PRESSED(pp, SK_INV_RIGHT)) + if (pp->KeyPressBits & SB_INVNEXT) { - FLAG_KEY_RELEASE(pp, SK_INV_RIGHT); + pp->KeyPressBits &= ~SB_INVNEXT; pp->InventoryBarTics = SEC(2); PlayerUpdateInventory(pp, pp->InventoryNum + 1); PutStringInfo(pp, InventoryData[pp->InventoryNum].Name); @@ -443,15 +441,14 @@ void InventoryKeys(PLAYERp pp) } else { - FLAG_KEY_RESET(pp, SK_INV_RIGHT); + pp->KeyPressBits |= SB_INVNEXT; } - if (TEST_SYNC_KEY(pp, SK_INV_USE)) + if (pp->input.actions & SB_INVUSE) { - if (FLAG_KEY_PRESSED(pp, SK_INV_USE)) + if (pp->KeyPressBits & SB_INVUSE) { - FLAG_KEY_RELEASE(pp, SK_INV_USE); - + pp->KeyPressBits &= ~SB_INVUSE; if (InventoryData[pp->InventoryNum].Init) { if (pp->InventoryAmount[pp->InventoryNum]) @@ -468,7 +465,7 @@ void InventoryKeys(PLAYERp pp) } else { - FLAG_KEY_RESET(pp, SK_INV_USE); + pp->KeyPressBits |= SB_INVUSE; } // test all 7 items diff --git a/source/sw/src/predict.cpp b/source/sw/src/predict.cpp index 6aaaa24ac..a98af3b8d 100644 --- a/source/sw/src/predict.cpp +++ b/source/sw/src/predict.cpp @@ -84,17 +84,15 @@ DoPrediction(PLAYERp ppp) // get rid of input bits so it doesn't go into other code branches that would // get it out of sync ppp->input.actions &= ~(SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS); - ppp->KeyPressBits |= (SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS); + ppp->KeyPressBits |= (SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS|SB_INVNEXT|SB_INVPREV|SB_INVUSE); RESET(ppp->input.bits, - BIT(SK_SHOOT)|BIT(SK_OPERATE)|BIT(SK_INV_LEFT)|BIT(SK_INV_RIGHT)| - BIT(SK_INV_USE)|BIT(SK_HIDE_WEAPON)| + BIT(SK_SHOOT)|BIT(SK_OPERATE)|BIT(SK_HIDE_WEAPON)| BIT(SK_AUTO_AIM)| BIT(SK_CENTER_VIEW) ); SET(ppp->KeyPressFlags, - BIT(SK_SHOOT)|BIT(SK_OPERATE)|BIT(SK_INV_LEFT)|BIT(SK_INV_RIGHT)| - BIT(SK_INV_USE)|BIT(SK_HIDE_WEAPON)| + BIT(SK_SHOOT)|BIT(SK_OPERATE)|BIT(SK_HIDE_WEAPON)| BIT(SK_AUTO_AIM)| BIT(SK_CENTER_VIEW) ); From e0ca98602dc7398c619bd8749f00967172a77ef7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 27 Aug 2020 22:29:45 +0200 Subject: [PATCH 11/43] - made Blood's inventory cycle-able. IMO it's a totally annoying limitations to block wraparound of the cursor. --- source/blood/src/player.cpp | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index e65348fc3..7600c4ab0 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -545,29 +545,42 @@ void packPrevItem(PLAYER *pPlayer) { if (pPlayer->packItemTime > 0) { - for (int nPrev = ClipLow(pPlayer->packItemId-1,0); nPrev >= 0; nPrev--) + for (int i = 0; i < 2; i++) { - if (pPlayer->packSlots[nPrev].curAmount) + for (int nPrev = pPlayer->packItemId-1; nPrev >= 0; nPrev--) { - pPlayer->packItemId = nPrev; - break; + if (pPlayer->packSlots[nPrev].curAmount) + { + pPlayer->packItemId = nPrev; + pPlayer->packItemTime = 600; + return; + } } + pPlayer->packItemId = 4; + if (pPlayer->packSlots[4].curAmount) break; } } + pPlayer->packItemTime = 600; } -void packNextItem(PLAYER *pPlayer) +void packNextItem(PLAYER* pPlayer) { if (pPlayer->packItemTime > 0) { - for (int nNext = ClipHigh(pPlayer->packItemId+1,5); nNext < 5; nNext++) + for (int i = 0; i < 2; i++) { - if (pPlayer->packSlots[nNext].curAmount) + for (int nNext = pPlayer->packItemId + 1; nNext < 5; nNext++) { - pPlayer->packItemId = nNext; - break; + if (pPlayer->packSlots[nNext].curAmount) + { + pPlayer->packItemId = nNext; + pPlayer->packItemTime = 600; + return; + } } + pPlayer->packItemId = 0; + if (pPlayer->packSlots[0].curAmount) break; } } pPlayer->packItemTime = 600; From ee7d55828237048916267da71a6a14bfadad335d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 27 Aug 2020 22:38:52 +0200 Subject: [PATCH 12/43] - removed the remains of sending pause with the input packets. None of this was really working anymore, but will have to be rethought once a network stream exists again. But even then, this is better sent as a separate command, and in MP only. --- source/blood/src/blood.cpp | 9 --------- source/blood/src/controls.cpp | 6 ------ source/core/gamecontrol.cpp | 2 +- source/core/inputstate.cpp | 6 ++++++ source/core/packet.h | 5 +---- source/exhumed/src/input.cpp | 1 - source/games/duke/src/input.cpp | 1 - source/sw/src/input.cpp | 1 - 8 files changed, 8 insertions(+), 23 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 44c2fe282..249545a3d 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -560,15 +560,6 @@ void ProcessFrame(void) levelRestart(); return; } - if (gPlayer[i].input.syncFlags.pause) - { - gPlayer[i].input.syncFlags.pause = 0; - if (paused && gGameOptions.nGameType > 0 && numplayers > 1) - { - sprintf(buffer,"%s paused the game",gProfile[i].name); - viewSetMessage(buffer); - } - } } viewClearInterpolations(); { diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 0240efb89..51e71e09d 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -125,11 +125,6 @@ void ctrlGetInput(void) return; } - if (paused != prevPauseState) - { - gInput.syncFlags.pause = 1; - } - if (paused) return; @@ -346,7 +341,6 @@ void ctrlGetInput(void) void registerinputcommands() { - C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend.pause = 1; sendPause = true; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend.lookCenter = 1; return CCMD_OK; }); C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend.holsterWeapon = 1; return CCMD_OK; }); C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend.spin180 = 1; return CCMD_OK; }); diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 07fafdd0e..12ab64eeb 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -100,7 +100,6 @@ auto vsnprintfptr = vsnprintf; // This is an inline in Visual Studio but we need int gameclock; int lastTic; -bool sendPause; int automapMode; bool automapFollow; @@ -908,6 +907,7 @@ void TickSubsystems() static void updatePauseStatus() { + // This must go through the network in multiplayer games. if (M_Active() || System_WantGuiCapture()) { paused = 1; diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index b92f9658e..db2f46148 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -44,6 +44,7 @@ static int WeaponToSend = 0; ESyncBits ActionsToSend = 0; static int dpad_lock = 0; +bool sendPause; //========================================================================== // @@ -294,6 +295,11 @@ CCMD(invuse) ActionsToSend |= SB_INVUSE; } +CCMD(pause) +{ + sendPause = true; +} + void ApplyGlobalInput(InputPacket& input, ControlInfo *info) diff --git a/source/core/packet.h b/source/core/packet.h index 6018ae106..e856e962a 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -70,7 +70,6 @@ enum EDukeSyncBits_ : uint32_t SKB_MULTIFLAG = 1 << 17, SKB_CENTER_VIEW = 1 << 18, SKB_HOLSTER = 1 << 19, - SKB_PAUSE = 1 << 21, SKB_QUICK_KICK = 1 << 22, SKB_AIMMODE = 1 << 23, SKB_GAMEQUIT = 1 << 26, @@ -79,7 +78,7 @@ enum EDukeSyncBits_ : uint32_t SKB_ESCAPE = 1u << 31, SKB_INTERFACE_BITS = (SKB_QUICK_KICK | \ - SKB_HOLSTER | SKB_PAUSE | \ + SKB_HOLSTER | \ SKB_TURNAROUND | SKB_OPEN | SKB_ESCAPE), SKB_NONE = 0, @@ -110,7 +109,6 @@ union SYNCFLAGS unsigned int lookLeft : 1; unsigned int lookRight : 1; unsigned int spin180 : 1; - unsigned int pause : 1; unsigned int quit : 1; unsigned int restart : 1; }; @@ -125,7 +123,6 @@ union SYNCFLAGS #define SK_AUTO_AIM 7 #define SK_CENTER_VIEW 8 -#define SK_PAUSE 9 #define SK_MESSAGE 11 #define SK_LOOK_UP 12 diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index 332b86585..4b748f42f 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -384,7 +384,6 @@ int ccmd_centerview(CCmdFuncPtr parm); void registerinputcommands() { - C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { /*BitsToSend |= SKB_PAUSE;*/ sendPause = true; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, ccmd_centerview); // These are only here to silence the engine when the keys bound to them are pressed. The functions do not exist. diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 9e46ea6cf..7e27e95ac 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -1154,7 +1154,6 @@ void GetInput() void registerinputcommands() { - C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_PAUSE; sendPause = true; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_CENTER_VIEW; return CCMD_OK; }); C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_HOLSTER; return CCMD_OK; }); diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index f3ec56ed2..49bbdaa18 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -469,7 +469,6 @@ getinput(InputPacket *loc, SWBOOL tied) void registerinputcommands() { - C_RegisterFunction("pause", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_PAUSE); sendPause = true; return CCMD_OK; }); C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_CENTER_VIEW); return CCMD_OK; }); C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_HIDE_WEAPON); return CCMD_OK; }); From d62d2eaec7dbfe12b99c61019398c0a9b043e32b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 28 Aug 2020 00:03:35 +0200 Subject: [PATCH 13/43] - processed all remaining local input CCMDs and removed some bits only needed for multiplayer. These MP bits should be reimplemented as network commands later, they only take up valuable space in the bit field. --- source/blood/src/blood.cpp | 8 ++++--- source/blood/src/blood.h | 1 - source/blood/src/controls.cpp | 35 ++------------------------- source/blood/src/d_menu.cpp | 3 +-- source/blood/src/misc.h | 1 - source/core/inputstate.cpp | 38 +++++++++++++++++++++++++++++- source/core/inputstate.h | 14 +++++------ source/core/packet.h | 30 +++++++---------------- source/exhumed/src/exhumed.cpp | 16 ++++++++++--- source/exhumed/src/exhumed.h | 1 - source/exhumed/src/input.cpp | 31 +----------------------- source/exhumed/src/player.cpp | 11 --------- source/games/duke/src/game.cpp | 2 -- source/games/duke/src/gameloop.cpp | 2 ++ source/games/duke/src/global.cpp | 1 - source/games/duke/src/global.h | 1 - source/games/duke/src/inlines.h | 6 +++++ source/games/duke/src/input.cpp | 38 +++++++----------------------- source/games/duke/src/player_d.cpp | 21 +++++++---------- source/games/duke/src/player_r.cpp | 11 ++++----- source/sw/src/game.cpp | 1 - source/sw/src/game.h | 2 -- source/sw/src/input.cpp | 34 -------------------------- source/sw/src/panel.cpp | 16 ++++++------- source/sw/src/player.cpp | 10 ++++---- source/sw/src/predict.cpp | 14 +++++------ 26 files changed, 123 insertions(+), 225 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 249545a3d..aec358c6b 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -74,6 +74,7 @@ char gUserMapFilename[BMAX_PATH]; short BloodVersion = 0x115; int gNetPlayers; +int gQuitRequest; int gChokeCounter = 0; @@ -81,7 +82,6 @@ double g_gameUpdateTime, g_gameUpdateAndDrawTime; double g_gameUpdateAvgTime = 0.001; bool gQuitGame; -int gQuitRequest; enum gametokens { @@ -522,7 +522,6 @@ bool gRestartGame = false; void ProcessFrame(void) { - char buffer[128]; for (int i = connecthead; i >= 0; i = connectpoint2[i]) { auto& inp = gPlayer[i].input; @@ -538,6 +537,7 @@ void ProcessFrame(void) } gNetFifoTail++; +#if 0 for (int i = connecthead; i >= 0; i = connectpoint2[i]) { if (gPlayer[i].input.syncFlags.quit) @@ -561,6 +561,7 @@ void ProcessFrame(void) return; } } +#endif viewClearInterpolations(); { if (paused || gEndGameMgr.at0 || (gGameOptions.nGameType == 0 && M_Active())) @@ -703,7 +704,6 @@ void GameInterface::app_init() Printf(PRINT_NONOTIFY, "Initializing sound system\n"); sndInit(); registerosdcommands(); - registerinputcommands(); gChoke.sub_83ff0(518, sub_84230); UpdateDacs(0, true); @@ -792,8 +792,10 @@ static void drawBackground() { twod->ClearScreen(); DrawTexture(twod, tileGetTexture(2518, true), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, TAG_DONE); +#if 0 if (gQuitRequest && !gQuitGame) netBroadcastMyLogoff(gQuitRequest == 2); +#endif } static void commonTicker() diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index 71b77fc59..10fecd4a6 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -87,7 +87,6 @@ struct GameInterface : ::GameInterface void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg) override; void QuitToTitle() override; FString GetCoordString() override; - void clearlocalinputstate() override; ReservedSpace GetReservedScreenSpace(int viewsize) override; GameStats getStats() override; diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 51e71e09d..253fa90cc 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -44,8 +44,6 @@ InputPacket gInput, gNetInput; bool bSilentAim = false; int iTurnCount = 0; -static int WeaponToSend; -static SYNCFLAGS BitsToSend; void ctrlInit(void) { @@ -131,7 +129,7 @@ void ctrlGetInput(void) InputPacket input = {}; bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - if (!mouseaim) gInput.syncFlags.lookCenter = 1; + if (!mouseaim) gInput.actions |= SB_CENTERVIEW; if (numplayers == 1) { @@ -141,15 +139,8 @@ void ctrlGetInput(void) CONTROL_GetInput(&info); - if (gQuitRequest) - gInput.syncFlags.quit = 1; - - gInput.syncFlags.value |= BitsToSend.value; ApplyGlobalInput(gInput, &info); - BitsToSend.value = 0; - WeaponToSend = 0; - if (buttonMap.ButtonDown(gamefunc_Shrink_Screen)) { if (automapMode != am_off) @@ -200,7 +191,7 @@ void ctrlGetInput(void) gInput.syncFlags.lookDown |= buttonMap.ButtonDown(gamefunc_Look_Down); if (buttonMap.ButtonDown(gamefunc_Look_Up) || buttonMap.ButtonDown(gamefunc_Look_Down)) - gInput.syncFlags.lookCenter = 1; + gInput.actions |= SB_CENTERVIEW; else { gInput.syncFlags.lookUp |= buttonMap.ButtonDown(gamefunc_Aim_Up); @@ -332,26 +323,4 @@ void ctrlGetInput(void) } } -//--------------------------------------------------------------------------- -// -// CCMD based input. The basics are from Randi's ZDuke but this uses dynamic -// registration to only have the commands active when this game module runs. -// -//--------------------------------------------------------------------------- - -void registerinputcommands() -{ - C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend.lookCenter = 1; return CCMD_OK; }); - C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend.holsterWeapon = 1; return CCMD_OK; }); - C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend.spin180 = 1; return CCMD_OK; }); -} - -// This is called from ImputState::ClearAllInput and resets all static state being used here. -void GameInterface::clearlocalinputstate() -{ - WeaponToSend = 0; - BitsToSend.value = 0; -} - - END_BLD_NS diff --git a/source/blood/src/d_menu.cpp b/source/blood/src/d_menu.cpp index 00c78acd9..6a6182dc3 100644 --- a/source/blood/src/d_menu.cpp +++ b/source/blood/src/d_menu.cpp @@ -295,8 +295,7 @@ void GameInterface::QuitToTitle() gQuitGame = true; gRestartGame = true; } - else - gQuitRequest = 2; + //else gQuitRequest = 2; } END_BLD_NS diff --git a/source/blood/src/misc.h b/source/blood/src/misc.h index 1afdcbf49..e6d5762a7 100644 --- a/source/blood/src/misc.h +++ b/source/blood/src/misc.h @@ -42,7 +42,6 @@ void sub_5571C(char mode); void sub_557C4(int x, int y, int interpolation); void DrawMirrors(int x, int y, int z, fix16_t a, fix16_t horiz, int smooth, int viewPlayer); int32_t registerosdcommands(void); -void registerinputcommands(void); int qanimateoffs(int a1, int a2); int32_t qgetpalookup(int32_t a1, int32_t a2); void HookReplaceFunctions(); diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index db2f46148..0529da3dc 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -295,6 +295,21 @@ CCMD(invuse) ActionsToSend |= SB_INVUSE; } +CCMD(centerview) +{ + ActionsToSend |= SB_CENTERVIEW; +} + +CCMD(turnaround) +{ + ActionsToSend |= SB_TURNAROUND; +} + +CCMD(holsterweapon) +{ + ActionsToSend |= SB_HOLSTER; +} + CCMD(pause) { sendPause = true; @@ -328,4 +343,25 @@ void ApplyGlobalInput(InputPacket& input, ControlInfo *info) input.actions |= ActionsToSend; ActionsToSend = 0; -} \ No newline at end of file +} + +#if 0 +void registerinputcommands() +{ + C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend.lookCenter = 1; return CCMD_OK; }); + C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend.holsterWeapon = 1; return CCMD_OK; }); + C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend.spin180 = 1; return CCMD_OK; }); +} + +//--------------------------------------------------------------------------- +// +// CCMD based input. The basics are from Randi's ZDuke but this uses dynamic +// registration to only have the commands active when this game module runs. +// +//--------------------------------------------------------------------------- + + C_RegisterFunction("backoff", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_ESCAPE; return CCMD_OK; }); +} + + +#endif diff --git a/source/core/inputstate.h b/source/core/inputstate.h index 1c28311d8..d33614389 100644 --- a/source/core/inputstate.h +++ b/source/core/inputstate.h @@ -66,11 +66,11 @@ int32_t handleevents(void); enum GameFunction_t { - gamefunc_Move_Forward, - gamefunc_Move_Backward, - gamefunc_Turn_Left, - gamefunc_Turn_Right, - gamefunc_Strafe, + gamefunc_Move_Forward, // + gamefunc_Move_Backward, // + gamefunc_Turn_Left, // + gamefunc_Turn_Right, // + gamefunc_Strafe, // gamefunc_Fire, gamefunc_Open, gamefunc_Run, @@ -81,8 +81,8 @@ enum GameFunction_t gamefunc_Look_Down, gamefunc_Look_Left, gamefunc_Look_Right, - gamefunc_Strafe_Left, - gamefunc_Strafe_Right, + gamefunc_Strafe_Left, // + gamefunc_Strafe_Right, // gamefunc_Aim_Up, gamefunc_Aim_Down, gamefunc_Shrink_Screen, // Automap only diff --git a/source/core/packet.h b/source/core/packet.h index e856e962a..53d9de8ba 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -18,14 +18,17 @@ enum ESyncBits_ : uint32_t SB_INVPREV = 1 << 11, SB_INVNEXT = 1 << 12, SB_INVUSE = 1 << 13, - + SB_CENTERVIEW = 1 << 14, + SB_TURNAROUND = 1 << 15, + SB_HOLSTER = 1 << 16, SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits SB_ITEMUSE_BITS = (127u * SB_ITEM_BIT_1), SB_BUTTON_MASK = 0, // all input from buttons (i.e. active while held) - SB_INTERFACE_MASK = (SB_INVPREV|SB_INVNEXT|SB_INVUSE), // all input from CCMDs - SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS | SB_ITEMUSE_BITS | SB_INTERFACE_MASK) + SB_INTERFACE_MASK = (SB_INVPREV|SB_INVNEXT|SB_INVUSE|SB_CENTERVIEW|SB_TURNAROUND|SB_HOLSTER), // all input from CCMDs + SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS | SB_ITEMUSE_BITS | SB_INTERFACE_MASK), + SB_ALL = ~0u }; // enforce type safe operations on the input bits. @@ -67,19 +70,13 @@ enum EDukeSyncBits_ : uint32_t SKB_LOOK_RIGHT = 1 << 7, SKB_LOOK_UP = 1 << 13, SKB_LOOK_DOWN = 1 << 14, - SKB_MULTIFLAG = 1 << 17, - SKB_CENTER_VIEW = 1 << 18, - SKB_HOLSTER = 1 << 19, SKB_QUICK_KICK = 1 << 22, SKB_AIMMODE = 1 << 23, - SKB_GAMEQUIT = 1 << 26, - SKB_TURNAROUND = 1 << 28, SKB_OPEN = 1 << 29, SKB_ESCAPE = 1u << 31, SKB_INTERFACE_BITS = (SKB_QUICK_KICK | \ - SKB_HOLSTER | \ - SKB_TURNAROUND | SKB_OPEN | SKB_ESCAPE), + SKB_OPEN | SKB_ESCAPE), SKB_NONE = 0, SKB_ALL = ~0u @@ -102,15 +99,12 @@ union SYNCFLAGS unsigned int shoot2 : 1; unsigned int lookUp : 1; unsigned int lookDown : 1; + + unsigned int action : 1; unsigned int jab : 1; - unsigned int holsterWeapon : 1; - unsigned int lookCenter : 1; unsigned int lookLeft : 1; unsigned int lookRight : 1; - unsigned int spin180 : 1; - unsigned int quit : 1; - unsigned int restart : 1; }; }; @@ -122,9 +116,7 @@ union SYNCFLAGS #define SK_AUTO_AIM 7 -#define SK_CENTER_VIEW 8 -#define SK_MESSAGE 11 #define SK_LOOK_UP 12 #define SK_LOOK_DOWN 13 #define SK_CRAWL_LOCK 14 @@ -137,11 +129,7 @@ union SYNCFLAGS #define SK_CRAWL 20 #define SK_SNAP_UP 21 #define SK_SNAP_DOWN 22 -#define SK_QUIT_GAME 23 -#define SK_TURN_180 25 - -#define SK_HIDE_WEAPON 30 #define SK_SPACE_BAR 31 diff --git a/source/exhumed/src/exhumed.cpp b/source/exhumed/src/exhumed.cpp index 099eca5cc..8221d88af 100644 --- a/source/exhumed/src/exhumed.cpp +++ b/source/exhumed/src/exhumed.cpp @@ -51,6 +51,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS +extern short bPlayerPan; +extern short bLockPan; extern const char* s_buildRev; extern const char* s_buildTimestamp; @@ -58,7 +60,6 @@ BEGIN_PS_NS void uploadCinemaPalettes(); int32_t registerosdcommands(void); -void registerinputcommands(); void InitFonts(); int htimer = 0; @@ -584,7 +585,17 @@ void GameTicker() } } - + if (localInput.actions & SB_CENTERVIEW) + { + bLockPan = false; + bPlayerPan = false; + PlayerList[nLocalPlayer].q16horiz = fix16_from_int(92); + nDestVertPan[nLocalPlayer] = fix16_from_int(92); + } + if (localInput.actions & SB_TURNAROUND) + { + // todo + } sPlayerInput[nLocalPlayer].xVel = lPlayerXVel; @@ -687,7 +698,6 @@ void GameInterface::app_init() SetCheats(excheats, countof(excheats)); registerosdcommands(); - registerinputcommands(); if (nNetPlayerCount == -1) { nNetPlayerCount = nCfgNetPlayers - 1; diff --git a/source/exhumed/src/exhumed.h b/source/exhumed/src/exhumed.h index a68d9b27a..8848d506c 100644 --- a/source/exhumed/src/exhumed.h +++ b/source/exhumed/src/exhumed.h @@ -252,7 +252,6 @@ struct GameInterface : ::GameInterface bool SaveGame(FSaveGameNode* sv) override; bool CanSave() override; ReservedSpace GetReservedScreenSpace(int viewsize) override { return { 0, 24 }; } - void clearlocalinputstate() override; void QuitToTitle(); FString statFPS() override; diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index 4b748f42f..55e923bbf 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -31,7 +31,6 @@ BEGIN_PS_NS extern short bPlayerPan; extern short bLockPan; -int BitsToSend; bool g_MyAimMode; short nInputStack = 0; @@ -371,32 +370,4 @@ void PlayerInterruptKeys(bool after) } - -//--------------------------------------------------------------------------- -// -// CCMD based input. The basics are from Randi's ZDuke but this uses dynamic -// registration to only have the commands active when this game module runs. -// -//--------------------------------------------------------------------------- - -int ccmd_centerview(CCmdFuncPtr parm); - - -void registerinputcommands() -{ - C_RegisterFunction("centerview", nullptr, ccmd_centerview); - - // These are only here to silence the engine when the keys bound to them are pressed. The functions do not exist. - C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { return CCMD_OK; }); - C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { return CCMD_OK; }); - -} - -// This is called from ImputState::ClearAllInput and resets all static state being used here. -void GameInterface::clearlocalinputstate() -{ - BitsToSend = 0; - -} - - END_PS_NS +END_PS_NS diff --git a/source/exhumed/src/player.cpp b/source/exhumed/src/player.cpp index 5b8fecc45..1d8eb9725 100644 --- a/source/exhumed/src/player.cpp +++ b/source/exhumed/src/player.cpp @@ -2870,17 +2870,6 @@ loc_1BD2E: } } -int ccmd_centerview(CCmdFuncPtr parm) -{ - return CCMD_OK; - bLockPan = false; - bPlayerPan = false; - PlayerList[nLocalPlayer].q16horiz = fix16_from_int(92); - nDestVertPan[nLocalPlayer] = fix16_from_int(92); - return CCMD_OK; -} - - static SavegameHelper sgh("player", SV(lPlayerXVel), SV(lPlayerYVel), diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index caa264c8f..0bd44c3f2 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -47,7 +47,6 @@ BEGIN_DUKE_NS void SetDispatcher(); void InitCheats(); int registerosdcommands(void); -void registerinputcommands(void); //--------------------------------------------------------------------------- // @@ -331,7 +330,6 @@ static void Startup(void) InitCheats(); checkcommandline(); registerosdcommands(); - registerinputcommands(); screenpeek = myconnectindex; ps[myconnectindex].palette = BASEPAL; diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index c0ec5f9bc..6f46fce67 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -197,6 +197,7 @@ int domovethings() GetNextInput(); updateinterpolations(); +#if 0 j = -1; for (i = connecthead; i >= 0; i = connectpoint2[i]) { @@ -227,6 +228,7 @@ int domovethings() } else j = i; } +#endif //if(ud.recstat == 1) record(); diff --git a/source/games/duke/src/global.cpp b/source/games/duke/src/global.cpp index cbe177461..831fcfb9d 100644 --- a/source/games/duke/src/global.cpp +++ b/source/games/duke/src/global.cpp @@ -65,7 +65,6 @@ int PHEIGHT = PHEIGHT_DUKE; int duke3d_globalflags; InputPacket loc; uint8_t ready2send; -int gamequit; int playerswhenstarted; int show_shareware; int screenpeek; diff --git a/source/games/duke/src/global.h b/source/games/duke/src/global.h index b9ac45b74..19493020b 100644 --- a/source/games/duke/src/global.h +++ b/source/games/duke/src/global.h @@ -52,7 +52,6 @@ extern int32_t PHEIGHT; extern int duke3d_globalflags; extern uint8_t ready2send; extern InputPacket loc; -extern int gamequit; extern int playerswhenstarted; extern int show_shareware; extern int screenpeek; diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index 93b4d0f14..ec03613aa 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -146,6 +146,12 @@ inline ESyncBits PlayerInputBits(int pl, ESyncBits bits) return (sync[pl].actions & bits); } +inline void PlayerSetInput(int pl, ESyncBits bit) +{ + sync[pl].actions |= bit; +} + + inline int PlayerNewWeapon(int pl) { return sync[pl].getNewWeapon(); diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 7e27e95ac..b59cddc1f 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -39,8 +39,6 @@ source as it is released. BEGIN_DUKE_NS -static EDukeSyncBits BitsToSend; - // State timer counters. static int nonsharedtimer; static int turnheldtime; @@ -336,7 +334,7 @@ void hud_input(int snum) // Here we have to be extra careful that the weapons do not get mixed up, so let's keep the code for Duke and RR completely separate. fi.selectweapon(snum, weap); - if (PlayerInput(snum, SKB_HOLSTER)) + if (PlayerInput(snum, SB_HOLSTER)) { if (p->curr_weapon > KNEE_WEAPON) { @@ -564,7 +562,7 @@ void hud_input(int snum) } } - if (PlayerInput(snum, SKB_TURNAROUND) && p->one_eighty_count == 0) + if (PlayerInput(snum, SB_TURNAROUND) && p->one_eighty_count == 0) { SetGameVarID(g_iReturnVarID, 0, -1, snum); OnEvent(EVENT_TURNAROUND, -1, snum, -1); @@ -612,13 +610,6 @@ static void processInputBits(player_struct *p, ControlInfo &info) if (buttonMap.ButtonDown(gamefunc_Fire)) loc.sbits |= SKB_FIRE; if (buttonMap.ButtonDown(gamefunc_Open)) loc.sbits |= SKB_OPEN; - // These 3 bits are only available when not riding a bike or boat. - if (onVehicle) BitsToSend &= ~(SKB_HOLSTER|SKB_TURNAROUND|SKB_CENTER_VIEW); - loc.sbits |= BitsToSend; - BitsToSend = 0; - - if (gamequit) loc.sbits |= SKB_GAMEQUIT; - if (!onVehicle) { if (buttonMap.ButtonDown(gamefunc_Jump)) loc.sbits |= SKB_JUMP; @@ -637,7 +628,12 @@ static void processInputBits(player_struct *p, ControlInfo &info) if (buttonMap.ButtonDown(gamefunc_Quick_Kick)) loc.sbits |= SKB_QUICK_KICK; if (in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming)) loc.sbits |= SKB_AIMMODE; - ApplyGlobalInput(loc, &info); + } + ApplyGlobalInput(loc, &info); + if (onVehicle) + { + // mask out all actions not compatible with vehicles. + loc.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER); } if (buttonMap.ButtonDown(gamefunc_Dpad_Aiming)) @@ -1102,7 +1098,6 @@ void GetInput() if (paused) { loc = {}; - if (gamequit) loc.sbits |= SKB_GAMEQUIT; return; } @@ -1145,26 +1140,9 @@ void GetInput() } } -//--------------------------------------------------------------------------- -// -// CCMD based input. The basics are from Randi's ZDuke but this uses dynamic -// registration to only have the commands active when this game module runs. -// -//--------------------------------------------------------------------------- - -void registerinputcommands() -{ - C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_CENTER_VIEW; return CCMD_OK; }); - C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_HOLSTER; return CCMD_OK; }); - - C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_TURNAROUND; return CCMD_OK; }); - C_RegisterFunction("backoff", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_ESCAPE; return CCMD_OK; }); -} - // This is called from ImputState::ClearAllInput and resets all static state being used here. void GameInterface::clearlocalinputstate() { - BitsToSend = 0; nonsharedtimer = 0; turnheldtime = 0; lastcontroltime = 0; diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 521f1540b..2186a93f2 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -1264,7 +1264,7 @@ void selectweapon_d(int snum, int weap) // playernum, weaponnum if (p->holster_weapon) { - PlayerSetInput(snum, SKB_HOLSTER); + PlayerSetInput(snum, SB_HOLSTER); p->weapon_pos = -9; } else if (j >= MIN_WEAPON && p->gotweapon[j] && (unsigned int)p->curr_weapon != j) switch (j) @@ -2518,14 +2518,14 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) // //--------------------------------------------------------------------------- -static void processweapon(int snum, EDukeSyncBits sb_snum, int psect) +static void processweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect) { auto p = &ps[snum]; int pi = p->i; auto s = &sprite[pi]; int shrunk = (s->yrepeat < 32); - if (isNamWW2GI() && (sb_snum & SKB_HOLSTER)) // 'Holster Weapon + if (isNamWW2GI() && (actions & SB_HOLSTER)) // 'Holster Weapon { if (isWW2GI()) { @@ -2604,6 +2604,7 @@ void processinput_d(int snum) int j, i, k, doubvel, fz, cz, hz, lz, truefdist; char shrunk; EDukeSyncBits sb_snum; + ESyncBits actions; short psect, psectlotag, pi; struct player_struct* p; spritetype* s; @@ -2615,6 +2616,7 @@ void processinput_d(int snum) resetinputhelpers(p); sb_snum = PlayerInputBits(snum, SKB_ALL); + actions = PlayerInputBits(snum, SB_ALL); auto sb_fvel = PlayerInputForwardVel(snum); auto sb_svel = PlayerInputSideVel(snum); @@ -2737,8 +2739,8 @@ void processinput_d(int snum) fi.doincrements(p); - if (isWW2GI() && aplWeaponWorksLike[p->curr_weapon][snum] == HANDREMOTE_WEAPON) processweapon(snum, sb_snum, psect); - if (!isWW2GI() && p->curr_weapon == HANDREMOTE_WEAPON) processweapon(snum, sb_snum, psect); + if (isWW2GI() && aplWeaponWorksLike[p->curr_weapon][snum] == HANDREMOTE_WEAPON) processweapon(snum, actions, sb_snum, psect); + if (!isWW2GI() && p->curr_weapon == HANDREMOTE_WEAPON) processweapon(snum, actions, sb_snum, psect); return; } @@ -3001,7 +3003,7 @@ HORIZONLY: } // center_view - if (sb_snum & SKB_CENTER_VIEW || p->hard_landing) + if (actions & SB_CENTERVIEW || p->hard_landing) { playerCenterView(snum); } @@ -3066,12 +3068,7 @@ HORIZONLY: } // HACKS - processweapon(snum, sb_snum, psect); -} - -void processweapon_d(int s, EDukeSyncBits ss, int p) -{ - processweapon(s, ss, p); + processweapon(snum, actions, sb_snum, psect); } void processmove_d(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist) diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index e176dab8f..9aba0c134 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -1067,7 +1067,7 @@ void selectweapon_r(int snum, int weap) if (p->holster_weapon) { - PlayerSetInput(snum, SKB_HOLSTER); + PlayerSetInput(snum, SB_HOLSTER); p->weapon_pos = -9; } else if (j >= MIN_WEAPON && p->gotweapon[j] && p->curr_weapon != j) switch (j) @@ -3402,6 +3402,7 @@ void processinput_r(int snum) int j, i, k, doubvel, fz, cz, hz, lz, truefdist, var60; char shrunk; EDukeSyncBits sb_snum; + ESyncBits actions; short psect, psectlotag, pi; struct player_struct* p; spritetype* s; @@ -3413,6 +3414,7 @@ void processinput_r(int snum) resetinputhelpers(p); sb_snum = PlayerInputBits(snum, SKB_ALL); + actions = PlayerInputBits(snum, SB_ALL); auto sb_fvel = PlayerInputForwardVel(snum); auto sb_svel = PlayerInputSideVel(snum); @@ -4027,7 +4029,7 @@ HORIZONLY: return; } - if (sb_snum & SKB_CENTER_VIEW || p->hard_landing) + if (actions & SB_CENTERVIEW || p->hard_landing) { playerCenterView(snum); } @@ -4103,11 +4105,6 @@ HORIZONLY: // //--------------------------------------------------------------------------- -void processweapon_r(int s, EDukeSyncBits ss, int p) -{ - processweapon(s, ss, p); -} - void processmove_r(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist) { int psectlotag = sector[psect].lotag; diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index e67c1283d..afb15ed02 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -198,7 +198,6 @@ void GameInterface::app_init() Printf("Copyright (c) 1997 3D Realms Entertainment\n"); registerosdcommands(); - registerinputcommands(); engineInit(); auto pal = fileSystem.LoadFile("3drealms.pal", 0); diff --git a/source/sw/src/game.h b/source/sw/src/game.h index b1b4244a0..a3bae2c55 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2223,7 +2223,6 @@ void LoadSaveMsg(const char *msg); void UpdateStatusBar(int arg); void InitFonts(); int32_t registerosdcommands(void); -void registerinputcommands(); void SW_InitMultiPsky(void); extern int PlayClock; @@ -2269,7 +2268,6 @@ struct GameInterface : ::GameInterface void SetAmbience(bool on) override { if (on) StartAmbientSound(); else StopAmbientSound(); } FString GetCoordString() override; ReservedSpace GetReservedScreenSpace(int viewsize) override; - void clearlocalinputstate() override; void QuitToTitle() override; void ResetFollowPos(bool message) override; diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index 49bbdaa18..5941e0f85 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -34,11 +34,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS -SWBOOL MultiPlayQuitFlag = FALSE; - -int BitsToSend = 0; - - void FunctionKeys(PLAYERp pp) { @@ -118,9 +113,6 @@ getinput(InputPacket *loc, SWBOOL tied) lastInputTicks = currentHiTicks; - // MAKE SURE THIS WILL GET SET - SET_LOC_KEY(loc->bits, SK_QUIT_GAME, MultiPlayQuitFlag); - bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); if (!CommEnabled) @@ -419,9 +411,6 @@ getinput(InputPacket *loc, SWBOOL tied) } - loc->bits |= BitsToSend; - BitsToSend = 0; - SET_LOC_KEY(loc->bits, SK_OPERATE, buttonMap.ButtonDown(gamefunc_Open)); SET_LOC_KEY(loc->bits, SK_JUMP, buttonMap.ButtonDown(gamefunc_Jump)); SET_LOC_KEY(loc->bits, SK_CRAWL, buttonMap.ButtonDown(gamefunc_Crouch)); @@ -459,27 +448,4 @@ getinput(InputPacket *loc, SWBOOL tied) FunctionKeys(pp); } - -//--------------------------------------------------------------------------- -// -// CCMD based input. The basics are from Randi's ZDuke but this uses dynamic -// registration to only have the commands active when this game module runs. -// -//--------------------------------------------------------------------------- - -void registerinputcommands() -{ - C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_CENTER_VIEW); return CCMD_OK; }); - C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_HIDE_WEAPON); return CCMD_OK; }); - - C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= BIT(SK_TURN_180); return CCMD_OK; }); -} - -// This is called from ImputState::ClearAllInput and resets all static state being used here. -void GameInterface::clearlocalinputstate() -{ - BitsToSend = 0; - -} - END_SW_NS diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index e10e2d9b7..eb85154a1 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -6627,18 +6627,18 @@ pWeaponUnHideKeys(PANEL_SPRITEp psp, PANEL_STATEp state) return FALSE; } - if (TEST_SYNC_KEY(psp->PlayerP, SK_HIDE_WEAPON)) + if (psp->PlayerP->input.actions & SB_HOLSTER) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_HIDE_WEAPON)) + if (psp->PlayerP->KeyPressBits & SB_HOLSTER) { - FLAG_KEY_RELEASE(psp->PlayerP, SK_HIDE_WEAPON); + psp->PlayerP->KeyPressBits &= ~SB_HOLSTER; pSetState(psp, state); return TRUE; } } else { - FLAG_KEY_RESET(psp->PlayerP, SK_HIDE_WEAPON); + psp->PlayerP->KeyPressBits |= SB_HOLSTER; } if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT)) @@ -6671,19 +6671,19 @@ pWeaponHideKeys(PANEL_SPRITEp psp, PANEL_STATEp state) return TRUE; } - if (TEST_SYNC_KEY(psp->PlayerP, SK_HIDE_WEAPON)) + if (psp->PlayerP->input.actions & SB_HOLSTER) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_HIDE_WEAPON)) + if (psp->PlayerP->KeyPressBits & SB_HOLSTER) { + psp->PlayerP->KeyPressBits &= ~SB_HOLSTER; PutStringInfo(psp->PlayerP,"Weapon Holstered"); - FLAG_KEY_RELEASE(psp->PlayerP, SK_HIDE_WEAPON); pSetState(psp, state); return TRUE; } } else { - FLAG_KEY_RESET(psp->PlayerP, SK_HIDE_WEAPON); + psp->PlayerP->KeyPressBits |= SB_HOLSTER; } return FALSE; diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index 21ad39895..51b389f3f 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -1566,13 +1566,13 @@ DoPlayerTurn(PLAYERp pp, fix16_t *pq16ang, fix16_t q16angvel) if (!TEST(pp->Flags, PF_TURN_180)) { - if (TEST_SYNC_KEY(pp, SK_TURN_180)) + if (pp->input.actions & SB_TURNAROUND) { - if (FLAG_KEY_PRESSED(pp, SK_TURN_180)) + if (pp->KeyPressBits & SB_TURNAROUND) { short delta_ang; - FLAG_KEY_RELEASE(pp, SK_TURN_180); + pp->KeyPressBits &= ~SB_TURNAROUND; pp->turn180_target = NORM_ANGLE(fix16_to_int(*pq16ang) + 1024); @@ -1591,7 +1591,7 @@ DoPlayerTurn(PLAYERp pp, fix16_t *pq16ang, fix16_t q16angvel) } else { - FLAG_KEY_RESET(pp, SK_TURN_180); + pp->KeyPressBits |= SB_TURNAROUND; } } @@ -1938,7 +1938,7 @@ DoPlayerHorizon(PLAYERp pp, fix16_t *pq16horiz, fix16_t q16aimvel) SET(pp->Flags, PF_LOCK_HORIZ | PF_LOOKING); } - if (TEST_SYNC_KEY(pp, SK_CENTER_VIEW)) + if (pp->input.actions & SB_CENTERVIEW) { if (PedanticMode) pp->q16horizbase = fix16_from_int(100); diff --git a/source/sw/src/predict.cpp b/source/sw/src/predict.cpp index a98af3b8d..a7892620b 100644 --- a/source/sw/src/predict.cpp +++ b/source/sw/src/predict.cpp @@ -83,18 +83,16 @@ DoPrediction(PLAYERp ppp) // get rid of input bits so it doesn't go into other code branches that would // get it out of sync - ppp->input.actions &= ~(SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS); - ppp->KeyPressBits |= (SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS|SB_INVNEXT|SB_INVPREV|SB_INVUSE); + ppp->input.actions &= ~(SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS|SB_HOLSTER|SB_CENTERVIEW); + ppp->KeyPressBits |= (SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS|SB_INVNEXT|SB_INVPREV|SB_INVUSE|SB_HOLSTER|SB_CENTERVIEW); RESET(ppp->input.bits, - BIT(SK_SHOOT)|BIT(SK_OPERATE)|BIT(SK_HIDE_WEAPON)| - BIT(SK_AUTO_AIM)| - BIT(SK_CENTER_VIEW) + BIT(SK_SHOOT)|BIT(SK_OPERATE)| + BIT(SK_AUTO_AIM) ); SET(ppp->KeyPressFlags, - BIT(SK_SHOOT)|BIT(SK_OPERATE)|BIT(SK_HIDE_WEAPON)| - BIT(SK_AUTO_AIM)| - BIT(SK_CENTER_VIEW) + BIT(SK_SHOOT)|BIT(SK_OPERATE)| + BIT(SK_AUTO_AIM) ); // back up things so they won't get stepped on From b9e0f493b2ae0e88d72436dc771d7dc1b9289413 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 28 Aug 2020 22:51:05 +0200 Subject: [PATCH 14/43] - transitioned the 5 primary action keys: Open, Jump, Crouch and Fire/AltFire. --- source/blood/src/actor.cpp | 2 +- source/blood/src/blood.cpp | 10 ++- source/blood/src/controls.cpp | 18 ---- source/blood/src/nnexts.cpp | 12 +-- source/blood/src/player.cpp | 45 +++++----- source/blood/src/weapon.cpp | 28 +++--- source/core/inputstate.cpp | 33 +++---- source/core/packet.h | 38 ++++---- source/exhumed/src/exhumed.cpp | 43 +-------- source/exhumed/src/input.cpp | 19 +--- source/exhumed/src/player.cpp | 15 ++-- source/games/duke/src/actors.cpp | 2 +- source/games/duke/src/actors_d.cpp | 10 +-- source/games/duke/src/actors_r.cpp | 6 +- source/games/duke/src/gameexec.cpp | 4 +- source/games/duke/src/gameloop.cpp | 2 +- source/games/duke/src/input.cpp | 23 ++--- source/games/duke/src/player_d.cpp | 80 ++++++++--------- source/games/duke/src/player_r.cpp | 102 +++++++++++----------- source/games/duke/src/player_w.cpp | 12 +-- source/games/duke/src/sectors_d.cpp | 6 +- source/games/duke/src/sectors_r.cpp | 6 +- source/sw/src/input.cpp | 11 +-- source/sw/src/panel.cpp | 131 +++++++++++++--------------- source/sw/src/player.cpp | 104 +++++++++++----------- source/sw/src/predict.cpp | 6 +- source/sw/src/sector.cpp | 20 ++--- 27 files changed, 352 insertions(+), 436 deletions(-) diff --git a/source/blood/src/actor.cpp b/source/blood/src/actor.cpp index f71f763ae..2fefb8676 100644 --- a/source/blood/src/actor.cpp +++ b/source/blood/src/actor.cpp @@ -4749,7 +4749,7 @@ void MoveDude(spritetype *pSprite) if (pPlayer) { pPlayer->posture = 0; pPlayer->bubbleTime = 0; - if (!pPlayer->cantJump && pPlayer->input.syncFlags.jump) { + if (!pPlayer->cantJump && (pPlayer->input.actions & SB_JUMP)) { zvel[nSprite] = -0x6aaaa; pPlayer->cantJump = 1; } diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index aec358c6b..e637998c0 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -73,6 +73,7 @@ char gUserMapFilename[BMAX_PATH]; short BloodVersion = 0x115; +bool gameRestart; int gNetPlayers; int gQuitRequest; @@ -529,7 +530,7 @@ void ProcessFrame(void) auto oldflags = inp.syncFlags.value; inp = gFifoInput[gNetFifoTail & 255][i]; - inp.actions |= oldactions & SB_INTERFACE_MASK; // should be everything non-button and non-weapon + inp.actions |= oldactions & ~(SB_BUTTON_MASK|SB_RUN|SB_WEAPONMASK_BITS); // should be everything non-button and non-weapon inp.syncFlags.value |= oldflags & ~flag_buttonmask; int newweap = inp.getNewWeapon(); @@ -562,6 +563,13 @@ void ProcessFrame(void) } } #endif + // This is single player only. + if (gameRestart) + { + gameRestart = false; + levelRestart(); + return; + } viewClearInterpolations(); { if (paused || gEndGameMgr.at0 || (gGameOptions.nGameType == 0 && M_Active())) diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 253fa90cc..3eeddedbf 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -169,24 +169,6 @@ void ctrlGetInput(void) cl_showweapon = (cl_showweapon + 1) & 3; } - if (buttonMap.ButtonDown(gamefunc_Jump)) - gInput.syncFlags.jump = 1; - - if (buttonMap.ButtonDown(gamefunc_Crouch)) - gInput.syncFlags.crouch = 1; - - if (buttonMap.ButtonDown(gamefunc_Fire)) - gInput.syncFlags.shoot = 1; - - if (buttonMap.ButtonDown(gamefunc_Alt_Fire)) - gInput.syncFlags.shoot2 = 1; - - if (buttonMap.ButtonDown(gamefunc_Open)) - { - buttonMap.ClearButton(gamefunc_Open); - gInput.syncFlags.action = 1; - } - gInput.syncFlags.lookUp |= buttonMap.ButtonDown(gamefunc_Look_Up); gInput.syncFlags.lookDown |= buttonMap.ButtonDown(gamefunc_Look_Down); diff --git a/source/blood/src/nnexts.cpp b/source/blood/src/nnexts.cpp index fe4ad0265..5993f5af7 100644 --- a/source/blood/src/nnexts.cpp +++ b/source/blood/src/nnexts.cpp @@ -1990,7 +1990,7 @@ void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { xsprite[pSpr->extra].medium = kMediumNormal; if (pPlayer) { - pPlayer->posture = (!pPlayer->input.syncFlags.crouch) ? kPostureStand : kPostureCrouch; + pPlayer->posture = (!(pPlayer->input.actions & SB_CROUCH)) ? kPostureStand : kPostureCrouch; pPlayer->nWaterPal = 0; } @@ -2087,7 +2087,7 @@ void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite) { xsprite[pSprite->extra].medium = kMediumNormal; if (pPlayer) { - pPlayer->posture = (!pPlayer->input.syncFlags.crouch) ? kPostureStand : kPostureCrouch; + pPlayer->posture = (!(pPlayer->input.actions & SB_CROUCH)) ? kPostureStand : kPostureCrouch; pPlayer->nWaterPal = 0; } @@ -2889,10 +2889,10 @@ bool condCheckPlayer(XSPRITE* pXCond, int cmpOp, bool PUSH) { case 2: return (pPlayer->input.fvel < 0); // backward case 3: return (pPlayer->input.svel > 0); // left case 4: return (pPlayer->input.svel < 0); // right - case 5: return (pPlayer->input.syncFlags.jump); // jump - case 6: return (pPlayer->input.syncFlags.crouch); // crouch - case 7: return (pPlayer->input.syncFlags.shoot); // normal fire weapon - case 8: return (pPlayer->input.syncFlags.shoot2); // alt fire weapon + case 5: return !!(pPlayer->input.actions & SB_JUMP); // jump + case 6: return !!(pPlayer->input.actions & SB_CROUCH); // crouch + case 7: return !!(pPlayer->input.actions & SB_FIRE); // normal fire weapon + case 8: return !!(pPlayer->input.actions & SB_ALTFIRE); // alt fire weapon default: condError(pXCond, "Player conditions:\nSpecify a correct key!"); break; diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index 7600c4ab0..fc950d0c7 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -51,6 +51,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS +extern bool gameRestart; + PROFILE gProfile[kMaxPlayers]; PLAYER gPlayer[kMaxPlayers]; @@ -762,6 +764,7 @@ void playerStart(int nPlayer, int bNewLevel) pPlayer->nextWeapon = 0; xvel[pSprite->index] = yvel[pSprite->index] = zvel[pSprite->index] = 0; pInput->q16avel = 0; + pInput->actions = 0; pInput->syncFlags.value = 0; pInput->fvel = 0; pInput->svel = 0; @@ -1330,7 +1333,7 @@ void ProcessInput(PLAYER *pPlayer) } pPlayer->isRunning = pInput->syncFlags.run; - if ((pInput->syncFlags.value & flag_buttonmask_norun) || pInput->fvel || pInput->svel || pInput->q16avel) + if ((pInput->syncFlags.value & flag_buttonmask_norun) || (pInput->actions & SB_BUTTON_MASK) || pInput->fvel || pInput->svel || pInput->q16avel) pPlayer->restTime = 0; else if (pPlayer->restTime >= 0) pPlayer->restTime += 4; @@ -1353,7 +1356,7 @@ void ProcessInput(PLAYER *pPlayer) } if (pPlayer->curWeapon) pInput->setNewWeapon(pPlayer->curWeapon); - if (pInput->syncFlags.action) + if (pInput->actions & SB_OPEN) { if (bSeqStat) { @@ -1369,12 +1372,12 @@ void ProcessInput(PLAYER *pPlayer) playerReset(pPlayer); if (gGameOptions.nGameType == 0 && numplayers == 1) { - pInput->syncFlags.restart = 1; + gameRestart = 1; } else playerStart(pPlayer->nPlayer); } - pInput->syncFlags.action = 0; + pInput->actions &= ~SB_OPEN; } return; } @@ -1431,11 +1434,11 @@ void ProcessInput(PLAYER *pPlayer) } if (pInput->q16avel) pPlayer->q16ang = (pPlayer->q16ang+pInput->q16avel)&0x7ffffff; - if (pInput->syncFlags.spin180) + if (pInput->actions & SB_TURNAROUND) { if (!pPlayer->spin) pPlayer->spin = -1024; - pInput->syncFlags.spin180 = 0; + pInput->actions &= ~SB_TURNAROUND; } if (pPlayer->spin < 0) { @@ -1453,22 +1456,22 @@ void ProcessInput(PLAYER *pPlayer) gViewAngleAdjust += float(pSprite->ang - pPlayer->angold); pPlayer->q16ang = (pPlayer->q16ang+fix16_from_int(pSprite->ang-pPlayer->angold))&0x7ffffff; pPlayer->angold = pSprite->ang = fix16_to_int(pPlayer->q16ang); - if (!pInput->syncFlags.jump) + if (!(pInput->actions & SB_JUMP)) pPlayer->cantJump = 0; switch (pPlayer->posture) { case 1: - if (pInput->syncFlags.jump) + if (pInput->actions & SB_JUMP) zvel[nSprite] -= pPosture->normalJumpZ;//0x5b05; - if (pInput->syncFlags.crouch) + if (pInput->actions & SB_CROUCH) zvel[nSprite] += pPosture->normalJumpZ;//0x5b05; break; case 2: - if (!pInput->syncFlags.crouch) + if (!(pInput->actions & SB_CROUCH)) pPlayer->posture = 0; break; default: - if (!pPlayer->cantJump && pInput->syncFlags.jump && pXSprite->height == 0) { + if (!pPlayer->cantJump && (pInput->actions & SB_JUMP) && pXSprite->height == 0) { #ifdef NOONE_EXTENSIONS if ((packItemActive(pPlayer, 4) && pPosture->pwupJumpZ != 0) || pPosture->normalJumpZ != 0) #endif @@ -1479,11 +1482,11 @@ void ProcessInput(PLAYER *pPlayer) pPlayer->cantJump = 1; } - if (pInput->syncFlags.crouch) + if (pInput->actions & SB_CROUCH) pPlayer->posture = 2; break; } - if (pInput->syncFlags.action) + if (pInput->actions & SB_OPEN) { int a2, a3; int hit = ActionScan(pPlayer, &a2, &a3); @@ -1556,18 +1559,18 @@ void ProcessInput(PLAYER *pPlayer) zvel[pSprite2->index] = zvel[nSprite]; pPlayer->hand = 0; } - pInput->syncFlags.action = 0; + pInput->actions &= ~SB_OPEN; } if (bVanilla) { - if (pInput->syncFlags.lookCenter && !pInput->syncFlags.lookUp && !pInput->syncFlags.lookDown) + if ((pInput->actions & SB_CENTERVIEW) && !pInput->syncFlags.lookUp && !pInput->syncFlags.lookDown) { if (pPlayer->q16look < 0) pPlayer->q16look = fix16_min(pPlayer->q16look+fix16_from_int(4), fix16_from_int(0)); if (pPlayer->q16look > 0) pPlayer->q16look = fix16_max(pPlayer->q16look-fix16_from_int(4), fix16_from_int(0)); if (!pPlayer->q16look) - pInput->syncFlags.lookCenter = 0; + pInput->actions &= ~SB_CENTERVIEW; } else { @@ -1590,14 +1593,14 @@ void ProcessInput(PLAYER *pPlayer) int downAngle = -347; double lookStepUp = 4.0*upAngle/60.0; double lookStepDown = -4.0*downAngle/60.0; - if (pInput->syncFlags.lookCenter && !pInput->syncFlags.lookUp && !pInput->syncFlags.lookDown) + if ((pInput->actions & SB_CENTERVIEW) && !pInput->syncFlags.lookUp && !pInput->syncFlags.lookDown) { if (pPlayer->q16look < 0) pPlayer->q16look = fix16_min(pPlayer->q16look+fix16_from_dbl(lookStepDown), fix16_from_int(0)); if (pPlayer->q16look > 0) pPlayer->q16look = fix16_max(pPlayer->q16look-fix16_from_dbl(lookStepUp), fix16_from_int(0)); if (!pPlayer->q16look) - pInput->syncFlags.lookCenter = 0; + pInput->actions &= ~SB_CENTERVIEW; } else { @@ -1616,7 +1619,7 @@ void ProcessInput(PLAYER *pPlayer) { gViewLookAdjust -= float(lookStepDown); } - gViewLookRecenter = pInput->syncFlags.lookCenter && !pInput->syncFlags.lookUp && !pInput->syncFlags.lookDown; + gViewLookRecenter = (pInput->actions & SB_CENTERVIEW) && !pInput->syncFlags.lookUp && !pInput->syncFlags.lookDown; } pPlayer->q16look = fix16_clamp(pPlayer->q16look+(pInput->q16horz<<3), fix16_from_int(downAngle), fix16_from_int(upAngle)); pPlayer->q16horiz = fix16_from_float(100.f*tanf(fix16_to_float(pPlayer->q16look)*fPI/1024.f)); @@ -1688,9 +1691,9 @@ void ProcessInput(PLAYER *pPlayer) if (pPlayer->packSlots[0].curAmount > 0) packUseItem(pPlayer, 0); } - if (pInput->syncFlags.holsterWeapon) + if (pInput->actions & SB_HOLSTER) { - pInput->syncFlags.holsterWeapon = 0; + pInput->actions &= ~SB_HOLSTER; if (pPlayer->curWeapon) { WeaponLower(pPlayer); diff --git a/source/blood/src/weapon.cpp b/source/blood/src/weapon.cpp index 581486447..6583ca9f1 100644 --- a/source/blood/src/weapon.cpp +++ b/source/blood/src/weapon.cpp @@ -1767,17 +1767,17 @@ char sub_4F0E0(PLAYER *pPlayer) switch (pPlayer->weaponState) { case 5: - if (!pPlayer->input.syncFlags.shoot2) + if (!(pPlayer->input.actions & SB_ALTFIRE)) pPlayer->weaponState = 6; return 1; case 6: - if (pPlayer->input.syncFlags.shoot2) + if (pPlayer->input.actions & SB_ALTFIRE) { pPlayer->weaponState = 3; pPlayer->fuseTime = pPlayer->weaponTimer; StartQAV(pPlayer, 13, nClientDropCan, 0); } - else if (pPlayer->input.syncFlags.shoot) + else if (pPlayer->input.actions & SB_FIRE) { pPlayer->weaponState = 7; pPlayer->fuseTime = 0; @@ -1787,7 +1787,7 @@ char sub_4F0E0(PLAYER *pPlayer) case 7: { pPlayer->throwPower = ClipHigh(divscale16(gFrameClock-pPlayer->throwTime,240), 65536); - if (!pPlayer->input.syncFlags.shoot) + if (!(pPlayer->input.actions & SB_FIRE)) { if (!pPlayer->fuseTime) pPlayer->fuseTime = pPlayer->weaponTimer; @@ -1805,17 +1805,17 @@ char sub_4F200(PLAYER *pPlayer) switch (pPlayer->weaponState) { case 4: - if (!pPlayer->input.syncFlags.shoot2) + if (!(pPlayer->input.actions & SB_ALTFIRE)) pPlayer->weaponState = 5; return 1; case 5: - if (pPlayer->input.syncFlags.shoot2) + if (pPlayer->input.actions & SB_ALTFIRE) { pPlayer->weaponState = 1; pPlayer->fuseTime = pPlayer->weaponTimer; StartQAV(pPlayer, 22, nClientDropBundle, 0); } - else if (pPlayer->input.syncFlags.shoot) + else if (pPlayer->input.actions & SB_FIRE) { pPlayer->weaponState = 6; pPlayer->fuseTime = 0; @@ -1825,7 +1825,7 @@ char sub_4F200(PLAYER *pPlayer) case 6: { pPlayer->throwPower = ClipHigh(divscale16(gFrameClock-pPlayer->throwTime,240), 65536); - if (!pPlayer->input.syncFlags.shoot) + if (!(pPlayer->input.actions & SB_FIRE)) { if (!pPlayer->fuseTime) pPlayer->fuseTime = pPlayer->weaponTimer; @@ -1845,7 +1845,7 @@ char sub_4F320(PLAYER *pPlayer) case 9: pPlayer->throwPower = ClipHigh(divscale16(gFrameClock-pPlayer->throwTime,240), 65536); pPlayer->weaponTimer = 0; - if (!pPlayer->input.syncFlags.shoot) + if (!(pPlayer->input.actions & SB_FIRE)) { pPlayer->weaponState = 8; StartQAV(pPlayer, 29, nClientThrowProx, 0); @@ -1861,7 +1861,7 @@ char sub_4F3A0(PLAYER *pPlayer) { case 13: pPlayer->throwPower = ClipHigh(divscale16(gFrameClock-pPlayer->throwTime,240), 65536); - if (!pPlayer->input.syncFlags.shoot) + if (!(pPlayer->input.actions & SB_FIRE)) { pPlayer->weaponState = 11; StartQAV(pPlayer, 39, nClientThrowRemote, 0); @@ -1880,7 +1880,7 @@ char sub_4F414(PLAYER *pPlayer) StartQAV(pPlayer, 114, nClientFireLifeLeech, 1); return 1; case 6: - if (!pPlayer->input.syncFlags.shoot2) + if (!(pPlayer->input.actions & SB_ALTFIRE)) { pPlayer->weaponState = 2; StartQAV(pPlayer, 118, -1, 0); @@ -1907,7 +1907,7 @@ char sub_4F484(PLAYER *pPlayer) StartQAV(pPlayer, 77, nClientFireTesla, 1); return 1; case 5: - if (!pPlayer->input.syncFlags.shoot) + if (!(pPlayer->input.actions & SB_FIRE)) { pPlayer->weaponState = 2; if (sub_4B2C8(pPlayer, 7, 10) && powerupCheck(pPlayer, kPwUpTwoGuns)) @@ -1968,8 +1968,8 @@ void WeaponProcess(PLAYER *pPlayer) { WeaponPlay(pPlayer); UpdateAimVector(pPlayer); pPlayer->weaponTimer -= 4; - char bShoot = pPlayer->input.syncFlags.shoot; - char bShoot2 = pPlayer->input.syncFlags.shoot2; + bool bShoot = pPlayer->input.actions & SB_FIRE; + bool bShoot2 = pPlayer->input.actions & SB_ALTFIRE; if (pPlayer->qavLoop && pPlayer->pXSprite->health > 0) { if (bShoot && CheckAmmo(pPlayer, pPlayer->weaponAmmo, 1)) diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index 0529da3dc..47af110d7 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -343,25 +343,28 @@ void ApplyGlobalInput(InputPacket& input, ControlInfo *info) input.actions |= ActionsToSend; ActionsToSend = 0; + if (buttonMap.ButtonDown(gamefunc_Jump)) + input.actions |= SB_JUMP; + + if (buttonMap.ButtonDown(gamefunc_Crouch)) + input.actions |= SB_CROUCH; + + if (buttonMap.ButtonDown(gamefunc_Fire)) + input.actions |= SB_FIRE; + + if (buttonMap.ButtonDown(gamefunc_Alt_Fire)) + input.actions |= SB_ALTFIRE; + + if (buttonMap.ButtonDown(gamefunc_Open)) + { + if (g_gameType & GAMEFLAG_BLOOD) buttonMap.ClearButton(gamefunc_Open); + input.actions |= SB_OPEN; + } + } #if 0 -void registerinputcommands() -{ - C_RegisterFunction("centerview", nullptr, [](CCmdFuncPtr)->int { BitsToSend.lookCenter = 1; return CCMD_OK; }); - C_RegisterFunction("holsterweapon", nullptr, [](CCmdFuncPtr)->int { BitsToSend.holsterWeapon = 1; return CCMD_OK; }); - C_RegisterFunction("turnaround", nullptr, [](CCmdFuncPtr)->int { BitsToSend.spin180 = 1; return CCMD_OK; }); -} - -//--------------------------------------------------------------------------- -// -// CCMD based input. The basics are from Randi's ZDuke but this uses dynamic -// registration to only have the commands active when this game module runs. -// -//--------------------------------------------------------------------------- C_RegisterFunction("backoff", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_ESCAPE; return CCMD_OK; }); -} - #endif diff --git a/source/core/packet.h b/source/core/packet.h index 53d9de8ba..50cf00b1d 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -21,12 +21,19 @@ enum ESyncBits_ : uint32_t SB_CENTERVIEW = 1 << 14, SB_TURNAROUND = 1 << 15, SB_HOLSTER = 1 << 16, + SB_OPEN = 1 << 17, + + SB_RUN = 1 << 27, + SB_JUMP = 1 << 28, + SB_CROUCH = 1 << 29, + SB_FIRE = 1 << 30, + SB_ALTFIRE = 1u << 31, SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits SB_ITEMUSE_BITS = (127u * SB_ITEM_BIT_1), - SB_BUTTON_MASK = 0, // all input from buttons (i.e. active while held) - SB_INTERFACE_MASK = (SB_INVPREV|SB_INVNEXT|SB_INVUSE|SB_CENTERVIEW|SB_TURNAROUND|SB_HOLSTER), // all input from CCMDs + SB_BUTTON_MASK = SB_ALTFIRE|SB_FIRE|SB_CROUCH|SB_JUMP, // all input from buttons (i.e. active while held) + SB_INTERFACE_MASK = (SB_INVPREV|SB_INVNEXT|SB_INVUSE|SB_CENTERVIEW|SB_TURNAROUND|SB_HOLSTER|SB_OPEN), // all input from CCMDs SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS | SB_ITEMUSE_BITS | SB_INTERFACE_MASK), SB_ALL = ~0u }; @@ -60,9 +67,6 @@ enum enum EDukeSyncBits_ : uint32_t { - SKB_JUMP = 1 << 0, - SKB_CROUCH = 1 << 1, - SKB_FIRE = 1 << 2, SKB_AIM_UP = 1 << 3, SKB_AIM_DOWN = 1 << 4, SKB_RUN = 1 << 5, @@ -72,11 +76,10 @@ enum EDukeSyncBits_ : uint32_t SKB_LOOK_DOWN = 1 << 14, SKB_QUICK_KICK = 1 << 22, SKB_AIMMODE = 1 << 23, - SKB_OPEN = 1 << 29, SKB_ESCAPE = 1u << 31, SKB_INTERFACE_BITS = (SKB_QUICK_KICK | \ - SKB_OPEN | SKB_ESCAPE), + SKB_ESCAPE), SKB_NONE = 0, SKB_ALL = ~0u @@ -93,15 +96,14 @@ union SYNCFLAGS struct { unsigned int run : 1; - unsigned int jump : 1; - unsigned int crouch : 1; - unsigned int shoot : 1; - unsigned int shoot2 : 1; + unsigned int _jump : 1; + unsigned int _crouch : 1; + unsigned int _shoot : 1; + unsigned int _shoot2 : 1; unsigned int lookUp : 1; unsigned int lookDown : 1; - unsigned int action : 1; unsigned int jab : 1; unsigned int lookLeft : 1; unsigned int lookRight : 1; @@ -123,12 +125,8 @@ union SYNCFLAGS #define SK_FLY 15 #define SK_RUN 16 -#define SK_SHOOT 17 -#define SK_OPERATE 18 -#define SK_JUMP 19 -#define SK_CRAWL 20 -#define SK_SNAP_UP 21 -#define SK_SNAP_DOWN 22 +#define SK_AIM_UP 21 +#define SK_AIM_DOWN 22 #define SK_SPACE_BAR 31 @@ -136,10 +134,6 @@ union SYNCFLAGS // Exhumed enum { - kButtonJump = 0x1, - kButtonOpen = 0x4, - kButtonFire = 0x8, - kButtonCrouch = 0x10, kButtonCheatGuns = 0x20, kButtonCheatGodMode = 0x40, kButtonCheatKeys = 0x80, diff --git a/source/exhumed/src/exhumed.cpp b/source/exhumed/src/exhumed.cpp index 8221d88af..e5e33e103 100644 --- a/source/exhumed/src/exhumed.cpp +++ b/source/exhumed/src/exhumed.cpp @@ -501,7 +501,6 @@ void GameTicker() { lastTic = currentTic; - int lLocalButtons = GetLocalInput(); // shouldn't this be placed in localInput? PlayerInterruptKeys(false); nPlayerDAng = fix16_sadd(nPlayerDAng, localInput.q16avel); @@ -601,7 +600,7 @@ void GameTicker() sPlayerInput[nLocalPlayer].xVel = lPlayerXVel; sPlayerInput[nLocalPlayer].yVel = lPlayerYVel; // make weapon selection persist until it gets used up. - sPlayerInput[nLocalPlayer].buttons = lLocalButtons | lLocalCodes; + sPlayerInput[nLocalPlayer].buttons = lLocalCodes; int weap = sPlayerInput[nLocalPlayer].getNewWeapon(); sPlayerInput[nLocalPlayer].actions = localInput.actions; if (weap2 <= 0 || weap2 > 7) sPlayerInput[nLocalPlayer].SetNewWeapon(weap); @@ -635,52 +634,12 @@ void InitTimer() htimer = 1; } -static const char* actions[] = -{ - "Move_Forward", - "Move_Backward", - "Turn_Left", - "Turn_Right", - "Strafe", - "Fire", - "Open", - "Run", - "Alt_Fire", // Duke3D", Blood - "Jump", - "Crouch", - "Look_Up", - "Look_Down", - "Look_Left", - "Look_Right", - "Strafe_Left", - "Strafe_Right", - "Aim_Up", - "Aim_Down", - "SendMessage", - "Shrink_Screen", - "Enlarge_Screen", - "Show_Opponents_Weapon", - "See_Coop_View", - "Mouse_Aiming", - "Dpad_Select", - "Dpad_Aiming", - "Last_Weapon", - "Alt_Weapon", - "Third_Person_View", - "Toggle_Crouch", // This is the last one used by EDuke32. -}; - - - - void GameInterface::app_init() { int i; //int esi = 1; //int edi = esi; - buttonMap.SetButtons(actions, NUM_ACTIONS); - help_disabled = true; // Create the global level table. Parts of the engine need it, even though the game itself does not. for (int i = 0; i <= 32; i++) diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index 55e923bbf..f1e5e6799 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -74,26 +74,10 @@ void InitInput() void ClearSpaceBar(short nPlayer) { - sPlayerInput[nPlayer].buttons &= 0x0FB; + sPlayerInput[nPlayer].actions &= SB_OPEN; buttonMap.ClearButton(gamefunc_Open); } -int GetLocalInput() -{ - int lLocalButtons; - if (PlayerList[nLocalPlayer].nHealth) - { - lLocalButtons = (buttonMap.ButtonDown(gamefunc_Crouch) << 4) | (buttonMap.ButtonDown(gamefunc_Fire) << 3) - | (buttonMap.ButtonDown(gamefunc_Jump) << 0); - } - else - { - lLocalButtons = 0; - } - - lLocalButtons |= buttonMap.ButtonDown(gamefunc_Open) << 2; - return lLocalButtons; -} void BackupInput() { @@ -189,6 +173,7 @@ void PlayerInterruptKeys(bool after) if (!after) { ApplyGlobalInput(localInput, &info); + if (PlayerList[nLocalPlayer].nHealth == 0) localInput.actions &= ~(SB_FIRE | SB_JUMP | SB_CROUCH); } diff --git a/source/exhumed/src/player.cpp b/source/exhumed/src/player.cpp index 1d8eb9725..264f1e609 100644 --- a/source/exhumed/src/player.cpp +++ b/source/exhumed/src/player.cpp @@ -1279,6 +1279,7 @@ loc_1AB8E: int var_5C = SectFlag[nViewSect] & kSectUnderwater; uint16_t buttons = sPlayerInput[nPlayer].buttons; + auto actions = sPlayerInput[nPlayer].actions; if (buttons & kButtonCheatGodMode) // LOBODEITY cheat { @@ -2535,7 +2536,7 @@ do_default_b: if (!PlayerList[nPlayer].bIsMummified) { - if (buttons & kButtonOpen) + if (actions & SB_OPEN) { ClearSpaceBar(nPlayer); @@ -2551,7 +2552,7 @@ do_default_b: } // was int var_38 = buttons & 0x8 - if (buttons & kButtonFire) + if (actions & SB_FIRE) { FireWeapon(nPlayer); } @@ -2568,7 +2569,7 @@ do_default_b: } // Jumping - if (buttons & kButtonJump) + if (actions & SB_JUMP) { if (bUnderwater) { @@ -2586,7 +2587,7 @@ do_default_b: // goto loc_1BE70: } - else if (buttons & kButtonCrouch) + else if (actions & SB_CROUCH) { if (bUnderwater) { @@ -2647,7 +2648,7 @@ loc_1BD2E: } } // loc_1BE30 - if (buttons & kButtonFire) // was var_38 + if (actions & SB_FIRE) // was var_38 { if (bUnderwater) { @@ -2679,7 +2680,7 @@ loc_1BD2E: } else // player is mummified { - if (buttons & kButtonFire) + if (actions & SB_FIRE) { FireWeapon(nPlayer); } @@ -2708,7 +2709,7 @@ loc_1BD2E: else // else, player's health is less than 0 { // loc_1C0E9 - if (buttons & kButtonOpen) + if (actions & SB_OPEN) { ClearSpaceBar(nPlayer); diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 84bae3b4e..c59123564 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -1522,7 +1522,7 @@ bool queball(int i, int pocket, int queball, int stripeball) // if(s->pal == 12) { j = getincangle(ps[p].getang(), getangle(s->x - ps[p].posx, s->y - ps[p].posy)); - if (j > -64 && j < 64 && PlayerInput(p, SKB_OPEN)) + if (j > -64 && j < 64 && PlayerInput(p, SB_OPEN)) if (ps[p].toggle_key_flag == 1) { int a = headspritestat[STAT_ACTOR]; diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index b992c6049..981670e95 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -2126,13 +2126,13 @@ void movetransports_d(void) else if (!(sectlotag == 1 && ps[p].on_ground == 1)) break; if (onfloorz == 0 && abs(sprite[i].z - ps[p].posz) < 6144) - if ((ps[p].jetpack_on == 0) || (ps[p].jetpack_on && (PlayerInput(p, SKB_JUMP))) || - (ps[p].jetpack_on && (PlayerInput(p, SKB_CROUCH) ^ !!ps[p].crouch_toggle))) + if ((ps[p].jetpack_on == 0) || (ps[p].jetpack_on && (PlayerInput(p, SB_JUMP))) || + (ps[p].jetpack_on && (PlayerInput(p, SB_CROUCH) ^ !!ps[p].crouch_toggle))) { ps[p].oposx = ps[p].posx += sprite[sprite[i].owner].x - sprite[i].x; ps[p].oposy = ps[p].posy += sprite[sprite[i].owner].y - sprite[i].y; - if (ps[p].jetpack_on && (PlayerInput(p, SKB_JUMP) || ps[p].jetpack_on < 11)) + if (ps[p].jetpack_on && (PlayerInput(p, SB_JUMP) || ps[p].jetpack_on < 11)) ps[p].posz = sprite[sprite[i].owner].z - 6144; else ps[p].posz = sprite[sprite[i].owner].z + 6144; ps[p].oposz = ps[p].posz; @@ -2149,7 +2149,7 @@ void movetransports_d(void) k = 0; - if (onfloorz && sectlotag == ST_1_ABOVE_WATER && ps[p].on_ground && ps[p].posz > (sector[sect].floorz - (16 << 8)) && (PlayerInput(p, SKB_CROUCH) || ps[p].poszv > 2048)) + if (onfloorz && sectlotag == ST_1_ABOVE_WATER && ps[p].on_ground && ps[p].posz > (sector[sect].floorz - (16 << 8)) && (PlayerInput(p, SB_CROUCH) || ps[p].poszv > 2048)) // if( onfloorz && sectlotag == 1 && ps[p].posz > (sector[sect].floorz-(6<<8)) ) { k = 1; @@ -2478,7 +2478,7 @@ static void greenslime(int i) s->ang = ps[p].getang(); - if ((PlayerInput(p, SKB_FIRE) || (ps[p].quick_kick > 0)) && sprite[ps[p].i].extra > 0) + if ((PlayerInput(p, SB_FIRE) || (ps[p].quick_kick > 0)) && sprite[ps[p].i].extra > 0) if (ps[p].quick_kick > 0 || (ps[p].curr_weapon != HANDREMOTE_WEAPON && ps[p].curr_weapon != HANDBOMB_WEAPON && ps[p].curr_weapon != TRIPBOMB_WEAPON && ps[p].ammo_amount[ps[p].curr_weapon] >= 0)) { for (x = 0; x < 8; x++) diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index 3ad0c5974..e0d416a66 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -1755,13 +1755,13 @@ void movetransports_r(void) else break; if (onfloorz == 0 && abs(sprite[i].z - ps[p].posz) < 6144) - if ((ps[p].jetpack_on == 0) || (ps[p].jetpack_on && PlayerInput(p, SKB_JUMP)) || - (ps[p].jetpack_on && PlayerInput(p, SKB_CROUCH))) + if ((ps[p].jetpack_on == 0) || (ps[p].jetpack_on && PlayerInput(p, SB_JUMP)) || + (ps[p].jetpack_on && PlayerInput(p, SB_CROUCH))) { ps[p].oposx = ps[p].posx += sprite[OW].x - sprite[i].x; ps[p].oposy = ps[p].posy += sprite[OW].y - sprite[i].y; - if (ps[p].jetpack_on && (PlayerInput(p, SKB_JUMP) || ps[p].jetpack_on < 11)) + if (ps[p].jetpack_on && (PlayerInput(p, SB_JUMP) || ps[p].jetpack_on < 11)) ps[p].posz = sprite[OW].z - 6144; else ps[p].posz = sprite[OW].z + 6144; ps[p].oposz = ps[p].posz; diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp index 52e9dfde3..5f25f5711 100644 --- a/source/games/duke/src/gameexec.cpp +++ b/source/games/duke/src/gameexec.cpp @@ -1163,7 +1163,7 @@ int ParseState::parse(void) s = g_sp->xvel; // sigh... this was yet another place where number literals were used as bit masks for every single value, making the code totally unreadable. - if( (l& pducking) && ps[g_p].on_ground && (PlayerInput(g_p, SKB_CROUCH) ^ !!(ps[g_p].crouch_toggle) )) + if( (l& pducking) && ps[g_p].on_ground && (PlayerInput(g_p, SB_CROUCH) ^ !!(ps[g_p].crouch_toggle) )) j = 1; else if( (l& pfalling) && ps[g_p].jumping_counter == 0 && !ps[g_p].on_ground && ps[g_p].poszv > 2048 ) j = 1; @@ -1244,7 +1244,7 @@ int ParseState::parse(void) parseifelse( (( hittype[g_i].floorz - hittype[g_i].ceilingz ) >> 8 ) < *insptr); break; case concmd_ifhitspace: - parseifelse(PlayerInput(g_p, SKB_OPEN)); + parseifelse(PlayerInput(g_p, SB_OPEN)); break; case concmd_ifoutside: parseifelse(sector[g_sp->sectnum].ceilingstat & 1); diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index 6f46fce67..585430861 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -178,7 +178,7 @@ void mploadsave() int domovethings() { - int i, j; + int i; // mplpadsave(); diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index b59cddc1f..6517b78cb 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -607,33 +607,34 @@ enum static void processInputBits(player_struct *p, ControlInfo &info) { bool onVehicle = p->OnMotorcycle || p->OnBoat; - if (buttonMap.ButtonDown(gamefunc_Fire)) loc.sbits |= SKB_FIRE; - if (buttonMap.ButtonDown(gamefunc_Open)) loc.sbits |= SKB_OPEN; if (!onVehicle) { - if (buttonMap.ButtonDown(gamefunc_Jump)) loc.sbits |= SKB_JUMP; - if (buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Toggle_Crouch) || p->crouch_toggle) + if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch) || p->crouch_toggle) { - loc.sbits |= SKB_CROUCH; - if (isRR()) loc.sbits &= ~SKB_JUMP; + loc.actions |= SB_CROUCH; } if (buttonMap.ButtonDown(gamefunc_Aim_Up) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && info.dz > 0)) loc.sbits |= SKB_AIM_UP; if ((buttonMap.ButtonDown(gamefunc_Aim_Down) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && info.dz < 0))) loc.sbits |= SKB_AIM_DOWN; if (G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run))) loc.sbits |= SKB_RUN; - if (buttonMap.ButtonDown(gamefunc_Look_Left) || (isRR() && p->drink_amt > 88)) loc.sbits |= SKB_LOOK_LEFT; + if (buttonMap.ButtonDown(gamefunc_Look_Left)) loc.sbits |= SKB_LOOK_LEFT; if (buttonMap.ButtonDown(gamefunc_Look_Right)) loc.sbits |= SKB_LOOK_RIGHT; if (buttonMap.ButtonDown(gamefunc_Look_Up)) loc.sbits |= SKB_LOOK_UP; - if (buttonMap.ButtonDown(gamefunc_Look_Down) || (isRR() && p->drink_amt > 99)) loc.sbits |= SKB_LOOK_DOWN; + if (buttonMap.ButtonDown(gamefunc_Look_Down)) loc.sbits |= SKB_LOOK_DOWN; if (buttonMap.ButtonDown(gamefunc_Quick_Kick)) loc.sbits |= SKB_QUICK_KICK; if (in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming)) loc.sbits |= SKB_AIMMODE; + if ((isRR() && p->drink_amt > 88)) loc.sbits |= SKB_LOOK_LEFT; + if ((isRR() && p->drink_amt > 99)) loc.sbits |= SKB_LOOK_DOWN; + } ApplyGlobalInput(loc, &info); + if (isRR() && (loc.actions & SB_CROUCH)) loc.actions &= ~SB_JUMP; + if (onVehicle) { // mask out all actions not compatible with vehicles. - loc.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER); + loc.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH); } if (buttonMap.ButtonDown(gamefunc_Dpad_Aiming)) @@ -978,11 +979,11 @@ static void processVehicleInput(player_struct *p, ControlInfo& info, InputPacket if (p->OnBoat || !p->moto_underwater) { if (buttonMap.ButtonDown(gamefunc_Move_Forward) || buttonMap.ButtonDown(gamefunc_Strafe)) - loc.sbits |= SKB_JUMP; + loc.actions |= SB_JUMP; if (buttonMap.ButtonDown(gamefunc_Move_Backward)) loc.sbits |= SKB_AIM_UP; if (buttonMap.ButtonDown(gamefunc_Run)) - loc.sbits |= SKB_CROUCH; + loc.actions |= SB_CROUCH; } if (turnl) diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 2186a93f2..f64d2661b 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -41,7 +41,7 @@ source as it is released. BEGIN_DUKE_NS void fireweapon_ww(int snum); -void operateweapon_ww(int snum, EDukeSyncBits sb_snum, int psect); +void operateweapon_ww(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect); //--------------------------------------------------------------------------- // @@ -1498,7 +1498,7 @@ int doincrements_d(struct player_struct* p) } S_PlayActorSound(DUKE_CRACK_FIRST, p->i); } - else if (p->knuckle_incs == 22 || PlayerInput(snum, SKB_FIRE)) + else if (p->knuckle_incs == 22 || PlayerInput(snum, SB_FIRE)) p->knuckle_incs = 0; return 1; @@ -1552,7 +1552,7 @@ void checkweapons_d(struct player_struct* p) // //--------------------------------------------------------------------------- -static void operateJetpack(int snum, EDukeSyncBits sb_snum, int psectlotag, int fz, int cz, int shrunk) +static void operateJetpack(int snum, ESyncBits actions, int psectlotag, int fz, int cz, int shrunk) { int j; auto p = &ps[snum]; @@ -1582,7 +1582,7 @@ static void operateJetpack(int snum, EDukeSyncBits sb_snum, int psectlotag, int if (shrunk) j = 512; else j = 2048; - if (sb_snum & SKB_JUMP) //A (soar high) + if (actions & SB_JUMP) //A (soar high) { // jump SetGameVarID(g_iReturnVarID, 0, pi, snum); @@ -1594,7 +1594,7 @@ static void operateJetpack(int snum, EDukeSyncBits sb_snum, int psectlotag, int } } - if (sb_snum & SKB_CROUCH) //Z (soar low) + if (actions & SB_CROUCH) //Z (soar low) { // crouch SetGameVarID(g_iReturnVarID, 0, pi, snum); @@ -1626,7 +1626,7 @@ static void operateJetpack(int snum, EDukeSyncBits sb_snum, int psectlotag, int // //--------------------------------------------------------------------------- -static void movement(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist, int psectlotag) +static void movement(int snum, ESyncBits actions, int psect, int fz, int cz, int shrunk, int truefdist, int psectlotag) { int j; auto p = &ps[snum]; @@ -1675,7 +1675,7 @@ static void movement(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, { // not jumping or crouching - if ((sb_snum & (SKB_JUMP|SKB_CROUCH)) == 0 && p->on_ground && (sector[psect].floorstat & 2) && p->posz >= (fz - (i << 8) - (16 << 8))) + if ((actions & (SB_JUMP|SB_CROUCH)) == 0 && p->on_ground && (sector[psect].floorstat & 2) && p->posz >= (fz - (i << 8) - (16 << 8))) p->posz = fz - (i << 8); else { @@ -1751,27 +1751,27 @@ static void movement(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, p->on_warping_sector = 0; - if (sb_snum & SKB_CROUCH) + if (actions & SB_CROUCH) { playerCrouch(snum); } // jumping - if ((sb_snum & SKB_JUMP) == 0 && p->jumping_toggle == 1) + if ((actions & SB_JUMP) == 0 && p->jumping_toggle == 1) p->jumping_toggle = 0; - else if ((sb_snum & SKB_JUMP)) + else if ((actions & SB_JUMP)) { playerJump(snum, fz, cz); } - if (p->jumping_counter && (sb_snum & SKB_JUMP) == 0) + if (p->jumping_counter && (actions & SB_JUMP) == 0) p->jumping_toggle = 0; } if (p->jumping_counter) { - if ((sb_snum & SKB_JUMP) == 0 && p->jumping_toggle == 1) + if ((actions & SB_JUMP) == 0 && p->jumping_toggle == 1) p->jumping_toggle = 0; if (p->jumping_counter < (1024 + 256)) @@ -1813,7 +1813,7 @@ static void movement(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, // //--------------------------------------------------------------------------- -static void underwater(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz) +static void underwater(int snum, ESyncBits actions, int psect, int fz, int cz) { int j; auto p = &ps[snum]; @@ -1830,14 +1830,14 @@ static void underwater(int snum, EDukeSyncBits sb_snum, int psect, int fz, int c if (!S_CheckActorSoundPlaying(pi, DUKE_UNDERWATER)) S_PlayActorSound(DUKE_UNDERWATER, pi); - if (sb_snum & SKB_JUMP) + if (actions & SB_JUMP) { // jump if (p->poszv > 0) p->poszv = 0; p->poszv -= 348; if (p->poszv < -(256 * 6)) p->poszv = -(256 * 6); } - else if (sb_snum & SKB_CROUCH) + else if (actions & SB_CROUCH) { // crouch if (p->poszv < 0) p->poszv = 0; @@ -2062,7 +2062,7 @@ static void fireweapon(int snum) // //--------------------------------------------------------------------------- -static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) +static void operateweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect) { auto p = &ps[snum]; int pi = p->i; @@ -2073,7 +2073,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) switch (p->curr_weapon) { case HANDBOMB_WEAPON: // grenade in NAM - if (p->kickback_pic == 6 && (sb_snum & SKB_FIRE)) + if (p->kickback_pic == 6 && (actions & SB_FIRE)) { p->rapid_fire_hold = 1; break; @@ -2083,7 +2083,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) { p->ammo_amount[HANDBOMB_WEAPON]--; - if (p->on_ground && (sb_snum & SKB_CROUCH)) + if (p->on_ground && (actions & SB_CROUCH)) { k = 15; i = ((p->gethorizsum() - 100) * 20); @@ -2122,7 +2122,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) p->hbomb_on = 1; } - else if (p->kickback_pic < 12 && (sb_snum & SKB_FIRE)) + else if (p->kickback_pic < 12 && (actions & SB_FIRE)) p->hbomb_hold_delay++; else if (p->kickback_pic > 19) { @@ -2282,7 +2282,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) p->visibility = 0; checkavailweapon(p); - if ((sb_snum & SKB_FIRE) == 0) + if ((actions & SB_FIRE) == 0) { p->okickback_pic = p->kickback_pic = 0; break; @@ -2291,7 +2291,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) } else if (p->kickback_pic > 10) { - if (sb_snum & SKB_FIRE) p->okickback_pic = p->kickback_pic = 1; + if (actions & SB_FIRE) p->okickback_pic = p->kickback_pic = 1; else p->okickback_pic = p->kickback_pic = 0; } @@ -2429,7 +2429,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) } else { - if (sb_snum & SKB_FIRE) + if (actions & SB_FIRE) { p->okickback_pic = p->kickback_pic = 1; S_PlayActorSound(CAT_FIRE, pi); @@ -2455,7 +2455,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) } else if (p->kickback_pic == 16) { - if ((sb_snum & SKB_FIRE) != 0) + if ((actions & SB_FIRE) != 0) { p->okickback_pic = p->kickback_pic = 1; S_PlayActorSound(FLAMETHROWER_INTRO, pi); @@ -2487,7 +2487,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) if (p->kickback_pic == 7) fi.shoot(pi, KNEE); else if (p->kickback_pic == 14) { - if (sb_snum & SKB_FIRE) + if (actions & SB_FIRE) p->okickback_pic = p->kickback_pic = 1 + (krand() & 3); else p->okickback_pic = p->kickback_pic = 0; } @@ -2547,7 +2547,7 @@ static void processweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, in p->ammo_amount[p->curr_weapon] % aplWeaponClip[p->curr_weapon][snum]; // p->kickback_pic = aplWeaponFireDelay[p->curr_weapon][snum]+1; // animate, but don't shoot... p->kickback_pic = aplWeaponTotalTime[p->curr_weapon][snum] + 1; // animate, but don't shoot... - sb_snum &= ~SKB_FIRE; // not firing... + actions &= ~SB_FIRE; // not firing... } return; } @@ -2560,7 +2560,7 @@ static void processweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, in // throw away the remaining clip p->ammo_amount[PISTOL_WEAPON] -= p->ammo_amount[PISTOL_WEAPON] % 20; p->kickback_pic = 3; // animate, but don't shoot... - sb_snum &= ~SKB_FIRE; // not firing... + actions &= ~SB_FIRE; // not firing... } return; } @@ -2575,13 +2575,13 @@ static void processweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, in if (p->rapid_fire_hold == 1) { - if (sb_snum & SKB_FIRE) return; + if (actions & SB_FIRE) return; p->rapid_fire_hold = 0; } if (shrunk || p->tipincs || p->access_incs) - sb_snum &= ~SKB_FIRE; - else if (shrunk == 0 && (sb_snum & SKB_FIRE) && p->kickback_pic == 0 && p->fist_incs == 0 && + actions &= ~SB_FIRE; + else if (shrunk == 0 && (actions & SB_FIRE) && p->kickback_pic == 0 && p->fist_incs == 0 && p->last_weapon == -1 && (p->weapon_pos == 0 || p->holster_weapon == 1)) { if (!isWW2GI()) fireweapon(snum); @@ -2589,8 +2589,8 @@ static void processweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, in } else if (p->kickback_pic) { - if (!isWW2GI()) operateweapon(snum, sb_snum, psect); - else operateweapon_ww(snum, sb_snum, psect); + if (!isWW2GI()) operateweapon(snum, actions, sb_snum, psect); + else operateweapon_ww(snum, actions, sb_snum, psect); } } //--------------------------------------------------------------------------- @@ -2764,16 +2764,16 @@ void processinput_d(int snum) if (psectlotag == ST_2_UNDERWATER) { - underwater(snum, sb_snum, psect, fz, cz); + underwater(snum, actions, psect, fz, cz); } else if (p->jetpack_on) { - operateJetpack(snum, sb_snum, psectlotag, fz, cz, shrunk); + operateJetpack(snum, actions, psectlotag, fz, cz, shrunk); } else if (psectlotag != ST_2_UNDERWATER) { - movement(snum, sb_snum, psect, fz, cz, shrunk, truefdist, psectlotag); + movement(snum, actions, psect, fz, cz, shrunk, truefdist, psectlotag); } p->psectlotag = psectlotag; @@ -2882,8 +2882,8 @@ void processinput_d(int snum) bool check; - if (!isWW2GI()) check = ((p->curr_weapon == KNEE_WEAPON && p->kickback_pic > 10 && p->on_ground) || (p->on_ground && (sb_snum & SKB_CROUCH))); - else check = ((aplWeaponWorksLike[p->curr_weapon][snum] == KNEE_WEAPON && p->kickback_pic > 10 && p->on_ground) || (p->on_ground && (sb_snum & SKB_CROUCH))); + if (!isWW2GI()) check = ((p->curr_weapon == KNEE_WEAPON && p->kickback_pic > 10 && p->on_ground) || (p->on_ground && (actions & SB_CROUCH))); + else check = ((aplWeaponWorksLike[p->curr_weapon][snum] == KNEE_WEAPON && p->kickback_pic > 10 && p->on_ground) || (p->on_ground && (actions & SB_CROUCH))); if (check) { p->posxv = mulscale(p->posxv, dukefriction - 0x2000, 16); @@ -3071,22 +3071,22 @@ HORIZONLY: processweapon(snum, actions, sb_snum, psect); } -void processmove_d(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist) +void processmove_d(int snum, ESyncBits actions, int psect, int fz, int cz, int shrunk, int truefdist) { int psectlotag = sector[psect].lotag; auto p = &ps[snum]; if (psectlotag == 2) { - underwater(snum, sb_snum, psect, fz, cz); + underwater(snum, actions, psect, fz, cz); } else if (p->jetpack_on) { - operateJetpack(snum, sb_snum, psectlotag, fz, cz, shrunk); + operateJetpack(snum, actions, psectlotag, fz, cz, shrunk); } else if (psectlotag != 2) { - movement(snum, sb_snum, psect, fz, cz, shrunk, truefdist, psectlotag); + movement(snum, actions, psect, fz, cz, shrunk, truefdist, psectlotag); } } END_DUKE_NS diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 9aba0c134..5f4d9ca76 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -1411,7 +1411,7 @@ int doincrements_r(struct player_struct* p) else S_PlayActorSound(DUKE_CRACK2, p->i); } } - else if (p->knuckle_incs == 22 || PlayerInput(snum, SKB_FIRE)) + else if (p->knuckle_incs == 22 || PlayerInput(snum, SB_FIRE)) p->knuckle_incs = 0; return 1; @@ -1513,7 +1513,7 @@ void checkweapons_r(struct player_struct* p) // //--------------------------------------------------------------------------- -static void onMotorcycle(int snum, EDukeSyncBits &sb_snum) +static void onMotorcycle(int snum, ESyncBits &actions, EDukeSyncBits &sb_snum) { auto p = &ps[snum]; auto pi = p->i; @@ -1523,18 +1523,18 @@ static void onMotorcycle(int snum, EDukeSyncBits &sb_snum) short var84; if (p->MotoSpeed < 0) p->MotoSpeed = 0; - if (sb_snum & SKB_CROUCH) + if (actions & SB_CROUCH) { var64 = 1; - sb_snum &= ~SKB_CROUCH; + actions &= ~SB_CROUCH; } else var64 = 0; - if (sb_snum & SKB_JUMP) + if (actions & SB_JUMP) { var68 = 1; - sb_snum &= ~SKB_JUMP; + actions &= ~SB_JUMP; if (p->on_ground) { if (p->MotoSpeed == 0 && var64) @@ -1806,7 +1806,7 @@ static void onMotorcycle(int snum, EDukeSyncBits &sb_snum) // //--------------------------------------------------------------------------- -static void onBoat(int snum, EDukeSyncBits& sb_snum) +static void onBoat(int snum, ESyncBits &actions, EDukeSyncBits& sb_snum) { auto p = &ps[snum]; auto pi = p->i; @@ -1829,19 +1829,19 @@ static void onBoat(int snum, EDukeSyncBits& sb_snum) } if (p->MotoSpeed < 0) p->MotoSpeed = 0; - if ((sb_snum & SKB_CROUCH) && (sb_snum & SKB_JUMP)) + if ((actions & SB_CROUCH) && (actions & SB_JUMP)) { vara8 = 1; varac = 0; varb0 = 0; - sb_snum &= ~(SKB_JUMP|SKB_CROUCH); + actions &= ~(SB_JUMP|SB_CROUCH); } else vara8 = 0; - if (sb_snum & SKB_JUMP) + if (actions & SB_JUMP) { varac = 1; - sb_snum &= ~SKB_JUMP; + actions &= ~SB_JUMP; if (p->MotoSpeed == 0 && !S_CheckActorSoundPlaying(pi, 89)) { if (S_CheckActorSoundPlaying(pi, 87)) @@ -1872,10 +1872,10 @@ static void onBoat(int snum, EDukeSyncBits& sb_snum) S_PlayActorSound(87, pi); } - if (sb_snum & SKB_CROUCH) + if (actions & SB_CROUCH) { varb0 = 1; - sb_snum &= ~SKB_CROUCH; + actions &= ~SB_CROUCH; } else varb0 = 0; @@ -2090,7 +2090,7 @@ static void onBoat(int snum, EDukeSyncBits& sb_snum) // //--------------------------------------------------------------------------- -static void movement(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist, int psectlotag) +static void movement(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist, int psectlotag) { auto p = &ps[snum]; auto pi = p->i; @@ -2148,7 +2148,7 @@ static void movement(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, if (p->posz < (fz - (i << 8))) //falling { - if ((sb_snum & (SKB_JUMP|SKB_CROUCH)) == 0 && p->on_ground && (sector[psect].floorstat & 2) && p->posz >= (fz - (i << 8) - (16 << 8))) + if ((actions & (SB_JUMP|SB_CROUCH)) == 0 && p->on_ground && (sector[psect].floorstat & 2) && p->posz >= (fz - (i << 8) - (16 << 8))) p->posz = fz - (i << 8); else { @@ -2262,15 +2262,15 @@ static void movement(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, p->on_warping_sector = 0; - if ((sb_snum & SKB_CROUCH) && !p->OnMotorcycle) + if ((actions & SB_CROUCH) && !p->OnMotorcycle) { playerCrouch(snum); } - if ((sb_snum & SKB_JUMP) == 0 && !p->OnMotorcycle && p->jumping_toggle == 1) + if ((actions & SB_JUMP) == 0 && !p->OnMotorcycle && p->jumping_toggle == 1) p->jumping_toggle = 0; - else if ((sb_snum & SKB_JUMP) && !p->OnMotorcycle && p->jumping_toggle == 0) + else if ((actions & SB_JUMP) && !p->OnMotorcycle && p->jumping_toggle == 0) { playerJump(snum, fz, cz); } @@ -2278,7 +2278,7 @@ static void movement(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, if (p->jumping_counter) { - if ((sb_snum & SKB_JUMP) == 0 && !p->OnMotorcycle && p->jumping_toggle == 1) + if ((actions & SB_JUMP) == 0 && !p->OnMotorcycle && p->jumping_toggle == 1) p->jumping_toggle = 0; if (p->jumping_counter < 768) @@ -2320,7 +2320,7 @@ static void movement(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, // //--------------------------------------------------------------------------- -static void underwater(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz) +static void underwater(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect, int fz, int cz) { int j; auto p = &ps[snum]; @@ -2336,13 +2336,13 @@ static void underwater(int snum, EDukeSyncBits sb_snum, int psect, int fz, int c if (!S_CheckActorSoundPlaying(pi, DUKE_UNDERWATER)) S_PlayActorSound(DUKE_UNDERWATER, pi); - if ((sb_snum & SKB_JUMP) && !p->OnMotorcycle) + if ((actions & SB_JUMP) && !p->OnMotorcycle) { if (p->poszv > 0) p->poszv = 0; p->poszv -= 348; if (p->poszv < -(256 * 6)) p->poszv = -(256 * 6); } - else if ((sb_snum & SKB_CROUCH) || p->OnMotorcycle) + else if ((actions & SB_CROUCH) || p->OnMotorcycle) { if (p->poszv < 0) p->poszv = 0; p->poszv += 348; @@ -2744,7 +2744,7 @@ static void fireweapon(int snum) // //--------------------------------------------------------------------------- -static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) +static void operateweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect) { auto p = &ps[snum]; int pi = p->i; @@ -2758,7 +2758,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) if (p->kickback_pic == 1) S_PlaySound(401); - if (p->kickback_pic == 6 && (sb_snum & SKB_FIRE)) + if (p->kickback_pic == 6 && (actions & SB_FIRE)) p->rapid_fire_hold = 1; p->kickback_pic++; if (p->kickback_pic > 19) @@ -2795,7 +2795,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) p->ammo_amount[DYNAMITE_WEAPON]--; if (p->ammo_amount[CROSSBOW_WEAPON]) p->ammo_amount[CROSSBOW_WEAPON]--; - if (p->on_ground && (sb_snum & SKB_CROUCH) && !p->OnMotorcycle) + if (p->on_ground && (actions & SB_CROUCH) && !p->OnMotorcycle) { k = 15; i = ((p->gethorizsum() - 100) * 20); @@ -2828,7 +2828,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) p->hbomb_on = 1; } - else if (p->kickback_pic < 12 && (sb_snum & SKB_FIRE)) + else if (p->kickback_pic < 12 && (actions & SB_FIRE)) p->hbomb_hold_delay++; if (p->kickback_pic == 40) @@ -2911,7 +2911,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) if (p->kickback_pic == 6) if (p->shotgun_state[0] == 0) if (p->ammo_amount[SHOTGUN_WEAPON] > 1) - if (sb_snum & SKB_FIRE) + if (actions & SB_FIRE) p->shotgun_state[1] = 1; if (p->kickback_pic == 4) @@ -3055,7 +3055,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) } checkavailweapon(p); - if ((sb_snum & SKB_FIRE) == 0) + if ((actions & SB_FIRE) == 0) { p->kickback_pic = 0; break; @@ -3064,7 +3064,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) } else if (p->kickback_pic > 10) { - if (sb_snum & SKB_FIRE) p->kickback_pic = 1; + if (actions & SB_FIRE) p->kickback_pic = 1; else p->kickback_pic = 0; } @@ -3119,7 +3119,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) } if (p->kickback_pic > 4) p->kickback_pic = 1; - if (!(sb_snum & SKB_FIRE)) + if (!(actions & SB_FIRE)) p->kickback_pic = 0; break; @@ -3149,7 +3149,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) } if (p->kickback_pic > 4) p->kickback_pic = 1; - if (!(sb_snum & SKB_FIRE)) + if (!(actions & SB_FIRE)) p->kickback_pic = 0; break; case BOAT_WEAPON: @@ -3205,7 +3205,7 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) { p->ammo_amount[POWDERKEG_WEAPON]--; p->gotweapon.Clear(POWDERKEG_WEAPON); - if (p->on_ground && (sb_snum & SKB_CROUCH) && !p->OnMotorcycle) + if (p->on_ground && (actions & SB_CROUCH) && !p->OnMotorcycle) { k = 15; i = ((p->gethorizsum() - 100) * 20); @@ -3336,14 +3336,14 @@ static void operateweapon(int snum, EDukeSyncBits sb_snum, int psect) // //--------------------------------------------------------------------------- -static void processweapon(int snum, EDukeSyncBits sb_snum, int psect) +static void processweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect) { auto p = &ps[snum]; int pi = p->i; auto s = &sprite[pi]; int shrunk = (s->yrepeat < 8); - if (sb_snum & SKB_FIRE) + if (actions & SB_FIRE) { int a = 0; } @@ -3374,20 +3374,20 @@ static void processweapon(int snum, EDukeSyncBits sb_snum, int psect) if (p->rapid_fire_hold == 1) { - if (sb_snum & SKB_FIRE) return; + if (actions & SB_FIRE) return; p->rapid_fire_hold = 0; } if (shrunk || p->tipincs || p->access_incs) - sb_snum &= ~SKB_FIRE; - else if (shrunk == 0 && (sb_snum & SKB_FIRE) && p->kickback_pic == 0 && p->fist_incs == 0 && + actions &= ~SB_FIRE; + else if (shrunk == 0 && (actions & SB_FIRE) && p->kickback_pic == 0 && p->fist_incs == 0 && p->last_weapon == -1 && (p->weapon_pos == 0 || p->holster_weapon == 1)) { fireweapon(snum); } else if (p->kickback_pic) { - operateweapon(snum, sb_snum, psect); + operateweapon(snum, actions, sb_snum, psect); } } @@ -3423,11 +3423,11 @@ void processinput_r(int snum) psect = p->cursectnum; if (p->OnMotorcycle && s->extra > 0) { - onMotorcycle(snum, sb_snum); + onMotorcycle(snum, actions, sb_snum); } else if (p->OnBoat && s->extra > 0) { - onBoat(snum, sb_snum); + onBoat(snum, actions, sb_snum); } if (psect == -1) { @@ -3510,7 +3510,7 @@ void processinput_r(int snum) if (!p->stairs) { p->stairs = 10; - if ((sb_snum & SKB_JUMP) && !p->OnMotorcycle) + if ((actions & SB_JUMP) && !p->OnMotorcycle) { hz = 0; cz = p->truecz; @@ -3560,7 +3560,7 @@ void processinput_r(int snum) if (!p->stairs) { p->stairs = 10; - if ((sb_snum & SKB_CROUCH) && !p->OnMotorcycle) + if ((actions & SB_CROUCH) && !p->OnMotorcycle) { cz = sprite[j].z; hz = 0; @@ -3572,7 +3572,7 @@ void processinput_r(int snum) } else if (sprite[j].picnum == TOILET || sprite[j].picnum == RRTILE2121) { - if ((sb_snum & SKB_CROUCH) && !p->OnMotorcycle) + if ((actions & SB_CROUCH) && !p->OnMotorcycle) //if (Sound[436].num == 0) { S_PlayActorSound(436, p->i); @@ -3634,7 +3634,7 @@ void processinput_r(int snum) fi.doincrements(p); - if (p->curr_weapon == THROWINGDYNAMITE_WEAPON) processweapon(snum, sb_snum, psect); + if (p->curr_weapon == THROWINGDYNAMITE_WEAPON) processweapon(snum, actions, sb_snum, psect); return; } @@ -3680,11 +3680,11 @@ void processinput_r(int snum) if (psectlotag == ST_2_UNDERWATER) { - underwater(snum, sb_snum, psect, fz, cz); + underwater(snum, actions, sb_snum, psect, fz, cz); } else { - movement(snum, sb_snum, psect, fz, cz, shrunk, truefdist, psectlotag); + movement(snum, actions, sb_snum, psect, fz, cz, shrunk, truefdist, psectlotag); } p->psectlotag = psectlotag; @@ -3780,7 +3780,7 @@ void processinput_r(int snum) p->posxv += ((sb_fvel * doubvel) << 6); p->posyv += ((sb_svel * doubvel) << 6); - if (!isRRRA() && ((p->curr_weapon == KNEE_WEAPON && p->kickback_pic > 10 && p->on_ground) || (p->on_ground && (sb_snum & SKB_CROUCH)))) + if (!isRRRA() && ((p->curr_weapon == KNEE_WEAPON && p->kickback_pic > 10 && p->on_ground) || (p->on_ground && (actions & SB_CROUCH)))) { p->posxv = mulscale(p->posxv, dukefriction - 0x2000, 16); p->posyv = mulscale(p->posyv, dukefriction - 0x2000, 16); @@ -4096,7 +4096,7 @@ HORIZONLY: else p->weapon_pos--; } - processweapon(snum, sb_snum, psect); + processweapon(snum, actions, sb_snum, psect); } //--------------------------------------------------------------------------- @@ -4105,17 +4105,17 @@ HORIZONLY: // //--------------------------------------------------------------------------- -void processmove_r(int snum, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist) +void processmove_r(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist) { int psectlotag = sector[psect].lotag; auto p = &ps[snum]; if (psectlotag == ST_2_UNDERWATER) { - underwater(snum, sb_snum, psect, fz, cz); + underwater(snum, actions, sb_snum, psect, fz, cz); } else { - movement(snum, sb_snum, psect, fz, cz, shrunk, truefdist, psectlotag); + movement(snum, actions, sb_snum, psect, fz, cz, shrunk, truefdist, psectlotag); } } diff --git a/source/games/duke/src/player_w.cpp b/source/games/duke/src/player_w.cpp index 29466ea0b..9521c1ece 100644 --- a/source/games/duke/src/player_w.cpp +++ b/source/games/duke/src/player_w.cpp @@ -306,7 +306,7 @@ void fireweapon_ww(int snum) // //--------------------------------------------------------------------------- -void operateweapon_ww(int snum, EDukeSyncBits sb_snum, int psect) +void operateweapon_ww(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect) { auto p = &ps[snum]; int pi = p->i; @@ -318,7 +318,7 @@ void operateweapon_ww(int snum, EDukeSyncBits sb_snum, int psect) { if (aplWeaponHoldDelay[p->curr_weapon][snum] // there is a hold delay && (p->kickback_pic == aplWeaponFireDelay[p->curr_weapon][snum]) // and we are 'at' hold - && (sb_snum & SKB_FIRE) // and 'fire' button is still down + && (actions & SB_FIRE) // and 'fire' button is still down ) // just hold here... { @@ -330,7 +330,7 @@ void operateweapon_ww(int snum, EDukeSyncBits sb_snum, int psect) { p->ammo_amount[p->curr_weapon]--; - if (p->on_ground && (sb_snum & SKB_CROUCH)) + if (p->on_ground && (actions & SB_CROUCH)) { k = 15; i = ((p->gethorizsum() - 100) * 20); @@ -374,7 +374,7 @@ void operateweapon_ww(int snum, EDukeSyncBits sb_snum, int psect) } else if (p->kickback_pic < aplWeaponHoldDelay[p->curr_weapon][snum] && - (sb_snum & SKB_CROUCH)) + (actions & SB_CROUCH)) { p->hbomb_hold_delay++; } @@ -461,7 +461,7 @@ void operateweapon_ww(int snum, EDukeSyncBits sb_snum, int psect) if (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_AUTOMATIC) { // an 'automatic' - if ((sb_snum & SKB_FIRE) == 0) + if ((actions & SB_FIRE) == 0) { p->kickback_pic = aplWeaponTotalTime[p->curr_weapon][snum]; } @@ -518,7 +518,7 @@ void operateweapon_ww(int snum, EDukeSyncBits sb_snum, int psect) { if (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_AUTOMATIC) { // an 'automatic' - if (sb_snum & SKB_FIRE) + if (actions & SB_FIRE) { // we are an AUTOMATIC. Fire again... if (aplWeaponFlags[p->curr_weapon][snum] & WEAPON_FLAG_RANDOMRESTART) diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index 9906218cd..d03d3fda7 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -1520,7 +1520,7 @@ void checksectors_d(int snum) if (chatmodeon || sprite[p->i].extra <= 0) return; - if (ud.cashman && PlayerInput(snum, SKB_OPEN)) + if (ud.cashman && PlayerInput(snum, SB_OPEN)) fi.lotsofmoney(&sprite[p->i], 2); if (p->newowner >= 0) @@ -1532,7 +1532,7 @@ void checksectors_d(int snum) } } - if (!(PlayerInput(snum, SKB_OPEN)) && !PlayerInput(snum, SKB_ESCAPE)) + if (!(PlayerInput(snum, SB_OPEN)) && !PlayerInput(snum, SKB_ESCAPE)) p->toggle_key_flag = 0; else if (!p->toggle_key_flag) @@ -1740,7 +1740,7 @@ void checksectors_d(int snum) } } - if (!PlayerInput(snum, SKB_OPEN)) return; + if (!PlayerInput(snum, SB_OPEN)) return; else if (p->newowner >= 0) { i = -1; goto CLEARCAMERAS; } if (neartagwall == -1 && neartagsector == -1 && neartagsprite == -1) diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index 7803b606d..7430e9bfa 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -2484,11 +2484,11 @@ void checksectors_r(int snum) if (chatmodeon || sprite[p->i].extra <= 0) return; - if (ud.cashman && PlayerInput(snum, SKB_OPEN)) + if (ud.cashman && PlayerInput(snum, SB_OPEN)) fi.lotsofmoney(&sprite[p->i], 2); - if (!(PlayerInput(snum, SKB_OPEN)) && !PlayerInput(snum, SKB_ESCAPE)) + if (!(PlayerInput(snum, SB_OPEN)) && !PlayerInput(snum, SKB_ESCAPE)) p->toggle_key_flag = 0; else if (!p->toggle_key_flag) @@ -2709,7 +2709,7 @@ void checksectors_r(int snum) } } - if (!PlayerInput(snum, SKB_OPEN)) return; + if (!PlayerInput(snum, SB_OPEN)) return; if (neartagwall == -1 && neartagsector == -1 && neartagsprite == -1) if (abs(hits(p->i)) < 512) diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index 5941e0f85..60746b28d 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -323,12 +323,10 @@ getinput(InputPacket *loc, SWBOOL tied) #endif } - SET_LOC_KEY(loc->bits, SK_RUN, buttonMap.ButtonDown(gamefunc_Run)); - SET_LOC_KEY(loc->bits, SK_SHOOT, buttonMap.ButtonDown(gamefunc_Fire)); // actually snap - SET_LOC_KEY(loc->bits, SK_SNAP_UP, buttonMap.ButtonDown(gamefunc_Aim_Up)); - SET_LOC_KEY(loc->bits, SK_SNAP_DOWN, buttonMap.ButtonDown(gamefunc_Aim_Down)); + SET_LOC_KEY(loc->bits, SK_AIM_UP, buttonMap.ButtonDown(gamefunc_Aim_Up)); + SET_LOC_KEY(loc->bits, SK_AIM_DOWN, buttonMap.ButtonDown(gamefunc_Aim_Down)); // actually just look SET_LOC_KEY(loc->bits, SK_LOOK_UP, buttonMap.ButtonDown(gamefunc_Look_Up)); @@ -410,11 +408,6 @@ getinput(InputPacket *loc, SWBOOL tied) loc->setNewWeapon(which_weapon); } - - SET_LOC_KEY(loc->bits, SK_OPERATE, buttonMap.ButtonDown(gamefunc_Open)); - SET_LOC_KEY(loc->bits, SK_JUMP, buttonMap.ButtonDown(gamefunc_Jump)); - SET_LOC_KEY(loc->bits, SK_CRAWL, buttonMap.ButtonDown(gamefunc_Crouch)); - // need BUTTON SET_LOC_KEY(loc->bits, SK_CRAWL_LOCK, buttonMap.ButtonDown(gamefunc_Toggle_Crouch)); diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index eb85154a1..4cc12b940 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -465,9 +465,9 @@ int WeaponOperate(PLAYERp pp) if (!TEST(pp->sop->flags, SOBJ_HAS_WEAPON)) break; - if (TEST_SYNC_KEY(pp, SK_SHOOT)) + if (pp->input.actions & SB_FIRE) { - if (FLAG_KEY_PRESSED(pp, SK_SHOOT)) + if (pp->KeyPressBits & SB_FIRE) { if (!pp->FirePause) { @@ -693,7 +693,7 @@ WeaponOK(PLAYERp pp) return TRUE; } - FLAG_KEY_RELEASE(pp, SK_SHOOT); + pp->KeyPressBits &= ~SB_FIRE; FindWeaponNum = WPN_SHOTGUN; // Start at the top @@ -984,8 +984,7 @@ InitWeaponSword(PLAYERp pp) PlayerSound(DIGI_ILIKESWORD, v3df_follow|v3df_dontpan,pp); } - FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); - FLAG_KEY_RESET(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits |= SB_FIRE; } @@ -1065,9 +1064,9 @@ pSwordSlideDown(PANEL_SPRITEp psp) if (psp->x < -40) { // if still holding down the fire key - continue swinging - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->input.actions & SB_FIRE) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->KeyPressBits & SB_FIRE) { DoPlayerChooseYell(psp->PlayerP); // continue to next state to swing right @@ -1150,9 +1149,9 @@ pSwordSlideDownR(PANEL_SPRITEp psp) if (psp->x > 350) { // if still holding down the fire key - continue swinging - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->input.actions & SB_FIRE) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->KeyPressBits & SB_FIRE) { DoPlayerChooseYell(psp->PlayerP); // back to action state @@ -1227,9 +1226,9 @@ pSwordRest(PANEL_SPRITEp psp) force = !!TEST(psp->flags, PANF_UNHIDE_SHOOT); - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { RESET(psp->flags, PANF_UNHIDE_SHOOT); @@ -1361,9 +1360,9 @@ PANEL_STATE ps_RetractStar[] = void pStarRestTest(PANEL_SPRITEp psp) { - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->input.actions & SB_FIRE) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->KeyPressBits & SB_FIRE) { if (!WeaponOK(psp->PlayerP)) return; @@ -1439,8 +1438,7 @@ InitWeaponStar(PLAYERp pp) PlayerSound(DIGI_ILIKESHURIKEN, v3df_follow|v3df_dontpan,pp); } - FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); - FLAG_KEY_RESET(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits |= SB_FIRE; } void @@ -1518,9 +1516,9 @@ pStarRest(PANEL_SPRITEp psp) pStarBobSetup(psp); pWeaponBob(psp, PLAYER_MOVING(psp->PlayerP)); - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { RESET(psp->flags, PANF_UNHIDE_SHOOT); @@ -2156,8 +2154,7 @@ InitWeaponUzi(PLAYERp pp) PlaySound(DIGI_UZI_UP, pp, v3df_follow); - FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); - FLAG_KEY_RESET(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits |= SB_FIRE; } PANEL_SPRITEp @@ -2358,7 +2355,7 @@ pUziRest(PANEL_SPRITEp psp) SetVisNorm(); - shooting = TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) && FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT); + shooting = (psp->PlayerP->input.actions & SB_FIRE) && (psp->PlayerP->KeyPressBits & SB_FIRE); shooting |= force; pUziBobSetup(psp); @@ -2383,7 +2380,7 @@ pUziAction(PANEL_SPRITEp psp) char shooting; static SWBOOL alternate = FALSE; - shooting = TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) && FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT); + shooting = (psp->PlayerP->input.actions & SB_FIRE) && (psp->PlayerP->KeyPressBits & SB_FIRE); if (shooting) { @@ -2803,8 +2800,7 @@ InitWeaponShotgun(PLAYERp pp) PlaySound(DIGI_SHOTGUN_UP, pp, v3df_follow); - FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); - FLAG_KEY_RESET(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits |= SB_FIRE; } void @@ -3056,9 +3052,9 @@ pShotgunRest(PANEL_SPRITEp psp) pWeaponBob(psp, PLAYER_MOVING(psp->PlayerP)); - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { RESET(psp->flags, PANF_UNHIDE_SHOOT); @@ -3100,9 +3096,9 @@ pShotgunRestTest(PANEL_SPRITEp psp) pShotgunBobSetup(psp); pWeaponBob(psp, PLAYER_MOVING(psp->PlayerP)); - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { RESET(psp->flags, PANF_UNHIDE_SHOOT); @@ -3315,8 +3311,7 @@ InitWeaponRail(PLAYERp pp) PlaySound(DIGI_RAILREADY, pp, v3df_follow | v3df_dontpan, CHAN_ITEM); // this one needs to be on a dedicated channel to allow switching it off without too many checks. Set3DSoundOwner(psp->PlayerP->PlayerSprite); - FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); - FLAG_KEY_RESET(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits |= SB_FIRE; } void @@ -3460,9 +3455,9 @@ pRailRest(PANEL_SPRITEp psp) pRailBobSetup(psp); pWeaponBob(psp, PLAYER_MOVING(psp->PlayerP)); - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { RESET(psp->flags, PANF_UNHIDE_SHOOT); @@ -3493,9 +3488,9 @@ pRailRestTest(PANEL_SPRITEp psp) pRailBobSetup(psp); pWeaponBob(psp, PLAYER_MOVING(psp->PlayerP)); - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { RESET(psp->flags, PANF_UNHIDE_SHOOT); @@ -3773,8 +3768,7 @@ InitWeaponHothead(PLAYERp pp) psp->ang = 768; psp->vel = 512; - FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); - FLAG_KEY_RESET(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits |= SB_FIRE; pHotHeadOverlays(psp, pp->WpnFlameType); psp->over[0].xoff = HOTHEAD_FINGER_XOFF; psp->over[0].yoff = HOTHEAD_FINGER_YOFF; @@ -3785,9 +3779,9 @@ InitWeaponHothead(PLAYERp pp) void pHotheadRestTest(PANEL_SPRITEp psp) { - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->input.actions & SB_FIRE) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->KeyPressBits & SB_FIRE) { //if (!TEST(psp->PlayerP->Flags,PF_DIVING)) { @@ -3883,9 +3877,9 @@ pHotheadRest(PANEL_SPRITEp psp) pHotheadBobSetup(psp); pWeaponBob(psp, PLAYER_MOVING(psp->PlayerP)); - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { RESET(psp->flags, PANF_UNHIDE_SHOOT); @@ -3917,7 +3911,7 @@ pHotheadAction(PANEL_SPRITEp psp) { char shooting; - shooting = TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) && FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT); + shooting = (psp->PlayerP->input.actions & SB_FIRE) && (psp->PlayerP->KeyPressBits & SB_FIRE); if (shooting) { @@ -4216,8 +4210,7 @@ InitWeaponMicro(PLAYERp pp) PlaySound(DIGI_ROCKET_UP, pp, v3df_follow); - FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); - FLAG_KEY_RESET(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits |= SB_FIRE; } @@ -4467,9 +4460,9 @@ pMicroRest(PANEL_SPRITEp psp) } } - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { RESET(psp->flags, PANF_UNHIDE_SHOOT); @@ -4729,8 +4722,7 @@ InitWeaponHeart(PLAYERp pp) psp->RestState = ps_HeartRest; pSetState(psp, psp->PresentState); - FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); - FLAG_KEY_RESET(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits |= SB_FIRE; } void @@ -4798,11 +4790,11 @@ pHeartRest(PANEL_SPRITEp psp) pHeartBobSetup(psp); pWeaponBob(psp, PLAYER_MOVING(psp->PlayerP)); - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { - FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits &= ~SB_FIRE; RESET(psp->flags, PANF_UNHIDE_SHOOT); if (!WeaponOK(psp->PlayerP)) @@ -4814,7 +4806,7 @@ pHeartRest(PANEL_SPRITEp psp) } else { - FLAG_KEY_RESET(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits |= SB_FIRE; WeaponOK(psp->PlayerP); } } @@ -5232,8 +5224,7 @@ InitWeaponGrenade(PLAYERp pp) PlaySound(DIGI_GRENADE_UP, pp, v3df_follow); - FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); - FLAG_KEY_RESET(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits |= SB_FIRE; } void @@ -5380,9 +5371,9 @@ pGrenadeRest(PANEL_SPRITEp psp) pGrenadeBobSetup(psp); pWeaponBob(psp, PLAYER_MOVING(psp->PlayerP)); - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { RESET(psp->flags, PANF_UNHIDE_SHOOT); @@ -5530,8 +5521,7 @@ InitWeaponMine(PLAYERp pp) PlaySound(DIGI_PULL, pp, v3df_follow|v3df_dontpan); - FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); - FLAG_KEY_RESET(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits |= SB_FIRE; } void @@ -5630,9 +5620,9 @@ pMineRest(PANEL_SPRITEp psp) pMineBobSetup(psp); pWeaponBob(psp, PLAYER_MOVING(psp->PlayerP)); - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force) + if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { RESET(psp->flags, PANF_UNHIDE_SHOOT); @@ -6197,8 +6187,7 @@ InitWeaponFist(PLAYERp pp) else if (rnd_num > 700) PlaySound(DIGI_PLAYERYELL2, pp, v3df_follow|v3df_dontpan); - FLAG_KEY_RELEASE(psp->PlayerP, SK_SHOOT); - FLAG_KEY_RESET(psp->PlayerP, SK_SHOOT); + psp->PlayerP->KeyPressBits |= SB_FIRE; } @@ -6298,9 +6287,9 @@ pFistSlideDown(PANEL_SPRITEp psp) if (psp->y > 440) { // if still holding down the fire key - continue swinging - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->input.actions & SB_FIRE) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->KeyPressBits & SB_FIRE) { DoPlayerChooseYell(psp->PlayerP); @@ -6417,9 +6406,9 @@ pFistSlideDownR(PANEL_SPRITEp psp) if (psp->y > 440) { // if still holding down the fire key - continue swinging - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->input.actions & SB_FIRE) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->KeyPressBits & SB_FIRE) { DoPlayerChooseYell(psp->PlayerP); @@ -6520,11 +6509,11 @@ pFistRest(PANEL_SPRITEp psp) // Reset move to default psp->PlayerP->WpnKungFuMove = 0; - //if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force || TEST_SYNC_KEY(psp->PlayerP, SK_OPERATE)) - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT) || force) + //if ((psp->PlayerP->input.actions & SB_FIRE) || force || TEST_SYNC_KEY(psp->PlayerP, SK_OPERATE)) + if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - //if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force || FLAG_KEY_PRESSED(psp->PlayerP, SK_OPERATE)) - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT) || force) + //if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force || FLAG_KEY_PRESSED(psp->PlayerP, SK_OPERATE)) + if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { RESET(psp->flags, PANF_UNHIDE_SHOOT); @@ -6585,7 +6574,7 @@ pFistBlock(PANEL_SPRITEp psp) pFistBobSetup(psp); pWeaponBob(psp, PLAYER_MOVING(psp->PlayerP)); - if (!TEST_SYNC_KEY(psp->PlayerP, SK_OPERATE)) + if (!(psp->PlayerP->input.actions & SB_OPEN)) { pStatePlusOne(psp); } @@ -6641,9 +6630,9 @@ pWeaponUnHideKeys(PANEL_SPRITEp psp, PANEL_STATEp state) psp->PlayerP->KeyPressBits |= SB_HOLSTER; } - if (TEST_SYNC_KEY(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->input.actions & SB_FIRE) { - if (FLAG_KEY_PRESSED(psp->PlayerP, SK_SHOOT)) + if (psp->PlayerP->KeyPressBits & SB_FIRE) { SET(psp->flags, PANF_UNHIDE_SHOOT); pSetState(psp, state); diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index 51b389f3f..724fc9505 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -1957,13 +1957,13 @@ DoPlayerHorizon(PLAYERp pp, fix16_t *pq16horiz, fix16_t q16aimvel) } // this is the locked type - if (TEST_SYNC_KEY(pp, SK_SNAP_UP) || TEST_SYNC_KEY(pp, SK_SNAP_DOWN)) + if (TEST_SYNC_KEY(pp, SK_AIM_UP) || TEST_SYNC_KEY(pp, SK_AIM_DOWN)) { // set looking because player is manually looking SET(pp->Flags, PF_LOCK_HORIZ | PF_LOOKING); // adjust *pq16horiz negative - if (TEST_SYNC_KEY(pp, SK_SNAP_DOWN)) + if (TEST_SYNC_KEY(pp, SK_AIM_DOWN)) { if (PedanticMode) pp->q16horizbase -= fix16_from_int((HORIZ_SPEED/2)); @@ -1972,7 +1972,7 @@ DoPlayerHorizon(PLAYERp pp, fix16_t *pq16horiz, fix16_t q16aimvel) } // adjust *pq16horiz positive - if (TEST_SYNC_KEY(pp, SK_SNAP_UP)) + if (TEST_SYNC_KEY(pp, SK_AIM_UP)) { if (PedanticMode) pp->q16horizbase += fix16_from_int((HORIZ_SPEED/2)); @@ -3485,16 +3485,16 @@ DoPlayerJump(PLAYERp pp) short i; // reset flag key for double jumps - if (!TEST_SYNC_KEY(pp, SK_JUMP)) + if (!(pp->input.actions & SB_JUMP)) { - FLAG_KEY_RESET(pp, SK_JUMP); + pp->KeyPressBits |= SB_JUMP; } // instead of multiplying by synctics, use a loop for greater accuracy for (i = 0; i < synctics; i++) { // PlayerGravity += synctics; // See how increase gravity as we go? - if (TEST_SYNC_KEY(pp, SK_JUMP)) + if (pp->input.actions & SB_JUMP) { if (pp->JumpDuration > 0) { @@ -3650,9 +3650,9 @@ DoPlayerFall(PLAYERp pp) int depth; // reset flag key for double jumps - if (!TEST_SYNC_KEY(pp, SK_JUMP)) + if (!(pp->input.actions & SB_JUMP)) { - FLAG_KEY_RESET(pp, SK_JUMP); + pp->KeyPressBits |= SB_JUMP; } if (pp->cursectnum >= 0 && SectorIsUnderwaterArea(pp->cursectnum)) @@ -3727,7 +3727,7 @@ DoPlayerFall(PLAYERp pp) StopPlayerSound(pp, DIGI_FALLSCREAM); // i any kind of crawl key get rid of recoil - if (DoPlayerTestCrawl(pp) || TEST_SYNC_KEY(pp, SK_CRAWL)) + if (DoPlayerTestCrawl(pp) || (pp->input.actions & SB_CROUCH)) { pp->posz = pp->loz - PLAYER_CRAWL_HEIGHT; } @@ -3767,7 +3767,7 @@ DoPlayerFall(PLAYERp pp) return; } - if (TEST_SYNC_KEY(pp, SK_CRAWL)) + if (pp->input.actions & SB_CROUCH) { StackedWaterSplash(pp); DoPlayerBeginCrawl(pp); @@ -3856,7 +3856,7 @@ DoPlayerClimb(PLAYERp pp) // need to rewrite this for FAF stuff // Jump off of the ladder - if (TEST_SYNC_KEY(pp, SK_JUMP)) + if (pp->input.actions & SB_JUMP) { RESET(pp->Flags, PF_CLIMBING|PF_WEAPON_DOWN); RESET(sp->cstat, CSTAT_SPRITE_YCENTER); @@ -4188,7 +4188,7 @@ DoPlayerCrawl(PLAYERp pp) } // Jump to get up - if (TEST_SYNC_KEY(pp, SK_JUMP)) + if (pp->input.actions & SB_JUMP) { if (labs(pp->loz - pp->hiz) >= PLAYER_STANDING_ROOM) { @@ -4204,7 +4204,7 @@ DoPlayerCrawl(PLAYERp pp) else { // Let off of crawl to get up - if (!TEST_SYNC_KEY(pp, SK_CRAWL)) + if (!(pp->input.actions & SB_CROUCH)) { if (labs(pp->loz - pp->hiz) >= PLAYER_STANDING_ROOM) { @@ -4331,7 +4331,7 @@ DoPlayerFly(PLAYERp pp) return; } - if (TEST_SYNC_KEY(pp, SK_CRAWL)) + if (pp->input.actions & SB_CROUCH) { pp->z_speed += PLAYER_FLY_INC; @@ -4339,7 +4339,7 @@ DoPlayerFly(PLAYERp pp) pp->z_speed = PLAYER_FLY_MAX_SPEED; } - if (TEST_SYNC_KEY(pp, SK_JUMP)) + if (pp->input.actions & SB_JUMP) { pp->z_speed -= PLAYER_FLY_INC; @@ -4550,7 +4550,7 @@ PlayerCanDive(PLAYERp pp) return FALSE; // Crawl - check for diving - if (TEST_SYNC_KEY(pp, SK_CRAWL) || pp->jump_speed > 0) + if ((pp->input.actions & SB_CROUCH) || pp->jump_speed > 0) { if (PlayerInDiveArea(pp)) { @@ -5183,7 +5183,7 @@ DoPlayerDive(PLAYERp pp) } } - if (TEST_SYNC_KEY(pp, SK_CRAWL)) + if (pp->input.actions & SB_CROUCH) { pp->z_speed += PLAYER_DIVE_INC; @@ -5191,7 +5191,7 @@ DoPlayerDive(PLAYERp pp) pp->z_speed = PLAYER_DIVE_MAX_SPEED; } - if (TEST_SYNC_KEY(pp, SK_JUMP)) + if (pp->input.actions & SB_JUMP) { pp->z_speed -= PLAYER_DIVE_INC; @@ -5456,13 +5456,13 @@ DoPlayerWade(PLAYERp pp) if (DebugOperate) { - if (TEST_SYNC_KEY(pp, SK_OPERATE)) + if (pp->input.actions & SB_OPEN) { - if (FLAG_KEY_PRESSED(pp, SK_OPERATE)) + if (pp->KeyPressBits & SB_OPEN) { if (TEST(sector[pp->cursectnum].extra, SECTFX_OPERATIONAL)) { - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; DoPlayerBeginOperate(pp); pp->bob_amt = 0; pp->bob_ndx = 0; @@ -5472,7 +5472,7 @@ DoPlayerWade(PLAYERp pp) } else { - FLAG_KEY_RESET(pp, SK_OPERATE); + pp->KeyPressBits |= SB_OPEN; } } @@ -5484,17 +5484,17 @@ DoPlayerWade(PLAYERp pp) } // Crawl Commanded - if (TEST_SYNC_KEY(pp, SK_CRAWL) && pp->WadeDepth <= PLAYER_CRAWL_WADE_DEPTH) + if ((pp->input.actions & SB_CROUCH) && pp->WadeDepth <= PLAYER_CRAWL_WADE_DEPTH) { DoPlayerBeginCrawl(pp); return; } - if (TEST_SYNC_KEY(pp, SK_JUMP)) + if (pp->input.actions & SB_JUMP) { - if (FLAG_KEY_PRESSED(pp, SK_JUMP)) + if (pp->KeyPressBits & SB_JUMP) { - FLAG_KEY_RELEASE(pp, SK_JUMP); + pp->KeyPressBits &= ~SB_JUMP; //DoPlayerHeight(pp); //DoPlayerHeight(pp); //DoPlayerHeight(pp); @@ -5507,7 +5507,7 @@ DoPlayerWade(PLAYERp pp) } else { - FLAG_KEY_RESET(pp, SK_JUMP); + pp->KeyPressBits |= SB_JUMP; } if (PlayerFlyKey()) @@ -5980,18 +5980,18 @@ DoPlayerOperateTurret(PLAYERp pp) { short save_sectnum; - if (TEST_SYNC_KEY(pp, SK_OPERATE)) + if (pp->input.actions & SB_OPEN) { - if (FLAG_KEY_PRESSED(pp, SK_OPERATE)) + if (pp->KeyPressBits & SB_OPEN) { - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; DoPlayerStopOperate(pp); return; } } else { - FLAG_KEY_RESET(pp, SK_OPERATE); + pp->KeyPressBits |= SB_OPEN; } if (pp->sop->max_damage != -9999 && pp->sop->max_damage <= 0) @@ -6020,18 +6020,18 @@ DoPlayerOperateBoat(PLAYERp pp) { short save_sectnum; - if (TEST_SYNC_KEY(pp, SK_OPERATE)) + if (pp->input.actions & SB_OPEN) { - if (FLAG_KEY_PRESSED(pp, SK_OPERATE)) + if (pp->KeyPressBits & SB_OPEN) { - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; DoPlayerStopOperate(pp); return; } } else { - FLAG_KEY_RESET(pp, SK_OPERATE); + pp->KeyPressBits |= SB_OPEN; } if (pp->sop->max_damage != -9999 && pp->sop->max_damage <= 0) @@ -6060,18 +6060,18 @@ DoPlayerOperateTank(PLAYERp pp) short save_sectnum; //ASSERT(!TEST_SYNC_KEY(pp, SK_OPERATE)); - if (TEST_SYNC_KEY(pp, SK_OPERATE)) + if (pp->input.actions & SB_OPEN) { - if (FLAG_KEY_PRESSED(pp, SK_OPERATE)) + if (pp->KeyPressBits & SB_OPEN) { - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; DoPlayerStopOperate(pp); return; } } else { - FLAG_KEY_RESET(pp, SK_OPERATE); + pp->KeyPressBits |= SB_OPEN; } if (pp->sop->max_damage != -9999 && pp->sop->max_damage <= 0) @@ -6574,9 +6574,9 @@ void DoPlayerDeathHurl(PLAYERp pp) { if (numplayers > 1) { - if (TEST_SYNC_KEY(pp, SK_SHOOT)) + if (pp->input.actions & SB_FIRE) { - if (FLAG_KEY_PRESSED(pp, SK_SHOOT)) + if (pp->KeyPressBits & SB_FIRE) { @@ -6637,7 +6637,7 @@ void DoPlayerDeathCheckKeys(PLAYERp pp) SPRITEp sp = pp->SpriteP; USERp u = User[pp->PlayerSprite]; - //if (TEST_SYNC_KEY(pp, SK_OPERATE)) + //if (pp->input.actions & SB_OPEN) if (TEST_SYNC_KEY(pp, SK_SPACE_BAR)) { // Spawn a dead LoWang body for non-head deaths @@ -7139,18 +7139,18 @@ DoPlayerRun(PLAYERp pp) } // Crawl Commanded - if (TEST_SYNC_KEY(pp, SK_CRAWL)) + if (pp->input.actions & SB_CROUCH) { DoPlayerBeginCrawl(pp); return; } // Jump - if (TEST_SYNC_KEY(pp, SK_JUMP)) + if (pp->input.actions & SB_JUMP) { - if (FLAG_KEY_PRESSED(pp, SK_JUMP)) + if (pp->KeyPressBits & SB_JUMP) { - FLAG_KEY_RELEASE(pp, SK_JUMP); + pp->KeyPressBits &= ~SB_JUMP; // make sure you stand at full heights for jumps/double jumps //DoPlayerHeight(pp); //DoPlayerHeight(pp); @@ -7164,7 +7164,7 @@ DoPlayerRun(PLAYERp pp) } else { - FLAG_KEY_RESET(pp, SK_JUMP); + pp->KeyPressBits |= SB_JUMP; } // Crawl lock @@ -7193,13 +7193,13 @@ DoPlayerRun(PLAYERp pp) { if (!TEST(pp->Flags, PF_DEAD) && !Prediction) { - if (TEST_SYNC_KEY(pp, SK_OPERATE)) + if (pp->input.actions & SB_OPEN) { - if (FLAG_KEY_PRESSED(pp, SK_OPERATE) && pp->cursectnum >= 0) + if ((pp->KeyPressBits & SB_OPEN) && pp->cursectnum >= 0) { if (TEST(sector[pp->cursectnum].extra, SECTFX_OPERATIONAL)) { - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; DoPlayerBeginOperate(pp); return; } @@ -7211,7 +7211,7 @@ DoPlayerRun(PLAYERp pp) if (sp && SP_TAG5(sp) == TRIGGER_TYPE_REMOTE_SO) { pp->remote_sprite = sp; - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; ASSERT(pp->remote_sprite); DoPlayerBeginRemoteOperate(pp, &SectorObject[SP_TAG7(pp->remote_sprite)]); return; @@ -7221,7 +7221,7 @@ DoPlayerRun(PLAYERp pp) } else { - FLAG_KEY_RESET(pp, SK_OPERATE); + pp->KeyPressBits |= SB_OPEN; } } } diff --git a/source/sw/src/predict.cpp b/source/sw/src/predict.cpp index a7892620b..56094b50a 100644 --- a/source/sw/src/predict.cpp +++ b/source/sw/src/predict.cpp @@ -83,15 +83,13 @@ DoPrediction(PLAYERp ppp) // get rid of input bits so it doesn't go into other code branches that would // get it out of sync - ppp->input.actions &= ~(SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS|SB_HOLSTER|SB_CENTERVIEW); - ppp->KeyPressBits |= (SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS|SB_INVNEXT|SB_INVPREV|SB_INVUSE|SB_HOLSTER|SB_CENTERVIEW); + ppp->input.actions &= ~(SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS|SB_INVNEXT|SB_INVPREV|SB_INVUSE|SB_HOLSTER|SB_CENTERVIEW|SB_FIRE|SB_OPEN);; + ppp->KeyPressBits |= (SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS|SB_INVNEXT|SB_INVPREV|SB_INVUSE|SB_HOLSTER|SB_CENTERVIEW|SB_FIRE|SB_OPEN); RESET(ppp->input.bits, - BIT(SK_SHOOT)|BIT(SK_OPERATE)| BIT(SK_AUTO_AIM) ); SET(ppp->KeyPressFlags, - BIT(SK_SHOOT)|BIT(SK_OPERATE)| BIT(SK_AUTO_AIM) ); diff --git a/source/sw/src/sector.cpp b/source/sw/src/sector.cpp index 7d5c4092f..58a2cb98c 100644 --- a/source/sw/src/sector.cpp +++ b/source/sw/src/sector.cpp @@ -2585,9 +2585,9 @@ PlayerOperateEnv(PLAYERp pp) // Switch & door activations // - if (TEST_SYNC_KEY(pp, SK_OPERATE)) + if (pp->input.actions & SB_OPEN) { - if (FLAG_KEY_PRESSED(pp, SK_OPERATE)) + if (pp->KeyPressBits & SB_OPEN) { // if space bar pressed short nt_ndx; @@ -2595,7 +2595,7 @@ PlayerOperateEnv(PLAYERp pp) if (DoPlayerGrabStar(pp)) { - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; } else { @@ -2613,7 +2613,7 @@ PlayerOperateEnv(PLAYERp pp) { if (OperateSprite(nti[nt_ndx].spritenum, TRUE)) { - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; found = TRUE; } } @@ -2642,7 +2642,7 @@ PlayerOperateEnv(PLAYERp pp) { if (OperateSprite(nti[nt_ndx].spritenum, TRUE)) { - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; break; } } @@ -2663,7 +2663,7 @@ PlayerOperateEnv(PLAYERp pp) if (OperateSector(neartagsector, TRUE)) { // Release the key - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; } } @@ -2671,7 +2671,7 @@ PlayerOperateEnv(PLAYERp pp) { if (OperateWall(neartagwall, TRUE)) { - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; } } } @@ -2690,11 +2690,11 @@ PlayerOperateEnv(PLAYERp pp) break; case TAG_SPRING_BOARD: DoSpringBoard(pp/*, pp->cursectnum*/); - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; break; case TAG_DOOR_ROTATE: if (OperateSector(pp->cursectnum, TRUE)) - FLAG_KEY_RELEASE(pp, SK_OPERATE); + pp->KeyPressBits &= ~SB_OPEN; break; } } @@ -2702,7 +2702,7 @@ PlayerOperateEnv(PLAYERp pp) else { // Reset the key when syncbit key is not in use - FLAG_KEY_RESET(pp, SK_OPERATE); + pp->KeyPressBits |= SB_OPEN; } // //////////////////////////// From fe7f3a2f9e83ca5af9fc94d73c99f05e46318821 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Aug 2020 00:57:07 +0200 Subject: [PATCH 15/43] - handle the run key. --- source/blood/src/controls.cpp | 7 ++----- source/blood/src/player.cpp | 2 +- source/core/inputstate.cpp | 2 ++ source/core/packet.h | 4 +--- source/exhumed/src/input.cpp | 2 +- source/games/duke/src/funct.h | 8 ++++---- source/games/duke/src/gameexec.cpp | 8 ++++---- source/games/duke/src/input.cpp | 9 ++++----- source/games/duke/src/player.cpp | 16 ++++++++-------- source/games/duke/src/player_d.cpp | 8 ++++---- source/games/duke/src/player_r.cpp | 8 ++++---- source/sw/src/input.cpp | 3 +-- source/sw/src/player.cpp | 23 ++--------------------- 13 files changed, 38 insertions(+), 62 deletions(-) diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 3eeddedbf..e994a2238 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -180,12 +180,9 @@ void ctrlGetInput(void) gInput.syncFlags.lookDown |= buttonMap.ButtonDown(gamefunc_Aim_Down); } - int const run = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)); - int const run2 = false; // What??? buttonMap.ButtonDown(gamefunc_Run); + int const run = !!(gInput.actions & SB_RUN); int const keyMove = (1 + run) << 10; - gInput.syncFlags.run |= run; - if (gInput.fvel < keyMove && gInput.fvel > -keyMove) { if (buttonMap.ButtonDown(gamefunc_Move_Forward)) @@ -244,7 +241,7 @@ void ctrlGetInput(void) if (turnRight) input.q16avel = fix16_sadd(input.q16avel, fix16_from_dbl(scaleAdjustmentToInterval(ClipHigh(12 * turnHeldTime, gTurnSpeed)>>2))); - if ((run2 || run) && turnHeldTime > 24) + if (run && turnHeldTime > 24) input.q16avel <<= 1; if (buttonMap.ButtonDown(gamefunc_Strafe)) diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index fc950d0c7..8193e745c 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -1332,7 +1332,7 @@ void ProcessInput(PLAYER *pPlayer) gViewLookAdjust = 0.f; } - pPlayer->isRunning = pInput->syncFlags.run; + pPlayer->isRunning = !!(pInput->actions & SB_RUN); if ((pInput->syncFlags.value & flag_buttonmask_norun) || (pInput->actions & SB_BUTTON_MASK) || pInput->fvel || pInput->svel || pInput->q16avel) pPlayer->restTime = 0; else if (pPlayer->restTime >= 0) diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index 47af110d7..34bb06189 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -360,6 +360,8 @@ void ApplyGlobalInput(InputPacket& input, ControlInfo *info) if (g_gameType & GAMEFLAG_BLOOD) buttonMap.ClearButton(gamefunc_Open); input.actions |= SB_OPEN; } + if (G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run))) + input.actions |= SB_RUN; } diff --git a/source/core/packet.h b/source/core/packet.h index 50cf00b1d..a3ce5ae74 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -69,7 +69,6 @@ enum EDukeSyncBits_ : uint32_t { SKB_AIM_UP = 1 << 3, SKB_AIM_DOWN = 1 << 4, - SKB_RUN = 1 << 5, SKB_LOOK_LEFT = 1 << 6, SKB_LOOK_RIGHT = 1 << 7, SKB_LOOK_UP = 1 << 13, @@ -95,7 +94,7 @@ union SYNCFLAGS uint32_t value; struct { - unsigned int run : 1; + unsigned int _run : 1; unsigned int _jump : 1; unsigned int _crouch : 1; unsigned int _shoot : 1; @@ -124,7 +123,6 @@ union SYNCFLAGS #define SK_CRAWL_LOCK 14 #define SK_FLY 15 -#define SK_RUN 16 #define SK_AIM_UP 21 #define SK_AIM_DOWN 22 diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index f1e5e6799..0c04a6db9 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -178,7 +178,7 @@ void PlayerInterruptKeys(bool after) // JBF: Run key behaviour is selectable - int const playerRunning = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)); + int const playerRunning = !!(localInput.actions & SB_RUN); int const turnAmount = playerRunning ? 12 : 8; int const keyMove = playerRunning ? 12 : 6; diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 3e396f62f..5621a1127 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -112,10 +112,10 @@ void playerJump(int snum, int fz, int cz); void applylook(int snum, double factor, fixed_t adjustment); void checklook(int snum, int sb_snum); void playerCenterView(int snum); -void playerLookUp(int snum, EDukeSyncBits sb_snum); -void playerLookDown(int snum, EDukeSyncBits sb_snum); -void playerAimUp(int snum, EDukeSyncBits sb_snum); -void playerAimDown(int snum, EDukeSyncBits sb_snum); +void playerLookUp(int snum, ESyncBits sb_snum); +void playerLookDown(int snum, ESyncBits sb_snum); +void playerAimUp(int snum, ESyncBits sb_snum); +void playerAimDown(int snum, ESyncBits sb_snum); bool view(struct player_struct* pp, int* vx, int* vy, int* vz, short* vsectnum, int ang, int horiz); void tracers(int x1, int y1, int z1, int x2, int y2, int z2, int n); int hits(int i); diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp index 5f25f5711..c10701986 100644 --- a/source/games/duke/src/gameexec.cpp +++ b/source/games/duke/src/gameexec.cpp @@ -1171,15 +1171,15 @@ int ParseState::parse(void) j = 1; else if( (l& pstanding) && s >= 0 && s < 8) j = 1; - else if( (l& pwalking) && s >= 8 && !(PlayerInput(g_p, SKB_RUN)) ) + else if( (l& pwalking) && s >= 8 && !(PlayerInput(g_p, SB_RUN)) ) j = 1; - else if( (l& prunning) && s >= 8 && PlayerInput(g_p, SKB_RUN) ) + else if( (l& prunning) && s >= 8 && PlayerInput(g_p, SB_RUN) ) j = 1; else if( (l& phigher) && ps[g_p].posz < (g_sp->z-(48<<8)) ) j = 1; - else if( (l& pwalkingback) && s <= -8 && !(PlayerInput(g_p, SKB_RUN)) ) + else if( (l& pwalkingback) && s <= -8 && !(PlayerInput(g_p, SB_RUN)) ) j = 1; - else if( (l& prunningback) && s <= -8 && (PlayerInput(g_p, SKB_RUN)) ) + else if( (l& prunningback) && s <= -8 && (PlayerInput(g_p, SB_RUN)) ) j = 1; else if( (l& pkicking) && ( ps[g_p].quick_kick > 0 || ( ps[g_p].curr_weapon == KNEE_WEAPON && ps[g_p].kickback_pic > 0 ) ) ) j = 1; diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 6517b78cb..760b98d42 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -616,7 +616,6 @@ static void processInputBits(player_struct *p, ControlInfo &info) } if (buttonMap.ButtonDown(gamefunc_Aim_Up) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && info.dz > 0)) loc.sbits |= SKB_AIM_UP; if ((buttonMap.ButtonDown(gamefunc_Aim_Down) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && info.dz < 0))) loc.sbits |= SKB_AIM_DOWN; - if (G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run))) loc.sbits |= SKB_RUN; if (buttonMap.ButtonDown(gamefunc_Look_Left)) loc.sbits |= SKB_LOOK_LEFT; if (buttonMap.ButtonDown(gamefunc_Look_Right)) loc.sbits |= SKB_LOOK_RIGHT; if (buttonMap.ButtonDown(gamefunc_Look_Up)) loc.sbits |= SKB_LOOK_UP; @@ -634,7 +633,7 @@ static void processInputBits(player_struct *p, ControlInfo &info) if (onVehicle) { // mask out all actions not compatible with vehicles. - loc.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH); + loc.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH | SB_RUN); } if (buttonMap.ButtonDown(gamefunc_Dpad_Aiming)) @@ -688,7 +687,7 @@ static void processMovement(player_struct *p, InputPacket &input, ControlInfo &i bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); // JBF: Run key behaviour is selectable - int running = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)); + int running = !!(loc.actions & SB_RUN); int turnamount = NORMALTURN << running; int keymove = NORMALKEYMOVE << running; @@ -982,7 +981,7 @@ static void processVehicleInput(player_struct *p, ControlInfo& info, InputPacket loc.actions |= SB_JUMP; if (buttonMap.ButtonDown(gamefunc_Move_Backward)) loc.sbits |= SKB_AIM_UP; - if (buttonMap.ButtonDown(gamefunc_Run)) + if (loc.buttons & SB_RUN) loc.actions |= SB_CROUCH; } @@ -1126,9 +1125,9 @@ void GetInput() } else { + processInputBits(p, info); processMovement(p, input, info, scaleAdjust); checkCrouchToggle(p); - processInputBits(p, info); FinalizeInput(myconnectindex, input, false); } diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index 41ce74954..ca67ca056 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -1050,7 +1050,7 @@ void playerCenterView(int snum) } } -void playerLookUp(int snum, EDukeSyncBits sb_snum) +void playerLookUp(int snum, ESyncBits actions) { auto p = &ps[snum]; SetGameVarID(g_iReturnVarID, 0, p->i, snum); @@ -1058,11 +1058,11 @@ void playerLookUp(int snum, EDukeSyncBits sb_snum) if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0) { p->return_to_center = 9; - p->pitchAdjust += (sb_snum & SKB_RUN) ? 12 : 24; + p->pitchAdjust += (actions & SB_RUN) ? 12 : 24; } } -void playerLookDown(int snum, EDukeSyncBits sb_snum) +void playerLookDown(int snum, ESyncBits actions) { auto p = &ps[snum]; SetGameVarID(g_iReturnVarID, 0, p->i, snum); @@ -1070,29 +1070,29 @@ void playerLookDown(int snum, EDukeSyncBits sb_snum) if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0) { p->return_to_center = 9; - p->pitchAdjust -= (sb_snum & SKB_RUN) ? 12 : 24; + p->pitchAdjust -= (actions & SB_RUN) ? 12 : 24; } } -void playerAimUp(int snum, EDukeSyncBits sb_snum) +void playerAimUp(int snum, ESyncBits actions) { auto p = &ps[snum]; SetGameVarID(g_iReturnVarID, 0, p->i, snum); OnEvent(EVENT_AIMUP, p->i, snum, -1); if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0) { - p->pitchAdjust += (sb_snum & SKB_RUN) ? 6 : 12; + p->pitchAdjust += (actions & SB_RUN) ? 6 : 12; } } -void playerAimDown(int snum, EDukeSyncBits sb_snum) +void playerAimDown(int snum, ESyncBits actions) { auto p = &ps[snum]; SetGameVarID(g_iReturnVarID, 0, p->i, snum); OnEvent(EVENT_AIMDOWN, p->i, snum, -1); if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0) { - p->pitchAdjust -= (sb_snum & SKB_RUN) ? 6 : 12; + p->pitchAdjust -= (actions & SB_RUN) ? 6 : 12; } } diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index f64d2661b..536b9c26c 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -3009,19 +3009,19 @@ HORIZONLY: } else if (sb_snum & SKB_LOOK_UP) { - playerLookUp(snum, sb_snum); + playerLookUp(snum, actions); } else if (sb_snum & SKB_LOOK_DOWN) { - playerLookDown(snum, sb_snum); + playerLookDown(snum, actions); } else if (sb_snum & SKB_AIM_UP) { - playerAimUp(snum, sb_snum); + playerAimUp(snum, actions); } else if (sb_snum & SKB_AIM_DOWN) { // aim_down - playerAimDown(snum, sb_snum); + playerAimDown(snum, actions); } if (cl_syncinput) diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 5f4d9ca76..6c00df7ee 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -4035,19 +4035,19 @@ HORIZONLY: } else if (sb_snum & SKB_LOOK_UP) { - playerLookUp(snum, sb_snum); + playerLookUp(snum, actions); } else if (sb_snum & SKB_LOOK_DOWN) { - playerLookDown(snum, sb_snum); + playerLookDown(snum, actions); } else if ((sb_snum & SKB_AIM_UP) && !p->OnMotorcycle) { - playerAimUp(snum, sb_snum); + playerAimUp(snum, actions); } else if ((sb_snum & SKB_AIM_DOWN) && !p->OnMotorcycle) { - playerAimDown(snum, sb_snum); + playerAimDown(snum, actions); } if (p->recoil && p->kickback_pic == 0) { diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index 60746b28d..53074c42e 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -149,7 +149,6 @@ getinput(InputPacket *loc, SWBOOL tied) SET_LOC_KEY(loc->bits, SK_SPACE_BAR, buttonMap.ButtonDown(gamefunc_Open)); - int const running = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)); int32_t turnamount; int32_t keymove; @@ -165,7 +164,7 @@ getinput(InputPacket *loc, SWBOOL tied) ApplyGlobalInput(*loc, &info); - if (running) + if (loc->actions & SB_RUN) { if (pp->sop_control) turnamount = RUNTURN * 3; diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index 724fc9505..225b46da2 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -2073,7 +2073,7 @@ DoPlayerBob(PLAYERp pp) dist = 0; // if running make a longer stride - if (G_CheckAutorun(TEST_SYNC_KEY(pp, SK_RUN))) + if (pp->input.actions & SB_RUN) { //amt = 10; amt = 12; @@ -2464,31 +2464,12 @@ MoveScrollMode2D(PLAYERp pp) if (M_Active()) return; -#if 0 - // Recenter view if told - if (buttonMap.ButtonDown(gamefunc_Center_View)) - { - Follow_posx = pp->posx; - Follow_posy = pp->posy; - } -#endif - if (buttonMap.ButtonDown(gamefunc_Strafe)) mfsvel -= scrl_input.dyaw / 4; mfsvel -= scrl_input.dx / 4; mfvel = -scrl_input.dz /4; -#if 0 - int const running = !!BUTTON(gamefunc_Run) ^ !!TEST(pp->Flags, PF_LOCK_RUN); - if (running) - { - keymove = NORMALKEYMOVE << 1; - } - else -#endif - { - keymove = NORMALKEYMOVE; - } + keymove = NORMALKEYMOVE; if (buttonMap.ButtonDown(gamefunc_Turn_Left)) { From 3a9bcb0b6467f9e5400d8467a521e3f9271687eb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Aug 2020 02:17:28 +0200 Subject: [PATCH 16/43] - moved Exhumed's cheat bits back into the game module. They are no longer part of the packet interface. --- source/core/packet.h | 15 --------------- source/exhumed/src/ps_input.h | 7 +++++++ 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/source/core/packet.h b/source/core/packet.h index 533d52365..bcbdb3d20 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -103,7 +103,6 @@ union SYNCFLAGS unsigned int lookDown : 1; - unsigned int jab : 1; unsigned int lookLeft : 1; unsigned int lookRight : 1; }; @@ -129,20 +128,6 @@ union SYNCFLAGS #define SK_SPACE_BAR 31 -// Exhumed - -enum { - kButtonCheatGuns = 0x20, - kButtonCheatGodMode = 0x40, - kButtonCheatKeys = 0x80, - kButtonCheatItems = 0x100, -}; - - - - - - struct InputPacket { int16_t svel; diff --git a/source/exhumed/src/ps_input.h b/source/exhumed/src/ps_input.h index 23ae1e3fb..c0f2f4cbc 100644 --- a/source/exhumed/src/ps_input.h +++ b/source/exhumed/src/ps_input.h @@ -24,6 +24,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS +enum { + kButtonCheatGuns = 0x20, + kButtonCheatGodMode = 0x40, + kButtonCheatKeys = 0x80, + kButtonCheatItems = 0x100, +}; + // 32 bytes struct PlayerInput { From 7659107b75b4ca19ac07865b8e2939050419cc96 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Aug 2020 02:19:41 +0200 Subject: [PATCH 17/43] - removed SW's SK_AUTO_AIM for good. When networking becomes a thing again this can be done as a server CVAR without such a messy approach. --- source/core/packet.h | 2 -- source/sw/src/input.cpp | 13 ------------- source/sw/src/predict.cpp | 7 ------- 3 files changed, 22 deletions(-) diff --git a/source/core/packet.h b/source/core/packet.h index bcbdb3d20..0097f5df1 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -115,8 +115,6 @@ union SYNCFLAGS // -#define SK_AUTO_AIM 7 - #define SK_LOOK_UP 12 #define SK_LOOK_DOWN 13 #define SK_CRAWL_LOCK 14 diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index 3c06285d5..1848cadc6 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -309,19 +309,6 @@ getinput(InputPacket *loc, SWBOOL tied) loc->q16avel += q16angvel; loc->q16horz += q16horz; - if (!CommEnabled) - { - // What a mess...:? -#if 0 - if (MenuButtonAutoAim) - { - MenuButtonAutoAim = FALSE; - if ((!!TEST(pp->Flags, PF_AUTO_AIM)) != !!cl_autoaim) - SET_LOC_KEY(loc->bits, SK_AUTO_AIM, TRUE); - } -#endif - } - // actually snap SET_LOC_KEY(loc->bits, SK_AIM_UP, buttonMap.ButtonDown(gamefunc_Aim_Up)); diff --git a/source/sw/src/predict.cpp b/source/sw/src/predict.cpp index 56094b50a..e89d817dc 100644 --- a/source/sw/src/predict.cpp +++ b/source/sw/src/predict.cpp @@ -85,13 +85,6 @@ DoPrediction(PLAYERp ppp) // get it out of sync ppp->input.actions &= ~(SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS|SB_INVNEXT|SB_INVPREV|SB_INVUSE|SB_HOLSTER|SB_CENTERVIEW|SB_FIRE|SB_OPEN);; ppp->KeyPressBits |= (SB_WEAPONMASK_BITS|SB_ITEMUSE_BITS|SB_INVNEXT|SB_INVPREV|SB_INVUSE|SB_HOLSTER|SB_CENTERVIEW|SB_FIRE|SB_OPEN); - RESET(ppp->input.bits, - BIT(SK_AUTO_AIM) - ); - - SET(ppp->KeyPressFlags, - BIT(SK_AUTO_AIM) - ); // back up things so they won't get stepped on bakrandomseed = randomseed; From 51a08fbaf34e86f9eb8ab69f4fc836ecf9c91b98 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 29 Aug 2020 21:27:58 +1000 Subject: [PATCH 18/43] - Duke: Implement `WeaponSel_Alt` for Duke and RR. --- source/games/duke/src/player_d.cpp | 13 ++++++++++++- source/games/duke/src/player_r.cpp | 31 +++++++++++++++++++++++++++++- wadsrc/static/engine/menudef.txt | 4 ++-- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index be6cd69a9..8d44d5b7b 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -1109,7 +1109,18 @@ void selectweapon_d(int snum, int weap) // playernum, weaponnum { if (weap == WeaponSel_Alt) { - // todo + switch (p->curr_weapon) + { + case SHRINKER_WEAPON: + j = PLUTOPAK ? GROW_WEAPON : p->curr_weapon; + break; + case GROW_WEAPON: + j = SHRINKER_WEAPON; + break; + default: + j = p->curr_weapon; + break; + } } else if (weap == WeaponSel_Next || weap == WeaponSel_Prev) { diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index f0543c108..ebe7d4748 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -957,7 +957,36 @@ void selectweapon_r(int snum, int weap) { if (weap == WeaponSel_Alt) { - // todo + switch (p->curr_weapon) + { + case THROWSAW_WEAPON: + j = BUZZSAW_WEAPON; + break; + case BUZZSAW_WEAPON: + j = THROWSAW_WEAPON; + break; + case POWDERKEG_WEAPON: + j = BOWLING_WEAPON; + break; + case BOWLING_WEAPON: + j = POWDERKEG_WEAPON; + break; + case KNEE_WEAPON: + j = isRRRA() ? SLINGBLADE_WEAPON : p->curr_weapon; + break; + case SLINGBLADE_WEAPON: + j = KNEE_WEAPON; + break; + case DYNAMITE_WEAPON: + j = isRRRA() ? CHICKEN_WEAPON : p->curr_weapon; + break; + case CHICKEN_WEAPON: + j = DYNAMITE_WEAPON; + break; + default: + j = p->curr_weapon; + break; + } } else if (weap == WeaponSel_Next || weap == WeaponSel_Prev) { diff --git a/wadsrc/static/engine/menudef.txt b/wadsrc/static/engine/menudef.txt index 14af5aa80..dbd584c15 100644 --- a/wadsrc/static/engine/menudef.txt +++ b/wadsrc/static/engine/menudef.txt @@ -481,9 +481,9 @@ OptionMenu "ActionControlsMenu"// protected { Control "$CNTRLMNU_ALTATTACK" , "+alt_fire" } - ifgame(ShadowWarrior) + ifgame(ShadowWarrior, Duke, Redneck) { - Control "$CNTRLMNU_ALTWEAPON" , "+alt_weapon" + Control "$CNTRLMNU_ALTWEAPON" , "weapalt" } StaticText "" From 694444b62abf782c2f5927a455007a937f0cdfa7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Aug 2020 13:32:14 +0200 Subject: [PATCH 19/43] - converted the remaining input bits. Looks like it is working in all games except Blood (not that it surprises me that it's Blood again which has issues...) --- source/blood/src/blood.cpp | 2 - source/blood/src/controls.cpp | 16 ++--- source/blood/src/player.cpp | 21 +++--- source/blood/src/prediction.cpp | 12 ++-- source/core/gamecvars.h | 1 - source/core/inputstate.cpp | 34 ++++++++-- source/core/packet.h | 95 ++++------------------------ source/exhumed/src/input.cpp | 53 ++++++++-------- source/games/duke/src/funct.h | 12 ++-- source/games/duke/src/inlines.h | 20 ------ source/games/duke/src/input.cpp | 61 ++++++++---------- source/games/duke/src/player.cpp | 10 +-- source/games/duke/src/player_d.cpp | 30 ++++----- source/games/duke/src/player_r.cpp | 70 ++++++++++---------- source/games/duke/src/player_w.cpp | 2 +- source/games/duke/src/prediction.cpp | 5 +- source/games/duke/src/sectors_d.cpp | 4 +- source/games/duke/src/sectors_r.cpp | 2 +- source/sw/src/eel.cpp | 3 - source/sw/src/game.h | 13 +--- source/sw/src/input.cpp | 74 ++++++++++------------ source/sw/src/network.cpp | 3 - source/sw/src/panel.cpp | 2 - source/sw/src/player.cpp | 47 +++++++------- 24 files changed, 235 insertions(+), 357 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 8428e798f..c7cd9e6a0 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -526,11 +526,9 @@ void ProcessFrame(void) { auto& inp = gPlayer[i].input; auto oldactions = inp.actions; - auto oldflags = inp.syncFlags.value; inp = gFifoInput[gNetFifoTail & 255][i]; inp.actions |= oldactions & ~(SB_BUTTON_MASK|SB_RUN|SB_WEAPONMASK_BITS); // should be everything non-button and non-weapon - inp.syncFlags.value |= oldflags & ~flag_buttonmask; int newweap = inp.getNewWeapon(); if (newweap > 0 && newweap < WeaponSel_MaxBlood) gPlayer[i].newWeapon = newweap; diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 2f32494ba..9dbbee9de 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -127,9 +127,6 @@ void ctrlGetInput(void) InputPacket input = {}; - bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - if (!mouseaim) gInput.actions |= SB_CENTERVIEW; - if (numplayers == 1) { gProfile[myconnectindex].nAutoAim = cl_autoaim; @@ -140,6 +137,9 @@ void ctrlGetInput(void) ApplyGlobalInput(gInput, &info); + bool mouseaim = !!(gInput.actions & SB_AIMMODE); + if (!mouseaim) gInput.actions |= SB_CENTERVIEW; + if (buttonMap.ButtonDown(gamefunc_Shrink_Screen)) { if (automapMode != am_off) @@ -168,16 +168,8 @@ void ctrlGetInput(void) cl_showweapon = (cl_showweapon + 1) & 3; } - gInput.syncFlags.lookUp |= buttonMap.ButtonDown(gamefunc_Look_Up); - gInput.syncFlags.lookDown |= buttonMap.ButtonDown(gamefunc_Look_Down); - - if (buttonMap.ButtonDown(gamefunc_Look_Up) || buttonMap.ButtonDown(gamefunc_Look_Down)) + if (gInput.actions & (SB_LOOK_UP|SB_LOOK_DOWN)) gInput.actions |= SB_CENTERVIEW; - else - { - gInput.syncFlags.lookUp |= buttonMap.ButtonDown(gamefunc_Aim_Up); - gInput.syncFlags.lookDown |= buttonMap.ButtonDown(gamefunc_Aim_Down); - } int const run = !!(gInput.actions & SB_RUN); int const keyMove = (1 + run) << 10; diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index 8193e745c..03c72f3a0 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -765,7 +765,6 @@ void playerStart(int nPlayer, int bNewLevel) xvel[pSprite->index] = yvel[pSprite->index] = zvel[pSprite->index] = 0; pInput->q16avel = 0; pInput->actions = 0; - pInput->syncFlags.value = 0; pInput->fvel = 0; pInput->svel = 0; pInput->q16horz = 0; @@ -1333,7 +1332,7 @@ void ProcessInput(PLAYER *pPlayer) } pPlayer->isRunning = !!(pInput->actions & SB_RUN); - if ((pInput->syncFlags.value & flag_buttonmask_norun) || (pInput->actions & SB_BUTTON_MASK) || pInput->fvel || pInput->svel || pInput->q16avel) + if ((pInput->actions & SB_BUTTON_MASK) || pInput->fvel || pInput->svel || pInput->q16avel) pPlayer->restTime = 0; else if (pPlayer->restTime >= 0) pPlayer->restTime += 4; @@ -1563,7 +1562,7 @@ void ProcessInput(PLAYER *pPlayer) } if (bVanilla) { - if ((pInput->actions & SB_CENTERVIEW) && !pInput->syncFlags.lookUp && !pInput->syncFlags.lookDown) + if ((pInput->actions & SB_CENTERVIEW) && !pInput->actions & (SB_LOOK_UP|SB_LOOK_DOWN)) { if (pPlayer->q16look < 0) pPlayer->q16look = fix16_min(pPlayer->q16look+fix16_from_int(4), fix16_from_int(0)); @@ -1574,9 +1573,9 @@ void ProcessInput(PLAYER *pPlayer) } else { - if (pInput->syncFlags.lookUp) + if (pInput->actions & (SB_LOOK_UP|SB_AIM_UP)) pPlayer->q16look = fix16_min(pPlayer->q16look+fix16_from_int(4), fix16_from_int(60)); - if (pInput->syncFlags.lookDown) + if (pInput->actions & (SB_LOOK_DOWN|SB_AIM_DOWN)) pPlayer->q16look = fix16_max(pPlayer->q16look-fix16_from_int(4), fix16_from_int(-60)); } pPlayer->q16look = fix16_clamp(pPlayer->q16look+pInput->q16horz, fix16_from_int(-60), fix16_from_int(60)); @@ -1593,7 +1592,7 @@ void ProcessInput(PLAYER *pPlayer) int downAngle = -347; double lookStepUp = 4.0*upAngle/60.0; double lookStepDown = -4.0*downAngle/60.0; - if ((pInput->actions & SB_CENTERVIEW) && !pInput->syncFlags.lookUp && !pInput->syncFlags.lookDown) + if ((pInput->actions & SB_CENTERVIEW) && !pInput->actions & (SB_LOOK_UP | SB_LOOK_DOWN)) { if (pPlayer->q16look < 0) pPlayer->q16look = fix16_min(pPlayer->q16look+fix16_from_dbl(lookStepDown), fix16_from_int(0)); @@ -1604,22 +1603,22 @@ void ProcessInput(PLAYER *pPlayer) } else { - if (pInput->syncFlags.lookUp) + if (pInput->actions & (SB_LOOK_UP | SB_AIM_UP)) pPlayer->q16look = fix16_min(pPlayer->q16look+fix16_from_dbl(lookStepUp), fix16_from_int(upAngle)); - if (pInput->syncFlags.lookDown) + if (pInput->actions & (SB_LOOK_DOWN | SB_AIM_DOWN)) pPlayer->q16look = fix16_max(pPlayer->q16look-fix16_from_dbl(lookStepDown), fix16_from_int(downAngle)); } if (pPlayer == gMe && numplayers == 1) { - if (pInput->syncFlags.lookUp) + if (pInput->actions & (SB_LOOK_UP | SB_AIM_UP)) { gViewLookAdjust += float(lookStepUp); } - if (pInput->syncFlags.lookDown) + if (pInput->actions & (SB_LOOK_DOWN | SB_AIM_DOWN)) { gViewLookAdjust -= float(lookStepDown); } - gViewLookRecenter = (pInput->actions & SB_CENTERVIEW) && !pInput->syncFlags.lookUp && !pInput->syncFlags.lookDown; + gViewLookRecenter = ((pInput->actions & SB_CENTERVIEW) && !pInput->actions & (SB_LOOK_UP | SB_LOOK_DOWN)); } pPlayer->q16look = fix16_clamp(pPlayer->q16look+(pInput->q16horz<<3), fix16_from_int(downAngle), fix16_from_int(upAngle)); pPlayer->q16horiz = fix16_from_float(100.f*tanf(fix16_to_float(pPlayer->q16look)*fPI/1024.f)); diff --git a/source/blood/src/prediction.cpp b/source/blood/src/prediction.cpp index 2d8e94f79..735acde05 100644 --- a/source/blood/src/prediction.cpp +++ b/source/blood/src/prediction.cpp @@ -262,7 +262,7 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) int downAngle = -347; double lookStepUp = 4.0*upAngle/60.0; double lookStepDown = -4.0*downAngle/60.0; - if (predict.at6e && !pInput->syncFlags.lookUp && !pInput->syncFlags.lookDown) + if (predict.at6e && !pInput->actions & (SB_LOOK_UP | SB_LOOK_DOWN)) { if (predict.at20 < 0) predict.at20 = fix16_min(predict.at20+fix16_from_dbl(lookStepDown), fix16_from_int(0)); @@ -273,22 +273,22 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) } else { - if (pInput->syncFlags.lookUp) + if (pInput->actions & (SB_LOOK_UP | SB_AIM_UP)) predict.at20 = fix16_min(predict.at20+fix16_from_dbl(lookStepUp), fix16_from_int(upAngle)); - if (pInput->syncFlags.lookDown) + if (pInput->actions & (SB_LOOK_DOWN | SB_AIM_DOWN)) predict.at20 = fix16_max(predict.at20-fix16_from_dbl(lookStepDown), fix16_from_int(downAngle)); } if (numplayers > 1 && gPrediction) { - if (pInput->syncFlags.lookUp) + if (pInput->actions & (SB_LOOK_UP | SB_AIM_UP)) { gViewLookAdjust += float(lookStepUp); } - if (pInput->syncFlags.lookDown) + if (pInput->actions & (SB_LOOK_DOWN | SB_AIM_DOWN)) { gViewLookAdjust -= float(lookStepDown); } - gViewLookRecenter = predict.at6e && !pInput->syncFlags.lookUp && !pInput->syncFlags.lookDown; + gViewLookRecenter = predict.at6e && !pInput->actions & (SB_LOOK_UP | SB_LOOK_DOWN); } predict.at20 = fix16_clamp(predict.at20+(pInput->q16horz<<3), fix16_from_int(downAngle), fix16_from_int(upAngle)); predict.at24 = fix16_from_float(100.f*tanf(fix16_to_float(predict.at20)*fPI/1024.f)); diff --git a/source/core/gamecvars.h b/source/core/gamecvars.h index 173a77c6b..aaecae826 100644 --- a/source/core/gamecvars.h +++ b/source/core/gamecvars.h @@ -88,7 +88,6 @@ EXTERN_CVAR(Int, gl_ssao) EXTERN_CVAR(Bool, use_joystick) EXTERN_CVAR(Int, in_mousebias) EXTERN_CVAR(Bool, in_mouseflip) -EXTERN_CVAR(Bool, in_mousemode) EXTERN_CVAR(Bool, in_mousesmoothing) EXTERN_CVAR(Float, in_mousesensitivity) EXTERN_CVAR(Float, in_mousescalex) diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index 2c1a0270e..8d5ba3a0e 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -329,6 +329,11 @@ CCMD(holsterweapon) ActionsToSend |= SB_HOLSTER; } +CCMD(backoff) +{ + ActionsToSend |= SB_ESCAPE; +} + CCMD(pause) { sendPause = true; @@ -362,6 +367,15 @@ void ApplyGlobalInput(InputPacket& input, ControlInfo *info) input.actions |= ActionsToSend; ActionsToSend = 0; + if (buttonMap.ButtonDown(gamefunc_Aim_Up) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && info->dz > 0)) + input.actions |= SB_AIM_UP; + + if ((buttonMap.ButtonDown(gamefunc_Aim_Down) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && info->dz < 0))) + input.actions |= SB_AIM_DOWN; + + if (buttonMap.ButtonDown(gamefunc_Dpad_Aiming)) + info->dz = 0; + if (buttonMap.ButtonDown(gamefunc_Jump)) input.actions |= SB_JUMP; @@ -382,10 +396,20 @@ void ApplyGlobalInput(InputPacket& input, ControlInfo *info) if (G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run))) input.actions |= SB_RUN; + if (in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming)) + input.actions |= SB_AIMMODE; + + if (buttonMap.ButtonDown(gamefunc_Look_Up)) + input.actions |= SB_LOOK_UP; + + if (buttonMap.ButtonDown(gamefunc_Look_Down)) + input.actions |= SB_LOOK_DOWN; + + if (buttonMap.ButtonDown(gamefunc_Look_Left)) + input.actions |= SB_LOOK_LEFT; + + if (buttonMap.ButtonDown(gamefunc_Look_Right)) + input.actions |= SB_LOOK_RIGHT; + } -#if 0 - - C_RegisterFunction("backoff", nullptr, [](CCmdFuncPtr)->int { BitsToSend |= SKB_ESCAPE; return CCMD_OK; }); - -#endif diff --git a/source/core/packet.h b/source/core/packet.h index 0097f5df1..7b4308f09 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -23,6 +23,18 @@ enum ESyncBits_ : uint32_t SB_HOLSTER = 1 << 16, SB_OPEN = 1 << 17, + SB_AIMMODE = 1 << 18, + + SB_AIM_UP = 1 << 19, + SB_AIM_DOWN = 1 << 20, + SB_LOOK_LEFT = 1 << 21, + SB_LOOK_RIGHT = 1 << 22, + SB_QUICK_KICK = 1 << 23, // Duke only. + SB_CROUCH_LOCK = 1 << 23, // SW only. + SB_ESCAPE = 1 << 24, + + SB_LOOK_UP = 1 << 25, + SB_LOOK_DOWN = 1 << 26, SB_RUN = 1 << 27, SB_JUMP = 1 << 28, SB_CROUCH = 1 << 29, @@ -33,7 +45,7 @@ enum ESyncBits_ : uint32_t SB_ITEMUSE_BITS = (127u * SB_ITEM_BIT_1), SB_BUTTON_MASK = SB_ALTFIRE|SB_FIRE|SB_CROUCH|SB_JUMP, // all input from buttons (i.e. active while held) - SB_INTERFACE_MASK = (SB_INVPREV|SB_INVNEXT|SB_INVUSE|SB_CENTERVIEW|SB_TURNAROUND|SB_HOLSTER|SB_OPEN), // all input from CCMDs + SB_INTERFACE_MASK = (SB_INVPREV|SB_INVNEXT|SB_INVUSE|SB_CENTERVIEW|SB_TURNAROUND|SB_HOLSTER|SB_OPEN|SB_ESCAPE|SB_QUICK_KICK), // all input from CCMDs SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS | SB_ITEMUSE_BITS | SB_INTERFACE_MASK), SB_ALL = ~0u }; @@ -43,14 +55,6 @@ using ESyncBits = TFlags; DEFINE_TFLAGS_OPERATORS(ESyncBits) -// Blood flags -enum -{ - flag_buttonmask = 127, - flag_buttonmask_norun = 126 -}; - - enum { // The maximum valid weapons for the respective games. @@ -65,67 +69,6 @@ enum WeaponSel_Alt = 15 }; -enum EDukeSyncBits_ : uint32_t -{ - SKB_AIM_UP = 1 << 3, - SKB_AIM_DOWN = 1 << 4, - SKB_LOOK_LEFT = 1 << 6, - SKB_LOOK_RIGHT = 1 << 7, - SKB_LOOK_UP = 1 << 13, - SKB_LOOK_DOWN = 1 << 14, - SKB_QUICK_KICK = 1 << 22, - SKB_AIMMODE = 1 << 23, - SKB_ESCAPE = 1u << 31, - - SKB_INTERFACE_BITS = (SKB_QUICK_KICK | \ - SKB_ESCAPE), - - SKB_NONE = 0, - SKB_ALL = ~0u - -}; - -// enforce type safe operations on the input bits. -using EDukeSyncBits = TFlags; -DEFINE_TFLAGS_OPERATORS(EDukeSyncBits) - -union SYNCFLAGS -{ - uint32_t value; - struct - { - unsigned int _run : 1; - unsigned int _jump : 1; - unsigned int _crouch : 1; - unsigned int _shoot : 1; - unsigned int _shoot2 : 1; - unsigned int lookUp : 1; - unsigned int lookDown : 1; - - - unsigned int lookLeft : 1; - unsigned int lookRight : 1; - }; -}; - -// SW - -// -// NETWORK - REDEFINABLE SHARED (SYNC) KEYS BIT POSITIONS -// - - -#define SK_LOOK_UP 12 -#define SK_LOOK_DOWN 13 -#define SK_CRAWL_LOCK 14 -#define SK_FLY 15 - -#define SK_AIM_UP 21 -#define SK_AIM_DOWN 22 - -#define SK_SPACE_BAR 31 - - struct InputPacket { int16_t svel; @@ -136,18 +79,6 @@ struct InputPacket fix16_t q16ang; // only used by SW ESyncBits actions; - // Making this a union lets some constructs fail. Since these names are transitional only the added memory use doesn't really matter. - // for Duke - EDukeSyncBits sbits; - - // for SW - int32_t bits; - - // for Blood - SYNCFLAGS syncFlags; - - // For Exhumed - uint16_t buttons; int getNewWeapon() const { diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index 0c04a6db9..ed84b54d4 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -31,8 +31,6 @@ BEGIN_PS_NS extern short bPlayerPan; extern short bLockPan; -bool g_MyAimMode; - short nInputStack = 0; short bStackNode[kMaxPlayers]; @@ -158,12 +156,12 @@ void PlayerInterruptKeys(bool after) if (paused) return; - localInput = {}; - InputPacket input{}; + InputPacket tempinput{}; fix16_t input_angle = 0; if (PlayerList[nLocalPlayer].nHealth == 0) { + localInput = {}; lPlayerYVel = 0; lPlayerXVel = 0; nPlayerDAng = 0; @@ -172,6 +170,7 @@ void PlayerInterruptKeys(bool after) if (!after) { + localInput = {}; ApplyGlobalInput(localInput, &info); if (PlayerList[nLocalPlayer].nHealth == 0) localInput.actions &= ~(SB_FIRE | SB_JUMP | SB_CROUCH); } @@ -184,8 +183,8 @@ void PlayerInterruptKeys(bool after) if (buttonMap.ButtonDown(gamefunc_Strafe)) { - input.svel -= info.mousex * 4.f; - input.svel -= info.dyaw * keyMove; + tempinput.svel -= info.mousex * 4.f; + tempinput.svel -= info.dyaw * keyMove; } else { @@ -193,26 +192,26 @@ void PlayerInterruptKeys(bool after) input_angle = fix16_sadd(input_angle, fix16_from_dbl(scaleAdjustmentToInterval(info.dyaw))); } - g_MyAimMode = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); + bool mouseaim = !!(localInput.actions & SB_AIMMODE); - if (g_MyAimMode) - input.q16horz = fix16_sadd(input.q16horz, fix16_from_float(info.mousey)); + if (mouseaim) + tempinput.q16horz = fix16_sadd(tempinput.q16horz, fix16_from_float(info.mousey)); else - input.fvel -= info.mousey * 8.f; + tempinput.fvel -= info.mousey * 8.f; - if (!in_mouseflip) input.q16horz = -input.q16horz; + if (!in_mouseflip) tempinput.q16horz = -tempinput.q16horz; - input.q16horz = fix16_ssub(input.q16horz, fix16_from_dbl(scaleAdjustmentToInterval(info.dpitch))); - input.svel -= info.dx * keyMove; - input.fvel -= info.dz * keyMove; + tempinput.q16horz = fix16_ssub(tempinput.q16horz, fix16_from_dbl(scaleAdjustmentToInterval(info.dpitch))); + tempinput.svel -= info.dx * keyMove; + tempinput.fvel -= info.dz * keyMove; if (buttonMap.ButtonDown(gamefunc_Strafe)) { if (buttonMap.ButtonDown(gamefunc_Turn_Left)) - input.svel -= -keyMove; + tempinput.svel -= -keyMove; if (buttonMap.ButtonDown(gamefunc_Turn_Right)) - input.svel -= keyMove; + tempinput.svel -= keyMove; } else { @@ -254,19 +253,19 @@ void PlayerInterruptKeys(bool after) } if (buttonMap.ButtonDown(gamefunc_Strafe_Left)) - input.svel += keyMove; + tempinput.svel += keyMove; if (buttonMap.ButtonDown(gamefunc_Strafe_Right)) - input.svel += -keyMove; + tempinput.svel += -keyMove; if (buttonMap.ButtonDown(gamefunc_Move_Forward)) - input.fvel += keyMove; + tempinput.fvel += keyMove; if (buttonMap.ButtonDown(gamefunc_Move_Backward)) - input.fvel += -keyMove; + tempinput.fvel += -keyMove; - localInput.fvel = clamp(localInput.fvel + input.fvel, -12, 12); - localInput.svel = clamp(localInput.svel + input.svel, -12, 12); + localInput.fvel = clamp(localInput.fvel + tempinput.fvel, -12, 12); + localInput.svel = clamp(localInput.svel + tempinput.svel, -12, 12); localInput.q16avel = fix16_sadd(localInput.q16avel, input_angle); @@ -277,11 +276,11 @@ void PlayerInterruptKeys(bool after) // A horiz diff of 128 equal 45 degrees, // so we convert horiz to 1024 angle units - float const horizAngle = clamp(atan2f(PlayerList[nLocalPlayer].q16horiz - fix16_from_int(92), fix16_from_int(128)) * (512.f / fPI) + fix16_to_float(input.q16horz), -255.f, 255.f); + float const horizAngle = clamp(atan2f(PlayerList[nLocalPlayer].q16horiz - fix16_from_int(92), fix16_from_int(128)) * (512.f / fPI) + fix16_to_float(tempinput.q16horz), -255.f, 255.f); PlayerList[nLocalPlayer].q16horiz = fix16_from_int(92) + Blrintf(fix16_from_int(128) * tanf(horizAngle * (fPI / 512.f))); // Look/aim up/down functions. - if (buttonMap.ButtonDown(gamefunc_Look_Up) || buttonMap.ButtonDown(gamefunc_Aim_Up)) + if (localInput.actions & (SB_LOOK_UP|SB_AIM_UP)) { bLockPan = false; if (PlayerList[nLocalPlayer].q16horiz < fix16_from_int(180)) { @@ -291,7 +290,7 @@ void PlayerInterruptKeys(bool after) bPlayerPan = true; nDestVertPan[nLocalPlayer] = PlayerList[nLocalPlayer].q16horiz; } - else if (buttonMap.ButtonDown(gamefunc_Look_Down) || buttonMap.ButtonDown(gamefunc_Aim_Down)) + else if (localInput.actions & (SB_LOOK_DOWN|SB_AIM_DOWN)) { bLockPan = false; if (PlayerList[nLocalPlayer].q16horiz > fix16_from_int(4)) { @@ -308,13 +307,13 @@ void PlayerInterruptKeys(bool after) bPlayerPan = false; } - if (g_MyAimMode) + if (mouseaim) bLockPan = true; // loc_1C05E fix16_t ecx = nDestVertPan[nLocalPlayer] - PlayerList[nLocalPlayer].q16horiz; - if (g_MyAimMode) + if (mouseaim) { ecx = 0; } diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 5621a1127..5cb8e16bf 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -110,12 +110,12 @@ int makepainsounds(int snum, int type); void playerCrouch(int snum); void playerJump(int snum, int fz, int cz); void applylook(int snum, double factor, fixed_t adjustment); -void checklook(int snum, int sb_snum); +void checklook(int snum, ESyncBits actions); void playerCenterView(int snum); -void playerLookUp(int snum, ESyncBits sb_snum); -void playerLookDown(int snum, ESyncBits sb_snum); -void playerAimUp(int snum, ESyncBits sb_snum); -void playerAimDown(int snum, ESyncBits sb_snum); +void playerLookUp(int snum, ESyncBits actions); +void playerLookDown(int snum, ESyncBits actions); +void playerAimUp(int snum, ESyncBits actions); +void playerAimDown(int snum, ESyncBits actions); bool view(struct player_struct* pp, int* vx, int* vy, int* vz, short* vsectnum, int ang, int horiz); void tracers(int x1, int y1, int z1, int x2, int y2, int z2, int n); int hits(int i); @@ -232,7 +232,7 @@ void PlayerColorChanged(void); void nonsharedkeys(void); void apply_seasick(player_struct* p, double scalefactor); void calcviewpitch(player_struct* p, double factor); -void sethorizon(int snum, int sb_snum, double factor, fixed_t adjustment); +void sethorizon(int snum, ESyncBits actions, double factor, fixed_t adjustment); bool movementBlocked(int snum); void GetInput(); void startmainmenu(); diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index ec03613aa..a4f8fae52 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -116,26 +116,6 @@ inline bool isIn(int value, const std::initializer_list& list) // these are mainly here to avoid directly accessing the input data so that it can be more easily refactored later. -inline bool PlayerInput(int pl, EDukeSyncBits bit) -{ - return (!!((sync[pl].sbits) & bit)); -} - -inline void PlayerSetInput(int pl, EDukeSyncBits bit) -{ - sync[pl].sbits |= bit; -} - -inline void PlayerClearInput(int pl, EDukeSyncBits bit) -{ - sync[pl].sbits &= ~bit; -} - -inline EDukeSyncBits PlayerInputBits(int pl, EDukeSyncBits bits) -{ - return (sync[pl].sbits & bits); -} - inline bool PlayerInput(int pl, ESyncBits bit) { return (!!((sync[pl].actions) & bit)); diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 760b98d42..ef50282bb 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -150,7 +150,7 @@ void hud_input(int snum) p = &ps[snum]; i = p->aim_mode; - p->aim_mode = PlayerInput(snum, SKB_AIMMODE); + p->aim_mode = PlayerInput(snum, SB_AIMMODE); if (p->aim_mode < i) p->return_to_center = 9; @@ -159,7 +159,7 @@ void hud_input(int snum) if (isRR()) { - if (PlayerInput(snum, SKB_QUICK_KICK) && p->last_pissed_time == 0) + if (PlayerInput(snum, SB_QUICK_KICK) && p->last_pissed_time == 0) { if (!isRRRA() || sprite[p->i].extra > 0) { @@ -177,7 +177,7 @@ void hud_input(int snum) } else { - if (PlayerInput(snum, SKB_QUICK_KICK) && p->quick_kick == 0 && (p->curr_weapon != KNEE_WEAPON || p->kickback_pic == 0)) + if (PlayerInput(snum, SB_QUICK_KICK) && p->quick_kick == 0 && (p->curr_weapon != KNEE_WEAPON || p->kickback_pic == 0)) { SetGameVarID(g_iReturnVarID, 0, -1, snum); OnEvent(EVENT_QUICKKICK, -1, snum, -1); @@ -189,9 +189,9 @@ void hud_input(int snum) } } } - if (!PlayerInput(snum, SKB_QUICK_KICK)) p->quick_kick_msg = false; + if (!PlayerInput(snum, SB_QUICK_KICK)) p->quick_kick_msg = false; - if (!PlayerInputBits(snum, SKB_INTERFACE_BITS) && ! PlayerInputBits(snum, SB_INTERFACE_BITS)) + if (!PlayerInputBits(snum, SB_INTERFACE_BITS)) p->interface_toggle_flag = 0; else if (p->interface_toggle_flag == 0) { @@ -606,38 +606,27 @@ enum static void processInputBits(player_struct *p, ControlInfo &info) { - bool onVehicle = p->OnMotorcycle || p->OnBoat; + ApplyGlobalInput(loc, &info); + if (isRR() && (loc.actions & SB_CROUCH)) loc.actions &= ~SB_JUMP; - if (!onVehicle) + if (p->OnMotorcycle || p->OnBoat) { + // mask out all actions not compatible with vehicles. + loc.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH | SB_RUN | + SB_AIM_UP | SB_AIM_DOWN | SB_AIMMODE | SB_LOOK_UP | SB_LOOK_DOWN | SB_LOOK_LEFT | SB_LOOK_RIGHT); + } + else + { + if (buttonMap.ButtonDown(gamefunc_Quick_Kick)) // this shares a bit with another function so cannot be in the common code. + loc.actions |= SB_QUICK_KICK; + if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch) || p->crouch_toggle) { loc.actions |= SB_CROUCH; } - if (buttonMap.ButtonDown(gamefunc_Aim_Up) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && info.dz > 0)) loc.sbits |= SKB_AIM_UP; - if ((buttonMap.ButtonDown(gamefunc_Aim_Down) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && info.dz < 0))) loc.sbits |= SKB_AIM_DOWN; - if (buttonMap.ButtonDown(gamefunc_Look_Left)) loc.sbits |= SKB_LOOK_LEFT; - if (buttonMap.ButtonDown(gamefunc_Look_Right)) loc.sbits |= SKB_LOOK_RIGHT; - if (buttonMap.ButtonDown(gamefunc_Look_Up)) loc.sbits |= SKB_LOOK_UP; - if (buttonMap.ButtonDown(gamefunc_Look_Down)) loc.sbits |= SKB_LOOK_DOWN; - if (buttonMap.ButtonDown(gamefunc_Quick_Kick)) loc.sbits |= SKB_QUICK_KICK; - if (in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming)) loc.sbits |= SKB_AIMMODE; - - if ((isRR() && p->drink_amt > 88)) loc.sbits |= SKB_LOOK_LEFT; - if ((isRR() && p->drink_amt > 99)) loc.sbits |= SKB_LOOK_DOWN; - + if ((isRR() && p->drink_amt > 88)) loc.actions |= SB_LOOK_LEFT; + if ((isRR() && p->drink_amt > 99)) loc.actions |= SB_LOOK_DOWN; } - ApplyGlobalInput(loc, &info); - if (isRR() && (loc.actions & SB_CROUCH)) loc.actions &= ~SB_JUMP; - - if (onVehicle) - { - // mask out all actions not compatible with vehicles. - loc.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH | SB_RUN); - } - - if (buttonMap.ButtonDown(gamefunc_Dpad_Aiming)) - info.dz = 0; } //--------------------------------------------------------------------------- @@ -684,7 +673,7 @@ int getticssincelastupdate() static void processMovement(player_struct *p, InputPacket &input, ControlInfo &info, double scaleFactor) { - bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); + bool mouseaim = !!(loc.actions & SB_AIMMODE); // JBF: Run key behaviour is selectable int running = !!(loc.actions & SB_RUN); @@ -980,15 +969,15 @@ static void processVehicleInput(player_struct *p, ControlInfo& info, InputPacket if (buttonMap.ButtonDown(gamefunc_Move_Forward) || buttonMap.ButtonDown(gamefunc_Strafe)) loc.actions |= SB_JUMP; if (buttonMap.ButtonDown(gamefunc_Move_Backward)) - loc.sbits |= SKB_AIM_UP; - if (loc.buttons & SB_RUN) + loc.actions |= SB_AIM_UP; + if (loc.actions & SB_RUN) loc.actions |= SB_CROUCH; } if (turnl) - loc.sbits |= SKB_AIM_DOWN; + loc.actions |= SB_AIM_DOWN; if (turnr) - loc.sbits |= SKB_LOOK_LEFT; + loc.actions |= SB_LOOK_LEFT; double turnvel; @@ -1136,7 +1125,7 @@ void GetInput() // Do these in the same order as the old code. calcviewpitch(p, scaleAdjust); applylook(myconnectindex, scaleAdjust, input.q16avel); - sethorizon(myconnectindex, loc.sbits, scaleAdjust, input.q16horz); + sethorizon(myconnectindex, loc.actions, scaleAdjust, input.q16horz); } } diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index 3d26c81f1..a10df4c78 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -968,13 +968,13 @@ void playerweaponsway(player_struct* p, spritetype* s) // //--------------------------------------------------------------------------- -void checklook(int snum, int sb_snum) +void checklook(int snum, ESyncBits actions) { auto p = &ps[snum]; p->lookLeft = false; p->lookRight = false; - if ((sb_snum & SKB_LOOK_LEFT) && !p->OnMotorcycle) + if ((actions & SB_LOOK_LEFT) && !p->OnMotorcycle) { SetGameVarID(g_iReturnVarID, 0, p->i, snum); OnEvent(EVENT_LOOKLEFT, p->i, snum, -1); @@ -984,7 +984,7 @@ void checklook(int snum, int sb_snum) } } - if ((sb_snum & SKB_LOOK_RIGHT) && !p->OnMotorcycle) + if ((actions & SB_LOOK_RIGHT) && !p->OnMotorcycle) { SetGameVarID(g_iReturnVarID, 0, p->i, snum); OnEvent(EVENT_LOOKRIGHT, p->i, snum, -1); @@ -1002,14 +1002,14 @@ void checklook(int snum, int sb_snum) // //--------------------------------------------------------------------------- -void sethorizon(int snum, int sb_snum, double factor, fixed_t adjustment) +void sethorizon(int snum, ESyncBits actions, double factor, fixed_t adjustment) { auto p = &ps[snum]; // Calculate adjustment as true pitch (Fixed point math really sucks...) double horizAngle = clamp2(atan2(p->q16horiz - F16(100), F16(128)) * (512. / pi::pi()) + (factor * p->pitchAdjust) + (adjustment / 65536.), -180, 180); - if (p->return_to_center > 0 && (sb_snum & (SKB_LOOK_UP | SKB_LOOK_DOWN)) == 0) // only snap back if no relevant button is pressed. + if (p->return_to_center > 0 && (actions & (SB_LOOK_UP | SB_LOOK_DOWN)) == 0) // only snap back if no relevant button is pressed. { p->return_to_center += -factor * (p->return_to_center / 2); horizAngle += -factor * (horizAngle / 2); diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 8d44d5b7b..79a952f8c 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -41,7 +41,7 @@ source as it is released. BEGIN_DUKE_NS void fireweapon_ww(int snum); -void operateweapon_ww(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect); +void operateweapon_ww(int snum, ESyncBits actions, int psect); //--------------------------------------------------------------------------- // @@ -2073,7 +2073,7 @@ static void fireweapon(int snum) // //--------------------------------------------------------------------------- -static void operateweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect) +static void operateweapon(int snum, ESyncBits actions, int psect) { auto p = &ps[snum]; int pi = p->i; @@ -2529,7 +2529,7 @@ static void operateweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, in // //--------------------------------------------------------------------------- -static void processweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect) +static void processweapon(int snum, ESyncBits actions, int psect) { auto p = &ps[snum]; int pi = p->i; @@ -2600,8 +2600,8 @@ static void processweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, in } else if (p->kickback_pic) { - if (!isWW2GI()) operateweapon(snum, actions, sb_snum, psect); - else operateweapon_ww(snum, actions, sb_snum, psect); + if (!isWW2GI()) operateweapon(snum, actions, psect); + else operateweapon_ww(snum, actions, psect); } } //--------------------------------------------------------------------------- @@ -2614,7 +2614,6 @@ void processinput_d(int snum) { int j, i, k, doubvel, fz, cz, hz, lz, truefdist; char shrunk; - EDukeSyncBits sb_snum; ESyncBits actions; short psect, psectlotag, pi; struct player_struct* p; @@ -2626,7 +2625,6 @@ void processinput_d(int snum) resetinputhelpers(p); - sb_snum = PlayerInputBits(snum, SKB_ALL); actions = PlayerInputBits(snum, SB_ALL); auto sb_fvel = PlayerInputForwardVel(snum); @@ -2750,14 +2748,14 @@ void processinput_d(int snum) fi.doincrements(p); - if (isWW2GI() && aplWeaponWorksLike[p->curr_weapon][snum] == HANDREMOTE_WEAPON) processweapon(snum, actions, sb_snum, psect); - if (!isWW2GI() && p->curr_weapon == HANDREMOTE_WEAPON) processweapon(snum, actions, sb_snum, psect); + if (isWW2GI() && aplWeaponWorksLike[p->curr_weapon][snum] == HANDREMOTE_WEAPON) processweapon(snum, actions, psect); + if (!isWW2GI() && p->curr_weapon == HANDREMOTE_WEAPON) processweapon(snum, actions, psect); return; } doubvel = TICSPERFRAME; - checklook(snum,sb_snum); + checklook(snum,actions); if (p->on_crane >= 0) goto HORIZONLY; @@ -3016,26 +3014,26 @@ HORIZONLY: { playerCenterView(snum); } - else if (sb_snum & SKB_LOOK_UP) + else if (actions & SB_LOOK_UP) { playerLookUp(snum, actions); } - else if (sb_snum & SKB_LOOK_DOWN) + else if (actions & SB_LOOK_DOWN) { playerLookDown(snum, actions); } - else if (sb_snum & SKB_AIM_UP) + else if (actions & SB_AIM_UP) { playerAimUp(snum, actions); } - else if (sb_snum & SKB_AIM_DOWN) + else if (actions & SB_AIM_DOWN) { // aim_down playerAimDown(snum, actions); } if (cl_syncinput) { - sethorizon(snum, sb_snum, 1, sync[snum].q16horz); + sethorizon(snum, actions, 1, sync[snum].q16horz); } checkhardlanding(p); @@ -3077,7 +3075,7 @@ HORIZONLY: } // HACKS - processweapon(snum, actions, sb_snum, psect); + processweapon(snum, actions, psect); } void processmove_d(int snum, ESyncBits actions, int psect, int fz, int cz, int shrunk, int truefdist) diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index ebe7d4748..c3ae51519 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -1542,7 +1542,7 @@ void checkweapons_r(struct player_struct* p) // //--------------------------------------------------------------------------- -static void onMotorcycle(int snum, ESyncBits &actions, EDukeSyncBits &sb_snum) +static void onMotorcycle(int snum, ESyncBits &actions) { auto p = &ps[snum]; auto pi = p->i; @@ -1605,29 +1605,29 @@ static void onMotorcycle(int snum, ESyncBits &actions, EDukeSyncBits &sb_snum) if (!S_CheckActorSoundPlaying(pi, 189) && !S_CheckActorSoundPlaying(pi, 187)) S_PlayActorSound(187, pi); } - if (sb_snum & SKB_AIM_UP) + if (actions & SB_AIM_UP) { var6c = 1; - sb_snum &= ~SKB_AIM_UP; + actions &= ~SB_AIM_UP; } else var6c = 0; - if (sb_snum & SKB_AIM_DOWN) + if (actions & SB_AIM_DOWN) { var70 = 1; var74 = 1; - sb_snum &= ~SKB_AIM_DOWN; + actions &= ~SB_AIM_DOWN; } else { var70 = 0; var74 = 0; } - if (sb_snum & SKB_LOOK_LEFT) + if (actions & SB_LOOK_LEFT) { var78 = 1; var7c = 1; - sb_snum &= ~SKB_LOOK_LEFT; + actions &= ~SB_LOOK_LEFT; } else { @@ -1835,7 +1835,7 @@ static void onMotorcycle(int snum, ESyncBits &actions, EDukeSyncBits &sb_snum) // //--------------------------------------------------------------------------- -static void onBoat(int snum, ESyncBits &actions, EDukeSyncBits& sb_snum) +static void onBoat(int snum, ESyncBits &actions) { auto p = &ps[snum]; auto pi = p->i; @@ -1908,17 +1908,17 @@ static void onBoat(int snum, ESyncBits &actions, EDukeSyncBits& sb_snum) } else varb0 = 0; - if (sb_snum & SKB_AIM_UP) + if (actions & SB_AIM_UP) { varb4 = 1; - sb_snum &= ~SKB_AIM_UP; + actions &= ~SB_AIM_UP; } else varb4 = 0; - if (sb_snum & SKB_AIM_DOWN) + if (actions & SB_AIM_DOWN) { varb8 = 1; varbc = 1; - sb_snum &= ~SKB_AIM_DOWN; + actions &= ~SB_AIM_DOWN; if (!S_CheckActorSoundPlaying(pi, 91) && p->MotoSpeed > 30 && !p->NotOnWater) S_PlayActorSound(91, pi); } @@ -1927,11 +1927,11 @@ static void onBoat(int snum, ESyncBits &actions, EDukeSyncBits& sb_snum) varb8 = 0; varbc = 0; } - if (sb_snum & SKB_LOOK_LEFT) + if (actions & SB_LOOK_LEFT) { varc0 = 1; varc4 = 1; - sb_snum &= ~SKB_LOOK_LEFT; + actions &= ~SB_LOOK_LEFT; if (!S_CheckActorSoundPlaying(pi, 91) && p->MotoSpeed > 30 && !p->NotOnWater) S_PlayActorSound(91, pi); } @@ -2119,7 +2119,7 @@ static void onBoat(int snum, ESyncBits &actions, EDukeSyncBits& sb_snum) // //--------------------------------------------------------------------------- -static void movement(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist, int psectlotag) +static void movement(int snum, ESyncBits actions, int psect, int fz, int cz, int shrunk, int truefdist, int psectlotag) { auto p = &ps[snum]; auto pi = p->i; @@ -2349,7 +2349,7 @@ static void movement(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int pse // //--------------------------------------------------------------------------- -static void underwater(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect, int fz, int cz) +static void underwater(int snum, ESyncBits actions, int psect, int fz, int cz) { int j; auto p = &ps[snum]; @@ -2773,7 +2773,7 @@ static void fireweapon(int snum) // //--------------------------------------------------------------------------- -static void operateweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect) +static void operateweapon(int snum, ESyncBits actions, int psect) { auto p = &ps[snum]; int pi = p->i; @@ -3365,7 +3365,7 @@ static void operateweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, in // //--------------------------------------------------------------------------- -static void processweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect) +static void processweapon(int snum, ESyncBits actions, int psect) { auto p = &ps[snum]; int pi = p->i; @@ -3416,7 +3416,7 @@ static void processweapon(int snum, ESyncBits actions, EDukeSyncBits sb_snum, in } else if (p->kickback_pic) { - operateweapon(snum, actions, sb_snum, psect); + operateweapon(snum, actions, psect); } } @@ -3430,7 +3430,6 @@ void processinput_r(int snum) { int j, i, k, doubvel, fz, cz, hz, lz, truefdist, var60; char shrunk; - EDukeSyncBits sb_snum; ESyncBits actions; short psect, psectlotag, pi; struct player_struct* p; @@ -3442,7 +3441,6 @@ void processinput_r(int snum) resetinputhelpers(p); - sb_snum = PlayerInputBits(snum, SKB_ALL); actions = PlayerInputBits(snum, SB_ALL); auto sb_fvel = PlayerInputForwardVel(snum); @@ -3452,11 +3450,11 @@ void processinput_r(int snum) psect = p->cursectnum; if (p->OnMotorcycle && s->extra > 0) { - onMotorcycle(snum, actions, sb_snum); + onMotorcycle(snum, actions); } else if (p->OnBoat && s->extra > 0) { - onBoat(snum, actions, sb_snum); + onBoat(snum, actions); } if (psect == -1) { @@ -3663,13 +3661,13 @@ void processinput_r(int snum) fi.doincrements(p); - if (p->curr_weapon == THROWINGDYNAMITE_WEAPON) processweapon(snum, actions, sb_snum, psect); + if (p->curr_weapon == THROWINGDYNAMITE_WEAPON) processweapon(snum, actions, psect); return; } doubvel = TICSPERFRAME; - checklook(snum, sb_snum); + checklook(snum, actions); if (p->on_crane >= 0) goto HORIZONLY; @@ -3709,11 +3707,11 @@ void processinput_r(int snum) if (psectlotag == ST_2_UNDERWATER) { - underwater(snum, actions, sb_snum, psect, fz, cz); + underwater(snum, actions, psect, fz, cz); } else { - movement(snum, actions, sb_snum, psect, fz, cz, shrunk, truefdist, psectlotag); + movement(snum, actions, psect, fz, cz, shrunk, truefdist, psectlotag); } p->psectlotag = psectlotag; @@ -4060,19 +4058,19 @@ HORIZONLY: { playerCenterView(snum); } - else if (sb_snum & SKB_LOOK_UP) + else if (actions & SB_LOOK_UP) { playerLookUp(snum, actions); } - else if (sb_snum & SKB_LOOK_DOWN) + else if (actions & SB_LOOK_DOWN) { playerLookDown(snum, actions); } - else if ((sb_snum & SKB_AIM_UP) && !p->OnMotorcycle) + else if ((actions & SB_AIM_UP) && !p->OnMotorcycle) { playerAimUp(snum, actions); } - else if ((sb_snum & SKB_AIM_DOWN) && !p->OnMotorcycle) + else if ((actions & SB_AIM_DOWN) && !p->OnMotorcycle) { playerAimDown(snum, actions); } @@ -4087,7 +4085,7 @@ HORIZONLY: if (cl_syncinput) { - sethorizon(snum, sb_snum, 1, sync[snum].q16horz); + sethorizon(snum, actions, 1, sync[snum].q16horz); } checkhardlanding(p); @@ -4123,7 +4121,7 @@ HORIZONLY: else p->weapon_pos--; } - processweapon(snum, actions, sb_snum, psect); + processweapon(snum, actions, psect); } //--------------------------------------------------------------------------- @@ -4132,17 +4130,17 @@ HORIZONLY: // //--------------------------------------------------------------------------- -void processmove_r(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect, int fz, int cz, int shrunk, int truefdist) +void processmove_r(int snum, ESyncBits actions, int psect, int fz, int cz, int shrunk, int truefdist) { int psectlotag = sector[psect].lotag; auto p = &ps[snum]; if (psectlotag == ST_2_UNDERWATER) { - underwater(snum, actions, sb_snum, psect, fz, cz); + underwater(snum, actions, psect, fz, cz); } else { - movement(snum, actions, sb_snum, psect, fz, cz, shrunk, truefdist, psectlotag); + movement(snum, actions, psect, fz, cz, shrunk, truefdist, psectlotag); } } diff --git a/source/games/duke/src/player_w.cpp b/source/games/duke/src/player_w.cpp index 031334a14..08e7beed0 100644 --- a/source/games/duke/src/player_w.cpp +++ b/source/games/duke/src/player_w.cpp @@ -306,7 +306,7 @@ void fireweapon_ww(int snum) // //--------------------------------------------------------------------------- -void operateweapon_ww(int snum, ESyncBits actions, EDukeSyncBits sb_snum, int psect) +void operateweapon_ww(int snum, ESyncBits actions, int psect) { auto p = &ps[snum]; int pi = p->i; diff --git a/source/games/duke/src/prediction.cpp b/source/games/duke/src/prediction.cpp index c96fa5431..48b8ff00b 100644 --- a/source/games/duke/src/prediction.cpp +++ b/source/games/duke/src/prediction.cpp @@ -98,14 +98,15 @@ void fakedomovethingscorrect(void) } +// This still needs fixing for the magic numbers in the input bits void fakedomovethings(void) { input *syn; struct player_struct *p; int i, j, k, doubvel, fz, cz, hz, lz, x, y; - EDukeSyncBits sb_snum; short psect, psectlotag, tempsect, backcstat; uint8_t shrunk, spritebridge; + ESyncBits actions; syn = (input *)&inputfifo[fakemovefifoplc&(MOVEFIFOSIZ-1)][myconnectindex]; @@ -114,7 +115,7 @@ void fakedomovethings(void) backcstat = sprite[p->i].cstat; sprite[p->i].cstat &= ~257; - sb_snum = syn->bits; + actions = syn->actions; psect = mycursectnum; psectlotag = sector[psect].lotag; diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index d03d3fda7..d7cc97477 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -1532,13 +1532,13 @@ void checksectors_d(int snum) } } - if (!(PlayerInput(snum, SB_OPEN)) && !PlayerInput(snum, SKB_ESCAPE)) + if (!(PlayerInput(snum, SB_OPEN))) p->toggle_key_flag = 0; else if (!p->toggle_key_flag) { - if (PlayerInput(snum, SKB_ESCAPE)) + if (PlayerInput(snum, SB_ESCAPE)) { if (p->newowner >= 0) { diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index 7430e9bfa..42ec2f645 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -2488,7 +2488,7 @@ void checksectors_r(int snum) fi.lotsofmoney(&sprite[p->i], 2); - if (!(PlayerInput(snum, SB_OPEN)) && !PlayerInput(snum, SKB_ESCAPE)) + if (!(PlayerInput(snum, SB_OPEN))) p->toggle_key_flag = 0; else if (!p->toggle_key_flag) diff --git a/source/sw/src/eel.cpp b/source/sw/src/eel.cpp index 6fdfe6acb..a93787e83 100644 --- a/source/sw/src/eel.cpp +++ b/source/sw/src/eel.cpp @@ -616,9 +616,6 @@ int DoEelMove(short SpriteNum) else (*u->ActorActionFunc)(SpriteNum); - //if (TEST_SYNC_KEY((Player+myconnectindex), SK_OPERATE)) - // CON_Message("Stop"); - DoEelMatchPlayerZ(SpriteNum); DoActorSectorDamage(SpriteNum); diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 8f68ac82e..7b44571cf 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -255,17 +255,6 @@ extern SWBOOL MenuInputMode; #define SectorIsDiveArea(sect) (TEST(sector[sect].extra, SECTFX_DIVE_AREA) ? TRUE : FALSE) #define SectorIsUnderwaterArea(sect) (TEST(sector[sect].extra, SECTFX_UNDERWATER|SECTFX_UNDERWATER2) ? TRUE : FALSE) -// Key Press Flags macros -#define FLAG_KEY_PRESSED(pp,sync_key) TEST(pp->KeyPressFlags,1<KeyPressFlags,1<KeyPressFlags,1<input.bits, ((!!(key_test)) << (sync_num))) -#define TEST_SYNC_KEY(player, sync_num) TEST((player)->input.bits, (1 << (sync_num))) -#define RESET_SYNC_KEY(player, sync_num) RESET((player)->input.bits, (1 << (sync_num))) - #define TRAVERSE_SPRITE_SECT(l, o, n) for ((o) = (l); (n) = (o) == -1 ? -1 : nextspritesect[o], (o) != -1; (o) = (n)) #define TRAVERSE_SPRITE_STAT(l, o, n) for ((o) = (l); (n) = (o) == -1 ? -1 : nextspritestat[o], (o) != -1; (o) = (n)) #define TRAVERSE_CONNECT(i) for (i = connecthead; i != -1; i = connectpoint2[i]) @@ -916,6 +905,7 @@ struct PLAYERstruct // variables that do not fit into sprite structure int hvel,tilt,tilt_dest; + bool centering; fix16_t q16horiz, q16horizbase, q16horizoff, q16ang; fix16_t camq16horiz, camq16ang; short recoil_amt; @@ -967,7 +957,6 @@ struct PLAYERstruct PLAYER_ACTION_FUNCp DoPlayerAction; int Flags, Flags2; ESyncBits KeyPressBits; - int KeyPressFlags; SECTOR_OBJECTp sop_control; // sector object pointer SECTOR_OBJECTp sop_riding; // sector object pointer diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index 1848cadc6..fcb3caac9 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -113,7 +113,37 @@ getinput(InputPacket *loc, SWBOOL tied) lastInputTicks = currentHiTicks; - bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); + ControlInfo info; + CONTROL_GetInput(&info); + + if (paused) + return; + + // If in 2D follow mode, scroll around using glob vars + // Tried calling this in domovethings, but key response it too poor, skips key presses + // Note: this get called only during follow mode + if (!tied && automapFollow && automapMode != am_off && pp == Player + myconnectindex && !Prediction) + MoveScrollMode2D(Player + myconnectindex); + + // !JIM! Added M_Active() so that you don't move at all while using menus + if (M_Active() || automapFollow) + return; + + int32_t turnamount; + int32_t keymove; + + // The function DoPlayerTurn() scales the player's q16angvel by 1.40625, so store as constant + // and use to scale back player's aim and ang values for a consistent feel between games. + float const angvelScale = 1.40625f; + float const aimvelScale = 1.203125f; + + // Shadow Warrior has a ticrate of 40, 25% more than the other games, so store below constant + // for dividing controller input to match speed input speed of other games. + float const ticrateScale = 0.75f; + + ApplyGlobalInput(*loc, &info); + + bool mouseaim = !!(loc->actions & SB_AIMMODE); if (!CommEnabled) { @@ -131,37 +161,10 @@ getinput(InputPacket *loc, SWBOOL tied) RESET(Player[myconnectindex].Flags, PF_AUTO_AIM); } - ControlInfo info; - CONTROL_GetInput(&info); - if (paused) - return; - // If in 2D follow mode, scroll around using glob vars - // Tried calling this in domovethings, but key response it too poor, skips key presses - // Note: this get called only during follow mode - if (!tied && automapFollow && automapMode != am_off && pp == Player + myconnectindex && !Prediction) - MoveScrollMode2D(Player + myconnectindex); - - // !JIM! Added M_Active() so that you don't move at all while using menus - if (M_Active() || automapFollow) - return; - - SET_LOC_KEY(loc->bits, SK_SPACE_BAR, buttonMap.ButtonDown(gamefunc_Open)); - - int32_t turnamount; - int32_t keymove; - - // The function DoPlayerTurn() scales the player's q16angvel by 1.40625, so store as constant - // and use to scale back player's aim and ang values for a consistent feel between games. - float const angvelScale = 1.40625f; - float const aimvelScale = 1.203125f; - - // Shadow Warrior has a ticrate of 40, 25% more than the other games, so store below constant - // for dividing controller input to match speed input speed of other games. - float const ticrateScale = 0.75f; - - ApplyGlobalInput(*loc, &info); + if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch)) // this shares a bit with another function so cannot be in the common code. + loc->actions |= SB_CROUCH_LOCK; if (loc->actions & SB_RUN) @@ -310,14 +313,6 @@ getinput(InputPacket *loc, SWBOOL tied) loc->q16horz += q16horz; - // actually snap - SET_LOC_KEY(loc->bits, SK_AIM_UP, buttonMap.ButtonDown(gamefunc_Aim_Up)); - SET_LOC_KEY(loc->bits, SK_AIM_DOWN, buttonMap.ButtonDown(gamefunc_Aim_Down)); - - // actually just look - SET_LOC_KEY(loc->bits, SK_LOOK_UP, buttonMap.ButtonDown(gamefunc_Look_Up)); - SET_LOC_KEY(loc->bits, SK_LOOK_DOWN, buttonMap.ButtonDown(gamefunc_Look_Down)); - if (loc->getNewWeapon() == WeaponSel_Next) { USERp u = User[pp->PlayerSprite]; @@ -394,9 +389,6 @@ getinput(InputPacket *loc, SWBOOL tied) loc->setNewWeapon(which_weapon); } - // need BUTTON - SET_LOC_KEY(loc->bits, SK_CRAWL_LOCK, buttonMap.ButtonDown(gamefunc_Toggle_Crouch)); - if (gNet.MultiGameType == MULTI_GAME_COOPERATIVE) { if (buttonMap.ButtonDown(gamefunc_See_Coop_View)) diff --git a/source/sw/src/network.cpp b/source/sw/src/network.cpp index 632ee2555..63afbcc87 100644 --- a/source/sw/src/network.cpp +++ b/source/sw/src/network.cpp @@ -82,7 +82,6 @@ typedef struct fix16_t q16horz; fix16_t q16ang; fix16_t q16horiz; - int32_t bits; ESyncBits actions; } SW_AVERAGE_PACKET; @@ -203,7 +202,6 @@ UpdateInputs(void) AveragePacket.q16horz += loc.q16horz; AveragePacket.q16ang = Player[myconnectindex].camq16ang; AveragePacket.q16horiz = Player[myconnectindex].camq16horiz; - SET(AveragePacket.bits, loc.bits); SET(AveragePacket.actions, loc.actions); // The above would or the weapon numbers together. Undo that now. The last one should win. AveragePacket.actions &= ~SB_WEAPONMASK_BITS; @@ -229,7 +227,6 @@ UpdateInputs(void) loc.q16horz = fix16_div(AveragePacket.q16horz, fix16_from_int(MovesPerPacket)); loc.q16ang = AveragePacket.q16ang; loc.q16horiz = AveragePacket.q16horiz; - loc.bits = AveragePacket.bits; loc.actions = AveragePacket.actions; memset(&AveragePacket, 0, sizeof(AveragePacket)); diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index 4cc12b940..829f22606 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -6509,10 +6509,8 @@ pFistRest(PANEL_SPRITEp psp) // Reset move to default psp->PlayerP->WpnKungFuMove = 0; - //if ((psp->PlayerP->input.actions & SB_FIRE) || force || TEST_SYNC_KEY(psp->PlayerP, SK_OPERATE)) if ((psp->PlayerP->input.actions & SB_FIRE) || force) { - //if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force || FLAG_KEY_PRESSED(psp->PlayerP, SK_OPERATE)) if ((psp->PlayerP->KeyPressBits & SB_FIRE) || force) { RESET(psp->flags, PANF_UNHIDE_SHOOT); diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index a0f817c8e..c49f87bc2 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -1938,7 +1938,7 @@ DoPlayerHorizon(PLAYERp pp, fix16_t *pq16horiz, fix16_t q16horz) SET(pp->Flags, PF_LOCK_HORIZ | PF_LOOKING); } - if (pp->input.actions & SB_CENTERVIEW) + if ((pp->input.actions & SB_CENTERVIEW) || pp->centering) { if (PedanticMode) pp->q16horizbase = fix16_from_int(100); @@ -1952,18 +1952,19 @@ DoPlayerHorizon(PLAYERp pp, fix16_t *pq16horiz, fix16_t q16horz) pp->q16horizbase = fix16_sadd(pp->q16horizbase, fix16_from_float(scaleAdjustmentToInterval((HORIZ_SPEED*6)))); pp->q16horizbase = fix16_min(pp->q16horizbase, fix16_from_int(100)); } + pp->centering = pp->q16horizbase != fix16_from_int(100); *pq16horiz = pp->q16horizbase; pp->q16horizoff = 0; } // this is the locked type - if (TEST_SYNC_KEY(pp, SK_AIM_UP) || TEST_SYNC_KEY(pp, SK_AIM_DOWN)) + if (pp->input.actions & (SB_AIM_UP|SB_AIM_DOWN)) { // set looking because player is manually looking SET(pp->Flags, PF_LOCK_HORIZ | PF_LOOKING); // adjust *pq16horiz negative - if (TEST_SYNC_KEY(pp, SK_AIM_DOWN)) + if (pp->input.actions & SB_AIM_DOWN) { if (PedanticMode) pp->q16horizbase -= fix16_from_int((HORIZ_SPEED/2)); @@ -1972,23 +1973,24 @@ DoPlayerHorizon(PLAYERp pp, fix16_t *pq16horiz, fix16_t q16horz) } // adjust *pq16horiz positive - if (TEST_SYNC_KEY(pp, SK_AIM_UP)) + if (pp->input.actions & SB_AIM_UP) { if (PedanticMode) pp->q16horizbase += fix16_from_int((HORIZ_SPEED/2)); else pp->q16horizbase = fix16_sadd(pp->q16horizbase, fix16_from_float(scaleAdjustmentToInterval((HORIZ_SPEED/2)))); } + pp->centering = false; } // this is the unlocked type - if (TEST_SYNC_KEY(pp, SK_LOOK_UP) || TEST_SYNC_KEY(pp, SK_LOOK_DOWN)) + if (pp->input.actions & (SB_LOOK_UP|SB_LOOK_DOWN)) { RESET(pp->Flags, PF_LOCK_HORIZ); SET(pp->Flags, PF_LOOKING); // adjust *pq16horiz negative - if (TEST_SYNC_KEY(pp, SK_LOOK_DOWN)) + if (pp->input.actions & SB_LOOK_DOWN) { if (PedanticMode) pp->q16horizbase -= fix16_from_int(HORIZ_SPEED); @@ -1997,18 +1999,19 @@ DoPlayerHorizon(PLAYERp pp, fix16_t *pq16horiz, fix16_t q16horz) } // adjust *pq16horiz positive - if (TEST_SYNC_KEY(pp, SK_LOOK_UP)) + if (pp->input.actions & SB_LOOK_UP) { if (PedanticMode) pp->q16horizbase += fix16_from_int(HORIZ_SPEED); else pp->q16horizbase = fix16_sadd(pp->q16horizbase, fix16_from_float(scaleAdjustmentToInterval(HORIZ_SPEED))); } + pp->centering = false; } if (!TEST(pp->Flags, PF_LOCK_HORIZ)) { - if (!(TEST_SYNC_KEY(pp, SK_LOOK_UP) || TEST_SYNC_KEY(pp, SK_LOOK_DOWN))) + if (!(pp->input.actions & (SB_LOOK_UP|SB_LOOK_DOWN))) { // not pressing the *pq16horiz keys if (pp->q16horizbase != fix16_from_int(100)) @@ -2043,9 +2046,6 @@ DoPlayerHorizon(PLAYERp pp, fix16_t *pq16horiz, fix16_t q16horz) else if (pp->q16horizbase + pp->q16horizoff > fix16_from_int(PLAYER_HORIZ_MAX)) pp->q16horizoff = fix16_from_int(PLAYER_HORIZ_MAX) - pp->q16horizbase; - ////DSPRINTF(ds,"base %d, off %d, base + off %d",fix16_to_int(pp->q16horizbase), fix16_to_int(pp->q16horizoff), fix16_to_int(pp->q16horizbase + pp->q16horizoff)); - //MONO_PRINT(ds); - // add base and offsets *pq16horiz = pp->q16horizbase + pp->q16horizoff; #else @@ -4148,14 +4148,14 @@ DoPlayerCrawl(PLAYERp pp) if (TEST(pp->Flags, PF_LOCK_CRAWL)) { - if (TEST_SYNC_KEY(pp, SK_CRAWL_LOCK)) + if (pp->input.actions & SB_CROUCH_LOCK) { - if (FLAG_KEY_PRESSED(pp, SK_CRAWL_LOCK)) + if (pp->KeyPressBits & SB_CROUCH_LOCK) { //if (pp->hiz < PLAYER_STANDING_ROOM(pp)) if (labs(pp->loz - pp->hiz) >= PLAYER_STANDING_ROOM) { - FLAG_KEY_RELEASE(pp, SK_CRAWL_LOCK); + pp->KeyPressBits&= ~SB_CROUCH_LOCK; RESET(pp->Flags, PF_CRAWLING); DoPlayerBeginRun(pp); @@ -4165,7 +4165,7 @@ DoPlayerCrawl(PLAYERp pp) } else { - FLAG_KEY_RESET(pp, SK_CRAWL_LOCK); + pp->KeyPressBits |= SB_CROUCH_LOCK; } // Jump to get up @@ -6040,7 +6040,6 @@ DoPlayerOperateTank(PLAYERp pp) { short save_sectnum; - //ASSERT(!TEST_SYNC_KEY(pp, SK_OPERATE)); if (pp->input.actions & SB_OPEN) { if (pp->KeyPressBits & SB_OPEN) @@ -6618,8 +6617,7 @@ void DoPlayerDeathCheckKeys(PLAYERp pp) SPRITEp sp = pp->SpriteP; USERp u = User[pp->PlayerSprite]; - //if (pp->input.actions & SB_OPEN) - if (TEST_SYNC_KEY(pp, SK_SPACE_BAR)) + if (pp->input.actions & SB_OPEN) { // Spawn a dead LoWang body for non-head deaths // Hey Frank, if you think of a better check, go ahead and put it in. @@ -7149,11 +7147,11 @@ DoPlayerRun(PLAYERp pp) } // Crawl lock - if (TEST_SYNC_KEY(pp, SK_CRAWL_LOCK)) + if (pp->input.actions & SB_CROUCH_LOCK) { - if (FLAG_KEY_PRESSED(pp, SK_CRAWL_LOCK)) + if (pp->KeyPressBits & SB_CROUCH_LOCK) { - FLAG_KEY_RELEASE(pp, SK_CRAWL_LOCK); + pp->KeyPressBits &= ~SB_CROUCH_LOCK; SET(pp->Flags, PF_LOCK_CRAWL); DoPlayerBeginCrawl(pp); return; @@ -7161,7 +7159,7 @@ DoPlayerRun(PLAYERp pp) } else { - FLAG_KEY_RESET(pp, SK_CRAWL_LOCK); + pp->KeyPressBits |= SB_CROUCH_LOCK; } if (PlayerFlyKey()) @@ -7407,8 +7405,8 @@ void ChopsCheck(PLAYERp pp) { if (!M_Active() && !TEST(pp->Flags, PF_DEAD) && !pp->sop_riding && numplayers <= 1) { - if ((pp->input.bits|pp->input.fvel|pp->input.svel|pp->input.q16avel|pp->input.q16horz) || - TEST(pp->Flags, PF_CLIMBING|PF_FALLING|PF_DIVING)) + if (pp->input.actions || pp->input.fvel || pp->input.svel || pp->input.q16avel || pp->input.q16horz || + TEST(pp->Flags, PF_CLIMBING | PF_FALLING | PF_DIVING)) { // Hit a input key or other reason to stop chops //if (pp->Chops && pp->Chops->State != pp->Chops->State->RetractState) @@ -7788,7 +7786,6 @@ InitAllPlayers(void) pp->WpnGotOnceFlags = 0; pp->DoPlayerAction = DoPlayerBeginRun; pp->KeyPressBits = ESyncBits::FromInt(0xFFFFFFFF); - pp->KeyPressFlags = 0xFFFFFFFF; memset(pp->KilledPlayer,0,sizeof(pp->KilledPlayer)); if (NewGame) From 7ff73ae2f18c8a3ea6523171b9dcaa3b7efc24b4 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 29 Aug 2020 22:30:45 +1000 Subject: [PATCH 20/43] - Duke: Add missing World Tour flamethrower from alt weapon mode implementation completed in 51a08fbaf34e86f9eb8ab69f4fc836ecf9c91b98. --- source/games/duke/src/player_d.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 79a952f8c..34eef0d52 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -1117,6 +1117,12 @@ void selectweapon_d(int snum, int weap) // playernum, weaponnum case GROW_WEAPON: j = SHRINKER_WEAPON; break; + case FREEZE_WEAPON: + j = isWorldTour() ? FLAMETHROWER_WEAPON : p->curr_weapon; + break; + case FLAMETHROWER_WEAPON: + j = FREEZE_WEAPON; + break; default: j = p->curr_weapon; break; From be33872b42b89881bbb6371e9abecbc38b2906ed Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Sat, 29 Aug 2020 22:51:20 +1000 Subject: [PATCH 21/43] - Blood: Implement `WeaponSel_Alt` for game. --- source/blood/src/weapon.cpp | 30 +++++++++++++++++++++++++++++- wadsrc/static/engine/menudef.txt | 2 +- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/source/blood/src/weapon.cpp b/source/blood/src/weapon.cpp index 6583ca9f1..28096c117 100644 --- a/source/blood/src/weapon.cpp +++ b/source/blood/src/weapon.cpp @@ -2060,7 +2060,35 @@ void WeaponProcess(PLAYER *pPlayer) { } else if (pPlayer->input.getNewWeapon() == WeaponSel_Alt) { - // todo + char weapon; + + switch (pPlayer->curWeapon) + { + case 6: + weapon = 11; + break; + case 11: + weapon = 12; + break; + case 12: + weapon = 6; + break; + default: + return; + } + + pPlayer->input.setNewWeapon(0); + pPlayer->weaponState = 0; + pPlayer->nextWeapon = 0; + int t = 0; + pPlayer->weaponMode[weapon] = t; + if (pPlayer->curWeapon) + { + WeaponLower(pPlayer); + pPlayer->nextWeapon = weapon; + return; + } + pPlayer->newWeapon = weapon; } if (pPlayer->weaponState == -1) { diff --git a/wadsrc/static/engine/menudef.txt b/wadsrc/static/engine/menudef.txt index dbd584c15..45aa9390c 100644 --- a/wadsrc/static/engine/menudef.txt +++ b/wadsrc/static/engine/menudef.txt @@ -481,7 +481,7 @@ OptionMenu "ActionControlsMenu"// protected { Control "$CNTRLMNU_ALTATTACK" , "+alt_fire" } - ifgame(ShadowWarrior, Duke, Redneck) + ifgame(ShadowWarrior, Duke, Redneck, Blood) { Control "$CNTRLMNU_ALTWEAPON" , "weapalt" } From eb34b417164c60c6ac27e8164a4994eb015c8d4f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Aug 2020 17:07:25 +0200 Subject: [PATCH 22/43] - fixed keyboard look in Blood. --- source/blood/src/player.cpp | 4 ++-- source/core/packet.h | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index 03c72f3a0..761b1f8f2 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -1562,7 +1562,7 @@ void ProcessInput(PLAYER *pPlayer) } if (bVanilla) { - if ((pInput->actions & SB_CENTERVIEW) && !pInput->actions & (SB_LOOK_UP|SB_LOOK_DOWN)) + if ((pInput->actions & SB_CENTERVIEW) && !(pInput->actions & (SB_LOOK_UP | SB_LOOK_DOWN))) { if (pPlayer->q16look < 0) pPlayer->q16look = fix16_min(pPlayer->q16look+fix16_from_int(4), fix16_from_int(0)); @@ -1592,7 +1592,7 @@ void ProcessInput(PLAYER *pPlayer) int downAngle = -347; double lookStepUp = 4.0*upAngle/60.0; double lookStepDown = -4.0*downAngle/60.0; - if ((pInput->actions & SB_CENTERVIEW) && !pInput->actions & (SB_LOOK_UP | SB_LOOK_DOWN)) + if ((pInput->actions & SB_CENTERVIEW) && !(pInput->actions & (SB_LOOK_UP | SB_LOOK_DOWN))) { if (pPlayer->q16look < 0) pPlayer->q16look = fix16_min(pPlayer->q16look+fix16_from_dbl(lookStepDown), fix16_from_int(0)); diff --git a/source/core/packet.h b/source/core/packet.h index 7b4308f09..696066d95 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -24,15 +24,14 @@ enum ESyncBits_ : uint32_t SB_OPEN = 1 << 17, SB_AIMMODE = 1 << 18, + SB_QUICK_KICK = 1 << 19, // Duke only. + SB_CROUCH_LOCK = 1 << 19, // SW only. + SB_ESCAPE = 1 << 20, - SB_AIM_UP = 1 << 19, - SB_AIM_DOWN = 1 << 20, - SB_LOOK_LEFT = 1 << 21, - SB_LOOK_RIGHT = 1 << 22, - SB_QUICK_KICK = 1 << 23, // Duke only. - SB_CROUCH_LOCK = 1 << 23, // SW only. - SB_ESCAPE = 1 << 24, - + SB_AIM_UP = 1 << 21, + SB_AIM_DOWN = 1 << 22, + SB_LOOK_LEFT = 1 << 23, + SB_LOOK_RIGHT = 1 << 24, SB_LOOK_UP = 1 << 25, SB_LOOK_DOWN = 1 << 26, SB_RUN = 1 << 27, @@ -44,7 +43,7 @@ enum ESyncBits_ : uint32_t SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits SB_ITEMUSE_BITS = (127u * SB_ITEM_BIT_1), - SB_BUTTON_MASK = SB_ALTFIRE|SB_FIRE|SB_CROUCH|SB_JUMP, // all input from buttons (i.e. active while held) + SB_BUTTON_MASK = SB_ALTFIRE|SB_FIRE|SB_CROUCH|SB_JUMP|SB_LOOK_UP|SB_LOOK_DOWN|SB_AIM_UP|SB_AIM_DOWN|SB_LOOK_LEFT|SB_LOOK_RIGHT, // all input from buttons (i.e. active while held) SB_INTERFACE_MASK = (SB_INVPREV|SB_INVNEXT|SB_INVUSE|SB_CENTERVIEW|SB_TURNAROUND|SB_HOLSTER|SB_OPEN|SB_ESCAPE|SB_QUICK_KICK), // all input from CCMDs SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS | SB_ITEMUSE_BITS | SB_INTERFACE_MASK), SB_ALL = ~0u From 56d0647412264e88933b35f228ffc4efd9a3bed8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Aug 2020 17:49:15 +0200 Subject: [PATCH 23/43] - migrated the last 3 remaining UI controls to CCMDs. --- source/blood/src/blood.cpp | 2 - source/blood/src/controls.cpp | 44 ------------ source/blood/src/osdcmd.cpp | 51 +++++++++++++- source/core/inputstate.cpp | 3 - source/core/inputstate.h | 3 - source/exhumed/src/exhumed.h | 1 - source/exhumed/src/gameloop.cpp | 1 - source/exhumed/src/input.cpp | 27 -------- source/exhumed/src/osdcmds.cpp | 26 +++++++ source/games/duke/src/ccmds.cpp | 49 +++++++++++-- source/games/duke/src/input.cpp | 39 ----------- source/sw/src/input.cpp | 59 ---------------- source/sw/src/osdcmds.cpp | 68 +++++++++++++++++-- wadsrc/static/engine/commonbinds.txt | 4 +- wadsrc/static/engine/defbinds.txt | 2 +- wadsrc/static/engine/menudef.txt | 2 +- .../static/filter/blood/engine/leftbinds.txt | 2 +- .../static/filter/blood/engine/origbinds.txt | 2 +- .../static/filter/duke/engine/leftbinds.txt | 2 +- .../static/filter/duke/engine/origbinds.txt | 2 +- wadsrc/static/filter/nam/engine/leftbinds.txt | 2 +- wadsrc/static/filter/nam/engine/origbinds.txt | 2 +- .../static/filter/redneck/engine/defbinds.txt | 2 +- .../filter/redneck/engine/leftbinds.txt | 2 +- .../filter/redneck/engine/origbinds.txt | 2 +- .../static/filter/ww2gi/engine/leftbinds.txt | 2 +- .../static/filter/ww2gi/engine/origbinds.txt | 2 +- 27 files changed, 195 insertions(+), 208 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index c7cd9e6a0..ce02bf0fc 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -63,7 +63,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS -void LocalKeys(void); void InitCheats(); bool bNoDemo = false; @@ -893,7 +892,6 @@ void GameInterface::RunGameFrame() case GS_LEVEL: gameTicker(); - LocalKeys(); break; case GS_FINALE: diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 9dbbee9de..cb12e93e9 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -64,44 +64,6 @@ float gViewAngleAdjust; float gViewLookAdjust; int gViewLookRecenter; -void LocalKeys(void) -{ - if (buttonMap.ButtonDown(gamefunc_Third_Person_View)) - { - buttonMap.ClearButton(gamefunc_Third_Person_View); - if (gViewPos > VIEWPOS_0) - gViewPos = VIEWPOS_0; - else - gViewPos = VIEWPOS_1; - } - if (buttonMap.ButtonDown(gamefunc_See_Coop_View)) - { - buttonMap.ClearButton(gamefunc_See_Coop_View); - if (gGameOptions.nGameType == 1) - { - gViewIndex = connectpoint2[gViewIndex]; - if (gViewIndex == -1) - gViewIndex = connecthead; - gView = &gPlayer[gViewIndex]; - } - else if (gGameOptions.nGameType == 3) - { - int oldViewIndex = gViewIndex; - do - { - gViewIndex = connectpoint2[gViewIndex]; - if (gViewIndex == -1) - gViewIndex = connecthead; - if (oldViewIndex == gViewIndex || gMe->teamId == gPlayer[gViewIndex].teamId) - break; - } while (oldViewIndex != gViewIndex); - gView = &gPlayer[gViewIndex]; - } - } -} - - - void ctrlGetInput(void) { int prevPauseState = paused; @@ -162,12 +124,6 @@ void ctrlGetInput(void) { } - if (buttonMap.ButtonDown(gamefunc_Show_Opponents_Weapon)) - { - buttonMap.ClearButton(gamefunc_Show_Opponents_Weapon); - cl_showweapon = (cl_showweapon + 1) & 3; - } - if (gInput.actions & (SB_LOOK_UP|SB_LOOK_DOWN)) gInput.actions |= SB_CENTERVIEW; diff --git a/source/blood/src/osdcmd.cpp b/source/blood/src/osdcmd.cpp index 41754ce10..965706299 100644 --- a/source/blood/src/osdcmd.cpp +++ b/source/blood/src/osdcmd.cpp @@ -204,17 +204,62 @@ static int osdcmd_warptocoords(CCmdFuncPtr parm) return CCMD_OK; } +static int osdcmd_third_person_view(CCmdFuncPtr parm) +{ + if (gamestate != GS_LEVEL || System_WantGuiCapture()) return CCMD_OK; + if (gViewPos > VIEWPOS_0) + gViewPos = VIEWPOS_0; + else + gViewPos = VIEWPOS_1; + return CCMD_OK; +} + +static int osdcmd_coop_view(CCmdFuncPtr parm) +{ + if (gamestate != GS_LEVEL || System_WantGuiCapture()) return CCMD_OK; + if (gGameOptions.nGameType == 1) + { + gViewIndex = connectpoint2[gViewIndex]; + if (gViewIndex == -1) + gViewIndex = connecthead; + gView = &gPlayer[gViewIndex]; + } + else if (gGameOptions.nGameType == 3) + { + int oldViewIndex = gViewIndex; + do + { + gViewIndex = connectpoint2[gViewIndex]; + if (gViewIndex == -1) + gViewIndex = connecthead; + if (oldViewIndex == gViewIndex || gMe->teamId == gPlayer[gViewIndex].teamId) + break; + } while (oldViewIndex != gViewIndex); + gView = &gPlayer[gViewIndex]; + } + return CCMD_OK; +} + +static int osdcmd_show_weapon(CCmdFuncPtr parm) +{ + if (gamestate != GS_LEVEL || System_WantGuiCapture()) return CCMD_OK; + cl_showweapon = (cl_showweapon + 1) & 3; + return CCMD_OK; +} + + + int32_t registerosdcommands(void) { C_RegisterFunction("map","map : loads the given map", osdcmd_map); - C_RegisterFunction("give","give : gives requested item", osdcmd_give); C_RegisterFunction("god","god: toggles god mode", osdcmd_god); C_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); - C_RegisterFunction("levelwarp","levelwarp : warp to episode 'e' and map 'm'", osdcmd_levelwarp); - C_RegisterFunction("warptocoords","warptocoords [x] [y] [z] [ang] (optional) [horiz] (optional): warps the player to the specified coordinates",osdcmd_warptocoords); + C_RegisterFunction("third_person_view", "Switch to third person view", osdcmd_third_person_view); + C_RegisterFunction("coop_view", "Switch player to view from in coop", osdcmd_coop_view); + C_RegisterFunction("show_weapon", "Show opponents' weapons", osdcmd_show_weapon); return 0; } diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index 8d5ba3a0e..3880e7e4f 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -235,12 +235,9 @@ void SetupGameButtons() "Aim_Down", "Shrink_Screen", "Enlarge_Screen", - "Show_Opponents_Weapon", - "See_Coop_View", "Mouse_Aiming", "Dpad_Select", "Dpad_Aiming", - "Third_Person_View", "Toggle_Crouch", "Quick_Kick", }; diff --git a/source/core/inputstate.h b/source/core/inputstate.h index d33614389..aa07f9d8f 100644 --- a/source/core/inputstate.h +++ b/source/core/inputstate.h @@ -87,12 +87,9 @@ enum GameFunction_t gamefunc_Aim_Down, gamefunc_Shrink_Screen, // Automap only gamefunc_Enlarge_Screen, // Automap only - gamefunc_Show_Opponents_Weapon, // CCMD - gamefunc_See_Coop_View, // CCMD gamefunc_Mouse_Aiming, gamefunc_Dpad_Select, gamefunc_Dpad_Aiming, - gamefunc_Third_Person_View, // CCMD gamefunc_Toggle_Crouch, gamefunc_Quick_Kick, NUM_ACTIONS diff --git a/source/exhumed/src/exhumed.h b/source/exhumed/src/exhumed.h index cf4b0f4e0..4f178b6f1 100644 --- a/source/exhumed/src/exhumed.h +++ b/source/exhumed/src/exhumed.h @@ -85,7 +85,6 @@ void StatusMessage(int messageTime, const char *fmt, ...); int DoSpiritHead(); -void CheckKeys(); void CheckKeys2(); void GameTicker(); void InitLevel(int); diff --git a/source/exhumed/src/gameloop.cpp b/source/exhumed/src/gameloop.cpp index bbf4e0747..55b38bb9d 100644 --- a/source/exhumed/src/gameloop.cpp +++ b/source/exhumed/src/gameloop.cpp @@ -254,7 +254,6 @@ void CheckProgression() void GameLoop() { - CheckKeys(); GameTicker(); PlayerInterruptKeys(true); UpdateSounds(); diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index ed84b54d4..451e4aab3 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -87,33 +87,6 @@ void SendInput() } -void CheckKeys() -{ - // go to 3rd person view? - if (buttonMap.ButtonDown(gamefunc_Third_Person_View)) - { - if (!nFreeze) - { - if (bCamera) { - bCamera = false; - } - else { - bCamera = true; - } - - if (bCamera) - GrabPalette(); - } - buttonMap.ClearButton(gamefunc_Third_Person_View); - return; - } - - if (paused) - { - return; - } -} - static int32_t nonsharedtimer; void CheckKeys2() diff --git a/source/exhumed/src/osdcmds.cpp b/source/exhumed/src/osdcmds.cpp index f1f12e7ac..73a0f08a2 100644 --- a/source/exhumed/src/osdcmds.cpp +++ b/source/exhumed/src/osdcmds.cpp @@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "aistuff.h" #include "ps_input.h" #include "cheathandler.h" +#include "gamestate.h" BEGIN_PS_NS @@ -196,7 +197,29 @@ static int osdcmd_spawn(CCmdFuncPtr parm) return CCMD_OK; } +static int osdcmd_third_person_view(CCmdFuncPtr parm) +{ + if (gamestate != GS_LEVEL || System_WantGuiCapture()) return CCMD_OK; + if (!nFreeze) + { + if (bCamera) { + bCamera = false; + } + else { + bCamera = true; + } + if (bCamera) + GrabPalette(); + } + return CCMD_OK; +} + +static int osdcmd_noop(CCmdFuncPtr parm) +{ + // this is for silencing key bindings only. + return CCMD_OK; +} int32_t registerosdcommands(void) { @@ -209,6 +232,9 @@ int32_t registerosdcommands(void) C_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); C_RegisterFunction("spawn","spawn : spawns a creature",osdcmd_spawn); C_RegisterFunction("warptocoords","warptocoords [x] [y] [z] [ang] (optional) [horiz] (optional): warps the player to the specified coordinates",osdcmd_warptocoords); + C_RegisterFunction("third_person_view", "Switch to third person view", osdcmd_third_person_view); + C_RegisterFunction("coop_view", "Switch player to view from in coop", osdcmd_noop); + C_RegisterFunction("show_weapon", "Show opponents' weapons", osdcmd_noop); return 0; } diff --git a/source/games/duke/src/ccmds.cpp b/source/games/duke/src/ccmds.cpp index fd261e7f1..272357dc7 100644 --- a/source/games/duke/src/ccmds.cpp +++ b/source/games/duke/src/ccmds.cpp @@ -33,6 +33,7 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) #include "mapinfo.h" #include "cheathandler.h" #include "c_dispatch.h" +#include "gamestate.h" BEGIN_DUKE_NS @@ -285,22 +286,62 @@ static int osdcmd_warptocoords(CCmdFuncPtr parm) return CCMD_OK; } +static int osdcmd_third_person_view(CCmdFuncPtr parm) +{ + if (gamestate != GS_LEVEL || System_WantGuiCapture()) return CCMD_OK; + if (!isRRRA() || (!ps[myconnectindex].OnMotorcycle && !ps[myconnectindex].OnBoat)) + { + if (ps[myconnectindex].over_shoulder_on) + ps[myconnectindex].over_shoulder_on = 0; + else + { + ps[myconnectindex].over_shoulder_on = 1; + cameradist = 0; + cameraclock = gameclock; + } + FTA(QUOTE_VIEW_MODE_OFF + ps[myconnectindex].over_shoulder_on, &ps[myconnectindex]); + } + return CCMD_OK; +} + +static int osdcmd_coop_view(CCmdFuncPtr parm) +{ + if (gamestate != GS_LEVEL || System_WantGuiCapture()) return CCMD_OK; + if (ud.coop || ud.recstat == 2) + { + screenpeek = connectpoint2[screenpeek]; + if (screenpeek == -1) screenpeek = 0; + } + return CCMD_OK; +} + +static int osdcmd_show_weapon(CCmdFuncPtr parm) +{ + if (gamestate != GS_LEVEL || System_WantGuiCapture()) return CCMD_OK; + if (ud.multimode > 1) + { + ud.showweapons = 1 - ud.showweapons; + cl_showweapon = ud.showweapons; + FTA(QUOTE_WEAPON_MODE_OFF - ud.showweapons, &ps[screenpeek]); + } + + return CCMD_OK; +} int registerosdcommands(void) { C_RegisterFunction("map","map : warp to the given map, identified by its name", ccmd_map); C_RegisterFunction("levelwarp","levelwarp : warp to episode 'e' and map 'm'", ccmd_levelwarp); - C_RegisterFunction("give","give : gives requested item", ccmd_give); C_RegisterFunction("god","god: toggles god mode", ccmd_god); - C_RegisterFunction("noclip","noclip: toggles clipping mode", ccmd_noclip); C_RegisterFunction("restartmap", "restartmap: restarts the current map", ccmd_restartmap); - C_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",ccmd_spawn); - C_RegisterFunction("warptocoords","warptocoords [x] [y] [z] [ang] (optional) [horiz] (optional): warps the player to the specified coordinates",osdcmd_warptocoords); + C_RegisterFunction("third_person_view", "Switch to third person view", osdcmd_third_person_view); + C_RegisterFunction("coop_view", "Switch player to view from in coop", osdcmd_coop_view); + C_RegisterFunction("show_weapon", "Show opponents' weapons", osdcmd_show_weapon); return 0; } diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index ef50282bb..3fed36a2d 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -65,48 +65,9 @@ void GameInterface::ResetFollowPos(bool message) void nonsharedkeys(void) { - if (ud.recstat == 2) - { - ControlInfo noshareinfo; - CONTROL_GetInput(&noshareinfo); - } - if (System_WantGuiCapture()) return; - if (buttonMap.ButtonDown(gamefunc_See_Coop_View) && (ud.coop || ud.recstat == 2)) - { - buttonMap.ClearButton(gamefunc_See_Coop_View); - screenpeek = connectpoint2[screenpeek]; - if (screenpeek == -1) screenpeek = 0; - } - - if ((ud.multimode > 1) && buttonMap.ButtonDown(gamefunc_Show_Opponents_Weapon)) - { - buttonMap.ClearButton(gamefunc_Show_Opponents_Weapon); - ud.showweapons = 1 - ud.showweapons; - cl_showweapon = ud.showweapons; - FTA(QUOTE_WEAPON_MODE_OFF - ud.showweapons, &ps[screenpeek]); - } - - if (buttonMap.ButtonDown(gamefunc_Third_Person_View)) - { - buttonMap.ClearButton(gamefunc_Third_Person_View); - - if (!isRRRA() || (!ps[myconnectindex].OnMotorcycle && !ps[myconnectindex].OnBoat)) - { - if (ps[myconnectindex].over_shoulder_on) - ps[myconnectindex].over_shoulder_on = 0; - else - { - ps[myconnectindex].over_shoulder_on = 1; - cameradist = 0; - cameraclock = gameclock; - } - FTA(QUOTE_VIEW_MODE_OFF + ps[myconnectindex].over_shoulder_on, &ps[myconnectindex]); - } - } - if (automapMode != am_off) { int j; diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index fcb3caac9..cc7c48915 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -34,36 +34,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS -void -FunctionKeys(PLAYERp pp) -{ - // F7 VIEW control - if (buttonMap.ButtonDown(gamefunc_Third_Person_View)) - { - buttonMap.ClearButton(gamefunc_Third_Person_View); - - if (inputState.ShiftPressed()) - { - if (TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE)) - pp->view_outside_dang = NORM_ANGLE(pp->view_outside_dang + 256); - } - else - { - if (TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE)) - { - RESET(pp->Flags, PF_VIEW_FROM_OUTSIDE); - } - else - { - SET(pp->Flags, PF_VIEW_FROM_OUTSIDE); - pp->camera_dist = 0; - } - } - } -} - - - double elapsedInputTicks; double scaleAdjustmentToInterval(double x) { return x * (120 / synctics) / (1000.0 / elapsedInputTicks); } @@ -388,35 +358,6 @@ getinput(InputPacket *loc, SWBOOL tied) short const which_weapon = u->WeaponNum + 1; loc->setNewWeapon(which_weapon); } - - if (gNet.MultiGameType == MULTI_GAME_COOPERATIVE) - { - if (buttonMap.ButtonDown(gamefunc_See_Coop_View)) - { - buttonMap.ClearButton(gamefunc_See_Coop_View); - - screenpeek = connectpoint2[screenpeek]; - - if (screenpeek < 0) - screenpeek = connecthead; - - if (screenpeek == myconnectindex) - { - // JBF: figure out what's going on here - DoPlayerDivePalette(pp); // Check Dive again - DoPlayerNightVisionPalette(pp); // Check Night Vision again - } - else - { - PLAYERp tp = Player+screenpeek; - DoPlayerDivePalette(tp); - DoPlayerNightVisionPalette(tp); - } - } - } - - if (!tied) - FunctionKeys(pp); } END_SW_NS diff --git a/source/sw/src/osdcmds.cpp b/source/sw/src/osdcmds.cpp index d137651dc..283d42ddd 100644 --- a/source/sw/src/osdcmds.cpp +++ b/source/sw/src/osdcmds.cpp @@ -45,6 +45,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "jsector.h" #include "network.h" #include "gamestate.h" +#include "player.h" BEGIN_SW_NS @@ -237,6 +238,62 @@ static int osdcmd_mirror(CCmdFuncPtr parm) return CCMD_OK; } +static int osdcmd_third_person_view(CCmdFuncPtr parm) +{ + if (gamestate != GS_LEVEL || System_WantGuiCapture()) return CCMD_OK; + auto pp = &Player[myconnectindex]; + if (inputState.ShiftPressed()) + { + if (TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE)) + pp->view_outside_dang = NORM_ANGLE(pp->view_outside_dang + 256); + } + else + { + if (TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE)) + { + RESET(pp->Flags, PF_VIEW_FROM_OUTSIDE); + } + else + { + SET(pp->Flags, PF_VIEW_FROM_OUTSIDE); + pp->camera_dist = 0; + } + } + return CCMD_OK; +} + +static int osdcmd_coop_view(CCmdFuncPtr parm) +{ + if (gamestate != GS_LEVEL || System_WantGuiCapture()) return CCMD_OK; + if (gNet.MultiGameType == MULTI_GAME_COOPERATIVE) + { + screenpeek = connectpoint2[screenpeek]; + + if (screenpeek < 0) + screenpeek = connecthead; + + if (screenpeek == myconnectindex) + { + // JBF: figure out what's going on here + auto pp = &Player[myconnectindex]; + DoPlayerDivePalette(pp); // Check Dive again + DoPlayerNightVisionPalette(pp); // Check Night Vision again + } + else + { + PLAYERp tp = Player + screenpeek; + DoPlayerDivePalette(tp); + DoPlayerNightVisionPalette(tp); + } + } + return CCMD_OK; +} + +static int osdcmd_noop(CCmdFuncPtr parm) +{ + // this is for silencing key bindings only. + return CCMD_OK; +} int32_t registerosdcommands(void) { @@ -244,17 +301,14 @@ int32_t registerosdcommands(void) C_RegisterFunction("give","give : gives requested item", osdcmd_give); C_RegisterFunction("god","god: toggles god mode", osdcmd_god); C_RegisterFunction("bunny", "bunny: toggles bunny rocket mode", osdcmd_bunny); - C_RegisterFunction("mirror", "mirror [mirrornum]: print mirror debug info", osdcmd_mirror); - + C_RegisterFunction("mirror_debug", "mirror [mirrornum]: print mirror debug info", osdcmd_mirror); C_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip); - C_RegisterFunction("levelwarp", "levelwarp : warp to level", osdcmd_levelwarp); - C_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap); - -// C_RegisterFunction("spawn","spawn [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn); - C_RegisterFunction("warptocoords","warptocoords [x] [y] [z] [ang] (optional) [horiz] (optional): warps the player to the specified coordinates",osdcmd_warptocoords); + C_RegisterFunction("third_person_view", "Switch to third person view", osdcmd_third_person_view); + C_RegisterFunction("coop_view", "Switch player to view from in coop", osdcmd_coop_view); + C_RegisterFunction("show_weapon", "Show opponents' weapons", osdcmd_noop); return 0; } diff --git a/wadsrc/static/engine/commonbinds.txt b/wadsrc/static/engine/commonbinds.txt index d38e6e8a9..cce8c0f5a 100644 --- a/wadsrc/static/engine/commonbinds.txt +++ b/wadsrc/static/engine/commonbinds.txt @@ -6,7 +6,7 @@ F3 "openloadmenu" F4 "openmenu SoundOptions" F5 "openmenu OptionsMenu" //this key performs some fuckery with the music in Duke Nukem,so the default here is Blood's. F6 "quicksave" -F7 "+Third_Person_View" +F7 "third_person_view" F8 "togglemessages" F9 "quickload" F10 "menu_endgame" @@ -41,7 +41,7 @@ mapbind - "+Shrink_Screen" mapbind = "+Enlarge_Screen" - "sizedown" = "sizeup" -K "+See_Coop_View" +K "coop_view" Mouse1 "+Fire" diff --git a/wadsrc/static/engine/defbinds.txt b/wadsrc/static/engine/defbinds.txt index 574bb04f8..4b98d9aca 100644 --- a/wadsrc/static/engine/defbinds.txt +++ b/wadsrc/static/engine/defbinds.txt @@ -16,5 +16,5 @@ mapbind KP- "+Shrink_Screen" mapbind KP+ "+Enlarge_Screen" - "sizedown" + "sizeup"" -Y "+Show_Opponents_Weapon" +Y "show_weapon" CapsLock "toggle cl_autorun" diff --git a/wadsrc/static/engine/menudef.txt b/wadsrc/static/engine/menudef.txt index 45aa9390c..349b5b709 100644 --- a/wadsrc/static/engine/menudef.txt +++ b/wadsrc/static/engine/menudef.txt @@ -685,7 +685,7 @@ OptionMenu "OtherControlsMenu"// protected MapControl "$MAPCNTRLMNU_ZOOMOUT" , "+shrink_screen" StaticText "" - Control "$CNTRLMNU_CHASECAM" , "+third_person_view" + Control "$CNTRLMNU_CHASECAM" , "third_person_view" StaticText "" Control "$CNTRLMNU_SCREENSHOT" , "screenshot" diff --git a/wadsrc/static/filter/blood/engine/leftbinds.txt b/wadsrc/static/filter/blood/engine/leftbinds.txt index 9fed4e5be..046a19317 100644 --- a/wadsrc/static/filter/blood/engine/leftbinds.txt +++ b/wadsrc/static/filter/blood/engine/leftbinds.txt @@ -1,5 +1,5 @@ // -W "+Show_Opponents_Weapon" +W "show_weapon" B "useitem 3" C "useitem 2" P "slot 11" diff --git a/wadsrc/static/filter/blood/engine/origbinds.txt b/wadsrc/static/filter/blood/engine/origbinds.txt index c8e4e65da..85f93e3dc 100644 --- a/wadsrc/static/filter/blood/engine/origbinds.txt +++ b/wadsrc/static/filter/blood/engine/origbinds.txt @@ -1,5 +1,5 @@ // -W "+Show_Opponents_Weapon" +W "show_weapon" B "useitem 3" C "useitem 2" P "slot 11" diff --git a/wadsrc/static/filter/duke/engine/leftbinds.txt b/wadsrc/static/filter/duke/engine/leftbinds.txt index d04297d13..a6e6be674 100644 --- a/wadsrc/static/filter/duke/engine/leftbinds.txt +++ b/wadsrc/static/filter/duke/engine/leftbinds.txt @@ -4,4 +4,4 @@ Q "+Quick_Kick" J "useitem 4" N "useitem 5" M "useitem 1" -W "+Show_Opponents_Weapon" +W "show_weapon" diff --git a/wadsrc/static/filter/duke/engine/origbinds.txt b/wadsrc/static/filter/duke/engine/origbinds.txt index 8c12f9162..73b92e205 100644 --- a/wadsrc/static/filter/duke/engine/origbinds.txt +++ b/wadsrc/static/filter/duke/engine/origbinds.txt @@ -1,7 +1,7 @@ // R "useitem 2" ` "+Quick_Kick" -W "+Show_Opponents_Weapon" +W "show_weapon" H "Holo_Duke" J "useitem 4" N "useitem 5" diff --git a/wadsrc/static/filter/nam/engine/leftbinds.txt b/wadsrc/static/filter/nam/engine/leftbinds.txt index d04297d13..a6e6be674 100644 --- a/wadsrc/static/filter/nam/engine/leftbinds.txt +++ b/wadsrc/static/filter/nam/engine/leftbinds.txt @@ -4,4 +4,4 @@ Q "+Quick_Kick" J "useitem 4" N "useitem 5" M "useitem 1" -W "+Show_Opponents_Weapon" +W "show_weapon" diff --git a/wadsrc/static/filter/nam/engine/origbinds.txt b/wadsrc/static/filter/nam/engine/origbinds.txt index 253985daa..505f465fb 100644 --- a/wadsrc/static/filter/nam/engine/origbinds.txt +++ b/wadsrc/static/filter/nam/engine/origbinds.txt @@ -1,7 +1,7 @@ // R "useitem 2" ` "+Quick_Kick" -W "+Show_Opponents_Weapon" +W "show_weapon" H "useitem 3" J "useitem 4" N "useitem 5" diff --git a/wadsrc/static/filter/redneck/engine/defbinds.txt b/wadsrc/static/filter/redneck/engine/defbinds.txt index 2ac4d63ac..d3d7a6468 100644 --- a/wadsrc/static/filter/redneck/engine/defbinds.txt +++ b/wadsrc/static/filter/redneck/engine/defbinds.txt @@ -1,5 +1,5 @@ // -V "+Show_Opponents_Weapon" +V "show_weapon" B "useitem 3" C "useitem 4" Y "useitem 5" diff --git a/wadsrc/static/filter/redneck/engine/leftbinds.txt b/wadsrc/static/filter/redneck/engine/leftbinds.txt index 83ffb9f72..f9f1b5b83 100644 --- a/wadsrc/static/filter/redneck/engine/leftbinds.txt +++ b/wadsrc/static/filter/redneck/engine/leftbinds.txt @@ -1,4 +1,4 @@ -E "+Show_Opponents_Weapon" +E "show_weapon" M "useitem 2" Q "+Quick_Kick" B "useitem 3" diff --git a/wadsrc/static/filter/redneck/engine/origbinds.txt b/wadsrc/static/filter/redneck/engine/origbinds.txt index ac76b35e8..f4f1b2421 100644 --- a/wadsrc/static/filter/redneck/engine/origbinds.txt +++ b/wadsrc/static/filter/redneck/engine/origbinds.txt @@ -1,5 +1,5 @@ V "toggleconsole" -E "+Show_Opponents_Weapon" +E "show_weapon" M "useitem 2" ` "+Quick_Kick" B "useitem 3" diff --git a/wadsrc/static/filter/ww2gi/engine/leftbinds.txt b/wadsrc/static/filter/ww2gi/engine/leftbinds.txt index d04297d13..a6e6be674 100644 --- a/wadsrc/static/filter/ww2gi/engine/leftbinds.txt +++ b/wadsrc/static/filter/ww2gi/engine/leftbinds.txt @@ -4,4 +4,4 @@ Q "+Quick_Kick" J "useitem 4" N "useitem 5" M "useitem 1" -W "+Show_Opponents_Weapon" +W "show_weapon" diff --git a/wadsrc/static/filter/ww2gi/engine/origbinds.txt b/wadsrc/static/filter/ww2gi/engine/origbinds.txt index 253985daa..505f465fb 100644 --- a/wadsrc/static/filter/ww2gi/engine/origbinds.txt +++ b/wadsrc/static/filter/ww2gi/engine/origbinds.txt @@ -1,7 +1,7 @@ // R "useitem 2" ` "+Quick_Kick" -W "+Show_Opponents_Weapon" +W "show_weapon" H "useitem 3" J "useitem 4" N "useitem 5" From a03b6cf57cfdacbe27c9b231842b579b407ec48c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Aug 2020 18:07:49 +0200 Subject: [PATCH 24/43] - pass loc as a parameter to Duke's GetInput function to uncouple it from the global variable. --- source/games/duke/src/funct.h | 2 +- source/games/duke/src/gameloop.cpp | 4 +- source/games/duke/src/input.cpp | 80 +++++++++++++++--------------- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 5cb8e16bf..81cda40ab 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -234,7 +234,7 @@ void apply_seasick(player_struct* p, double scalefactor); void calcviewpitch(player_struct* p, double factor); void sethorizon(int snum, ESyncBits actions, double factor, fixed_t adjustment); bool movementBlocked(int snum); -void GetInput(); +void GetInput(InputPacket &loc); void startmainmenu(); void loadcons(); diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index a6893fa5c..db51adb06 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -333,7 +333,7 @@ bool GameTicker() { lastTic = currentTic; - GetInput(); + GetInput(loc); auto const pPlayer = &ps[myconnectindex]; auto const q16ang = fix16_to_int(pPlayer->q16ang); auto& input = nextinput(myconnectindex); @@ -366,7 +366,7 @@ bool GameTicker() if (!cl_syncinput) { - GetInput(); + GetInput(loc); } drawtime.Reset(); diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 3fed36a2d..8633d686e 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -565,28 +565,28 @@ enum // //--------------------------------------------------------------------------- -static void processInputBits(player_struct *p, ControlInfo &info) +static void processInputBits(InputPacket &locInput, player_struct *p, ControlInfo &info) { ApplyGlobalInput(loc, &info); - if (isRR() && (loc.actions & SB_CROUCH)) loc.actions &= ~SB_JUMP; + if (isRR() && (locInput.actions & SB_CROUCH)) locInput.actions &= ~SB_JUMP; if (p->OnMotorcycle || p->OnBoat) { // mask out all actions not compatible with vehicles. - loc.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH | SB_RUN | + locInput.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH | SB_RUN | SB_AIM_UP | SB_AIM_DOWN | SB_AIMMODE | SB_LOOK_UP | SB_LOOK_DOWN | SB_LOOK_LEFT | SB_LOOK_RIGHT); } else { if (buttonMap.ButtonDown(gamefunc_Quick_Kick)) // this shares a bit with another function so cannot be in the common code. - loc.actions |= SB_QUICK_KICK; + locInput.actions |= SB_QUICK_KICK; if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch) || p->crouch_toggle) { - loc.actions |= SB_CROUCH; + locInput.actions |= SB_CROUCH; } - if ((isRR() && p->drink_amt > 88)) loc.actions |= SB_LOOK_LEFT; - if ((isRR() && p->drink_amt > 99)) loc.actions |= SB_LOOK_DOWN; + if ((isRR() && p->drink_amt > 88)) locInput.actions |= SB_LOOK_LEFT; + if ((isRR() && p->drink_amt > 99)) locInput.actions |= SB_LOOK_DOWN; } } @@ -632,12 +632,12 @@ int getticssincelastupdate() // //--------------------------------------------------------------------------- -static void processMovement(player_struct *p, InputPacket &input, ControlInfo &info, double scaleFactor) +static void processMovement(player_struct *p, InputPacket& locInput, InputPacket &input, ControlInfo &info, double scaleFactor) { - bool mouseaim = !!(loc.actions & SB_AIMMODE); + bool mouseaim = !!(locInput.actions & SB_AIMMODE); // JBF: Run key behaviour is selectable - int running = !!(loc.actions & SB_RUN); + int running = !!(locInput.actions & SB_RUN); int turnamount = NORMALTURN << running; int keymove = NORMALKEYMOVE << running; @@ -659,7 +659,7 @@ static void processMovement(player_struct *p, InputPacket &input, ControlInfo &i if (buttonMap.ButtonDown(gamefunc_Strafe)) { - if (!loc.svel) + if (!locInput.svel) { if (buttonMap.ButtonDown(gamefunc_Turn_Left)) input.svel = keymove; @@ -690,7 +690,7 @@ static void processMovement(player_struct *p, InputPacket &input, ControlInfo &i } - if (abs(loc.svel) < keymove) + if (abs(locInput.svel) < keymove) { if (buttonMap.ButtonDown(gamefunc_Strafe_Left)) input.svel += keymove; @@ -699,7 +699,7 @@ static void processMovement(player_struct *p, InputPacket &input, ControlInfo &i input.svel += -keymove; } - if (abs(loc.fvel) < keymove) + if (abs(locInput.fvel) < keymove) { if (isRR() && p->drink_amt >= 66 && p->drink_amt <= 87) { @@ -910,7 +910,7 @@ static double boatApplyTurn(player_struct *p, int turnl, int turnr, int boat_tur // //--------------------------------------------------------------------------- -static void processVehicleInput(player_struct *p, ControlInfo& info, InputPacket& input, double scaleAdjust) +static void processVehicleInput(player_struct *p, ControlInfo& info, InputPacket& locInput, InputPacket& input, double scaleAdjust) { auto turnspeed = info.mousex + scaleAdjust * info.dyaw * (1. / 32); // originally this was 64, not 32. Why the change? int turnl = buttonMap.ButtonDown(gamefunc_Turn_Left) || buttonMap.ButtonDown(gamefunc_Strafe_Left); @@ -928,17 +928,17 @@ static void processVehicleInput(player_struct *p, ControlInfo& info, InputPacket if (p->OnBoat || !p->moto_underwater) { if (buttonMap.ButtonDown(gamefunc_Move_Forward) || buttonMap.ButtonDown(gamefunc_Strafe)) - loc.actions |= SB_JUMP; + locInput.actions |= SB_JUMP; if (buttonMap.ButtonDown(gamefunc_Move_Backward)) - loc.actions |= SB_AIM_UP; - if (loc.actions & SB_RUN) - loc.actions |= SB_CROUCH; + locInput.actions |= SB_AIM_UP; + if (locInput.actions & SB_RUN) + locInput.actions |= SB_CROUCH; } if (turnl) - loc.actions |= SB_AIM_DOWN; + locInput.actions |= SB_AIM_DOWN; if (turnr) - loc.actions |= SB_LOOK_LEFT; + locInput.actions |= SB_LOOK_LEFT; double turnvel; @@ -968,7 +968,7 @@ static void processVehicleInput(player_struct *p, ControlInfo& info, InputPacket // //--------------------------------------------------------------------------- -static void FinalizeInput(int playerNum, InputPacket& input, bool vehicle) +static void FinalizeInput(int playerNum, InputPacket& locInput, InputPacket& input, bool vehicle) { auto p = &ps[playerNum]; bool blocked = movementBlocked(playerNum) || sprite[p->i].extra <= 0 || (p->dead_flag && !ud.god); @@ -981,8 +981,8 @@ static void FinalizeInput(int playerNum, InputPacket& input, bool vehicle) ud.folavel = fix16_to_int(input.q16avel); } - loc.fvel = loc.svel = 0; - loc.q16avel = loc.q16horz = 0; + locInput.fvel = locInput.svel = 0; + locInput.q16avel = locInput.q16horz = 0; input.q16avel = input.q16horz = 0; } else @@ -991,21 +991,21 @@ static void FinalizeInput(int playerNum, InputPacket& input, bool vehicle) { if (!vehicle) { - loc.fvel = clamp(loc.fvel + input.fvel, -MAXVEL, MAXVEL); - loc.svel = clamp(loc.svel + input.svel, -MAXSVEL, MAXSVEL); + locInput.fvel = clamp(locInput.fvel + input.fvel, -MAXVEL, MAXVEL); + locInput.svel = clamp(locInput.svel + input.svel, -MAXSVEL, MAXSVEL); } else - loc.fvel = clamp(input.fvel, -(MAXVELMOTO / 8), MAXVELMOTO); + locInput.fvel = clamp(input.fvel, -(MAXVELMOTO / 8), MAXVELMOTO); } else { - loc.fvel = input.fvel = 0; - loc.svel = input.svel = 0; + locInput.fvel = input.fvel = 0; + locInput.svel = input.svel = 0; } if (p->on_crane < 0 && p->newowner == -1) { - loc.q16avel = fix16_clamp(loc.q16avel + input.q16avel, F16(-MAXANGVEL), F16(MAXANGVEL)); + locInput.q16avel = fix16_clamp(locInput.q16avel + input.q16avel, F16(-MAXANGVEL), F16(MAXANGVEL)); if (!cl_syncinput && input.q16avel) { p->one_eighty_count = 0; @@ -1013,16 +1013,16 @@ static void FinalizeInput(int playerNum, InputPacket& input, bool vehicle) } else { - loc.q16avel = input.q16avel = 0; + locInput.q16avel = input.q16avel = 0; } if (p->newowner == -1 && p->return_to_center <= 0) { - loc.q16horz = fix16_clamp(loc.q16horz + input.q16horz, F16(-MAXHORIZVEL), F16(MAXHORIZVEL)); + locInput.q16horz = fix16_clamp(locInput.q16horz + input.q16horz, F16(-MAXHORIZVEL), F16(MAXHORIZVEL)); } else { - loc.q16horz = input.q16horz = 0; + locInput.q16horz = input.q16horz = 0; } } } @@ -1033,7 +1033,7 @@ static void FinalizeInput(int playerNum, InputPacket& input, bool vehicle) // //--------------------------------------------------------------------------- -void GetInput() +void GetInput(InputPacket &locInput) { double elapsedInputTicks; auto const p = &ps[myconnectindex]; @@ -1064,9 +1064,9 @@ void GetInput() if (isRRRA() && (p->OnMotorcycle || p->OnBoat)) { p->crouch_toggle = 0; - processInputBits(p, info); - processVehicleInput(p, info, input, scaleAdjust); - FinalizeInput(myconnectindex, input, true); + processInputBits(locInput, p, info); + processVehicleInput(p, info, locInput, input, scaleAdjust); + FinalizeInput(myconnectindex, locInput, input, true); if (!cl_syncinput && sprite[p->i].extra > 0) { @@ -1075,10 +1075,10 @@ void GetInput() } else { - processInputBits(p, info); - processMovement(p, input, info, scaleAdjust); + processInputBits(locInput, p, info); + processMovement(p, input, locInput, info, scaleAdjust); checkCrouchToggle(p); - FinalizeInput(myconnectindex, input, false); + FinalizeInput(myconnectindex, locInput, input, false); } if (!cl_syncinput) @@ -1086,7 +1086,7 @@ void GetInput() // Do these in the same order as the old code. calcviewpitch(p, scaleAdjust); applylook(myconnectindex, scaleAdjust, input.q16avel); - sethorizon(myconnectindex, loc.actions, scaleAdjust, input.q16horz); + sethorizon(myconnectindex, locInput.actions, scaleAdjust, input.q16horz); } } From e3839b01bc979fe498b627d7caf476f659b5ffa3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Aug 2020 18:37:22 +0200 Subject: [PATCH 25/43] - removed in_mousesmoothing. This not only was redundant with m_filter, even worse, it was in the wrong place. Control_GetInput is used to read the current input state from the backend and can get called at uneven intervals, or even multiple times during the same frame, so smoothing the movement here can lead to erratic behavior. With this change CONTROL_GetInput will return the same data unless it gets updated between calls. --- source/core/inputstate.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index 3880e7e4f..4feaab77e 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -55,22 +55,9 @@ bool sendPause; void InputState::GetMouseDelta(ControlInfo * info) { - vec2f_t input, finput; - - input = g_mousePos; + vec2f_t finput = g_mousePos; g_mousePos = {}; - if (in_mousesmoothing) - { - static vec2f_t last; - finput = { (input.x + last.x) * 0.5f, (input.y + last.y) * 0.5f }; - last = input; - } - else - { - finput = { input.x, input.y }; - } - info->mousex = finput.x * (16.f / 32.f) * in_mousesensitivity * in_mousescalex / 3.f; info->mousey = finput.y * (16.f / 64.f) * in_mousesensitivity * in_mousescaley; From 20426a5a4f27bf97c7aa22ede031bfba41b308cc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Aug 2020 21:09:04 +0200 Subject: [PATCH 26/43] Revert "- pass loc as a parameter to Duke's GetInput function to uncouple it from the global variable." This reverts commit a03b6cf57cfdacbe27c9b231842b579b407ec48c. Turns out this wasn't really useful. --- source/games/duke/src/funct.h | 2 +- source/games/duke/src/gameloop.cpp | 4 +- source/games/duke/src/input.cpp | 80 +++++++++++++++--------------- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 81cda40ab..5cb8e16bf 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -234,7 +234,7 @@ void apply_seasick(player_struct* p, double scalefactor); void calcviewpitch(player_struct* p, double factor); void sethorizon(int snum, ESyncBits actions, double factor, fixed_t adjustment); bool movementBlocked(int snum); -void GetInput(InputPacket &loc); +void GetInput(); void startmainmenu(); void loadcons(); diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index db51adb06..a6893fa5c 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -333,7 +333,7 @@ bool GameTicker() { lastTic = currentTic; - GetInput(loc); + GetInput(); auto const pPlayer = &ps[myconnectindex]; auto const q16ang = fix16_to_int(pPlayer->q16ang); auto& input = nextinput(myconnectindex); @@ -366,7 +366,7 @@ bool GameTicker() if (!cl_syncinput) { - GetInput(loc); + GetInput(); } drawtime.Reset(); diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 8633d686e..3fed36a2d 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -565,28 +565,28 @@ enum // //--------------------------------------------------------------------------- -static void processInputBits(InputPacket &locInput, player_struct *p, ControlInfo &info) +static void processInputBits(player_struct *p, ControlInfo &info) { ApplyGlobalInput(loc, &info); - if (isRR() && (locInput.actions & SB_CROUCH)) locInput.actions &= ~SB_JUMP; + if (isRR() && (loc.actions & SB_CROUCH)) loc.actions &= ~SB_JUMP; if (p->OnMotorcycle || p->OnBoat) { // mask out all actions not compatible with vehicles. - locInput.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH | SB_RUN | + loc.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH | SB_RUN | SB_AIM_UP | SB_AIM_DOWN | SB_AIMMODE | SB_LOOK_UP | SB_LOOK_DOWN | SB_LOOK_LEFT | SB_LOOK_RIGHT); } else { if (buttonMap.ButtonDown(gamefunc_Quick_Kick)) // this shares a bit with another function so cannot be in the common code. - locInput.actions |= SB_QUICK_KICK; + loc.actions |= SB_QUICK_KICK; if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch) || p->crouch_toggle) { - locInput.actions |= SB_CROUCH; + loc.actions |= SB_CROUCH; } - if ((isRR() && p->drink_amt > 88)) locInput.actions |= SB_LOOK_LEFT; - if ((isRR() && p->drink_amt > 99)) locInput.actions |= SB_LOOK_DOWN; + if ((isRR() && p->drink_amt > 88)) loc.actions |= SB_LOOK_LEFT; + if ((isRR() && p->drink_amt > 99)) loc.actions |= SB_LOOK_DOWN; } } @@ -632,12 +632,12 @@ int getticssincelastupdate() // //--------------------------------------------------------------------------- -static void processMovement(player_struct *p, InputPacket& locInput, InputPacket &input, ControlInfo &info, double scaleFactor) +static void processMovement(player_struct *p, InputPacket &input, ControlInfo &info, double scaleFactor) { - bool mouseaim = !!(locInput.actions & SB_AIMMODE); + bool mouseaim = !!(loc.actions & SB_AIMMODE); // JBF: Run key behaviour is selectable - int running = !!(locInput.actions & SB_RUN); + int running = !!(loc.actions & SB_RUN); int turnamount = NORMALTURN << running; int keymove = NORMALKEYMOVE << running; @@ -659,7 +659,7 @@ static void processMovement(player_struct *p, InputPacket& locInput, InputPacket if (buttonMap.ButtonDown(gamefunc_Strafe)) { - if (!locInput.svel) + if (!loc.svel) { if (buttonMap.ButtonDown(gamefunc_Turn_Left)) input.svel = keymove; @@ -690,7 +690,7 @@ static void processMovement(player_struct *p, InputPacket& locInput, InputPacket } - if (abs(locInput.svel) < keymove) + if (abs(loc.svel) < keymove) { if (buttonMap.ButtonDown(gamefunc_Strafe_Left)) input.svel += keymove; @@ -699,7 +699,7 @@ static void processMovement(player_struct *p, InputPacket& locInput, InputPacket input.svel += -keymove; } - if (abs(locInput.fvel) < keymove) + if (abs(loc.fvel) < keymove) { if (isRR() && p->drink_amt >= 66 && p->drink_amt <= 87) { @@ -910,7 +910,7 @@ static double boatApplyTurn(player_struct *p, int turnl, int turnr, int boat_tur // //--------------------------------------------------------------------------- -static void processVehicleInput(player_struct *p, ControlInfo& info, InputPacket& locInput, InputPacket& input, double scaleAdjust) +static void processVehicleInput(player_struct *p, ControlInfo& info, InputPacket& input, double scaleAdjust) { auto turnspeed = info.mousex + scaleAdjust * info.dyaw * (1. / 32); // originally this was 64, not 32. Why the change? int turnl = buttonMap.ButtonDown(gamefunc_Turn_Left) || buttonMap.ButtonDown(gamefunc_Strafe_Left); @@ -928,17 +928,17 @@ static void processVehicleInput(player_struct *p, ControlInfo& info, InputPacket if (p->OnBoat || !p->moto_underwater) { if (buttonMap.ButtonDown(gamefunc_Move_Forward) || buttonMap.ButtonDown(gamefunc_Strafe)) - locInput.actions |= SB_JUMP; + loc.actions |= SB_JUMP; if (buttonMap.ButtonDown(gamefunc_Move_Backward)) - locInput.actions |= SB_AIM_UP; - if (locInput.actions & SB_RUN) - locInput.actions |= SB_CROUCH; + loc.actions |= SB_AIM_UP; + if (loc.actions & SB_RUN) + loc.actions |= SB_CROUCH; } if (turnl) - locInput.actions |= SB_AIM_DOWN; + loc.actions |= SB_AIM_DOWN; if (turnr) - locInput.actions |= SB_LOOK_LEFT; + loc.actions |= SB_LOOK_LEFT; double turnvel; @@ -968,7 +968,7 @@ static void processVehicleInput(player_struct *p, ControlInfo& info, InputPacket // //--------------------------------------------------------------------------- -static void FinalizeInput(int playerNum, InputPacket& locInput, InputPacket& input, bool vehicle) +static void FinalizeInput(int playerNum, InputPacket& input, bool vehicle) { auto p = &ps[playerNum]; bool blocked = movementBlocked(playerNum) || sprite[p->i].extra <= 0 || (p->dead_flag && !ud.god); @@ -981,8 +981,8 @@ static void FinalizeInput(int playerNum, InputPacket& locInput, InputPacket& inp ud.folavel = fix16_to_int(input.q16avel); } - locInput.fvel = locInput.svel = 0; - locInput.q16avel = locInput.q16horz = 0; + loc.fvel = loc.svel = 0; + loc.q16avel = loc.q16horz = 0; input.q16avel = input.q16horz = 0; } else @@ -991,21 +991,21 @@ static void FinalizeInput(int playerNum, InputPacket& locInput, InputPacket& inp { if (!vehicle) { - locInput.fvel = clamp(locInput.fvel + input.fvel, -MAXVEL, MAXVEL); - locInput.svel = clamp(locInput.svel + input.svel, -MAXSVEL, MAXSVEL); + loc.fvel = clamp(loc.fvel + input.fvel, -MAXVEL, MAXVEL); + loc.svel = clamp(loc.svel + input.svel, -MAXSVEL, MAXSVEL); } else - locInput.fvel = clamp(input.fvel, -(MAXVELMOTO / 8), MAXVELMOTO); + loc.fvel = clamp(input.fvel, -(MAXVELMOTO / 8), MAXVELMOTO); } else { - locInput.fvel = input.fvel = 0; - locInput.svel = input.svel = 0; + loc.fvel = input.fvel = 0; + loc.svel = input.svel = 0; } if (p->on_crane < 0 && p->newowner == -1) { - locInput.q16avel = fix16_clamp(locInput.q16avel + input.q16avel, F16(-MAXANGVEL), F16(MAXANGVEL)); + loc.q16avel = fix16_clamp(loc.q16avel + input.q16avel, F16(-MAXANGVEL), F16(MAXANGVEL)); if (!cl_syncinput && input.q16avel) { p->one_eighty_count = 0; @@ -1013,16 +1013,16 @@ static void FinalizeInput(int playerNum, InputPacket& locInput, InputPacket& inp } else { - locInput.q16avel = input.q16avel = 0; + loc.q16avel = input.q16avel = 0; } if (p->newowner == -1 && p->return_to_center <= 0) { - locInput.q16horz = fix16_clamp(locInput.q16horz + input.q16horz, F16(-MAXHORIZVEL), F16(MAXHORIZVEL)); + loc.q16horz = fix16_clamp(loc.q16horz + input.q16horz, F16(-MAXHORIZVEL), F16(MAXHORIZVEL)); } else { - locInput.q16horz = input.q16horz = 0; + loc.q16horz = input.q16horz = 0; } } } @@ -1033,7 +1033,7 @@ static void FinalizeInput(int playerNum, InputPacket& locInput, InputPacket& inp // //--------------------------------------------------------------------------- -void GetInput(InputPacket &locInput) +void GetInput() { double elapsedInputTicks; auto const p = &ps[myconnectindex]; @@ -1064,9 +1064,9 @@ void GetInput(InputPacket &locInput) if (isRRRA() && (p->OnMotorcycle || p->OnBoat)) { p->crouch_toggle = 0; - processInputBits(locInput, p, info); - processVehicleInput(p, info, locInput, input, scaleAdjust); - FinalizeInput(myconnectindex, locInput, input, true); + processInputBits(p, info); + processVehicleInput(p, info, input, scaleAdjust); + FinalizeInput(myconnectindex, input, true); if (!cl_syncinput && sprite[p->i].extra > 0) { @@ -1075,10 +1075,10 @@ void GetInput(InputPacket &locInput) } else { - processInputBits(locInput, p, info); - processMovement(p, input, locInput, info, scaleAdjust); + processInputBits(p, info); + processMovement(p, input, info, scaleAdjust); checkCrouchToggle(p); - FinalizeInput(myconnectindex, locInput, input, false); + FinalizeInput(myconnectindex, input, false); } if (!cl_syncinput) @@ -1086,7 +1086,7 @@ void GetInput(InputPacket &locInput) // Do these in the same order as the old code. calcviewpitch(p, scaleAdjust); applylook(myconnectindex, scaleAdjust, input.q16avel); - sethorizon(myconnectindex, locInput.actions, scaleAdjust, input.q16horz); + sethorizon(myconnectindex, loc.actions, scaleAdjust, input.q16horz); } } From fab561d757afaafac150018f442fc2f47bcf4c0e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Aug 2020 21:20:10 +0200 Subject: [PATCH 27/43] - cleaned up Duke's main GameTicker function. * moved the part that alters the input before queuing it to GetInput * moved moveloop into the main function * reshuffled a few things for better grouping by task. --- source/core/gamecontrol.cpp | 2 +- source/core/gamecvars.cpp | 2 - source/core/gamecvars.h | 1 - source/core/gamestruct.h | 2 + source/games/duke/src/duke3d.h | 3 +- source/games/duke/src/funct.h | 3 +- source/games/duke/src/game_misc.cpp | 2 +- source/games/duke/src/gameloop.cpp | 106 ++++++++++------------------ source/games/duke/src/global.cpp | 1 - source/games/duke/src/global.h | 1 - source/games/duke/src/input.cpp | 38 +++++++++- 11 files changed, 82 insertions(+), 79 deletions(-) diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index d617aef53..084802a17 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -118,7 +118,7 @@ CCMD(togglefollow) gi->ResetFollowPos(true); } -glcycle_t thinktime, actortime, gameupdatetime, drawtime; +cycle_t thinktime, actortime, gameupdatetime, drawtime; gamestate_t gamestate = GS_STARTUP; diff --git a/source/core/gamecvars.cpp b/source/core/gamecvars.cpp index 9975ebb75..a30852efe 100644 --- a/source/core/gamecvars.cpp +++ b/source/core/gamecvars.cpp @@ -229,8 +229,6 @@ CUSTOM_CVARD(Int, in_mousebias, 0, CVAR_GLOBALCONFIG|CVAR_ARCHIVE, "emulates the else if (self > 32) self = 32; } -CVARD(Bool, in_mousesmoothing, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE, "enable/disable mouse input smoothing") - CUSTOM_CVARD(Float, in_mousesensitivity, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "changes the mouse sensitivity") { if (self < 0) self = 0; diff --git a/source/core/gamecvars.h b/source/core/gamecvars.h index aaecae826..e412cd54f 100644 --- a/source/core/gamecvars.h +++ b/source/core/gamecvars.h @@ -88,7 +88,6 @@ EXTERN_CVAR(Int, gl_ssao) EXTERN_CVAR(Bool, use_joystick) EXTERN_CVAR(Int, in_mousebias) EXTERN_CVAR(Bool, in_mouseflip) -EXTERN_CVAR(Bool, in_mousesmoothing) EXTERN_CVAR(Float, in_mousesensitivity) EXTERN_CVAR(Float, in_mousescalex) EXTERN_CVAR(Float, in_mousescaley) diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h index 7ae7977b7..adbf617d1 100644 --- a/source/core/gamestruct.h +++ b/source/core/gamestruct.h @@ -5,6 +5,7 @@ bool System_WantGuiCapture(); // During playing this tells us whether the game m #include #include "vectors.h" #include "engineerrors.h" +#include "packet.h" struct GameStats { @@ -91,6 +92,7 @@ struct GameInterface virtual void ExitFromMenu() { throw CExitEvent(0); } virtual ReservedSpace GetReservedScreenSpace(int viewsize) { return { 0, 0 }; } virtual void ResetFollowPos(bool) {} + virtual void GetInput(InputPacket* packet) {} }; diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 4ebde4370..0d24c1c62 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -22,7 +22,7 @@ #include "stats.h" #include "binaryangle.h" -extern glcycle_t drawtime, actortime, thinktime, gameupdatetime; +extern cycle_t drawtime, actortime, thinktime, gameupdatetime; BEGIN_DUKE_NS @@ -57,6 +57,7 @@ struct GameInterface : public ::GameInterface ReservedSpace GetReservedScreenSpace(int viewsize) override; void DrawPlayerSprite(const DVector2& origin, bool onteam) override; void ResetFollowPos(bool message) override; + void GetInput(InputPacket* packet) override; }; diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 5cb8e16bf..3027c5bf4 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -212,7 +212,7 @@ void dobonus(int bonusonly, const CompletionFunc& completion); void dobonus_d(bool bonusonly, const CompletionFunc& completion); void dobonus_r(bool bonusonly, const CompletionFunc& completion); -void displayrest(double smoothratio); +void drawoverlays(double smoothratio); void drawbackground(void); void displayrooms(int32_t playerNum, double smoothratio); void setgamepalette(int palid); @@ -234,7 +234,6 @@ void apply_seasick(player_struct* p, double scalefactor); void calcviewpitch(player_struct* p, double factor); void sethorizon(int snum, ESyncBits actions, double factor, fixed_t adjustment); bool movementBlocked(int snum); -void GetInput(); void startmainmenu(); void loadcons(); diff --git a/source/games/duke/src/game_misc.cpp b/source/games/duke/src/game_misc.cpp index 8c5b57b4d..db93759a2 100644 --- a/source/games/duke/src/game_misc.cpp +++ b/source/games/duke/src/game_misc.cpp @@ -235,7 +235,7 @@ void V_AddBlend (float r, float g, float b, float a, float v_blend[4]) // //--------------------------------------------------------------------------- -void displayrest(double smoothratio) +void drawoverlays(double smoothratio) { int i, j; unsigned char fader = 0, fadeg = 0, fadeb = 0, fadef = 0, tintr = 0, tintg = 0, tintb = 0, tintf = 0, dotint = 0; diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index a6893fa5c..5099e7d19 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -51,7 +51,6 @@ static int bufferjitter; void clearfifo(void) { - loc = {}; memset(&inputfifo, 0, sizeof(inputfifo)); memset(sync, 0, sizeof(sync)); } @@ -280,48 +279,17 @@ int domovethings() // //--------------------------------------------------------------------------- -int moveloop() -{ - prediction(); - - if (numplayers < 2) bufferjitter = 0; - while (shouldprocessinput(myconnectindex)) - { - if( domovethings() ) return 1; - } - return 0; -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -static void checkTimerActive() -{ - FStat *stat = FStat::FindStat("fps"); - glcycle_t::active = (stat != NULL && stat->isActive()); -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -bool GameTicker() +void GameTicker() { if (ps[myconnectindex].gm == MODE_DEMO) { M_ClearMenus(); - return true; + gamestate = GS_STARTUP; + return; } //Net_GetPackets(); - nonsharedkeys(); - checkTimerActive(); gameupdatetime.Reset(); gameupdatetime.Clock(); @@ -332,31 +300,24 @@ bool GameTicker() while (playrunning() && currentTic - lastTic >= 1) { lastTic = currentTic; - - GetInput(); - auto const pPlayer = &ps[myconnectindex]; - auto const q16ang = fix16_to_int(pPlayer->q16ang); auto& input = nextinput(myconnectindex); - input = loc; - input.fvel = mulscale9(loc.fvel, sintable[(q16ang + 2560) & 2047]) + - mulscale9(loc.svel, sintable[(q16ang + 2048) & 2047]) + - pPlayer->fric.x; - input.svel = mulscale9(loc.fvel, sintable[(q16ang + 2048) & 2047]) + - mulscale9(loc.svel, sintable[(q16ang + 1536) & 2047]) + - pPlayer->fric.y; - loc = {}; + gi->GetInput(&input); advancequeue(myconnectindex); if (playrunning()) { - moveloop(); + prediction(); + + if (numplayers < 2) bufferjitter = 0; + while (shouldprocessinput(myconnectindex)) + { + if (domovethings()) break; + } } } - double const smoothRatio = playrunning() ? I_GetTimeFrac() * MaxSmoothRatio : MaxSmoothRatio; - gameupdatetime.Unclock(); if (ps[myconnectindex].gm & (MODE_EOL | MODE_RESTART)) @@ -366,17 +327,23 @@ bool GameTicker() if (!cl_syncinput) { - GetInput(); + gi->GetInput(nullptr); } + nonsharedkeys(); + S_Update(); drawtime.Reset(); drawtime.Clock(); - S_Update(); + videoSetBrightness(thunder_brightness); + double const smoothRatio = playrunning() ? I_GetTimeFrac() * MaxSmoothRatio : MaxSmoothRatio; displayrooms(screenpeek, smoothRatio); - displayrest(smoothRatio); + drawoverlays(smoothRatio); drawtime.Unclock(); - return (ps[myconnectindex].gm & MODE_DEMO); + if (ps[myconnectindex].gm == MODE_DEMO) + { + gamestate = GS_STARTUP; + } } //--------------------------------------------------------------------------- @@ -393,18 +360,9 @@ void startmainmenu() FX_StopAllSounds(); } -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- -void GameInterface::RunGameFrame() +static void Startup() { - switch (gamestate) - { - default: - case GS_STARTUP: I_ResetTime(); lastTic = -1; gameclock = 0; @@ -432,6 +390,21 @@ void GameInterface::RunGameFrame() { fi.ShowLogo([](bool) { startmainmenu(); }); } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void GameInterface::RunGameFrame() +{ + switch (gamestate) + { + default: + case GS_STARTUP: + Startup(); break; case GS_MENUSCREEN: @@ -440,13 +413,12 @@ void GameInterface::RunGameFrame() break; case GS_LEVEL: - if (GameTicker()) gamestate = GS_STARTUP; - else videoSetBrightness(thunder_brightness); + GameTicker(); break; case GS_INTERMISSION: case GS_INTRO: - RunScreenJobFrame(); // This handles continuation through its completion callback. + RunScreenJobFrame(); break; } diff --git a/source/games/duke/src/global.cpp b/source/games/duke/src/global.cpp index 831fcfb9d..ed76dc31f 100644 --- a/source/games/duke/src/global.cpp +++ b/source/games/duke/src/global.cpp @@ -63,7 +63,6 @@ int16_t max_ammo_amount[MAX_WEAPONS]; int16_t weaponsandammosprites[15]; int PHEIGHT = PHEIGHT_DUKE; int duke3d_globalflags; -InputPacket loc; uint8_t ready2send; int playerswhenstarted; int show_shareware; diff --git a/source/games/duke/src/global.h b/source/games/duke/src/global.h index 19493020b..9e13c619c 100644 --- a/source/games/duke/src/global.h +++ b/source/games/duke/src/global.h @@ -51,7 +51,6 @@ extern int16_t weaponsandammosprites[15]; extern int32_t PHEIGHT; extern int duke3d_globalflags; extern uint8_t ready2send; -extern InputPacket loc; extern int playerswhenstarted; extern int show_shareware; extern int screenpeek; diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 3fed36a2d..5f6e94d81 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -44,6 +44,7 @@ static int nonsharedtimer; static int turnheldtime; static int lastcontroltime; static double lastCheck; +static InputPacket loc; // input accumulation buffer. void GameInterface::ResetFollowPos(bool message) { @@ -1033,7 +1034,7 @@ static void FinalizeInput(int playerNum, InputPacket& input, bool vehicle) // //--------------------------------------------------------------------------- -void GetInput() +static void GetInputInternal(InputPacket &locInput) { double elapsedInputTicks; auto const p = &ps[myconnectindex]; @@ -1090,14 +1091,47 @@ void GetInput() } } +//--------------------------------------------------------------------------- +// +// External entry point +// +//--------------------------------------------------------------------------- + +void GameInterface::GetInput(InputPacket* packet) +{ + GetInputInternal(loc); + if (packet) + { + auto const pPlayer = &ps[myconnectindex]; + auto const q16ang = fix16_to_int(pPlayer->q16ang); + + *packet = loc; + auto fvel = loc.fvel; + auto svel = loc.svel; + packet->fvel = mulscale9(fvel, sintable[(q16ang + 2560) & 2047]) + + mulscale9(svel, sintable[(q16ang + 2048) & 2047]) + + pPlayer->fric.x; + packet->svel = mulscale9(fvel, sintable[(q16ang + 2048) & 2047]) + + mulscale9(svel, sintable[(q16ang + 1536) & 2047]) + + pPlayer->fric.y; + loc = {}; + } +} + +//--------------------------------------------------------------------------- +// // This is called from ImputState::ClearAllInput and resets all static state being used here. +// +//--------------------------------------------------------------------------- + void GameInterface::clearlocalinputstate() { + loc = {}; nonsharedtimer = 0; turnheldtime = 0; lastcontroltime = 0; lastCheck = 0; - } + END_DUKE_NS From 15adf1f6e5a84cacea84aed3cfe0c25d691aa2dc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Aug 2020 22:07:47 +0200 Subject: [PATCH 28/43] - hooked up ZDoom's i_net.cpp to compile within the project. Note about the license: This file was available from GZDoom 2.4.x under the Doom source license which is compatible with Build. This isn't used yet. --- source/common/engine/i_interface.h | 1 + source/common/engine/i_net.cpp | 1070 ++++++++++++++++++++++++++++ source/common/engine/i_net.h | 84 +++ 3 files changed, 1155 insertions(+) create mode 100644 source/common/engine/i_net.cpp create mode 100644 source/common/engine/i_net.h diff --git a/source/common/engine/i_interface.h b/source/common/engine/i_interface.h index f5fed4531..db46eb885 100644 --- a/source/common/engine/i_interface.h +++ b/source/common/engine/i_interface.h @@ -18,6 +18,7 @@ struct SystemCallbacks IntRect(*GetSceneRect)(); FString(*GetLocationDescription)(); void (*MenuDim)(); + FString(*GetPlayerName)(int i); }; extern SystemCallbacks *sysCallbacks; diff --git a/source/common/engine/i_net.cpp b/source/common/engine/i_net.cpp new file mode 100644 index 000000000..0563c40b1 --- /dev/null +++ b/source/common/engine/i_net.cpp @@ -0,0 +1,1070 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id: i_net.c,v 1.2 1997/12/29 19:50:54 pekangas Exp $ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// DESCRIPTION: +// Low-level networking code. Uses BSD sockets for UDP networking. +// +//----------------------------------------------------------------------------- + + +/* [Petteri] Check if compiling for Win32: */ +#if defined(__WINDOWS__) || defined(__NT__) || defined(_MSC_VER) || defined(_WIN32) +#ifndef __WIN32__ +# define __WIN32__ +#endif +#endif +/* Follow #ifdef __WIN32__ marks */ + +#include +#include + +/* [Petteri] Use Winsock for Win32: */ +#ifdef __WIN32__ +# define WIN32_LEAN_AND_MEAN +# include +# include +#else +# include +# include +# include +# include +# include +# include +# include +# ifdef __sun +# include +# endif +#endif + +//#include "doomtype.h" +#include "i_system.h" +//#include "d_net.h" +#include "m_argv.h" +#include "m_crc32.h" +//#include "d_player.h" +#include "st_start.h" +//#include "m_misc.h" +#include "engineerrors.h" +#include "cmdlib.h" +#include "printf.h" +#include "i_interface.h" +#include "templates.h" + +#include "i_net.h" + +// As per http://support.microsoft.com/kb/q192599/ the standard +// size for network buffers is 8k. +#define TRANSMIT_SIZE 8000 + +/* [Petteri] Get more portable: */ +#ifndef __WIN32__ +typedef int SOCKET; +#define SOCKET_ERROR -1 +#define INVALID_SOCKET -1 +#define closesocket close +#define ioctlsocket ioctl +#define Sleep(x) usleep (x * 1000) +#define WSAEWOULDBLOCK EWOULDBLOCK +#define WSAECONNRESET ECONNRESET +#define WSAGetLastError() errno +#endif + +#ifndef IPPORT_USERRESERVED +#define IPPORT_USERRESERVED 5000 +#endif + +#ifdef __WIN32__ +typedef int socklen_t; +#endif + +bool netgame, multiplayer; +int consoleplayer; // i.e. myconnectindex in Build. +doomcom_t doomcom; + +// +// NETWORKING +// + +static u_short DOOMPORT = (IPPORT_USERRESERVED + 29); +static SOCKET mysocket = INVALID_SOCKET; +static sockaddr_in sendaddress[MAXNETNODES]; +static uint8_t sendplayer[MAXNETNODES]; + +#ifdef __WIN32__ +const char *neterror (void); +#else +#define neterror() strerror(errno) +#endif + +enum +{ + PRE_CONNECT, // Sent from guest to host for initial connection + PRE_KEEPALIVE, + PRE_DISCONNECT, // Sent from guest that aborts the game + PRE_ALLHERE, // Sent from host to guest when everybody has connected + PRE_CONACK, // Sent from host to guest to acknowledge PRE_CONNECT receipt + PRE_ALLFULL, // Sent from host to an unwanted guest + PRE_ALLHEREACK, // Sent from guest to host to acknowledge PRE_ALLHEREACK receipt + PRE_GO // Sent from host to guest to continue game startup +}; + +// Set PreGamePacket.fake to this so that the game rejects any pregame packets +// after it starts. This translates to NCMD_SETUP|NCMD_MULTI. +#define PRE_FAKE 0x30 + +struct PreGamePacket +{ + uint8_t Fake; + uint8_t Message; + uint8_t NumNodes; + union + { + uint8_t ConsoleNum; + uint8_t NumPresent; + }; + struct + { + uint32_t address; + uint16_t port; + uint8_t player; + uint8_t pad; + } machines[MAXNETNODES]; +}; + +uint8_t TransmitBuffer[TRANSMIT_SIZE]; + +FString GetPlayerName(int num) +{ + if (sysCallbacks && sysCallbacks->GetPlayerName) return sysCallbacks->GetPlayerName(num); + else return FStringf("Player %d", num + 1); +} + +// +// UDPsocket +// +SOCKET UDPsocket (void) +{ + SOCKET s; + + // allocate a socket + s = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (s == INVALID_SOCKET) + I_FatalError ("can't create socket: %s", neterror ()); + + return s; +} + +// +// BindToLocalPort +// +void BindToLocalPort (SOCKET s, u_short port) +{ + int v; + sockaddr_in address; + + memset (&address, 0, sizeof(address)); + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(port); + + v = bind (s, (sockaddr *)&address, sizeof(address)); + if (v == SOCKET_ERROR) + I_FatalError ("BindToPort: %s", neterror ()); +} + +int FindNode (const sockaddr_in *address) +{ + int i; + + // find remote node number + for (i = 0; isin_addr.s_addr == sendaddress[i].sin_addr.s_addr + && address->sin_port == sendaddress[i].sin_port) + break; + + if (i == doomcom.numnodes) + { + // packet is not from one of the players (new game broadcast?) + i = -1; + } + return i; +} + +// +// PacketSend +// +void PacketSend (void) +{ + int c; + + // FIXME: Catch this before we've overflown the buffer. With long chat + // text and lots of backup tics, it could conceivably happen. (Though + // apparently it hasn't yet, which is good.) + if (doomcom.datalength > MAX_MSGLEN) + { + I_FatalError("Netbuffer overflow!"); + } + assert(!(doomcom.data[0] & NCMD_COMPRESSED)); + + uLong size = TRANSMIT_SIZE - 1; + if (doomcom.datalength >= 10) + { + TransmitBuffer[0] = doomcom.data[0] | NCMD_COMPRESSED; + c = compress2(TransmitBuffer + 1, &size, doomcom.data + 1, doomcom.datalength - 1, 9); + size += 1; + } + else + { + c = -1; // Just some random error code to avoid sending the compressed buffer. + } + if (c == Z_OK && size < (uLong)doomcom.datalength) + { +// Printf("send %lu/%d\n", size, doomcom.datalength); + c = sendto(mysocket, (char *)TransmitBuffer, size, + 0, (sockaddr *)&sendaddress[doomcom.remotenode], + sizeof(sendaddress[doomcom.remotenode])); + } + else + { + if (doomcom.datalength > TRANSMIT_SIZE) + { + I_Error("Net compression failed (zlib error %d)", c); + } + else + { +// Printf("send %d\n", doomcom.datalength); + c = sendto(mysocket, (char *)doomcom.data, doomcom.datalength, + 0, (sockaddr *)&sendaddress[doomcom.remotenode], + sizeof(sendaddress[doomcom.remotenode])); + } + } + // if (c == -1) + // I_Error ("SendPacket error: %s",strerror(errno)); +} + + +// +// PacketGet +// +void PacketGet (void) +{ + int c; + socklen_t fromlen; + sockaddr_in fromaddress; + int node; + + fromlen = sizeof(fromaddress); + c = recvfrom (mysocket, (char*)TransmitBuffer, TRANSMIT_SIZE, 0, + (sockaddr *)&fromaddress, &fromlen); + node = FindNode (&fromaddress); + + if (node >= 0 && c == SOCKET_ERROR) + { + int err = WSAGetLastError(); + + if (err == WSAECONNRESET) + { // The remote node aborted unexpectedly, so pretend it sent an exit packet + + if (StartScreen != NULL) + { + StartScreen->NetMessage ("The connection from %s was dropped.\n", + GetPlayerName(node).GetChars()); + } + else + { + Printf("The connection from %s was dropped.\n", + GetPlayerName(node).GetChars()); + } + + doomcom.data[0] = 0x80; // NCMD_EXIT + c = 1; + } + else if (err != WSAEWOULDBLOCK) + { + I_Error ("GetPacket: %s", neterror ()); + } + else + { + doomcom.remotenode = -1; // no packet + return; + } + } + else if (node >= 0 && c > 0) + { + doomcom.data[0] = TransmitBuffer[0] & ~NCMD_COMPRESSED; + if (TransmitBuffer[0] & NCMD_COMPRESSED) + { + uLongf msgsize = MAX_MSGLEN - 1; + int err = uncompress(doomcom.data + 1, &msgsize, TransmitBuffer + 1, c - 1); +// Printf("recv %d/%lu\n", c, msgsize + 1); + if (err != Z_OK) + { + Printf("Net decompression failed (zlib error %s)\n", M_ZLibError(err).GetChars()); + // Pretend no packet + doomcom.remotenode = -1; + return; + } + c = msgsize + 1; + } + else + { +// Printf("recv %d\n", c); + memcpy(doomcom.data + 1, TransmitBuffer + 1, c - 1); + } + } + else if (c > 0) + { //The packet is not from any in-game node, so we might as well discard it. + // Don't show the message for disconnect notifications. + if (c != 2 || TransmitBuffer[0] != PRE_FAKE || TransmitBuffer[1] != PRE_DISCONNECT) + { + DPrintf(DMSG_WARNING, "Dropped packet: Unknown host (%s:%d)\n", inet_ntoa(fromaddress.sin_addr), fromaddress.sin_port); + } + doomcom.remotenode = -1; + return; + } + + doomcom.remotenode = node; + doomcom.datalength = (short)c; +} + +sockaddr_in *PreGet (void *buffer, int bufferlen, bool noabort) +{ + static sockaddr_in fromaddress; + socklen_t fromlen; + int c; + + fromlen = sizeof(fromaddress); + c = recvfrom (mysocket, (char *)buffer, bufferlen, 0, + (sockaddr *)&fromaddress, &fromlen); + + if (c == SOCKET_ERROR) + { + int err = WSAGetLastError(); + if (err == WSAEWOULDBLOCK || (noabort && err == WSAECONNRESET)) + return NULL; // no packet + I_Error ("PreGet: %s", neterror ()); + } + return &fromaddress; +} + +void PreSend (const void *buffer, int bufferlen, const sockaddr_in *to) +{ + sendto (mysocket, (const char *)buffer, bufferlen, 0, (const sockaddr *)to, sizeof(*to)); +} + +void BuildAddress (sockaddr_in *address, const char *name) +{ + hostent *hostentry; // host information entry + u_short port; + const char *portpart; + bool isnamed = false; + int curchar; + char c; + FString target; + + address->sin_family = AF_INET; + + if ( (portpart = strchr (name, ':')) ) + { + target = FString(name, portpart - name); + port = atoi (portpart + 1); + if (!port) + { + Printf ("Weird port: %s (using %d)\n", portpart + 1, DOOMPORT); + port = DOOMPORT; + } + } + else + { + target = name; + port = DOOMPORT; + } + address->sin_port = htons(port); + + for (curchar = 0; (c = target[curchar]) ; curchar++) + { + if ((c < '0' || c > '9') && c != '.') + { + isnamed = true; + break; + } + } + + if (!isnamed) + { + address->sin_addr.s_addr = inet_addr (target); + Printf ("Node number %d, address %s\n", doomcom.numnodes, target.GetChars()); + } + else + { + hostentry = gethostbyname (target); + if (!hostentry) + I_FatalError ("gethostbyname: couldn't find %s\n%s", target.GetChars(), neterror()); + address->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; + Printf ("Node number %d, hostname %s\n", + doomcom.numnodes, hostentry->h_name); + } +} + +void CloseNetwork (void) +{ + if (mysocket != INVALID_SOCKET) + { + closesocket (mysocket); + mysocket = INVALID_SOCKET; + } +#ifdef __WIN32__ + WSACleanup (); +#endif +} + +void StartNetwork (bool autoPort) +{ + u_long trueval = 1; +#ifdef __WIN32__ + WSADATA wsad; + + if (WSAStartup (0x0101, &wsad)) + { + I_FatalError ("Could not initialize Windows Sockets"); + } +#endif + + netgame = true; + multiplayer = true; + + // create communication socket + mysocket = UDPsocket (); + BindToLocalPort (mysocket, autoPort ? 0 : DOOMPORT); +#ifndef __sun + ioctlsocket (mysocket, FIONBIO, &trueval); +#else + fcntl(mysocket, F_SETFL, trueval | O_NONBLOCK); +#endif +} + +void SendAbort (void) +{ + uint8_t dis[2] = { PRE_FAKE, PRE_DISCONNECT }; + int i, j; + + if (doomcom.numnodes > 1) + { + if (consoleplayer == 0) + { + // The host needs to let everyone know + for (i = 1; i < doomcom.numnodes; ++i) + { + for (j = 4; j > 0; --j) + { + PreSend (dis, 2, &sendaddress[i]); + } + } + } + else + { + // Guests only need to let the host know. + for (i = 4; i > 0; --i) + { + PreSend (dis, 2, &sendaddress[1]); + } + } + } +} + +static void SendConAck (int num_connected, int num_needed) +{ + PreGamePacket packet; + + packet.Fake = PRE_FAKE; + packet.Message = PRE_CONACK; + packet.NumNodes = num_needed; + packet.NumPresent = num_connected; + for (int node = 1; node < doomcom.numnodes; ++node) + { + PreSend (&packet, 4, &sendaddress[node]); + } + StartScreen->NetProgress (doomcom.numnodes); +} + +bool Host_CheckForConnects (void *userdata) +{ + PreGamePacket packet; + int numplayers = (int)(intptr_t)userdata; + sockaddr_in *from; + int node; + + while ( (from = PreGet (&packet, sizeof(packet), false)) ) + { + if (packet.Fake != PRE_FAKE) + { + continue; + } + switch (packet.Message) + { + case PRE_CONNECT: + node = FindNode (from); + if (doomcom.numnodes == numplayers) + { + if (node == -1) + { + const uint8_t *s_addr_bytes = (const uint8_t *)&from->sin_addr; + StartScreen->NetMessage ("Got extra connect from %d.%d.%d.%d:%d", + s_addr_bytes[0], s_addr_bytes[1], s_addr_bytes[2], s_addr_bytes[3], + from->sin_port); + packet.Message = PRE_ALLFULL; + PreSend (&packet, 2, from); + } + } + else + { + if (node == -1) + { + node = doomcom.numnodes++; + sendaddress[node] = *from; + StartScreen->NetMessage ("Got connect from node %d.", node); + } + + // Let the new guest (and everyone else) know we got their message. + SendConAck (doomcom.numnodes, numplayers); + } + break; + + case PRE_DISCONNECT: + node = FindNode (from); + if (node >= 0) + { + StartScreen->NetMessage ("Got disconnect from node %d.", node); + doomcom.numnodes--; + while (node < doomcom.numnodes) + { + sendaddress[node] = sendaddress[node+1]; + node++; + } + + // Let remaining guests know that somebody left. + SendConAck (doomcom.numnodes, numplayers); + } + break; + + case PRE_KEEPALIVE: + break; + } + } + if (doomcom.numnodes < numplayers) + { + // Send message to everyone as a keepalive + SendConAck(doomcom.numnodes, numplayers); + return false; + } + + // It's possible somebody bailed out after all players were found. + // Unfortunately, this isn't guaranteed to catch all of them. + // Oh well. Better than nothing. + while ( (from = PreGet (&packet, sizeof(packet), false)) ) + { + if (packet.Fake == PRE_FAKE && packet.Message == PRE_DISCONNECT) + { + node = FindNode (from); + if (node >= 0) + { + doomcom.numnodes--; + while (node < doomcom.numnodes) + { + sendaddress[node] = sendaddress[node+1]; + node++; + } + // Let remaining guests know that somebody left. + SendConAck (doomcom.numnodes, numplayers); + } + break; + } + } + return doomcom.numnodes >= numplayers; +} + +bool Host_SendAllHere (void *userdata) +{ + int *gotack = (int *)userdata; // ackcount is at gotack[MAXNETNODES] + PreGamePacket packet; + int node; + sockaddr_in *from; + + // Send out address information to all guests. Guests that have already + // acknowledged receipt effectively get just a heartbeat packet. + packet.Fake = PRE_FAKE; + packet.Message = PRE_ALLHERE; + for (node = 1; node < doomcom.numnodes; node++) + { + int machine, spot = 0; + + packet.ConsoleNum = node; + if (!gotack[node]) + { + for (spot = 0, machine = 1; machine < doomcom.numnodes; machine++) + { + if (node != machine) + { + packet.machines[spot].address = sendaddress[machine].sin_addr.s_addr; + packet.machines[spot].port = sendaddress[machine].sin_port; + packet.machines[spot].player = node; + + spot++; // fixes problem of new address replacing existing address in + // array; it's supposed to increment the index before getting + // and storing in the packet the next address. + } + } + packet.NumNodes = doomcom.numnodes - 2; + } + else + { + packet.NumNodes = 0; + } + PreSend (&packet, 4 + spot*8, &sendaddress[node]); + } + + // Check for replies. + while ( (from = PreGet (&packet, sizeof(packet), false)) ) + { + if (packet.Fake == PRE_FAKE && packet.Message == PRE_ALLHEREACK) + { + node = FindNode (from); + if (node >= 0) + { + if (!gotack[node]) + { + gotack[node] = true; + gotack[MAXNETNODES]++; + } + } + PreSend (&packet, 2, from); + } + } + + // If everybody has replied, then this loop can end. + return gotack[MAXNETNODES] == doomcom.numnodes - 1; +} + +bool HostGame (int i) +{ + PreGamePacket packet; + int numplayers; + int node; + int gotack[MAXNETNODES+1]; + + if ((i == Args->NumArgs() - 1) || !(numplayers = atoi (Args->GetArg(i+1)))) + { // No player count specified, assume 2 + numplayers = 2; + } + + if (numplayers > MAXNETNODES) + { + I_FatalError("You cannot host a game with %d players. The limit is currently %d.", numplayers, MAXNETNODES); + } + + if (numplayers == 1) + { // Special case: Only 1 player, so don't bother starting the network + netgame = false; + multiplayer = true; + doomcom.id = DOOMCOM_ID; + doomcom.numplayers = doomcom.numnodes = 1; + doomcom.consoleplayer = 0; + return true; + } + + StartNetwork (false); + + // [JC] - this computer is starting the game, therefore it should + // be the Net Arbitrator. + doomcom.consoleplayer = 0; + Printf ("Console player number: %d\n", doomcom.consoleplayer); + + doomcom.numnodes = 1; + + StartScreen->NetInit ("Waiting for players", numplayers); + + // Wait for numplayers-1 different connections + if (!StartScreen->NetLoop (Host_CheckForConnects, (void *)(intptr_t)numplayers)) + { + SendAbort(); + return false; + } + + // Now inform everyone of all machines involved in the game + memset (gotack, 0, sizeof(gotack)); + StartScreen->NetMessage ("Sending all here."); + StartScreen->NetInit ("Done waiting", 1); + + if (!StartScreen->NetLoop (Host_SendAllHere, (void *)gotack)) + { + SendAbort(); + return false; + } + + // Now go + StartScreen->NetMessage ("Go"); + packet.Fake = PRE_FAKE; + packet.Message = PRE_GO; + for (node = 1; node < doomcom.numnodes; node++) + { + // If we send the packets eight times to each guest, + // hopefully at least one of them will get through. + for (int i = 8; i != 0; --i) + { + PreSend (&packet, 2, &sendaddress[node]); + } + } + + StartScreen->NetMessage ("Total players: %d", doomcom.numnodes); + + doomcom.id = DOOMCOM_ID; + doomcom.numplayers = doomcom.numnodes; + + // On the host, each player's number is the same as its node number + for (i = 0; i < doomcom.numnodes; ++i) + { + sendplayer[i] = i; + } + return true; +} + +// This routine is used by a guest to notify the host of its presence. +// Once that host acknowledges receipt of the notification, this routine +// is never called again. + +bool Guest_ContactHost (void *userdata) +{ + sockaddr_in *from; + PreGamePacket packet; + + // Let the host know we are here. + packet.Fake = PRE_FAKE; + packet.Message = PRE_CONNECT; + PreSend (&packet, 2, &sendaddress[1]); + + // Listen for a reply. + while ( (from = PreGet (&packet, sizeof(packet), true)) ) + { + if (packet.Fake == PRE_FAKE && FindNode(from) == 1) + { + if (packet.Message == PRE_CONACK) + { + StartScreen->NetMessage ("Total players: %d", packet.NumNodes); + StartScreen->NetInit ("Waiting for other players", packet.NumNodes); + StartScreen->NetProgress (packet.NumPresent); + return true; + } + else if (packet.Message == PRE_DISCONNECT) + { + doomcom.numnodes = 0; + I_FatalError ("The host cancelled the game."); + } + else if (packet.Message == PRE_ALLFULL) + { + doomcom.numnodes = 0; + I_FatalError ("The game is full."); + } + } + } + + // In case the progress bar could not be marqueed, bump it. + StartScreen->NetProgress (0); + + return false; +} + +bool Guest_WaitForOthers (void *userdata) +{ + sockaddr_in *from; + PreGamePacket packet; + + while ( (from = PreGet (&packet, sizeof(packet), false)) ) + { + if (packet.Fake != PRE_FAKE || FindNode(from) != 1) + { + continue; + } + switch (packet.Message) + { + case PRE_CONACK: + StartScreen->NetProgress (packet.NumPresent); + break; + + case PRE_ALLHERE: + if (doomcom.numnodes == 2) + { + int node; + + doomcom.numnodes = packet.NumNodes + 2; + sendplayer[0] = packet.ConsoleNum; // My player number + doomcom.consoleplayer = packet.ConsoleNum; + StartScreen->NetMessage ("Console player number: %d", doomcom.consoleplayer); + for (node = 0; node < packet.NumNodes; node++) + { + sendaddress[node+2].sin_addr.s_addr = packet.machines[node].address; + sendaddress[node+2].sin_port = packet.machines[node].port; + sendplayer[node+2] = packet.machines[node].player; + + // [JC] - fixes problem of games not starting due to + // no address family being assigned to nodes stored in + // sendaddress[] from the All Here packet. + sendaddress[node+2].sin_family = AF_INET; + } + } + + StartScreen->NetMessage ("Received All Here, sending ACK."); + packet.Fake = PRE_FAKE; + packet.Message = PRE_ALLHEREACK; + PreSend (&packet, 2, &sendaddress[1]); + break; + + case PRE_GO: + StartScreen->NetMessage ("Received \"Go.\""); + return true; + + case PRE_DISCONNECT: + I_FatalError ("The host cancelled the game."); + break; + } + } + + packet.Fake = PRE_FAKE; + packet.Message = PRE_KEEPALIVE; + PreSend(&packet, 2, &sendaddress[1]); + + return false; +} + +bool JoinGame (int i) +{ + if ((i == Args->NumArgs() - 1) || + (Args->GetArg(i+1)[0] == '-') || + (Args->GetArg(i+1)[0] == '+')) + I_FatalError ("You need to specify the host machine's address"); + + StartNetwork (true); + + // Host is always node 1 + BuildAddress (&sendaddress[1], Args->GetArg(i+1)); + sendplayer[1] = 0; + doomcom.numnodes = 2; + + + // Let host know we are here + StartScreen->NetInit ("Contacting host", 0); + + if (!StartScreen->NetLoop (Guest_ContactHost, NULL)) + { + SendAbort(); + return false; + } + + // Wait for everyone else to connect + if (!StartScreen->NetLoop (Guest_WaitForOthers, 0)) + { + SendAbort(); + return false; + } + + StartScreen->NetMessage ("Total players: %d", doomcom.numnodes); + + doomcom.id = DOOMCOM_ID; + doomcom.numplayers = doomcom.numnodes; + return true; +} + +static int PrivateNetOf(in_addr in) +{ + int addr = ntohl(in.s_addr); + if ((addr & 0xFFFF0000) == 0xC0A80000) // 192.168.0.0 + { + return 0xC0A80000; + } + else if ((addr & 0xFFF00000) == 0xAC100000) // 172.16.0.0 + { + return 0xAC100000; + } + else if ((addr & 0xFF000000) == 0x0A000000) // 10.0.0.0 + { + return 0x0A000000; + } + else if ((addr & 0xFF000000) == 0x7F000000) // 127.0.0.0 (localhost) + { + return 0x7F000000; + } + // Not a private IP + return 0; +} + +// +// NodesOnSameNetwork +// +// The best I can really do here is check if the others are on the same +// private network, since that means we (probably) are too. +// + +static bool NodesOnSameNetwork() +{ + int net1; + + net1 = PrivateNetOf(sendaddress[1].sin_addr); +// Printf("net1 = %08x\n", net1); + if (net1 == 0) + { + return false; + } + for (int i = 2; i < doomcom.numnodes; ++i) + { + int net = PrivateNetOf(sendaddress[i].sin_addr); +// Printf("Net[%d] = %08x\n", i, net); + if (net != net1) + { + return false; + } + } + return true; +} + +// +// I_InitNetwork +// +// Returns true if packet server mode might be a good idea. +// +int I_InitNetwork (void) +{ + int i; + const char *v; + + memset (&doomcom, 0, sizeof(doomcom)); + + // set up for network + v = Args->CheckValue ("-dup"); + if (v) + { + doomcom.ticdup = clamp (atoi (v), 1, MAXTICDUP); + } + else + { + doomcom.ticdup = 1; + } + + v = Args->CheckValue ("-port"); + if (v) + { + DOOMPORT = atoi (v); + Printf ("using alternate port %i\n", DOOMPORT); + } + + // parse network game options, + // player 1: -host + // player x: -join + if ( (i = Args->CheckParm ("-host")) ) + { + if (!HostGame (i)) return -1; + } + else if ( (i = Args->CheckParm ("-join")) ) + { + if (!JoinGame (i)) return -1; + } + else + { + // single player game + netgame = false; + multiplayer = false; + doomcom.id = DOOMCOM_ID; + doomcom.numplayers = doomcom.numnodes = 1; + doomcom.consoleplayer = 0; + return false; + } + if (doomcom.numnodes < 3) + { // Packet server mode with only two players is effectively the same as + // peer-to-peer but with some slightly larger packets. + return false; + } + return doomcom.numnodes > 3 || !NodesOnSameNetwork(); +} + + +void I_NetCmd (void) +{ + if (doomcom.command == CMD_SEND) + { + PacketSend (); + } + else if (doomcom.command == CMD_GET) + { + PacketGet (); + } + else + I_Error ("Bad net cmd: %i\n",doomcom.command); +} + +#ifdef __WIN32__ +const char *neterror (void) +{ + static char neterr[16]; + int code; + + switch (code = WSAGetLastError ()) { + case WSAEACCES: return "EACCES"; + case WSAEADDRINUSE: return "EADDRINUSE"; + case WSAEADDRNOTAVAIL: return "EADDRNOTAVAIL"; + case WSAEAFNOSUPPORT: return "EAFNOSUPPORT"; + case WSAEALREADY: return "EALREADY"; + case WSAECONNABORTED: return "ECONNABORTED"; + case WSAECONNREFUSED: return "ECONNREFUSED"; + case WSAECONNRESET: return "ECONNRESET"; + case WSAEDESTADDRREQ: return "EDESTADDRREQ"; + case WSAEFAULT: return "EFAULT"; + case WSAEHOSTDOWN: return "EHOSTDOWN"; + case WSAEHOSTUNREACH: return "EHOSTUNREACH"; + case WSAEINPROGRESS: return "EINPROGRESS"; + case WSAEINTR: return "EINTR"; + case WSAEINVAL: return "EINVAL"; + case WSAEISCONN: return "EISCONN"; + case WSAEMFILE: return "EMFILE"; + case WSAEMSGSIZE: return "EMSGSIZE"; + case WSAENETDOWN: return "ENETDOWN"; + case WSAENETRESET: return "ENETRESET"; + case WSAENETUNREACH: return "ENETUNREACH"; + case WSAENOBUFS: return "ENOBUFS"; + case WSAENOPROTOOPT: return "ENOPROTOOPT"; + case WSAENOTCONN: return "ENOTCONN"; + case WSAENOTSOCK: return "ENOTSOCK"; + case WSAEOPNOTSUPP: return "EOPNOTSUPP"; + case WSAEPFNOSUPPORT: return "EPFNOSUPPORT"; + case WSAEPROCLIM: return "EPROCLIM"; + case WSAEPROTONOSUPPORT: return "EPROTONOSUPPORT"; + case WSAEPROTOTYPE: return "EPROTOTYPE"; + case WSAESHUTDOWN: return "ESHUTDOWN"; + case WSAESOCKTNOSUPPORT: return "ESOCKTNOSUPPORT"; + case WSAETIMEDOUT: return "ETIMEDOUT"; + case WSAEWOULDBLOCK: return "EWOULDBLOCK"; + case WSAHOST_NOT_FOUND: return "HOST_NOT_FOUND"; + case WSANOTINITIALISED: return "NOTINITIALISED"; + case WSANO_DATA: return "NO_DATA"; + case WSANO_RECOVERY: return "NO_RECOVERY"; + case WSASYSNOTREADY: return "SYSNOTREADY"; + case WSATRY_AGAIN: return "TRY_AGAIN"; + case WSAVERNOTSUPPORTED: return "VERNOTSUPPORTED"; + case WSAEDISCON: return "EDISCON"; + + default: + mysnprintf (neterr, countof(neterr), "%d", code); + return neterr; + } +} +#endif diff --git a/source/common/engine/i_net.h b/source/common/engine/i_net.h new file mode 100644 index 000000000..bddd20b18 --- /dev/null +++ b/source/common/engine/i_net.h @@ -0,0 +1,84 @@ +#ifndef __I_NET_H__ +#define __I_NET_H__ + +#include + +// Called by D_DoomMain. +int I_InitNetwork (void); +void I_NetCmd (void); + +enum ENetConstants +{ + MAXNETNODES = 8, // max computers in a game + DOOMCOM_ID = 0x12345678, + BACKUPTICS = 36, // number of tics to remember + MAXTICDUP = 5, + LOCALCMDTICS =(BACKUPTICS*MAXTICDUP), + MAX_MSGLEN = 14000, + + CMD_SEND = 1, + CMD_GET = 2, +}; + +// [RH] +// New generic packet structure: +// +// Header: +// One byte with following flags. +// One byte with starttic +// One byte with master's maketic (master -> slave only!) +// If NCMD_RETRANSMIT set, one byte with retransmitfrom +// If NCMD_XTICS set, one byte with number of tics (minus 3, so theoretically up to 258 tics in one packet) +// If NCMD_QUITTERS, one byte with number of players followed by one byte with each player's consolenum +// If NCMD_MULTI, one byte with number of players followed by one byte with each player's consolenum +// - The first player's consolenum is not included in this list, because it always matches the sender +// +// For each tic: +// Two bytes with consistancy check, followed by tic data +// +// Setup packets are different, and are described just before D_ArbitrateNetStart(). + +enum ENCMD +{ + NCMD_EXIT = 0x80, + NCMD_RETRANSMIT = 0x40, + NCMD_SETUP = 0x20, + NCMD_MULTI = 0x10, // multiple players in this packet + NCMD_QUITTERS = 0x08, // one or more players just quit (packet server only) + NCMD_COMPRESSED = 0x04, // remainder of packet is compressed + + NCMD_XTICS = 0x03, // packet contains >2 tics + NCMD_2TICS = 0x02, // packet contains 2 tics + NCMD_1TICS = 0x01, // packet contains 1 tic + NCMD_0TICS = 0x00, // packet contains 0 tics +}; + +// +// Network packet data. +// +struct doomcom_t +{ + uint32_t id; // should be DOOMCOM_ID + int16_t intnum; // DOOM executes an int to execute commands + +// communication between DOOM and the driver + int16_t command; // CMD_SEND or CMD_GET + int16_t remotenode; // dest for send, set by get (-1 = no packet). + int16_t datalength; // bytes in data to be sent + +// info common to all nodes + int16_t numnodes; // console is always node 0. + int16_t ticdup; // 1 = no duplication, 2-5 = dup for slow nets + +// info specific to this node + int16_t consoleplayer; + int16_t numplayers; + +// packet data to be sent + uint8_t data[MAX_MSGLEN]; + +}; + +extern doomcom_t doomcom; + +#endif From c0ebe3e08becba85715851986936ec6a0bd9df69 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Aug 2020 23:24:18 +0200 Subject: [PATCH 29/43] - hooked up ZDoom's d_net.cpp file. Still not active but this contains some code needed to do a proper main loop that can work with the networker. --- source/CMakeLists.txt | 3 + source/core/d_net.cpp | 2356 ++++++++++++++++++++++++++++++++++++ source/core/d_net.h | 74 ++ source/core/d_protocol.cpp | 443 +++++++ source/core/d_protocol.h | 119 ++ source/core/d_ticcmd.h | 42 + source/core/version.h | 2 + 7 files changed, 3039 insertions(+) create mode 100644 source/core/d_net.cpp create mode 100644 source/core/d_net.h create mode 100644 source/core/d_protocol.cpp create mode 100644 source/core/d_protocol.h create mode 100644 source/core/d_ticcmd.h diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 8d2a06c15..e9cdbfa68 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -783,6 +783,8 @@ set (PCH_SOURCES core/mathutil.cpp core/rts.cpp core/ct_chat.cpp + core/d_net.cpp + core/d_protocol.cpp core/gameconfigfile.cpp core/gamecvars.cpp core/gamecontrol.cpp @@ -912,6 +914,7 @@ set (PCH_SOURCES common/engine/sc_man.cpp common/engine/palettecontainer.cpp common/engine/stringtable.cpp + common/engine/i_net.cpp common/engine/i_interface.cpp common/engine/renderstyle.cpp common/engine/v_colortables.cpp diff --git a/source/core/d_net.cpp b/source/core/d_net.cpp new file mode 100644 index 000000000..9fa2794d1 --- /dev/null +++ b/source/core/d_net.cpp @@ -0,0 +1,2356 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright 1999-2016 Randy Heit +// Copyright 2002-2020 Christoph Oelckers +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// $Log:$ +// +// DESCRIPTION: +// DOOM Network game communication and protocol, +// all OS independent parts. +// +//----------------------------------------------------------------------------- + +#include +#define __STDC_FORMAT_MACROS +#include + +#include "version.h" +#include "menu.h" +#include "i_video.h" +#include "c_console.h" +#include "d_net.h" +#include "d_protocol.h" +#include "cmdlib.h" +#include "c_dispatch.h" +#include "gameconfigfile.h" +#include "st_start.h" +#include "d_event.h" +#include "m_argv.h" +#include "hardware.h" +#include "i_time.h" +#include "i_system.h" +#include "vm.h" +#include "gstrings.h" +#include "s_music.h" +#include "mmulti.h" +#include "printf.h" +#include "i_time.h" +#include "d_ticcmd.h" + +// Placeholders to make it compile. +FILE* debugfile; +int gametic; +extern bool netgame; +bool demoplayback; +int Net_Arbitrator; +bool playeringame[MAXPLAYERS]; +bool pauseext; +bool singletics; +char* startmap; +int rngseed; +bool autostart; +bool usergame; +void D_ReadUserInfoStrings(int, uint8_t**, bool) {} +void D_WriteUserInfoStrings(int, uint8_t**, bool) {} +FString GetPlayerName(int num); +void G_BuildTiccmd(ticcmd_t*) {} + + + +EXTERN_CVAR (Int, disableautosave) +EXTERN_CVAR (Int, autosavecount) +EXTERN_CVAR(Bool, cl_capfps) + +//#define SIMULATEERRORS (RAND_MAX/3) +#define SIMULATEERRORS 0 + +extern uint8_t *demo_p; // [RH] Special "ticcmds" get recorded in demos +extern FString savedescription; +extern FString savegamefile; + +short consistancy[MAXPLAYERS][BACKUPTICS]; + +#define netbuffer (doomcom.data) + +enum { NET_PeerToPeer, NET_PacketServer }; +uint8_t NetMode = NET_PeerToPeer; + + + +// +// NETWORKING +// +// gametic is the tic about to (or currently being) run +// maketic is the tick that hasn't had control made for it yet +// nettics[] has the maketics for all players +// +// a gametic cannot be run until nettics[] > gametic for all players +// +#define RESENDCOUNT 10 +#define PL_DRONE 0x80 // bit flag in doomdata->player + +ticcmd_t localcmds[LOCALCMDTICS]; + +FDynamicBuffer NetSpecs[MAXPLAYERS][BACKUPTICS]; +ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS]; +int nettics[MAXNETNODES]; +bool nodeingame[MAXNETNODES]; // set false as nodes leave game +bool nodejustleft[MAXNETNODES]; // set when a node just left +bool remoteresend[MAXNETNODES]; // set when local needs tics +int resendto[MAXNETNODES]; // set when remote needs tics +int resendcount[MAXNETNODES]; + +uint64_t lastrecvtime[MAXPLAYERS]; // [RH] Used for pings +uint64_t currrecvtime[MAXPLAYERS]; +uint64_t lastglobalrecvtime; // Identify the last time a packet was received. +bool hadlate; +int netdelay[MAXNETNODES][BACKUPTICS]; // Used for storing network delay times. +int lastaverage; + +int nodeforplayer[MAXPLAYERS]; +int playerfornode[MAXNETNODES]; + +int maketic; +int skiptics; +int ticdup; + +void D_ProcessEvents (void); +void G_BuildTiccmd (ticcmd_t *cmd); +void D_DoAdvanceDemo (void); + +static void SendSetup (uint32_t playersdetected[MAXNETNODES], uint8_t gotsetup[MAXNETNODES], int len); +static void RunScript(uint8_t **stream, AActor *pawn, int snum, int argn, int always); + +int reboundpacket; +uint8_t reboundstore[MAX_MSGLEN]; + +int frameon; +int frameskip[4]; +int oldnettics; +int mastertics; + +static int entertic; +static int oldentertics; + +extern bool advancedemo; + +CVAR(Bool, net_ticbalance, false, CVAR_SERVERINFO | CVAR_NOSAVE) +CUSTOM_CVAR(Int, net_extratic, 0, CVAR_SERVERINFO | CVAR_NOSAVE) +{ + if (self < 0) + { + self = 0; + } + else if (self > 2) + { + self = 2; + } +} + +#ifdef _DEBUG +CVAR(Int, net_fakelatency, 0, 0); + +struct PacketStore +{ + int timer; + doomcom_t message; +}; + +static TArray InBuffer; +static TArray OutBuffer; +#endif + +// [RH] Special "ticcmds" get stored in here +static struct TicSpecial +{ + uint8_t *streams[BACKUPTICS]; + size_t used[BACKUPTICS]; + uint8_t *streamptr; + size_t streamoffs; + size_t specialsize; + int lastmaketic; + bool okay; + + TicSpecial () + { + int i; + + lastmaketic = -1; + specialsize = 256; + + for (i = 0; i < BACKUPTICS; i++) + streams[i] = NULL; + + for (i = 0; i < BACKUPTICS; i++) + { + streams[i] = (uint8_t *)M_Malloc (256); + used[i] = 0; + } + okay = true; + } + + ~TicSpecial () + { + int i; + + for (i = 0; i < BACKUPTICS; i++) + { + if (streams[i]) + { + M_Free (streams[i]); + streams[i] = NULL; + used[i] = 0; + } + } + okay = false; + } + + // Make more room for special commands. + void GetMoreSpace (size_t needed) + { + int i; + + specialsize = std::max(specialsize * 2, needed + 30); + + DPrintf (DMSG_NOTIFY, "Expanding special size to %zu\n", specialsize); + + for (i = 0; i < BACKUPTICS; i++) + streams[i] = (uint8_t *)M_Realloc (streams[i], specialsize); + + streamptr = streams[(maketic/ticdup)%BACKUPTICS] + streamoffs; + } + + void CheckSpace (size_t needed) + { + if (streamoffs + needed >= specialsize) + GetMoreSpace (streamoffs + needed); + + streamoffs += needed; + } + + void NewMakeTic () + { + int mt = maketic / ticdup; + if (lastmaketic != -1) + { + if (lastmaketic == mt) + return; + used[lastmaketic%BACKUPTICS] = streamoffs; + } + + lastmaketic = mt; + streamptr = streams[mt%BACKUPTICS]; + streamoffs = 0; + } + + TicSpecial &operator << (uint8_t it) + { + if (streamptr) + { + CheckSpace (1); + WriteByte (it, &streamptr); + } + return *this; + } + + TicSpecial &operator << (short it) + { + if (streamptr) + { + CheckSpace (2); + WriteWord (it, &streamptr); + } + return *this; + } + + TicSpecial &operator << (int it) + { + if (streamptr) + { + CheckSpace (4); + WriteLong (it, &streamptr); + } + return *this; + } + + TicSpecial &operator << (float it) + { + if (streamptr) + { + CheckSpace (4); + WriteFloat (it, &streamptr); + } + return *this; + } + + TicSpecial &operator << (const char *it) + { + if (streamptr) + { + CheckSpace (strlen (it) + 1); + WriteString (it, &streamptr); + } + return *this; + } + +} specials; + +void Net_ClearBuffers () +{ + int i, j; + + memset (localcmds, 0, sizeof(localcmds)); + memset (netcmds, 0, sizeof(netcmds)); + memset (nettics, 0, sizeof(nettics)); + memset (nodeingame, 0, sizeof(nodeingame)); + memset (nodeforplayer, 0, sizeof(nodeforplayer)); + memset (playerfornode, 0, sizeof(playerfornode)); + memset (remoteresend, 0, sizeof(remoteresend)); + memset (resendto, 0, sizeof(resendto)); + memset (resendcount, 0, sizeof(resendcount)); + memset (lastrecvtime, 0, sizeof(lastrecvtime)); + memset (currrecvtime, 0, sizeof(currrecvtime)); + memset (consistancy, 0, sizeof(consistancy)); + nodeingame[0] = true; + + for (i = 0; i < MAXPLAYERS; i++) + { + for (j = 0; j < BACKUPTICS; j++) + { + NetSpecs[i][j].SetData (NULL, 0); + } + } + + oldentertics = entertic; + gametic = 0; + maketic = 0; + + lastglobalrecvtime = 0; +} + +// +// [RH] Rewritten to properly calculate the packet size +// with our variable length commands. +// +int NetbufferSize () +{ + if (netbuffer[0] & (NCMD_EXIT | NCMD_SETUP)) + { + return doomcom.datalength; + } + + int k = 2, count, numtics; + + if (netbuffer[0] & NCMD_RETRANSMIT) + k++; + + if (NetMode == NET_PacketServer && doomcom.remotenode == nodeforplayer[Net_Arbitrator]) + k++; + + numtics = netbuffer[0] & NCMD_XTICS; + if (numtics == 3) + { + numtics += netbuffer[k++]; + } + + if (netbuffer[0] & NCMD_QUITTERS) + { + k += netbuffer[k] + 1; + } + + // Network delay byte + k++; + + if (netbuffer[0] & NCMD_MULTI) + { + count = netbuffer[k]; + k += count; + } + else + { + count = 1; + } + + // Need at least 3 bytes per tic per player + if (doomcom.datalength < k + 3 * count * numtics) + { + return k + 3 * count * numtics; + } + + uint8_t *skipper = &netbuffer[k]; + if ((netbuffer[0] & NCMD_EXIT) == 0) + { + while (count-- > 0) + { + SkipTicCmd (&skipper, numtics); + } + } + return int(skipper - netbuffer); +} + +// +// +// +int ExpandTics (int low) +{ + int delta; + int mt = maketic / ticdup; + + delta = low - (mt&0xff); + + if (delta >= -64 && delta <= 64) + return (mt&~0xff) + low; + if (delta > 64) + return (mt&~0xff) - 256 + low; + if (delta < -64) + return (mt&~0xff) + 256 + low; + + I_Error ("ExpandTics: strange value %i at maketic %i", low, maketic); + return 0; +} + + + +// +// HSendPacket +// +void HSendPacket (int node, int len) +{ + if (debugfile && node != 0) + { + int i, k, realretrans; + + if (netbuffer[0] & NCMD_SETUP) + { + fprintf (debugfile,"%i/%i send %i = SETUP [%3i]", gametic, maketic, node, len); + for (i = 0; i < len; i++) + fprintf (debugfile," %2x", ((uint8_t *)netbuffer)[i]); + } + else if (netbuffer[0] & NCMD_EXIT) + { + fprintf (debugfile,"%i/%i send %i = EXIT [%3i]", gametic, maketic, node, len); + for (i = 0; i < len; i++) + fprintf (debugfile," %2x", ((uint8_t *)netbuffer)[i]); + } + else + { + k = 2; + + if (NetMode == NET_PacketServer && myconnectindex == Net_Arbitrator && + node != 0) + { + k++; + } + + if (netbuffer[0] & NCMD_RETRANSMIT) + realretrans = ExpandTics (netbuffer[k++]); + else + realretrans = -1; + + int numtics = netbuffer[0] & 3; + if (numtics == 3) + numtics += netbuffer[k++]; + + fprintf (debugfile,"%i/%i send %i = (%i + %i, R %i) [%3i]", + gametic, maketic, + node, + ExpandTics(netbuffer[1]), + numtics, realretrans, len); + + for (i = 0; i < len; i++) + fprintf (debugfile, "%c%2x", i==k?'|':' ', ((uint8_t *)netbuffer)[i]); + } + fprintf (debugfile, " [[ "); + for (i = 0; i < doomcom.numnodes; ++i) + { + if (nodeingame[i]) + { + fprintf (debugfile, "%d ", nettics[i]); + } + else + { + fprintf (debugfile, "--- "); + } + } + fprintf (debugfile, "]]\n"); + } + + if (node == 0) + { + memcpy (reboundstore, netbuffer, len); + reboundpacket = len; + return; + } + + if (demoplayback) + return; + + if (!netgame) + I_Error ("Tried to transmit to another node"); + +#if SIMULATEERRORS + if (rand() < SIMULATEERRORS) + { + if (debugfile) + fprintf (debugfile, "Drop!\n"); + return; + } +#endif + + doomcom.command = CMD_SEND; + doomcom.remotenode = node; + doomcom.datalength = len; + +#ifdef _DEBUG + if (net_fakelatency / 2 > 0) + { + PacketStore store; + store.message = doomcom; + store.timer = I_GetTime() + ((net_fakelatency / 2) / (1000 / GameTicRate)); + OutBuffer.Push(store); + } + else + I_NetCmd(); + + for (unsigned int i = 0; i < OutBuffer.Size(); i++) + { + if (OutBuffer[i].timer <= I_GetTime()) + { + doomcom = OutBuffer[i].message; + I_NetCmd(); + OutBuffer.Delete(i); + i = -1; + } + } +#else + I_NetCmd(); +#endif +} + +// +// HGetPacket +// Returns false if no packet is waiting +// +bool HGetPacket (void) +{ + if (reboundpacket) + { + memcpy (netbuffer, reboundstore, reboundpacket); + doomcom.remotenode = 0; + reboundpacket = 0; + return true; + } + + if (!netgame) + return false; + + if (demoplayback) + return false; + + doomcom.command = CMD_GET; + I_NetCmd (); + +#ifdef _DEBUG + if (net_fakelatency / 2 > 0 && doomcom.remotenode != -1) + { + PacketStore store; + store.message = doomcom; + store.timer = I_GetTime() + ((net_fakelatency / 2) / (1000 / GameTicRate)); + InBuffer.Push(store); + doomcom.remotenode = -1; + } + + if (doomcom.remotenode == -1) + { + bool gotmessage = false; + for (unsigned int i = 0; i < InBuffer.Size(); i++) + { + if (InBuffer[i].timer <= I_GetTime()) + { + doomcom = InBuffer[i].message; + InBuffer.Delete(i); + gotmessage = true; + break; + } + } + if (!gotmessage) + return false; + } +#else + if (doomcom.remotenode == -1) + { + return false; + } +#endif + + if (debugfile) + { + int i, k, realretrans; + + if (netbuffer[0] & NCMD_SETUP) + { + fprintf (debugfile,"%i/%i get %i = SETUP [%3i]", gametic, maketic, doomcom.remotenode, doomcom.datalength); + for (i = 0; i < doomcom.datalength; i++) + fprintf (debugfile, " %2x", ((uint8_t *)netbuffer)[i]); + fprintf (debugfile, "\n"); + } + else if (netbuffer[0] & NCMD_EXIT) + { + fprintf (debugfile,"%i/%i get %i = EXIT [%3i]", gametic, maketic, doomcom.remotenode, doomcom.datalength); + for (i = 0; i < doomcom.datalength; i++) + fprintf (debugfile, " %2x", ((uint8_t *)netbuffer)[i]); + fprintf (debugfile, "\n"); + } + else { + k = 2; + + if (NetMode == NET_PacketServer && + doomcom.remotenode == nodeforplayer[Net_Arbitrator]) + { + k++; + } + + if (netbuffer[0] & NCMD_RETRANSMIT) + realretrans = ExpandTics (netbuffer[k++]); + else + realretrans = -1; + + int numtics = netbuffer[0] & 3; + if (numtics == 3) + numtics += netbuffer[k++]; + + fprintf (debugfile,"%i/%i get %i = (%i + %i, R %i) [%3i]", + gametic, maketic, + doomcom.remotenode, + ExpandTics(netbuffer[1]), + numtics, realretrans, doomcom.datalength); + + for (i = 0; i < doomcom.datalength; i++) + fprintf (debugfile, "%c%2x", i==k?'|':' ', ((uint8_t *)netbuffer)[i]); + if (numtics) + fprintf (debugfile, " <<%4x>>\n", + consistancy[playerfornode[doomcom.remotenode]][nettics[doomcom.remotenode]%BACKUPTICS] & 0xFFFF); + else + fprintf (debugfile, "\n"); + } + } + + if (doomcom.datalength != NetbufferSize ()) + { + Printf("Bad packet length %i (calculated %i)\n", + doomcom.datalength, NetbufferSize()); + + if (debugfile) + fprintf (debugfile,"---bad packet length %i (calculated %i)\n", + doomcom.datalength, NetbufferSize()); + return false; + } + + return true; +} + +void PlayerIsGone (int netnode, int netconsole) +{ + int i; + + if (nodeingame[netnode]) + { + for (i = netnode + 1; i < doomcom.numnodes; ++i) + { + if (nodeingame[i]) + break; + } + if (i == doomcom.numnodes) + { + doomcom.numnodes = netnode; + } + +#if 0 + if (playeringame[netconsole]) + { + players[netconsole].playerstate = PST_GONE; + } +#endif + nodeingame[netnode] = false; + nodejustleft[netnode] = false; + } + else if (nodejustleft[netnode]) // Packet Server + { + if (netnode + 1 == doomcom.numnodes) + { + doomcom.numnodes = netnode; + } +#if 0 + if (playeringame[netconsole]) + { + players[netconsole].playerstate = PST_GONE; + } +#endif + nodejustleft[netnode] = false; + } + else return; + + if (netconsole == Net_Arbitrator) + { + // Pick a new network arbitrator + for (int i = 0; i < MAXPLAYERS; i++) + { +#if 0 + if (i != netconsole && playeringame[i] && players[i].Bot == NULL) + { + Net_Arbitrator = i; + players[i].settings_controller = true; + Printf("%s is the new arbitrator\n", players[i].userinfo.GetName()); + break; + } +#endif + } + } + + if (debugfile && NetMode == NET_PacketServer) + { + if (Net_Arbitrator == myconnectindex) + { + fprintf(debugfile, "I am the new master!\n"); + } + else + { + fprintf(debugfile, "Node %d is the new master!\n", nodeforplayer[Net_Arbitrator]); + } + } + +#if 0 + if (demorecording) + { + G_CheckDemoStatus (); + + //WriteByte (DEM_DROPPLAYER, &demo_p); + //WriteByte ((uint8_t)netconsole, &demo_p); + } +#endif +} + +// +// GetPackets +// + +void GetPackets (void) +{ + int netconsole; + int netnode; + int realend; + int realstart; + int numtics; + int retransmitfrom; + int k; + uint8_t playerbytes[MAXNETNODES]; + int numplayers; + + while ( HGetPacket() ) + { + if (netbuffer[0] & NCMD_SETUP) + { + if (myconnectindex == Net_Arbitrator) + { + // This player apparantly doesn't realise the game has started + netbuffer[0] = NCMD_SETUP+3; + HSendPacket (doomcom.remotenode, 1); + } + continue; // extra setup packet + } + + netnode = doomcom.remotenode; + netconsole = playerfornode[netnode] & ~PL_DRONE; + + // [RH] Get "ping" times - totally useless, since it's bound to the frequency + // packets go out at. + lastrecvtime[netconsole] = currrecvtime[netconsole]; + currrecvtime[netconsole] = I_msTime (); + + // check for exiting the game + if (netbuffer[0] & NCMD_EXIT) + { + if (!nodeingame[netnode]) + continue; + + if (NetMode != NET_PacketServer || netconsole == Net_Arbitrator) + { + PlayerIsGone (netnode, netconsole); + if (NetMode == NET_PacketServer) + { + uint8_t *foo = &netbuffer[2]; + for (int i = 0; i < MAXPLAYERS; ++i) + { + if (playeringame[i]) + { + int resend = ReadLong (&foo); + if (i != myconnectindex) + { + resendto[nodeforplayer[i]] = resend; + } + } + } + } + } + else + { + nodeingame[netnode] = false; + nodejustleft[netnode] = true; + } + continue; + } + + k = 2; + + if (NetMode == NET_PacketServer && + netconsole == Net_Arbitrator && + netconsole != myconnectindex) + { + mastertics = ExpandTics (netbuffer[k++]); + } + + if (netbuffer[0] & NCMD_RETRANSMIT) + { + retransmitfrom = netbuffer[k++]; + } + else + { + retransmitfrom = 0; + } + + numtics = (netbuffer[0] & NCMD_XTICS); + if (numtics == 3) + { + numtics += netbuffer[k++]; + } + + if (netbuffer[0] & NCMD_QUITTERS) + { + numplayers = netbuffer[k++]; + for (int i = 0; i < numplayers; ++i) + { + PlayerIsGone (nodeforplayer[netbuffer[k]], netbuffer[k]); + k++; + } + } + + // Pull current network delay from node + netdelay[netnode][(nettics[netnode]+1) % BACKUPTICS] = netbuffer[k++]; + + playerbytes[0] = netconsole; + if (netbuffer[0] & NCMD_MULTI) + { + numplayers = netbuffer[k++]; + memcpy (playerbytes+1, &netbuffer[k], numplayers - 1); + k += numplayers - 1; + } + else + { + numplayers = 1; + } + + // to save bytes, only the low byte of tic numbers are sent + // Figure out what the rest of the bytes are + realstart = ExpandTics (netbuffer[1]); + realend = (realstart + numtics); + + nodeforplayer[netconsole] = netnode; + + // check for retransmit request + if (resendcount[netnode] <= 0 && (netbuffer[0] & NCMD_RETRANSMIT)) + { + resendto[netnode] = ExpandTics (retransmitfrom); + if (debugfile) + fprintf (debugfile,"retransmit from %i\n", resendto[netnode]); + resendcount[netnode] = RESENDCOUNT; + } + else + { + resendcount[netnode]--; + } + + // check for out of order / duplicated packet + if (realend == nettics[netnode]) + continue; + + if (realend < nettics[netnode]) + { + if (debugfile) + fprintf (debugfile, "out of order packet (%i + %i)\n" , + realstart, numtics); + continue; + } + + // check for a missed packet + if (realstart > nettics[netnode]) + { + // stop processing until the other system resends the missed tics + if (debugfile) + fprintf (debugfile, "missed tics from %i (%i to %i)\n", + netnode, nettics[netnode], realstart); + remoteresend[netnode] = true; + continue; + } + + // update command store from the packet + { + uint8_t *start; + int i, tics; + remoteresend[netnode] = false; + + start = &netbuffer[k]; + + for (i = 0; i < numplayers; ++i) + { + int node = nodeforplayer[playerbytes[i]]; + + SkipTicCmd (&start, nettics[node] - realstart); + for (tics = nettics[node]; tics < realend; tics++) + ReadTicCmd (&start, playerbytes[i], tics); + + nettics[nodeforplayer[playerbytes[i]]] = realend; + } + } + } +} + +// +// NetUpdate +// Builds ticcmds for console player, +// sends out a packet +// +int gametime; + +void NetUpdate (void) +{ + int lowtic; + int nowtime; + int newtics; + int i,j; + int realstart; + uint8_t *cmddata; + bool resendOnly; + + GC::CheckGC(); + + if (ticdup == 0) + { + return; + } + + // check time + nowtime = I_GetTime (); + newtics = nowtime - gametime; + gametime = nowtime; + + if (newtics <= 0) // nothing new to update + { + GetPackets (); + return; + } + + if (skiptics <= newtics) + { + newtics -= skiptics; + skiptics = 0; + } + else + { + skiptics -= newtics; + newtics = 0; + } + + // build new ticcmds for console player + for (i = 0; i < newtics; i++) + { + I_StartTic (); + D_ProcessEvents (); + if (pauseext || (maketic - gametic) / ticdup >= BACKUPTICS/2-1) + break; // can't hold any more + + //Printf ("mk:%i ",maketic); + G_BuildTiccmd (&localcmds[maketic % LOCALCMDTICS]); + maketic++; + + if (ticdup == 1 || maketic == 0) + { + Net_NewMakeTic (); + } + else + { + // Once ticdup tics have been collected, average their movements + // and combine their buttons, since they will all be sent as a + // single tic that gets duplicated ticdup times. Even with ticdup, + // tics are still collected at the normal rate so that, with the + // help of prediction, the game seems as responsive as normal. + if (maketic % ticdup != 0) + { + int mod = maketic - maketic % ticdup; + int j; + + // Update the buttons for all tics in this ticdup set as soon as + // possible so that the prediction shows jumping as correctly as + // possible. (If you press +jump in the middle of a ticdup set, + // the jump will actually begin at the beginning of the set, not + // in the middle.) + for (j = maketic-2; j >= mod; --j) + { + localcmds[j % LOCALCMDTICS].ucmd.actions |= + localcmds[(j + 1) % LOCALCMDTICS].ucmd.actions; + localcmds[j % LOCALCMDTICS].ucmd.setNewWeapon(localcmds[(j + 1) % LOCALCMDTICS].ucmd.getNewWeapon()); + } + } + else + { + // Average the ticcmds between these tics to get the + // movement that is actually sent across the network. We + // need to update them in all the localcmds slots that + // are dupped so that prediction works properly. + int mod = maketic - ticdup; + int modp, j; + + int svel; + int fvel; + int64_t q16avel; + int64_t q16horz; + int64_t q16horiz; // only used by SW + int64_t q16ang; // only used by SW + + for (j = 0; j < ticdup; ++j) + { + modp = (mod + j) % LOCALCMDTICS; + svel += localcmds[modp].ucmd.svel; + fvel += localcmds[modp].ucmd.fvel; + q16avel += localcmds[modp].ucmd.q16avel; + q16horz += localcmds[modp].ucmd.q16horz; + q16horiz += localcmds[modp].ucmd.q16horiz; + q16ang += localcmds[modp].ucmd.q16ang; + } + + svel /= ticdup; + fvel /= ticdup; + q16avel /= ticdup; + q16horz /= ticdup; + q16horiz /= ticdup; + q16ang /= ticdup; + + for (j = 0; j < ticdup; ++j) + { + modp = (mod + j) % LOCALCMDTICS; + localcmds[modp].ucmd.svel = svel; + localcmds[modp].ucmd.fvel = fvel; + localcmds[modp].ucmd.q16avel = q16avel; + localcmds[modp].ucmd.q16horz = q16horz; + localcmds[modp].ucmd.q16horiz = q16horiz; + localcmds[modp].ucmd.q16ang = q16ang; + } + + Net_NewMakeTic (); + } + } + } + + if (singletics) + return; // singletic update is synchronous + + if (demoplayback) + { + resendto[0] = nettics[0] = (maketic / ticdup); + return; // Don't touch netcmd data while playing a demo, as it'll already exist. + } + + // If maketic didn't cross a ticdup boundary, only send packets + // to players waiting for resends. + resendOnly = (maketic / ticdup) == (maketic - i) / ticdup; + + // send the packet to the other nodes + int count = 1; + int quitcount = 0; + + if (myconnectindex == Net_Arbitrator) + { + if (NetMode == NET_PacketServer) + { + for (j = 0; j < MAXPLAYERS; j++) + { + if (playeringame[j]) + { + count++; + } + } + + // The loop above added the local player to the count a second time, + // and it also added the player being sent the packet to the count. + count -= 2; + + for (j = 0; j < doomcom.numnodes; ++j) + { + if (nodejustleft[j]) + { + if (count == 0) + { + PlayerIsGone (j, playerfornode[j]); + } + else + { + quitcount++; + } + } + } + + if (count == 0) + { + count = 1; + } + } + } + + for (i = 0; i < doomcom.numnodes; i++) + { + uint8_t playerbytes[MAXPLAYERS]; + + if (!nodeingame[i]) + { + continue; + } + if (NetMode == NET_PacketServer && + myconnectindex != Net_Arbitrator && + i != nodeforplayer[Net_Arbitrator] && + i != 0) + { + continue; + } + if (resendOnly && resendcount[i] <= 0 && !remoteresend[i] && nettics[i]) + { + continue; + } + + int numtics; + int k; + + lowtic = maketic / ticdup; + + netbuffer[0] = 0; + netbuffer[1] = realstart = resendto[i]; + k = 2; + + if (NetMode == NET_PacketServer && + myconnectindex == Net_Arbitrator && + i != 0) + { + for (j = 1; j < doomcom.numnodes; ++j) + { + if (nodeingame[j] && nettics[j] < lowtic && j != i) + { + lowtic = nettics[j]; + } + } + netbuffer[k++] = lowtic; + } + + numtics = std::max(0, lowtic - realstart); + if (numtics > BACKUPTICS) + I_Error ("NetUpdate: Node %d missed too many tics", i); + + switch (net_extratic) + { + case 0: + default: + resendto[i] = lowtic; break; + case 1: resendto[i] = std::max(0, lowtic - 1); break; + case 2: resendto[i] = nettics[i]; break; + } + + if (numtics == 0 && resendOnly && !remoteresend[i] && nettics[i]) + { + continue; + } + + if (remoteresend[i]) + { + netbuffer[0] |= NCMD_RETRANSMIT; + netbuffer[k++] = nettics[i]; + } + + if (numtics < 3) + { + netbuffer[0] |= numtics; + } + else + { + netbuffer[0] |= NCMD_XTICS; + netbuffer[k++] = numtics - 3; + } + + if (quitcount > 0) + { + netbuffer[0] |= NCMD_QUITTERS; + netbuffer[k++] = quitcount; + for (int l = 0; l < doomcom.numnodes; ++l) + { + if (nodejustleft[l]) + { + netbuffer[k++] = playerfornode[l]; + } + } + } + + // Send current network delay + // The number of tics we just made should be removed from the count. + netbuffer[k++] = ((maketic - numtics - gametic) / ticdup); + + if (numtics > 0) + { + int l; + + if (count > 1 && i != 0 && myconnectindex == Net_Arbitrator) + { + netbuffer[0] |= NCMD_MULTI; + netbuffer[k++] = count; + + if (NetMode == NET_PacketServer) + { + for (l = 1, j = 0; j < MAXPLAYERS; j++) + { + if (playeringame[j] && j != playerfornode[i] && j != myconnectindex) + { + playerbytes[l++] = j; + netbuffer[k++] = j; + } + } + } + } + + cmddata = &netbuffer[k]; + + for (l = 0; l < count; ++l) + { + for (j = 0; j < numtics; j++) + { + int start = realstart + j, prev = start - 1; + int localstart, localprev; + + localstart = (start * ticdup) % LOCALCMDTICS; + localprev = (prev * ticdup) % LOCALCMDTICS; + start %= BACKUPTICS; + prev %= BACKUPTICS; + + // The local player has their tics sent first, followed by + // the other players. + if (l == 0) + { + WriteWord (localcmds[localstart].consistancy, &cmddata); + // [RH] Write out special "ticcmds" before real ticcmd + if (specials.used[start]) + { + memcpy (cmddata, specials.streams[start], specials.used[start]); + cmddata += specials.used[start]; + } + WriteUserCmdMessage (&localcmds[localstart].ucmd, + localprev >= 0 ? &localcmds[localprev].ucmd : NULL, &cmddata); + } + else if (i != 0) + { + int len; + uint8_t *spec; + + WriteWord (netcmds[playerbytes[l]][start].consistancy, &cmddata); + spec = NetSpecs[playerbytes[l]][start].GetData (&len); + if (spec != NULL) + { + memcpy (cmddata, spec, len); + cmddata += len; + } + + WriteUserCmdMessage (&netcmds[playerbytes[l]][start].ucmd, + prev >= 0 ? &netcmds[playerbytes[l]][prev].ucmd : NULL, &cmddata); + } + } + } + HSendPacket (i, int(cmddata - netbuffer)); + } + else + { + HSendPacket (i, k); + } + } + + // listen for other packets + GetPackets (); + + if (!resendOnly) + { + // ideally nettics[0] should be 1 - 3 tics above lowtic + // if we are consistantly slower, speed up time + + // [RH] I had erroneously assumed frameskip[] had 4 entries + // because there were 4 players, but that's not the case at + // all. The game is comparing the lag behind the master for + // four runs of TryRunTics. If our tic count is ahead of the + // master all 4 times, the next run of NetUpdate will not + // process any new input. If we have less input than the + // master, the next run of NetUpdate will process extra tics + // (because gametime gets decremented here). + + // the key player does not adapt + if (myconnectindex != Net_Arbitrator) + { + // I'm not sure about this when using a packet server, because + // if left unmodified from the P2P version, it can make the game + // very jerky. The way I have it written right now basically means + // that it won't adapt. Fortunately, player prediction helps + // alleviate the lag somewhat. + + if (NetMode == NET_PeerToPeer) + { + int totalavg = 0; + if (net_ticbalance) + { + // Try to guess ahead the time it takes to send responses to the slowest node + int nodeavg = 0, arbavg = 0; + + for (j = 0; j < BACKUPTICS; j++) + { + arbavg += netdelay[nodeforplayer[Net_Arbitrator]][j]; + nodeavg += netdelay[0][j]; + } + arbavg /= BACKUPTICS; + nodeavg /= BACKUPTICS; + + // We shouldn't adapt if we are already the arbitrator isn't what we are waiting for, otherwise it just adds more latency + if (arbavg > nodeavg) + { + lastaverage = totalavg = ((arbavg + nodeavg) / 2); + } + else + { + // Allow room to guess two tics ahead + if (nodeavg > (arbavg + 2) && lastaverage > 0) + lastaverage--; + totalavg = lastaverage; + } + } + + mastertics = nettics[nodeforplayer[Net_Arbitrator]] + totalavg; + } + if (nettics[0] <= mastertics) + { + gametime--; + if (debugfile) fprintf(debugfile, "-"); + } + if (NetMode != NET_PacketServer) + { + frameskip[(maketic / ticdup) & 3] = (oldnettics > mastertics); + } + else + { + frameskip[(maketic / ticdup) & 3] = (oldnettics - mastertics) > 3; + } + if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3]) + { + skiptics = 1; + if (debugfile) fprintf(debugfile, "+"); + } + oldnettics = nettics[0]; + } + } +} + + +// +// D_ArbitrateNetStart +// +// User info packets look like this: +// +// 0 One byte set to NCMD_SETUP or NCMD_SETUP+1; if NCMD_SETUP+1, omit byte 9 +// 1 One byte for the player's number +//2-4 Three bytes for the game version (255,high byte,low byte) +//5-8 A bit mask for each player the sender knows about +// 9 The high bit is set if the sender got the game info +// 10 A stream of bytes with the user info +// +// The guests always send NCMD_SETUP packets, and the host always +// sends NCMD_SETUP+1 packets. +// +// Game info packets look like this: +// +// 0 One byte set to NCMD_SETUP+2 +// 1 One byte for ticdup setting +// 2 One byte for NetMode setting +// 3 String with starting map's name +// . Four bytes for the RNG seed +// . Stream containing remaining game info +// +// Finished packet looks like this: +// +// 0 One byte set to NCMD_SETUP+3 +// +// Each machine sends user info packets to the host. The host sends user +// info packets back to the other machines as well as game info packets. +// Negotiation is done when all the guests have reported to the host that +// they know about the other nodes. + +struct ArbitrateData +{ + uint32_t playersdetected[MAXNETNODES]; + uint8_t gotsetup[MAXNETNODES]; +}; + +bool DoArbitrate (void *userdata) +{ + ArbitrateData *data = (ArbitrateData *)userdata; + char *s; + uint8_t *stream; + int version; + int node; + int i, j; + + while (HGetPacket ()) + { + if (netbuffer[0] == NCMD_EXIT) + { + I_FatalError ("The game was aborted."); + } + + if (doomcom.remotenode == 0) + { + continue; + } + + if (netbuffer[0] == NCMD_SETUP || netbuffer[0] == NCMD_SETUP+1) // got user info + { + node = (netbuffer[0] == NCMD_SETUP) ? doomcom.remotenode : nodeforplayer[netbuffer[1]]; + + data->playersdetected[node] = + (netbuffer[5] << 24) | (netbuffer[6] << 16) | (netbuffer[7] << 8) | netbuffer[8]; + + if (netbuffer[0] == NCMD_SETUP) + { // Sent to host + data->gotsetup[node] = netbuffer[9] & 0x80; + stream = &netbuffer[10]; + } + else + { // Sent from host + stream = &netbuffer[9]; + } + + D_ReadUserInfoStrings (netbuffer[1], &stream, false); + if (!nodeingame[node]) + { + version = (netbuffer[2] << 16) | (netbuffer[3] << 8) | netbuffer[4]; + if (version != (0xFF0000 | NETGAMEVERSION)) + { + I_Error ("Different " GAMENAME " versions cannot play a net game"); + } + + playeringame[netbuffer[1]] = true; + nodeingame[node] = true; + + data->playersdetected[0] |= 1 << netbuffer[1]; + + StartScreen->NetMessage ("Found %s (node %d, player %d)", GetPlayerName(netbuffer[1]).GetChars(), + node, netbuffer[1]+1); + } + } + else if (netbuffer[0] == NCMD_SETUP+2) // got game info + { + data->gotsetup[0] = 0x80; + + ticdup = doomcom.ticdup = netbuffer[1]; + NetMode = netbuffer[2]; + + stream = &netbuffer[3]; + s = ReadString (&stream); + startmap = s; + delete[] s; + rngseed = ReadLong (&stream); + C_ReadCVars (&stream); + } + else if (netbuffer[0] == NCMD_SETUP+3) + { + return true; + } + } + + // If everybody already knows everything, it's time to go + if (myconnectindex == Net_Arbitrator) + { + for (i = 0; i < doomcom.numnodes; ++i) + if (data->playersdetected[i] != uint32_t(1 << doomcom.numnodes) - 1 || !data->gotsetup[i]) + break; + + if (i == doomcom.numnodes) + return true; + } + + netbuffer[2] = 255; + netbuffer[3] = (NETGAMEVERSION >> 8) & 255; + netbuffer[4] = NETGAMEVERSION & 255; + netbuffer[5] = data->playersdetected[0] >> 24; + netbuffer[6] = data->playersdetected[0] >> 16; + netbuffer[7] = data->playersdetected[0] >> 8; + netbuffer[8] = data->playersdetected[0]; + + if (myconnectindex != Net_Arbitrator) + { // Send user info for the local node + netbuffer[0] = NCMD_SETUP; + netbuffer[1] = myconnectindex; + netbuffer[9] = data->gotsetup[0]; + stream = &netbuffer[10]; + D_WriteUserInfoStrings (myconnectindex, &stream, true); + SendSetup (data->playersdetected, data->gotsetup, int(stream - netbuffer)); + } + else + { // Send user info for all nodes + netbuffer[0] = NCMD_SETUP+1; + for (i = 1; i < doomcom.numnodes; ++i) + { + for (j = 0; j < doomcom.numnodes; ++j) + { + // Send info about player j to player i? + if ((data->playersdetected[0] & (1<playersdetected[i] & (1<playersdetected, data->gotsetup, int(stream - netbuffer)); + } + return false; +} + +bool D_ArbitrateNetStart (void) +{ + ArbitrateData data; + int i; + + // Return right away if we're just playing with ourselves. + if (doomcom.numnodes == 1) + return true; + + autostart = true; + + memset (data.playersdetected, 0, sizeof(data.playersdetected)); + memset (data.gotsetup, 0, sizeof(data.gotsetup)); + + // The arbitrator knows about himself, but the other players must + // be told about themselves, in case the host had to adjust their + // userinfo (e.g. assign them to a different team). + if (myconnectindex == Net_Arbitrator) + { + data.playersdetected[0] = 1 << myconnectindex; + } + + // Assign nodes to players. The local player is always node 0. + // If the local player is not the host, then the host is node 1. + // Any remaining players are assigned node numbers in the order + // they were detected. + playerfornode[0] = myconnectindex; + nodeforplayer[myconnectindex] = 0; + if (myconnectindex == Net_Arbitrator) + { + for (i = 1; i < doomcom.numnodes; ++i) + { + playerfornode[i] = i; + nodeforplayer[i] = i; + } + } + else + { + playerfornode[1] = 0; + nodeforplayer[0] = 1; + for (i = 1; i < doomcom.numnodes; ++i) + { + if (i < myconnectindex) + { + playerfornode[i+1] = i; + nodeforplayer[i] = i+1; + } + else if (i > myconnectindex) + { + playerfornode[i] = i; + nodeforplayer[i] = i; + } + } + } + + if (myconnectindex == Net_Arbitrator) + { + data.gotsetup[0] = 0x80; + } + + StartScreen->NetInit ("Exchanging game information", 1); + if (!StartScreen->NetLoop (DoArbitrate, &data)) + { + return false; + } + + if (myconnectindex == Net_Arbitrator) + { + netbuffer[0] = NCMD_SETUP+3; + SendSetup (data.playersdetected, data.gotsetup, 1); + } + + if (debugfile) + { + for (i = 0; i < doomcom.numnodes; ++i) + { + fprintf (debugfile, "player %d is on node %d\n", i, nodeforplayer[i]); + } + } + StartScreen->NetDone(); + return true; +} + +static void SendSetup (uint32_t playersdetected[MAXNETNODES], uint8_t gotsetup[MAXNETNODES], int len) +{ + if (myconnectindex != Net_Arbitrator) + { + if (playersdetected[1] & (1 << myconnectindex)) + { + HSendPacket (1, 10); + } + else + { + HSendPacket (1, len); + } + } + else + { + for (int i = 1; i < doomcom.numnodes; ++i) + { + if (!gotsetup[i] || netbuffer[0] == NCMD_SETUP+3) + { + HSendPacket (i, len); + } + } + } +} + +// +// D_CheckNetGame +// Works out player numbers among the net participants +// + +bool D_CheckNetGame (void) +{ + const char *v; + int i; + + for (i = 0; i < MAXNETNODES; i++) + { + nodeingame[i] = false; + nettics[i] = 0; + remoteresend[i] = false; // set when local needs tics + resendto[i] = 0; // which tic to start sending + } + + // Packet server has proven to be rather slow over the internet. Print a warning about it. + v = Args->CheckValue("-netmode"); + if (v != NULL && (atoi(v) != 0)) + { + Printf(TEXTCOLOR_YELLOW "Notice: Using PacketServer (netmode 1) over the internet is prone to running too slow on some internet configurations." + "\nIf the game is running well below expected speeds, use netmode 0 (P2P) instead.\n"); + } + + int result = I_InitNetwork (); + // I_InitNetwork sets doomcom and netgame + if (result == -1) + { + return false; + } + else if (result > 0) + { + // For now, stop auto selecting PacketServer, as it's more likely to cause confusion. + //NetMode = NET_PacketServer; + } + if (doomcom.id != DOOMCOM_ID) + { + I_FatalError ("Doomcom buffer invalid!"); + } +#if 0 + players[0].settings_controller = true; +#endif + + myconnectindex = doomcom.consoleplayer; + + if (myconnectindex == Net_Arbitrator) + { + v = Args->CheckValue("-netmode"); + if (v != NULL) + { + NetMode = atoi(v) != 0 ? NET_PacketServer : NET_PeerToPeer; + } + if (doomcom.numnodes > 1) + { + Printf("Selected " TEXTCOLOR_BLUE "%s" TEXTCOLOR_NORMAL " networking mode. (%s)\n", NetMode == NET_PeerToPeer ? "peer to peer" : "packet server", + v != NULL ? "forced" : "auto"); + } + + if (Args->CheckParm("-extratic")) + { + net_extratic = 1; + } + } + +#if 0 + // [RH] Setup user info + D_SetupUserInfo (); +#endif + + if (Args->CheckParm ("-debugfile")) + { + char filename[20]; + mysnprintf (filename, countof(filename), "debug%i.txt", myconnectindex); + Printf ("debug output to: %s\n", filename); + debugfile = fopen (filename, "w"); + } + + if (netgame) + { + GameConfig->ReadNetVars (); // [RH] Read network ServerInfo cvars + if (!D_ArbitrateNetStart ()) return false; + } + + // read values out of doomcom + ticdup = doomcom.ticdup; + + for (i = 0; i < doomcom.numplayers; i++) + playeringame[i] = true; + for (i = 0; i < doomcom.numnodes; i++) + nodeingame[i] = true; + + if (myconnectindex != Net_Arbitrator && doomcom.numnodes > 1) + { + Printf("Arbitrator selected " TEXTCOLOR_BLUE "%s" TEXTCOLOR_NORMAL " networking mode.\n", NetMode == NET_PeerToPeer ? "peer to peer" : "packet server"); + } + + if (!batchrun) Printf ("player %i of %i (%i nodes)\n", + myconnectindex+1, doomcom.numplayers, doomcom.numnodes); + + return true; +} + + +// +// D_QuitNetGame +// Called before quitting to leave a net game +// without hanging the other players +// +void D_QuitNetGame (void) +{ + int i, j, k; + + if (!netgame || !usergame || myconnectindex == -1 || demoplayback) + return; + + // send a bunch of packets for security + netbuffer[0] = NCMD_EXIT; + netbuffer[1] = 0; + + k = 2; + if (NetMode == NET_PacketServer && myconnectindex == Net_Arbitrator) + { + uint8_t *foo = &netbuffer[2]; + + // Let the new arbitrator know what resendto counts to use + + for (i = 0; i < MAXPLAYERS; ++i) + { + if (playeringame[i] && i != myconnectindex) + WriteLong (resendto[nodeforplayer[i]], &foo); + } + k = int(foo - netbuffer); + } + + for (i = 0; i < 4; i++) + { + if (NetMode == NET_PacketServer && myconnectindex != Net_Arbitrator) + { + HSendPacket (nodeforplayer[Net_Arbitrator], 2); + } + else + { + for (j = 1; j < doomcom.numnodes; j++) + if (nodeingame[j]) + HSendPacket (j, k); + } + I_WaitVBL (1); + } + + if (debugfile) + fclose (debugfile); +} + +// Forces playsim processing time to be consistent across frames. +// This improves interpolation for frames in between tics. +// +// With this cvar off the mods with a high playsim processing time will appear +// less smooth as the measured time used for interpolation will vary. + +CVAR(Bool, r_ticstability, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) + +static uint64_t stabilityticduration = 0; +static uint64_t stabilitystarttime = 0; + +static void TicStabilityWait() +{ + using namespace std::chrono; + using namespace std::this_thread; + + if (!r_ticstability) + return; + + uint64_t start = duration_cast(steady_clock::now().time_since_epoch()).count(); + while (true) + { + uint64_t cur = duration_cast(steady_clock::now().time_since_epoch()).count(); + if (cur - start > stabilityticduration) + break; + } +} + +static void TicStabilityBegin() +{ + using namespace std::chrono; + stabilitystarttime = duration_cast(steady_clock::now().time_since_epoch()).count(); +} + +static void TicStabilityEnd() +{ + using namespace std::chrono; + uint64_t stabilityendtime = duration_cast(steady_clock::now().time_since_epoch()).count(); + stabilityticduration = std::min(stabilityendtime - stabilitystarttime, (uint64_t)1'000'000); +} + +// +// TryRunTics +// +void TryRunTics (void) +{ +#if 0 + int i; + int lowtic; + int realtics; + int availabletics; + int counts; + int numplaying; + + // If paused, do not eat more CPU time than we need, because it + // will all be wasted anyway. + if (pauseext) + r_NoInterpolate = true; + bool doWait = cl_capfps || r_NoInterpolate /*|| netgame*/; + + // get real tics + if (doWait) + { + entertic = I_WaitForTic (oldentertics); + } + else + { + entertic = I_GetTime (); + } + realtics = entertic - oldentertics; + oldentertics = entertic; + + // get available tics + NetUpdate (); + + if (pauseext) + return; + + lowtic = INT_MAX; + numplaying = 0; + for (i = 0; i < doomcom.numnodes; i++) + { + if (nodeingame[i]) + { + numplaying++; + if (nettics[i] < lowtic) + lowtic = nettics[i]; + } + } + + if (ticdup == 1) + { + availabletics = lowtic - gametic; + } + else + { + availabletics = lowtic - gametic / ticdup; + } + + // decide how many tics to run + if (realtics < availabletics-1) + counts = realtics+1; + else if (realtics < availabletics) + counts = realtics; + else + counts = availabletics; + + // Uncapped framerate needs seprate checks + if (counts == 0 && !doWait) + { + TicStabilityWait(); + + // Check possible stall conditions + Net_CheckLastReceived(counts); + if (realtics >= 1) + { + C_Ticker(); + M_Ticker(); + // Repredict the player for new buffered movement + P_UnPredictPlayer(); + P_PredictPlayer(&players[myconnectindex]); + } + return; + } + + if (counts < 1) + counts = 1; + + if (debugfile) + fprintf (debugfile, + "=======real: %i avail: %i game: %i\n", + realtics, availabletics, counts); + + // wait for new tics if needed + while (lowtic < gametic + counts) + { + NetUpdate (); + lowtic = INT_MAX; + + for (i = 0; i < doomcom.numnodes; i++) + if (nodeingame[i] && nettics[i] < lowtic) + lowtic = nettics[i]; + + lowtic = lowtic * ticdup; + + if (lowtic < gametic) + I_Error ("TryRunTics: lowtic < gametic"); + + // Check possible stall conditions + Net_CheckLastReceived (counts); + + // Update time returned by I_GetTime, but only if we are stuck in this loop + if (lowtic < gametic + counts) + I_SetFrameTime(); + + // don't stay in here forever -- give the menu a chance to work + if (I_GetTime () - entertic >= 1) + { + C_Ticker (); + M_Ticker (); + // Repredict the player for new buffered movement + P_UnPredictPlayer(); + P_PredictPlayer(&players[myconnectindex]); + return; + } + } + + //Tic lowtic is high enough to process this gametic. Clear all possible waiting info + hadlate = false; + for (i = 0; i < MAXPLAYERS; i++) + players[i].waiting = false; + lastglobalrecvtime = I_GetTime (); //Update the last time the game tic'd over + + // run the count tics + if (counts > 0) + { + P_UnPredictPlayer(); + while (counts--) + { + TicStabilityBegin(); + if (gametic > lowtic) + { + I_Error ("gametic>lowtic"); + } + if (advancedemo) + { + D_DoAdvanceDemo (); + } + if (debugfile) fprintf (debugfile, "run tic %d\n", gametic); + C_Ticker (); + M_Ticker (); + G_Ticker(); + gametic++; + + NetUpdate (); // check for new console commands + TicStabilityEnd(); + } + P_PredictPlayer(&players[myconnectindex]); + S_UpdateSounds (players[myconnectindex].camera); // move positional sounds + } + else + { + TicStabilityWait(); + } +#endif +} + +void Net_CheckLastReceived (int counts) +{ +#if 0 + // [Ed850] Check to see the last time a packet was received. + // If it's longer then 3 seconds, a node has likely stalled. + if (I_GetTime() - lastglobalrecvtime >= GameTicRate * 3) + { + lastglobalrecvtime = I_GetTime(); //Bump the count + + if (NetMode == NET_PeerToPeer || myconnectindex == Net_Arbitrator) + { + //Keep the local node in the for loop so we can still log any cases where the local node is /somehow/ late. + //However, we don't send a resend request for sanity reasons. + for (int i = 0; i < doomcom.numnodes; i++) + { + if (nodeingame[i] && nettics[i] <= gametic + counts) + { + # + if (debugfile && !players[playerfornode[i]].waiting) + fprintf(debugfile, "%i is slow (%i to %i)\n", + i, nettics[i], gametic + counts); + //Send resend request to the late node. Also mark the node as waiting to display it in the hud. + if (i != 0) + remoteresend[i] = players[playerfornode[i]].waiting = hadlate = true; + } + else + players[playerfornode[i]].waiting = false; + } + } + else + { //Send a resend request to the Arbitrator, as it's obvious we are stuck here. + if (debugfile && !players[Net_Arbitrator].waiting) + fprintf(debugfile, "Arbitrator is slow (%i to %i)\n", + nettics[nodeforplayer[Net_Arbitrator]], gametic + counts); + //Send resend request to the Arbitrator. Also mark the Arbitrator as waiting to display it in the hud. + remoteresend[nodeforplayer[Net_Arbitrator]] = players[Net_Arbitrator].waiting = hadlate = true; + } + } +#endif +} + +void Net_NewMakeTic (void) +{ + specials.NewMakeTic (); +} + +void Net_WriteByte (uint8_t it) +{ + specials << it; +} + +void Net_WriteWord (short it) +{ + specials << it; +} + +void Net_WriteLong (int it) +{ + specials << it; +} + +void Net_WriteFloat (float it) +{ + specials << it; +} + +void Net_WriteString (const char *it) +{ + specials << it; +} + +void Net_WriteBytes (const uint8_t *block, int len) +{ + while (len--) + specials << *block++; +} + +//========================================================================== +// +// Dynamic buffer interface +// +//========================================================================== + +FDynamicBuffer::FDynamicBuffer () +{ + m_Data = NULL; + m_Len = m_BufferLen = 0; +} + +FDynamicBuffer::~FDynamicBuffer () +{ + if (m_Data) + { + M_Free (m_Data); + m_Data = NULL; + } + m_Len = m_BufferLen = 0; +} + +void FDynamicBuffer::SetData (const uint8_t *data, int len) +{ + if (len > m_BufferLen) + { + m_BufferLen = (len + 255) & ~255; + m_Data = (uint8_t *)M_Realloc (m_Data, m_BufferLen); + } + if (data != NULL) + { + m_Len = len; + memcpy (m_Data, data, len); + } + else + { + m_Len = 0; + } +} + +uint8_t *FDynamicBuffer::GetData (int *len) +{ + if (len) + *len = m_Len; + return m_Len ? m_Data : NULL; +} + + +// [RH] Execute a special "ticcmd". The type byte should +// have already been read, and the stream is positioned +// at the beginning of the command's actual data. +void Net_DoCommand (int type, uint8_t **stream, int player) +{ +#if 0 + uint8_t pos = 0; + char *s = NULL; + int i; + + switch (type) + { + + default: + I_Error ("Unknown net command: %d", type); + break; + } + + if (s) + delete[] s; +#endif +} + + +void Net_SkipCommand (int type, uint8_t **stream) +{ +#if 0 + uint8_t t; + size_t skip = 0; + + switch (type) + { + + default: + return; + } + + *stream += skip; +#endif +} + +// This was taken out of shared_hud, because UI code shouldn't do low level calculations that may change if the backing implementation changes. +int Net_GetLatency(int *ld, int *ad) +{ + int i, localdelay = 0, arbitratordelay = 0; + + for (i = 0; i < BACKUPTICS; i++) localdelay += netdelay[0][i]; + for (i = 0; i < BACKUPTICS; i++) arbitratordelay += netdelay[nodeforplayer[Net_Arbitrator]][i]; + arbitratordelay = ((arbitratordelay / BACKUPTICS) * ticdup) * (1000 / GameTicRate); + localdelay = ((localdelay / BACKUPTICS) * ticdup) * (1000 / GameTicRate); + int severity = 0; + + if (std::max(localdelay, arbitratordelay) > 200) + { + severity = 1; + } + if (std::max(localdelay, arbitratordelay) > 400) + { + severity = 2; + } + if (std::max(localdelay, arbitratordelay) >= ((BACKUPTICS / 2 - 1) * ticdup) * (1000 / GameTicRate)) + { + severity = 3; + } + *ld = localdelay; + *ad = arbitratordelay; + return severity; +} + +// [RH] List "ping" times +CCMD (pings) +{ + int i; + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i]) + Printf("% 4" PRId64 " %s\n", currrecvtime[i] - lastrecvtime[i], GetPlayerName(i).GetChars()); +} + +//========================================================================== +// +// Network_Controller +// +// Implement players who have the ability to change settings in a network +// game. +// +//========================================================================== + +static void Network_Controller (int playernum, bool add) +{ +#if 0 + if (myconnectindex != Net_Arbitrator) + { + Printf ("This command is only accessible to the net arbitrator.\n"); + return; + } + + if (players[playernum].settings_controller && add) + { + Printf ("%s is already on the setting controller list.\n", players[playernum].userinfo.GetName()); + return; + } + + if (!players[playernum].settings_controller && !add) + { + Printf ("%s is not on the setting controller list.\n", players[playernum].userinfo.GetName()); + return; + } + + if (!playeringame[playernum]) + { + Printf ("Player (%d) not found!\n", playernum); + return; + } + + if (players[playernum].Bot != NULL) + { + Printf ("Bots cannot be added to the controller list.\n"); + return; + } + + if (playernum == Net_Arbitrator) + { + Printf ("The net arbitrator cannot have their status changed on this list.\n"); + return; + } + + if (add) + Net_WriteByte (DEM_ADDCONTROLLER); + else + Net_WriteByte (DEM_DELCONTROLLER); + + Net_WriteByte (playernum); +#endif +} + +//========================================================================== +// +// CCMD net_addcontroller +// +//========================================================================== + +CCMD (net_addcontroller) +{ + if (!netgame) + { + Printf ("This command can only be used when playing a net game.\n"); + return; + } + + if (argv.argc () < 2) + { + Printf ("Usage: net_addcontroller \n"); + return; + } + + Network_Controller (atoi (argv[1]), true); +} + +//========================================================================== +// +// CCMD net_removecontroller +// +//========================================================================== + +CCMD (net_removecontroller) +{ + if (!netgame) + { + Printf ("This command can only be used when playing a net game.\n"); + return; + } + + if (argv.argc () < 2) + { + Printf ("Usage: net_removecontroller \n"); + return; + } + + Network_Controller (atoi (argv[1]), false); +} + +//========================================================================== +// +// CCMD net_listcontrollers +// +//========================================================================== + +CCMD (net_listcontrollers) +{ +#if 0 + if (!netgame) + { + Printf ("This command can only be used when playing a net game.\n"); + return; + } + + Printf ("The following players can change the game settings:\n"); + + for (int i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].settings_controller) + { + Printf ("- %s\n", players[i].userinfo.GetName()); + } + } +#endif +} diff --git a/source/core/d_net.h b/source/core/d_net.h new file mode 100644 index 000000000..25d6749e7 --- /dev/null +++ b/source/core/d_net.h @@ -0,0 +1,74 @@ + +#ifndef __D_NET__ +#define __D_NET__ + +#include "i_net.h" +#include "d_ticcmd.h" + +enum +{ + MAXPLAYERS = 8 +}; + +class FDynamicBuffer +{ +public: + FDynamicBuffer (); + ~FDynamicBuffer (); + + void SetData (const uint8_t *data, int len); + uint8_t *GetData (int *len = NULL); + +private: + uint8_t *m_Data; + int m_Len, m_BufferLen; +}; + +extern FDynamicBuffer NetSpecs[MAXPLAYERS][BACKUPTICS]; + +// Create any new ticcmds and broadcast to other players. +void NetUpdate (void); + +// Broadcasts special packets to other players +// to notify of game exit +void D_QuitNetGame (void); + +//? how many ticks to run? +void TryRunTics (void); + +//Use for checking to see if the netgame has stalled +void Net_CheckLastReceived(int); + +// [RH] Functions for making and using special "ticcmds" +void Net_NewMakeTic (); +void Net_WriteByte (uint8_t); +void Net_WriteWord (short); +void Net_WriteLong (int); +void Net_WriteFloat (float); +void Net_WriteString (const char *); +void Net_WriteBytes (const uint8_t *, int len); + +void Net_DoCommand (int type, uint8_t **stream, int player); +void Net_SkipCommand (int type, uint8_t **stream); + +void Net_ClearBuffers (); + + +// Netgame stuff (buffers and pointers, i.e. indices). + +// This is the interface to the packet driver, a separate program +// in DOS, but just an abstraction here. +extern doomcom_t doomcom; + +extern struct ticcmd_t localcmds[LOCALCMDTICS]; + +extern int maketic; +extern int nettics[MAXNETNODES]; +extern int netdelay[MAXNETNODES][BACKUPTICS]; +extern int nodeforplayer[MAXPLAYERS]; + +extern ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS]; +extern int ticdup; + + +#endif diff --git a/source/core/d_protocol.cpp b/source/core/d_protocol.cpp new file mode 100644 index 000000000..a11eba662 --- /dev/null +++ b/source/core/d_protocol.cpp @@ -0,0 +1,443 @@ +/* +** d_protocol.cpp +** Basic network packet creation routines and simple IFF parsing +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + + +#include "d_protocol.h" +#include "d_net.h" +#include "cmdlib.h" +#include "serializer.h" + +extern int gametic; + + +char *ReadString (uint8_t **stream) +{ + char *string = *((char **)stream); + + *stream += strlen (string) + 1; + return copystring (string); +} + +const char *ReadStringConst(uint8_t **stream) +{ + const char *string = *((const char **)stream); + *stream += strlen (string) + 1; + return string; +} + +int ReadByte (uint8_t **stream) +{ + uint8_t v = **stream; + *stream += 1; + return v; +} + +int ReadWord (uint8_t **stream) +{ + short v = (((*stream)[0]) << 8) | (((*stream)[1])); + *stream += 2; + return v; +} + +int ReadLong (uint8_t **stream) +{ + int v = (((*stream)[0]) << 24) | (((*stream)[1]) << 16) | (((*stream)[2]) << 8) | (((*stream)[3])); + *stream += 4; + return v; +} + +float ReadFloat (uint8_t **stream) +{ + union + { + int i; + float f; + } fakeint; + fakeint.i = ReadLong (stream); + return fakeint.f; +} + +void WriteString (const char *string, uint8_t **stream) +{ + char *p = *((char **)stream); + + while (*string) { + *p++ = *string++; + } + + *p++ = 0; + *stream = (uint8_t *)p; +} + + +void WriteByte (uint8_t v, uint8_t **stream) +{ + **stream = v; + *stream += 1; +} + +void WriteWord (short v, uint8_t **stream) +{ + (*stream)[0] = v >> 8; + (*stream)[1] = v & 255; + *stream += 2; +} + +void WriteLong (int v, uint8_t **stream) +{ + (*stream)[0] = v >> 24; + (*stream)[1] = (v >> 16) & 255; + (*stream)[2] = (v >> 8) & 255; + (*stream)[3] = v & 255; + *stream += 4; +} + +void WriteFloat (float v, uint8_t **stream) +{ + union + { + int i; + float f; + } fakeint; + fakeint.f = v; + WriteLong (fakeint.i, stream); +} + +// Returns the number of bytes read +int UnpackUserCmd (InputPacket *ucmd, const InputPacket *basis, uint8_t **stream) +{ + uint8_t *start = *stream; + uint8_t flags; + + if (basis != NULL) + { + if (basis != ucmd) + { + memcpy (ucmd, basis, sizeof(InputPacket)); + } + } + else + { + memset (ucmd, 0, sizeof(InputPacket)); + } + + flags = ReadByte (stream); + + if (flags) + { + // We can support up to 29 buttons, using from 0 to 4 bytes to store them. + if (flags & UCMDF_BUTTONS) + ucmd->actions = ESyncBits::FromInt(ReadLong(stream)); + if (flags & UCMDF_PITCH) + ucmd->q16horz = ReadLong(stream); + if (flags & UCMDF_YAW) + ucmd->q16avel = ReadLong(stream); + if (flags & UCMDF_FORWARDMOVE) + ucmd->fvel = ReadWord (stream); + if (flags & UCMDF_SIDEMOVE) + ucmd->svel = ReadWord (stream); + if (flags & UCMDF_UPMOVE) + ucmd->q16horiz = ReadWord (stream); + if (flags & UCMDF_ROLL) + ucmd->q16ang = ReadWord (stream); + } + + return int(*stream - start); +} + +// Returns the number of bytes written +int PackUserCmd (const InputPacket *ucmd, const InputPacket *basis, uint8_t **stream) +{ + uint8_t flags = 0; + uint8_t *temp = *stream; + uint8_t *start = *stream; + InputPacket blank; + + if (basis == NULL) + { + memset (&blank, 0, sizeof(blank)); + basis = ␣ + } + + WriteByte (0, stream); // Make room for the packing bits + + if (ucmd->actions != basis->actions) + { + flags |= UCMDF_BUTTONS; + WriteLong(ucmd->actions, stream); + } + if (ucmd->q16horz != basis->q16horz) + { + flags |= UCMDF_PITCH; + WriteLong (ucmd->q16horz, stream); + } + if (ucmd->q16avel != basis->q16avel) + { + flags |= UCMDF_YAW; + WriteLong (ucmd->q16avel, stream); + } + if (ucmd->fvel != basis->fvel) + { + flags |= UCMDF_FORWARDMOVE; + WriteWord (ucmd->fvel, stream); + } + if (ucmd->svel != basis->svel) + { + flags |= UCMDF_SIDEMOVE; + WriteWord (ucmd->svel, stream); + } + if (ucmd->q16horiz != basis->q16horiz) + { + flags |= UCMDF_UPMOVE; + WriteLong (ucmd->q16horiz, stream); + } + if (ucmd->q16ang != basis->q16ang) + { + flags |= UCMDF_ROLL; + WriteLong (ucmd->q16ang, stream); + } + + // Write the packing bits + WriteByte (flags, &temp); + + return int(*stream - start); +} + +FSerializer &Serialize(FSerializer &arc, const char *key, ticcmd_t &cmd, ticcmd_t *def) +{ + if (arc.BeginObject(key)) + { + arc("consistency", cmd.consistancy) + ("ucmd", cmd.ucmd) + .EndObject(); + } + return arc; +} + +FSerializer &Serialize(FSerializer &arc, const char *key, InputPacket &cmd, InputPacket *def) +{ + if (arc.BeginObject(key)) + { + arc("actions", cmd.actions) + ("horz", cmd.q16horz) + ("avel", cmd.q16avel) + ("ang", cmd.q16ang) + ("fvel", cmd.fvel) + ("svwl", cmd.svel) + ("q16horiz", cmd.q16horiz) + .EndObject(); + } + return arc; +} + +int WriteUserCmdMessage (InputPacket *ucmd, const InputPacket *basis, uint8_t **stream) +{ + if (basis == NULL) + { + if (ucmd->actions != 0 || + ucmd->q16horz != 0 || + ucmd->q16avel != 0 || + ucmd->fvel != 0 || + ucmd->svel != 0 || + ucmd->q16horiz != 0 || + ucmd->q16ang != 0) + { + WriteByte (DEM_USERCMD, stream); + return PackUserCmd (ucmd, basis, stream) + 1; + } + } + else + if (ucmd->actions != basis->actions || + ucmd->q16horz != basis->q16horz || + ucmd->q16avel != basis->q16avel || + ucmd->fvel != basis->fvel || + ucmd->svel != basis->svel || + ucmd->q16horiz != basis->q16horiz || + ucmd->q16ang != basis->q16ang) + { + WriteByte (DEM_USERCMD, stream); + return PackUserCmd (ucmd, basis, stream) + 1; + } + + WriteByte (DEM_EMPTYUSERCMD, stream); + return 1; +} + + +int SkipTicCmd (uint8_t **stream, int count) +{ + int i, skip; + uint8_t *flow = *stream; + + for (i = count; i > 0; i--) + { + bool moreticdata = true; + + flow += 2; // Skip consistancy marker + while (moreticdata) + { + uint8_t type = *flow++; + + if (type == DEM_USERCMD) + { + moreticdata = false; + skip = 1; + if (*flow & UCMDF_PITCH) skip += 4; + if (*flow & UCMDF_YAW) skip += 4; + if (*flow & UCMDF_FORWARDMOVE) skip += 2; + if (*flow & UCMDF_SIDEMOVE) skip += 2; + if (*flow & UCMDF_UPMOVE) skip += 4; + if (*flow & UCMDF_ROLL) skip += 4; + if (*flow & UCMDF_BUTTONS) skip += 4; + flow += skip; + } + else if (type == DEM_EMPTYUSERCMD) + { + moreticdata = false; + } + else + { + Net_SkipCommand (type, &flow); + } + } + } + + skip = int(flow - *stream); + *stream = flow; + + return skip; +} + +extern short consistancy[MAXPLAYERS][BACKUPTICS]; +void ReadTicCmd (uint8_t **stream, int player, int tic) +{ + int type; + uint8_t *start; + ticcmd_t *tcmd; + + int ticmod = tic % BACKUPTICS; + + tcmd = &netcmds[player][ticmod]; + tcmd->consistancy = ReadWord (stream); + + start = *stream; + + while ((type = ReadByte (stream)) != DEM_USERCMD && type != DEM_EMPTYUSERCMD) + Net_SkipCommand (type, stream); + + NetSpecs[player][ticmod].SetData (start, int(*stream - start - 1)); + + if (type == DEM_USERCMD) + { + UnpackUserCmd (&tcmd->ucmd, + tic ? &netcmds[player][(tic-1)%BACKUPTICS].ucmd : NULL, stream); + } + else + { + if (tic) + { + memcpy (&tcmd->ucmd, &netcmds[player][(tic-1)%BACKUPTICS].ucmd, sizeof(tcmd->ucmd)); + } + else + { + memset (&tcmd->ucmd, 0, sizeof(tcmd->ucmd)); + } + } +#if 0 + if (player==consoleplayer&&tic>BACKUPTICS) + assert(consistancy[player][ticmod] == tcmd->consistancy); +#endif +} + +void RunNetSpecs (int player, int buf) +{ + uint8_t *stream; + int len; + + if (gametic % ticdup == 0) + { + stream = NetSpecs[player][buf].GetData (&len); + if (stream) + { + uint8_t *end = stream + len; + while (stream < end) + { + int type = ReadByte (&stream); + Net_DoCommand (type, &stream, player); + } +#if 0 + if (!demorecording) +#endif + NetSpecs[player][buf].SetData (NULL, 0); + } + } +} + +uint8_t *lenspot; + +// Write the header of an IFF chunk and leave space +// for the length field. +void StartChunk (int id, uint8_t **stream) +{ + WriteLong (id, stream); + lenspot = *stream; + *stream += 4; +} + +// Write the length field for the chunk and insert +// pad byte if the chunk is odd-sized. +void FinishChunk (uint8_t **stream) +{ + int len; + + if (!lenspot) + return; + + len = int(*stream - lenspot - 4); + WriteLong (len, &lenspot); + if (len & 1) + WriteByte (0, stream); + + lenspot = NULL; +} + +// Skip past an unknown chunk. *stream should be +// pointing to the chunk's length field. +void SkipChunk (uint8_t **stream) +{ + int len; + + len = ReadLong (stream); + *stream += len + (len & 1); +} diff --git a/source/core/d_protocol.h b/source/core/d_protocol.h new file mode 100644 index 000000000..5f8948d96 --- /dev/null +++ b/source/core/d_protocol.h @@ -0,0 +1,119 @@ +/* +** d_protocol.h +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#ifndef __D_PROTOCOL_H__ +#define __D_PROTOCOL_H__ + +#include +#include "packet.h" + +// The IFF routines here all work with big-endian IDs, even if the host +// system is little-endian. +#define BIGE_ID(a,b,c,d) ((d)|((c)<<8)|((b)<<16)|((a)<<24)) + +#define FORM_ID BIGE_ID('F','O','R','M') +#define ZDEM_ID BIGE_ID('R','D','E','M') +#define ZDHD_ID BIGE_ID('R','Z','H','D') +#define VARS_ID BIGE_ID('V','A','R','S') +#define UINF_ID BIGE_ID('U','I','N','F') +#define COMP_ID BIGE_ID('C','O','M','P') +#define BODY_ID BIGE_ID('B','O','D','Y') +#define NETD_ID BIGE_ID('N','E','T','D') +#define WEAP_ID BIGE_ID('W','E','A','P') + +#define ANGLE2SHORT(x) ((((x)/360) & 65535) +#define SHORT2ANGLE(x) ((x)*360) + + +struct zdemoheader_s { + uint8_t demovermajor; + uint8_t demoverminor; + uint8_t minvermajor; + uint8_t minverminor; + uint8_t map[8]; + unsigned int rngseed; + uint8_t consoleplayer; +}; + + +class FArchive; + +// When transmitted, the above message is preceded by a uint8_t +// indicating which fields are actually present in the message. +enum +{ + UCMDF_BUTTONS = 0x01, + UCMDF_PITCH = 0x02, + UCMDF_YAW = 0x04, + UCMDF_FORWARDMOVE = 0x08, + UCMDF_SIDEMOVE = 0x10, + UCMDF_UPMOVE = 0x20, + UCMDF_ROLL = 0x40, +}; + +// When changing the following enum, be sure to update Net_SkipCommand() +// and Net_DoCommand() in d_net.cpp. +enum EDemoCommand +{ + DEM_BAD, // 0 Bad command + DEM_USERCMD, + DEM_EMPTYUSERCMD, +}; + +void StartChunk (int id, uint8_t **stream); +void FinishChunk (uint8_t **stream); +void SkipChunk (uint8_t **stream); + +int UnpackUserCmd (InputPacket *ucmd, const InputPacket*basis, uint8_t **stream); +int PackUserCmd (const InputPacket*ucmd, const InputPacket*basis, uint8_t **stream); +int WriteUserCmdMessage (InputPacket*ucmd, const InputPacket*basis, uint8_t **stream); + +struct ticcmd_t; + +int SkipTicCmd (uint8_t **stream, int count); +void ReadTicCmd (uint8_t **stream, int player, int tic); +void RunNetSpecs (int player, int buf); + +int Readuint8_t (uint8_t **stream); +int Reauint32_t (uint8_t **stream); +int ReadLong (uint8_t **stream); +float ReadFloat (uint8_t **stream); +char *ReadString (uint8_t **stream); +const char *ReadStringConst(uint8_t **stream); +void WriteByte (uint8_t val, uint8_t **stream); +void WriteWord (short val, uint8_t **stream); +void WriteLong (int val, uint8_t **stream); +void WriteFloat (float val, uint8_t **stream); +void WriteString (const char *string, uint8_t **stream); + +#endif //__D_PROTOCOL_H__ diff --git a/source/core/d_ticcmd.h b/source/core/d_ticcmd.h new file mode 100644 index 000000000..cf1e1e95b --- /dev/null +++ b/source/core/d_ticcmd.h @@ -0,0 +1,42 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// DESCRIPTION: +// System specific interface stuff. +// +//----------------------------------------------------------------------------- + + +#ifndef __D_TICCMD_H__ +#define __D_TICCMD_H__ + +#include "d_protocol.h" +#include "packet.h" + +// The data sampled per tick (single player) +// and transmitted to other peers (multiplayer). +// Mainly movements/button commands per game tick, +// plus a checksum for internal state consistency. +struct ticcmd_t +{ + InputPacket ucmd; + uint16_t consistancy; // checks for net game +}; + + +FArchive &operator<< (FArchive &arc, ticcmd_t &cmd); + +#endif // __D_TICCMD_H__ diff --git a/source/core/version.h b/source/core/version.h index 6a61b4466..ff436c00a 100644 --- a/source/core/version.h +++ b/source/core/version.h @@ -82,6 +82,8 @@ const char *GetVersionString(); #define SAVEVER_SW 7 #define SAVEVER_PS 6 +#define NETGAMEVERSION 1 + #if defined(__APPLE__) || defined(_WIN32) #define GAME_DIR GAMENAME #else From d49aedacead33aadb38b5c201aed1c6811cdd2a7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 00:55:49 +0200 Subject: [PATCH 30/43] - continued work on main loop - added a few new entry points to the game interface. --- source/CMakeLists.txt | 1 + source/blood/src/blood.cpp | 2 +- source/blood/src/blood.h | 3 +- source/blood/src/sfx.cpp | 2 +- source/blood/src/sound.h | 1 - source/common/rendering/v_framebuffer.cpp | 2 +- source/core/d_net.cpp | 217 +---------- source/core/d_net.h | 3 + source/core/gamecontrol.cpp | 1 + source/core/gamestruct.h | 3 + source/core/mainloop.cpp | 453 ++++++++++++++++++++++ source/exhumed/src/exhumed.h | 2 + source/exhumed/src/gameloop.cpp | 88 ++--- source/exhumed/src/sound.cpp | 2 +- source/exhumed/src/sound.h | 1 - source/games/duke/src/d_menu.cpp | 2 +- source/games/duke/src/duke3d.h | 1 + source/games/duke/src/gameloop.cpp | 2 +- source/games/duke/src/sounds.cpp | 2 +- source/games/duke/src/sounds.h | 1 - source/sw/src/d_menu.cpp | 2 +- source/sw/src/game.cpp | 90 ++--- source/sw/src/game.h | 2 + source/sw/src/player.cpp | 2 +- source/sw/src/sounds.cpp | 2 +- source/sw/src/sounds.h | 1 - 26 files changed, 566 insertions(+), 322 deletions(-) create mode 100644 source/core/mainloop.cpp diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index e9cdbfa68..ab56e5543 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -785,6 +785,7 @@ set (PCH_SOURCES core/ct_chat.cpp core/d_net.cpp core/d_protocol.cpp + core/mainloop.cpp core/gameconfigfile.cpp core/gamecvars.cpp core/gamecontrol.cpp diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index ce02bf0fc..a8336a6d8 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -589,7 +589,7 @@ void ProcessFrame(void) ambProcess(); viewUpdateDelirium(); viewUpdateShake(); - sfxUpdate3DSounds(); + gi->UpdateSounds(); if (gMe->hand == 1) { const int CHOKERATE = 8; diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index a795da1ad..27c57a9f3 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -89,7 +89,8 @@ struct GameInterface : ::GameInterface void QuitToTitle() override; FString GetCoordString() override; ReservedSpace GetReservedScreenSpace(int viewsize) override; - + void UpdateSounds() override; + GameStats getStats() override; }; diff --git a/source/blood/src/sfx.cpp b/source/blood/src/sfx.cpp index 7c600ed12..75a206069 100644 --- a/source/blood/src/sfx.cpp +++ b/source/blood/src/sfx.cpp @@ -121,7 +121,7 @@ void BloodSoundEngine::CalcPosVel(int type, const void* source, const float pt[3 } -void sfxUpdate3DSounds(void) +void GameInterface::UpdateSounds() { SoundListener listener; diff --git a/source/blood/src/sound.h b/source/blood/src/sound.h index b95ac7987..c512ccd16 100644 --- a/source/blood/src/sound.h +++ b/source/blood/src/sound.h @@ -60,7 +60,6 @@ void sfxPlay3DSound(spritetype *pSprite, int soundId, int a3 = -1, int a4 = 0); void sfxPlay3DSoundCP(spritetype* pSprite, int soundId, int a3 = -1, int a4 = 0, int pitch = 0, int volume = -1); void sfxKill3DSound(spritetype *pSprite, int a2 = -1, int a3 = -1); void sfxKillAllSounds(void); -void sfxUpdate3DSounds(void); void sfxSetReverb(bool toggle); void sfxSetReverb2(bool toggle); diff --git a/source/common/rendering/v_framebuffer.cpp b/source/common/rendering/v_framebuffer.cpp index 4d55989c3..315931d1e 100644 --- a/source/common/rendering/v_framebuffer.cpp +++ b/source/common/rendering/v_framebuffer.cpp @@ -58,7 +58,7 @@ CVAR(Bool, gl_scale_viewport, true, CVAR_ARCHIVE); EXTERN_CVAR(Int, vid_maxfps) -CVAR(Bool, cl_capfps, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +EXTERN_CVAR(Bool, cl_capfps) EXTERN_CVAR(Int, screenblocks) //========================================================================== diff --git a/source/core/d_net.cpp b/source/core/d_net.cpp index 9fa2794d1..303ffa62d 100644 --- a/source/core/d_net.cpp +++ b/source/core/d_net.cpp @@ -51,14 +51,15 @@ #include "i_time.h" #include "d_ticcmd.h" +extern bool pauseext; +extern int gametic; + // Placeholders to make it compile. FILE* debugfile; -int gametic; extern bool netgame; bool demoplayback; int Net_Arbitrator; bool playeringame[MAXPLAYERS]; -bool pauseext; bool singletics; char* startmap; int rngseed; @@ -69,12 +70,6 @@ void D_WriteUserInfoStrings(int, uint8_t**, bool) {} FString GetPlayerName(int num); void G_BuildTiccmd(ticcmd_t*) {} - - -EXTERN_CVAR (Int, disableautosave) -EXTERN_CVAR (Int, autosavecount) -EXTERN_CVAR(Bool, cl_capfps) - //#define SIMULATEERRORS (RAND_MAX/3) #define SIMULATEERRORS 0 @@ -1812,212 +1807,6 @@ void D_QuitNetGame (void) fclose (debugfile); } -// Forces playsim processing time to be consistent across frames. -// This improves interpolation for frames in between tics. -// -// With this cvar off the mods with a high playsim processing time will appear -// less smooth as the measured time used for interpolation will vary. - -CVAR(Bool, r_ticstability, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) - -static uint64_t stabilityticduration = 0; -static uint64_t stabilitystarttime = 0; - -static void TicStabilityWait() -{ - using namespace std::chrono; - using namespace std::this_thread; - - if (!r_ticstability) - return; - - uint64_t start = duration_cast(steady_clock::now().time_since_epoch()).count(); - while (true) - { - uint64_t cur = duration_cast(steady_clock::now().time_since_epoch()).count(); - if (cur - start > stabilityticduration) - break; - } -} - -static void TicStabilityBegin() -{ - using namespace std::chrono; - stabilitystarttime = duration_cast(steady_clock::now().time_since_epoch()).count(); -} - -static void TicStabilityEnd() -{ - using namespace std::chrono; - uint64_t stabilityendtime = duration_cast(steady_clock::now().time_since_epoch()).count(); - stabilityticduration = std::min(stabilityendtime - stabilitystarttime, (uint64_t)1'000'000); -} - -// -// TryRunTics -// -void TryRunTics (void) -{ -#if 0 - int i; - int lowtic; - int realtics; - int availabletics; - int counts; - int numplaying; - - // If paused, do not eat more CPU time than we need, because it - // will all be wasted anyway. - if (pauseext) - r_NoInterpolate = true; - bool doWait = cl_capfps || r_NoInterpolate /*|| netgame*/; - - // get real tics - if (doWait) - { - entertic = I_WaitForTic (oldentertics); - } - else - { - entertic = I_GetTime (); - } - realtics = entertic - oldentertics; - oldentertics = entertic; - - // get available tics - NetUpdate (); - - if (pauseext) - return; - - lowtic = INT_MAX; - numplaying = 0; - for (i = 0; i < doomcom.numnodes; i++) - { - if (nodeingame[i]) - { - numplaying++; - if (nettics[i] < lowtic) - lowtic = nettics[i]; - } - } - - if (ticdup == 1) - { - availabletics = lowtic - gametic; - } - else - { - availabletics = lowtic - gametic / ticdup; - } - - // decide how many tics to run - if (realtics < availabletics-1) - counts = realtics+1; - else if (realtics < availabletics) - counts = realtics; - else - counts = availabletics; - - // Uncapped framerate needs seprate checks - if (counts == 0 && !doWait) - { - TicStabilityWait(); - - // Check possible stall conditions - Net_CheckLastReceived(counts); - if (realtics >= 1) - { - C_Ticker(); - M_Ticker(); - // Repredict the player for new buffered movement - P_UnPredictPlayer(); - P_PredictPlayer(&players[myconnectindex]); - } - return; - } - - if (counts < 1) - counts = 1; - - if (debugfile) - fprintf (debugfile, - "=======real: %i avail: %i game: %i\n", - realtics, availabletics, counts); - - // wait for new tics if needed - while (lowtic < gametic + counts) - { - NetUpdate (); - lowtic = INT_MAX; - - for (i = 0; i < doomcom.numnodes; i++) - if (nodeingame[i] && nettics[i] < lowtic) - lowtic = nettics[i]; - - lowtic = lowtic * ticdup; - - if (lowtic < gametic) - I_Error ("TryRunTics: lowtic < gametic"); - - // Check possible stall conditions - Net_CheckLastReceived (counts); - - // Update time returned by I_GetTime, but only if we are stuck in this loop - if (lowtic < gametic + counts) - I_SetFrameTime(); - - // don't stay in here forever -- give the menu a chance to work - if (I_GetTime () - entertic >= 1) - { - C_Ticker (); - M_Ticker (); - // Repredict the player for new buffered movement - P_UnPredictPlayer(); - P_PredictPlayer(&players[myconnectindex]); - return; - } - } - - //Tic lowtic is high enough to process this gametic. Clear all possible waiting info - hadlate = false; - for (i = 0; i < MAXPLAYERS; i++) - players[i].waiting = false; - lastglobalrecvtime = I_GetTime (); //Update the last time the game tic'd over - - // run the count tics - if (counts > 0) - { - P_UnPredictPlayer(); - while (counts--) - { - TicStabilityBegin(); - if (gametic > lowtic) - { - I_Error ("gametic>lowtic"); - } - if (advancedemo) - { - D_DoAdvanceDemo (); - } - if (debugfile) fprintf (debugfile, "run tic %d\n", gametic); - C_Ticker (); - M_Ticker (); - G_Ticker(); - gametic++; - - NetUpdate (); // check for new console commands - TicStabilityEnd(); - } - P_PredictPlayer(&players[myconnectindex]); - S_UpdateSounds (players[myconnectindex].camera); // move positional sounds - } - else - { - TicStabilityWait(); - } -#endif -} void Net_CheckLastReceived (int counts) { diff --git a/source/core/d_net.h b/source/core/d_net.h index 25d6749e7..444c189bf 100644 --- a/source/core/d_net.h +++ b/source/core/d_net.h @@ -69,6 +69,9 @@ extern int nodeforplayer[MAXPLAYERS]; extern ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS]; extern int ticdup; +extern bool nodeingame[MAXNETNODES]; // set false as nodes leave game +extern bool hadlate; +extern uint64_t lastglobalrecvtime; // Identify the last time a packet was received. #endif diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 084802a17..9bd27b29e 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -966,6 +966,7 @@ void app_loop() } catch (CRecoverableError& err) { + gi->ErrorCleanup(); C_FullConsole(); Printf(TEXTCOLOR_RED "%s\n", err.what()); } diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h index adbf617d1..fa553dcb1 100644 --- a/source/core/gamestruct.h +++ b/source/core/gamestruct.h @@ -93,6 +93,9 @@ struct GameInterface virtual ReservedSpace GetReservedScreenSpace(int viewsize) { return { 0, 0 }; } virtual void ResetFollowPos(bool) {} virtual void GetInput(InputPacket* packet) {} + virtual void UpdateSounds() {} + virtual void ErrorCleanup() {} + virtual void Render() {} }; diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp new file mode 100644 index 000000000..598c992b4 --- /dev/null +++ b/source/core/mainloop.cpp @@ -0,0 +1,453 @@ +/* +** mainloop.cpp +** Implements the main game loop +** +**--------------------------------------------------------------------------- +** Copyright 2020 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + + +// For TryRunTics the following applies: +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright 1999-2016 Randy Heit +// Copyright 2002-2020 Christoph Oelckers +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// $Log:$ +// +// DESCRIPTION: +// DOOM Network game communication and protocol, +// all OS independent parts. +// +//----------------------------------------------------------------------------- + + +#include +#include +#include "c_cvars.h" +#include "i_time.h" +#include "d_net.h" +#include "gamecontrol.h" +#include "c_console.h" +#include "menu.h" +#include "i_system.h" +#include "raze_sound.h" +#include "raze_music.h" +#include "vm.h" + + + +// Forces playsim processing time to be consistent across frames. +// This improves interpolation for frames in between tics. +// +// With this cvar off the mods with a high playsim processing time will appear +// less smooth as the measured time used for interpolation will vary. + +CVAR(Bool, r_ticstability, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Bool, cl_capfps, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) + +static uint64_t stabilityticduration = 0; +static uint64_t stabilitystarttime = 0; + +bool pauseext; +bool r_NoInterpolate; +int entertic; +int oldentertics; +int gametic; + + +static void TicStabilityWait() +{ + using namespace std::chrono; + using namespace std::this_thread; + + if (!r_ticstability) + return; + + uint64_t start = duration_cast(steady_clock::now().time_since_epoch()).count(); + while (true) + { + uint64_t cur = duration_cast(steady_clock::now().time_since_epoch()).count(); + if (cur - start > stabilityticduration) + break; + } +} + +static void TicStabilityBegin() +{ + using namespace std::chrono; + stabilitystarttime = duration_cast(steady_clock::now().time_since_epoch()).count(); +} + +static void TicStabilityEnd() +{ + using namespace std::chrono; + uint64_t stabilityendtime = duration_cast(steady_clock::now().time_since_epoch()).count(); + stabilityticduration = std::min(stabilityendtime - stabilitystarttime, (uint64_t)1'000'000); +} + +// +// TryRunTics +// +void TryRunTics (void) +{ + int i; + int lowtic; + int realtics; + int availabletics; + int counts; + int numplaying; + + // If paused, do not eat more CPU time than we need, because it + // will all be wasted anyway. + if (pauseext) + r_NoInterpolate = true; + bool doWait = cl_capfps || r_NoInterpolate /*|| netgame*/; + + // get real tics + if (doWait) + { + entertic = I_WaitForTic (oldentertics); + } + else + { + entertic = I_GetTime (); + } + realtics = entertic - oldentertics; + oldentertics = entertic; + + // get available tics + NetUpdate (); + + if (pauseext) + return; + + lowtic = INT_MAX; + numplaying = 0; + for (i = 0; i < doomcom.numnodes; i++) + { + if (nodeingame[i]) + { + numplaying++; + if (nettics[i] < lowtic) + lowtic = nettics[i]; + } + } + + if (ticdup == 1) + { + availabletics = lowtic - gametic; + } + else + { + availabletics = lowtic - gametic / ticdup; + } + + // decide how many tics to run + if (realtics < availabletics-1) + counts = realtics+1; + else if (realtics < availabletics) + counts = realtics; + else + counts = availabletics; + + // Uncapped framerate needs seprate checks + if (counts == 0 && !doWait) + { + TicStabilityWait(); + + // Check possible stall conditions + Net_CheckLastReceived(counts); + if (realtics >= 1) + { + C_Ticker(); + M_Ticker(); + // Repredict the player for new buffered movement +#if 0 + gi->Unpredict(); + gi->Predict(myconnectindex); +#endif + } + return; + } + + if (counts < 1) + counts = 1; + + // wait for new tics if needed + while (lowtic < gametic + counts) + { + NetUpdate (); + lowtic = INT_MAX; + + for (i = 0; i < doomcom.numnodes; i++) + if (nodeingame[i] && nettics[i] < lowtic) + lowtic = nettics[i]; + + lowtic = lowtic * ticdup; + + if (lowtic < gametic) + I_Error ("TryRunTics: lowtic < gametic"); + + // Check possible stall conditions + Net_CheckLastReceived (counts); + + // Update time returned by I_GetTime, but only if we are stuck in this loop + if (lowtic < gametic + counts) + I_SetFrameTime(); + + // don't stay in here forever -- give the menu a chance to work + if (I_GetTime () - entertic >= 1) + { + C_Ticker (); + M_Ticker (); + // Repredict the player for new buffered movement +#if 0 + gi->Unpredict(); + gi->Predict(myconnectindex); +#endif + return; + } + } + + //Tic lowtic is high enough to process this gametic. Clear all possible waiting info + hadlate = false; +#if 0 + for (i = 0; i < MAXPLAYERS; i++) + players[i].waiting = false; +#endif + lastglobalrecvtime = I_GetTime (); //Update the last time the game tic'd over + + // run the count tics + if (counts > 0) + { +#if 0 + gi->Unpredict(); +#endif + while (counts--) + { + TicStabilityBegin(); + if (gametic > lowtic) + { + I_Error ("gametic>lowtic"); + } +#if 0 + if (advancedemo) + { + D_DoAdvanceDemo (); + } +#endif + //if (debugfile) fprintf (debugfile, "run tic %d\n", gametic); + C_Ticker (); + M_Ticker (); + //G_Ticker(); + gametic++; + + NetUpdate (); // check for new console commands + TicStabilityEnd(); + } +#if 0 + gi->Predict(myconnectindex); +#endif + gi->UpdateSounds(); + soundEngine->UpdateSounds(I_GetTime()); + } + else + { + TicStabilityWait(); + } +} + + +//========================================================================== +// +// D_DoomLoop +// +// Manages timing and IO, calls all ?_Responder, ?_Ticker, and ?_Drawer, +// calls I_GetTime, I_StartFrame, and I_StartTic +// +//========================================================================== + +void MainLoop () +{ + int lasttic = 0; + + // Clamp the timer to TICRATE until the playloop has been entered. + r_NoInterpolate = true; + + //vid_cursor.Callback(); + + for (;;) + { + try + { + // frame syncronous IO operations + if (gametic > lasttic) + { + lasttic = gametic; + I_StartFrame (); + } + I_SetFrameTime(); + + TryRunTics (); // will run at least one tic + // Update display, next frame, with current state. + I_StartTic (); + gi->Render(); + Mus_UpdateMusic(); // must be at the end. + } + catch (CRecoverableError &error) + { + if (error.GetMessage ()) + { + Printf (PRINT_BOLD, "\n%s\n", error.GetMessage()); + } + gi->ErrorCleanup(); + C_FullConsole(); + } + catch (CVMAbortException &error) + { + error.MaybePrintMessage(); + Printf("%s", error.stacktrace.GetChars()); + gi->ErrorCleanup(); + C_FullConsole(); + } + } +} + + +//--------------------------------------------------------------------------- +// +// The one and only main loop in the entire engine. Yay! +// +//--------------------------------------------------------------------------- +#if 0 + +void _TickSubsystems() +{ + // run these on an independent timer until we got something working for the games. + static const uint64_t tickInterval = 1'000'000'000 / 30; + static uint64_t nexttick = 0; + + auto nowtick = I_nsTime(); + if (nexttick == 0) nexttick = nowtick; + int cnt = 0; + while (nexttick <= nowtick && cnt < 5) + { + nexttick += tickInterval; + C_Ticker(); + M_Ticker(); + C_RunDelayedCommands(); + cnt++; + } + // If this took too long the engine was most likely suspended so recalibrate the timer. + // Perfect precision is not needed here. + if (cnt == 5) nexttick = nowtick + tickInterval; +} + +static void _updatePauseStatus() +{ + // This must go through the network in multiplayer games. + if (M_Active() || System_WantGuiCapture()) + { + paused = 1; + } + else if (!M_Active() || !System_WantGuiCapture()) + { + if (!pausedWithKey) + { + paused = 0; + } + + if (sendPause) + { + sendPause = false; + paused = pausedWithKey ? 0 : 2; + pausedWithKey = !!paused; + } + } + + paused ? S_PauseSound(!pausedWithKey, !paused) : S_ResumeSound(paused); +} + + +void _app_loop() +{ + gamestate = GS_STARTUP; + + while (true) + { + try + { + I_SetFrameTime(); + TickSubsystems(); + twod->SetSize(screen->GetWidth(), screen->GetHeight()); + twodpsp.SetSize(screen->GetWidth(), screen->GetHeight()); + + handleevents(); + updatePauseStatus(); + D_ProcessEvents(); + + gi->RunGameFrame(); + + // Draw overlay elements to the 2D drawer + FStat::PrintStat(twod); + CT_Drawer(); + C_DrawConsole(); + M_Drawer(); + + // Handle the final 2D overlays. + if (gamestate == GS_LEVEL) DrawFullscreenBlends(); + DrawRateStuff(); + + + videoShowFrame(0); + videoSetBrightness(0); // immediately reset this so that the value doesn't stick around in the backend. + } + catch (CRecoverableError& err) + { + C_FullConsole(); + Printf(TEXTCOLOR_RED "%s\n", err.what()); + } + } +} + + +#endif \ No newline at end of file diff --git a/source/exhumed/src/exhumed.h b/source/exhumed/src/exhumed.h index 4f178b6f1..f79a2bc48 100644 --- a/source/exhumed/src/exhumed.h +++ b/source/exhumed/src/exhumed.h @@ -251,6 +251,8 @@ struct GameInterface : ::GameInterface bool CanSave() override; ReservedSpace GetReservedScreenSpace(int viewsize) override { return { 0, 24 }; } void QuitToTitle() override; + void UpdateSounds() override; + void ErrorCleanup() override; FString statFPS() override; ::GameStats getStats() override; diff --git a/source/exhumed/src/gameloop.cpp b/source/exhumed/src/gameloop.cpp index 55b38bb9d..81db62bbf 100644 --- a/source/exhumed/src/gameloop.cpp +++ b/source/exhumed/src/gameloop.cpp @@ -256,7 +256,7 @@ void GameLoop() { GameTicker(); PlayerInterruptKeys(true); - UpdateSounds(); + gi->UpdateSounds(); CheckKeys2(); } @@ -264,55 +264,51 @@ void GameLoop() void GameInterface::RunGameFrame() { again: - try + CheckProgression(); + switch (gamestate) { - CheckProgression(); - switch (gamestate) - { - default: - case GS_STARTUP: - resettiming(); - GameAction = -1; - EndLevel = false; - - if (userConfig.CommandMap.IsNotEmpty()) - { - auto map = FindMapByName(userConfig.CommandMap); - if (map) GameAction = map->levelNumber; - userConfig.CommandMap = ""; - goto again; - } - else - { - DoTitle([](bool) { startmainmenu(); }); - } - break; - - case GS_MENUSCREEN: - case GS_FULLCONSOLE: - drawmenubackground(); - break; - - case GS_LEVEL: - GameLoop(); - GameDisplay(); - break; - - case GS_INTERMISSION: - case GS_INTRO: - RunScreenJobFrame(); // This handles continuation through its completion callback. - break; - - } - } - catch (CRecoverableError&) - { - // Clear all progression sensitive variables here. + default: + case GS_STARTUP: + resettiming(); GameAction = -1; EndLevel = false; - throw; - } + if (userConfig.CommandMap.IsNotEmpty()) + { + auto map = FindMapByName(userConfig.CommandMap); + if (map) GameAction = map->levelNumber; + userConfig.CommandMap = ""; + goto again; + } + else + { + DoTitle([](bool) { startmainmenu(); }); + } + break; + + case GS_MENUSCREEN: + case GS_FULLCONSOLE: + drawmenubackground(); + break; + + case GS_LEVEL: + GameLoop(); + GameDisplay(); + break; + + case GS_INTERMISSION: + case GS_INTRO: + RunScreenJobFrame(); // This handles continuation through its completion callback. + break; + + } +} + +void GameInterface::ErrorCleanup() +{ + // Clear all progression sensitive variables here. + GameAction = -1; + EndLevel = false; } END_PS_NS diff --git a/source/exhumed/src/sound.cpp b/source/exhumed/src/sound.cpp index 96bf57e53..557167338 100644 --- a/source/exhumed/src/sound.cpp +++ b/source/exhumed/src/sound.cpp @@ -490,7 +490,7 @@ void EXSoundEngine::CalcPosVel(int type, const void* source, const float pt[3], // //========================================================================== -void UpdateSounds() +void GameInterface::UpdateSounds() { if (nFreeze) return; diff --git a/source/exhumed/src/sound.h b/source/exhumed/src/sound.h index 9e33e6b04..5904594de 100644 --- a/source/exhumed/src/sound.h +++ b/source/exhumed/src/sound.h @@ -117,7 +117,6 @@ extern short nCreepyTimer; extern short StaticSound[]; -void UpdateSounds(); void UpdateCreepySounds(); void InitFX(); diff --git a/source/games/duke/src/d_menu.cpp b/source/games/duke/src/d_menu.cpp index 172fdb4aa..43dd57d7e 100644 --- a/source/games/duke/src/d_menu.cpp +++ b/source/games/duke/src/d_menu.cpp @@ -293,7 +293,7 @@ void GameInterface::StartGame(FNewGameStartup& gs) while (S_CheckSoundPlaying(skillsound)) { - S_Update(); + gi->UpdateSounds(); soundEngine->UpdateSounds(I_GetTime()); I_GetEvent(); } diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 0d24c1c62..315422fcb 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -58,6 +58,7 @@ struct GameInterface : public ::GameInterface void DrawPlayerSprite(const DVector2& origin, bool onteam) override; void ResetFollowPos(bool message) override; void GetInput(InputPacket* packet) override; + void UpdateSounds() override; }; diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index 5099e7d19..fc57bd5de 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -331,7 +331,7 @@ void GameTicker() } nonsharedkeys(); - S_Update(); + gi->UpdateSounds(); drawtime.Reset(); drawtime.Clock(); videoSetBrightness(thunder_brightness); diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index dfb5ef329..444ebb8ac 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -318,7 +318,7 @@ void DukeSoundEngine::CalcPosVel(int type, const void* source, const float pt[3] // //========================================================================== -void S_Update(void) +void GameInterface::UpdateSounds(void) { SoundListener listener; vec3_t* c; diff --git a/source/games/duke/src/sounds.h b/source/games/duke/src/sounds.h index 56d015451..6d8c68df9 100644 --- a/source/games/duke/src/sounds.h +++ b/source/games/duke/src/sounds.h @@ -36,7 +36,6 @@ enum esound_t }; void S_InitSound(); -void S_Update(void); void S_CacheAllSounds(void); int S_DefineSound(unsigned index, const char* filename, int ps, int pe, int pr, int m, int vo, float vol); diff --git a/source/sw/src/d_menu.cpp b/source/sw/src/d_menu.cpp index edaa634f6..b00b5aca0 100644 --- a/source/sw/src/d_menu.cpp +++ b/source/sw/src/d_menu.cpp @@ -230,7 +230,7 @@ void GameInterface::StartGame(FNewGameStartup& gs) while (soundEngine->IsSourcePlayingSomething(SOURCE_None, nullptr, CHAN_VOICE)) { - DoUpdateSounds(); + gi->UpdateSounds(); soundEngine->UpdateSounds(I_GetTime()); I_GetEvent(); } diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 1d1964d2e..c12201525 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -767,59 +767,55 @@ void GameTicker(void) void GameInterface::RunGameFrame() { - try + // if the menu initiazed a new game or loaded a savegame, switch to play mode. + if (SavegameLoaded || NextLevel) gamestate = GS_LEVEL; + gi->UpdateSounds(); + switch (gamestate) { - // if the menu initiazed a new game or loaded a savegame, switch to play mode. - if (SavegameLoaded || NextLevel) gamestate = GS_LEVEL; - DoUpdateSounds(); - switch (gamestate) + default: + case GS_STARTUP: + I_ResetTime(); + lastTic = -1; + ogameclock = gameclock = 0; + + if (userConfig.CommandMap.IsNotEmpty()) { - default: - case GS_STARTUP: - I_ResetTime(); - lastTic = -1; - ogameclock = gameclock = 0; - - if (userConfig.CommandMap.IsNotEmpty()) - { - } - else - { - if (!userConfig.nologo) Logo([](bool) { StartMenu(); }); - else StartMenu(); - } - break; - - case GS_MENUSCREEN: - case GS_FULLCONSOLE: - DrawMenuLevelScreen(); - break; - - case GS_LEVEL: - GameTicker(); - break; - - case GS_INTERMISSION: - case GS_INTRO: - RunScreenJobFrame(); // This handles continuation through its completion callback. - break; - } - } - catch (CRecoverableError&) - { - // Make sure we do not leave the game in an unstable state - TerminateLevel(); - NextLevel = nullptr; - SavegameLoaded = false; - ExitLevel = false; - FinishAnim = 0; - FinishedLevel = false; - throw; - } + else + { + if (!userConfig.nologo) Logo([](bool) { StartMenu(); }); + else StartMenu(); + } + break; + case GS_MENUSCREEN: + case GS_FULLCONSOLE: + DrawMenuLevelScreen(); + break; + + case GS_LEVEL: + GameTicker(); + break; + + case GS_INTERMISSION: + case GS_INTRO: + RunScreenJobFrame(); // This handles continuation through its completion callback. + break; + + } } + +void GameInterface::ErrorCleanup() +{ + // Make sure we do not leave the game in an unstable state + TerminateLevel(); + NextLevel = nullptr; + SavegameLoaded = false; + ExitLevel = false; + FinishAnim = 0; + FinishedLevel = false; +} //--------------------------------------------------------------------------- // // diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 7b44571cf..c7a1ec15c 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2259,6 +2259,8 @@ struct GameInterface : ::GameInterface ReservedSpace GetReservedScreenSpace(int viewsize) override; void QuitToTitle() override; void ResetFollowPos(bool message) override; + void UpdateSounds() override; + void ErrorCleanup() override; FString statFPS() override; GameStats getStats() override; diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index c49f87bc2..92758ee86 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -7727,7 +7727,7 @@ domovethings(void) MultiPlayLimits(); //if (MoveSkip8 == 0) // 8=5x 4=10x, 2=20x, 0=40x per second - DoUpdateSounds(); + gi->UpdateSounds(); CorrectPrediction(movefifoplc - 1); diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index 8c096a3fb..6339d882c 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -585,7 +585,7 @@ void SWSoundEngine::CalcPosVel(int type, const void* source, const float pt[3], // //========================================================================== -void DoUpdateSounds(void) +void GameInterface::UpdateSounds(void) { PLAYERp pp = Player + screenpeek; SoundListener listener; diff --git a/source/sw/src/sounds.h b/source/sw/src/sounds.h index eab266b92..9cbbc1602 100644 --- a/source/sw/src/sounds.h +++ b/source/sw/src/sounds.h @@ -71,7 +71,6 @@ struct ambientstruct; typedef struct ambientstruct AMB_INFO, *AMB_INFOp; -void DoUpdateSounds(void); void Terminate3DSounds(void); void Set3DSoundOwner(short spritenum); From cc04d41903d776c367e1b50689a58536ca0c0458 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 07:53:20 +0200 Subject: [PATCH 31/43] - Duke: moved the clock reset to a separate function and deleted the unused lockclock variable. --- source/games/duke/src/funct.h | 1 + source/games/duke/src/gameloop.cpp | 14 ++++++++------ source/games/duke/src/global.cpp | 2 -- source/games/duke/src/global.h | 2 -- source/games/duke/src/premap.cpp | 6 +----- source/games/duke/src/savegame.cpp | 3 --- 6 files changed, 10 insertions(+), 18 deletions(-) diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 3027c5bf4..a6df8ffae 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -243,6 +243,7 @@ void setinterpolation(int* posptr); void stopinterpolation(int* posptr); void dointerpolations(int smoothratio); int* animateptr(int i); +void resetGameClock(); void backuppos(player_struct* p, bool noclipping = false); void backuplook(player_struct* p); diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index fc57bd5de..0178cefc2 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -182,7 +182,6 @@ int domovethings() // mplpadsave(); ud.camerasprite = -1; - lockclock += TICSPERFRAME; if (earthquaketime > 0) earthquaketime--; if (rtsplaying > 0) rtsplaying--; @@ -360,14 +359,17 @@ void startmainmenu() FX_StopAllSounds(); } +void resetGameClock() +{ + I_ResetTime(); + lastTic = -1; + gameclock = 0; + cloudclock = 0; +} static void Startup() { - I_ResetTime(); - lastTic = -1; - gameclock = 0; - lockclock = 0; - + resetGameClock(); ps[myconnectindex].ftq = 0; if (userConfig.CommandMap.IsNotEmpty()) diff --git a/source/games/duke/src/global.cpp b/source/games/duke/src/global.cpp index ed76dc31f..262b940a0 100644 --- a/source/games/duke/src/global.cpp +++ b/source/games/duke/src/global.cpp @@ -114,8 +114,6 @@ int16_t cyclers[MAXCYCLERS][6]; int16_t mirrorsector[64]; int16_t mirrorwall[64]; -int lockclock; - // Redneck Rampage int wupass; int chickenplant; diff --git a/source/games/duke/src/global.h b/source/games/duke/src/global.h index 9e13c619c..41768b54e 100644 --- a/source/games/duke/src/global.h +++ b/source/games/duke/src/global.h @@ -106,8 +106,6 @@ extern int16_t cyclers[MAXCYCLERS][6]; extern int16_t mirrorsector[64]; extern int16_t mirrorwall[64]; -extern int lockclock; - extern int wupass; extern int chickenplant; extern int thunderon; diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index d6b27c58e..b49b56023 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -756,12 +756,8 @@ void prelevel_common(int g) void resettimevars(void) { - I_ResetTime(); - lastTic = -1; - gameclock = 0; - cloudclock = 0; + resetGameClock(); levelTextTime = 85; - lockclock = 0; ready2send = 1; if (camsprite >= 0) hittype[camsprite].temp_data[0] = 0; diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index 3a89f2358..01137ccf8 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -443,7 +443,6 @@ void GameInterface::SerializeGameState(FSerializer& arc) ("mirrorcnt", mirrorcnt) .Array("mirrorsector", mirrorsector, mirrorcnt) .Array("mirrorwall", mirrorwall, mirrorcnt) - ("lockclock", lockclock) ("wupass", wupass) ("chickenplant", chickenplant) ("thunderon", thunderon) @@ -482,8 +481,6 @@ void GameInterface::SerializeGameState(FSerializer& arc) // Todo: move to backend ("gameclock", gameclock) - ("lockclock", lockclock) - .Array("po", po, ud.multimode) .EndObject(); From 34510ae9b33b48fccc3eed249a134c2373c9a5c0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 08:03:03 +0200 Subject: [PATCH 32/43] - added ticker stub to the game interface. --- source/core/gamestruct.h | 1 + source/core/mainloop.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h index fa553dcb1..6e41b2edb 100644 --- a/source/core/gamestruct.h +++ b/source/core/gamestruct.h @@ -96,6 +96,7 @@ struct GameInterface virtual void UpdateSounds() {} virtual void ErrorCleanup() {} virtual void Render() {} + virtual void Ticker() {} }; diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 598c992b4..1ee24e759 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -278,7 +278,7 @@ void TryRunTics (void) //if (debugfile) fprintf (debugfile, "run tic %d\n", gametic); C_Ticker (); M_Ticker (); - //G_Ticker(); + gi->Ticker(); gametic++; NetUpdate (); // check for new console commands From 49106c5b5e7a375ed79fea9af58810f6cf4f183b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 08:04:33 +0200 Subject: [PATCH 33/43] - Duke: Do not reset the global ticker. The new main loop code cannot handle that. Instead set a start value for gameclock so that gameclock can be based on an arbitrary time value instead of directly representing global time. --- source/core/gamecontrol.cpp | 2 +- source/core/gamecontrol.h | 1 + source/games/duke/src/gameloop.cpp | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 9bd27b29e..7fae461f3 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -95,7 +95,7 @@ GameInterface* gi; int myconnectindex, numplayers; int connecthead, connectpoint2[MAXMULTIPLAYERS]; auto vsnprintfptr = vsnprintf; // This is an inline in Visual Studio but we need an address for it to satisfy the MinGW compiled libraries. -int gameclock; +int gameclock, gameclockstart; int lastTic; int automapMode; diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index 9f1a173b0..8c10e090d 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -219,4 +219,5 @@ extern int automapMode; extern bool automapFollow; extern bool sendPause; extern int gameclock; +extern int gameclockstart; extern int lastTic; diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index 0178cefc2..14c1c70ca 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -294,7 +294,7 @@ void GameTicker() gameupdatetime.Clock(); int const currentTic = I_GetTime(); - gameclock = I_GetBuildTime(); + gameclock = I_GetBuildTime() - gameclockstart; while (playrunning() && currentTic - lastTic >= 1) { @@ -361,8 +361,8 @@ void startmainmenu() void resetGameClock() { - I_ResetTime(); - lastTic = -1; + I_SetFrameTime(); + gameclockstart = I_GetTime(); gameclock = 0; cloudclock = 0; } From 1e0b8038e52bb229a850a6c2efb2ecc39a9fc33c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 08:13:34 +0200 Subject: [PATCH 34/43] - removed I_ResetTime entirely and refactored SW's use of it. --- source/common/utility/i_time.cpp | 5 ----- source/common/utility/i_time.h | 3 --- source/games/duke/src/gameloop.cpp | 2 +- source/sw/src/game.cpp | 13 +++++++++---- source/sw/src/network.cpp | 5 ++--- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/source/common/utility/i_time.cpp b/source/common/utility/i_time.cpp index ce14e52d4..f54c80d78 100644 --- a/source/common/utility/i_time.cpp +++ b/source/common/utility/i_time.cpp @@ -175,11 +175,6 @@ int I_GetBuildTime() return NSToBuildTic(CurrentFrameStartTime - FirstFrameStartTime); } -void I_ResetTime() -{ - FirstFrameStartTime = CurrentFrameStartTime = 0; -} - double I_GetTimeFrac() { int currentTic = NSToTic(CurrentFrameStartTime - FirstFrameStartTime); diff --git a/source/common/utility/i_time.h b/source/common/utility/i_time.h index 1f28df893..78a399939 100644 --- a/source/common/utility/i_time.h +++ b/source/common/utility/i_time.h @@ -15,9 +15,6 @@ uint64_t I_GetTimeNS(); // Called by Build games in lieu of totalclock, returns current time in tics at ticrate of 120. int I_GetBuildTime(); -// Reset timer variables to zero when called. -void I_ResetTime(); - double I_GetTimeFrac(); double I_GetBuildTimeFrac(); diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index 14c1c70ca..0920d59a6 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -362,7 +362,7 @@ void startmainmenu() void resetGameClock() { I_SetFrameTime(); - gameclockstart = I_GetTime(); + gameclockstart = I_GetBuildTime(); gameclock = 0; cloudclock = 0; } diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index c12201525..083bfd86f 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -730,7 +730,7 @@ void GameTicker(void) ready2send = 1; int const currentTic = I_GetTime(); - gameclock = I_GetBuildTime(); + gameclock = I_GetBuildTime() - gameclockstart; if (paused) { @@ -765,6 +765,13 @@ void GameTicker(void) } +void resetGameClock() +{ + I_SetFrameTime(); + gameclockstart = I_GetBuildTime(); + ogameclock = gameclock = 0; +} + void GameInterface::RunGameFrame() { // if the menu initiazed a new game or loaded a savegame, switch to play mode. @@ -774,9 +781,7 @@ void GameInterface::RunGameFrame() { default: case GS_STARTUP: - I_ResetTime(); - lastTic = -1; - ogameclock = gameclock = 0; + resetGameClock(); if (userConfig.CommandMap.IsNotEmpty()) { diff --git a/source/sw/src/network.cpp b/source/sw/src/network.cpp index 63afbcc87..83eabcd97 100644 --- a/source/sw/src/network.cpp +++ b/source/sw/src/network.cpp @@ -43,6 +43,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS void getinput(InputPacket *, SWBOOL); +void resetGameClock(); static uint8_t tempbuf[576], packbuf[576]; int PlayClock; @@ -163,9 +164,7 @@ InitTimingVars(void) // resettiming(); totalsynctics = 0; - I_ResetTime(); - lastTic = -1; - ogameclock = gameclock = 0; + resetGameClock(); randomseed = 17L; MoveSkip8 = 2; From 367b4ce051b62cc6bcc7e54bf1fa5ed847155ee9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 09:32:34 +0200 Subject: [PATCH 35/43] - this should be all we need from GZDoom to hook up the main loop. --- source/common/engine/i_net.h | 1 + source/core/console/c_console.cpp | 1 - source/core/d_net.cpp | 4 +- source/core/d_net.h | 3 + source/core/gamecontrol.cpp | 3 - source/core/gamecontrol.h | 1 + source/core/gamestruct.h | 3 + source/core/inputstate.cpp | 2 + source/core/mainloop.cpp | 285 ++++++++++++++++++------------ source/core/palette.h | 1 + source/glbackend/glbackend.cpp | 1 + 11 files changed, 182 insertions(+), 123 deletions(-) diff --git a/source/common/engine/i_net.h b/source/common/engine/i_net.h index bddd20b18..e50955295 100644 --- a/source/common/engine/i_net.h +++ b/source/common/engine/i_net.h @@ -80,5 +80,6 @@ struct doomcom_t }; extern doomcom_t doomcom; +extern bool netgame, multiplayer; #endif diff --git a/source/core/console/c_console.cpp b/source/core/console/c_console.cpp index 60de7b380..d5edf4120 100644 --- a/source/core/console/c_console.cpp +++ b/source/core/console/c_console.cpp @@ -92,7 +92,6 @@ static FGameTexture *conback; static uint32_t conshade; static bool conline; -extern int gametic; extern bool advancedemo; extern FBaseCVar *CVars; diff --git a/source/core/d_net.cpp b/source/core/d_net.cpp index 303ffa62d..c9d399a6d 100644 --- a/source/core/d_net.cpp +++ b/source/core/d_net.cpp @@ -56,10 +56,9 @@ extern int gametic; // Placeholders to make it compile. FILE* debugfile; -extern bool netgame; bool demoplayback; int Net_Arbitrator; -bool playeringame[MAXPLAYERS]; +bool playeringame[MAXPLAYERS] = { true }; // as long as network isn't working - true for the first player, false for all others. bool singletics; char* startmap; int rngseed; @@ -68,7 +67,6 @@ bool usergame; void D_ReadUserInfoStrings(int, uint8_t**, bool) {} void D_WriteUserInfoStrings(int, uint8_t**, bool) {} FString GetPlayerName(int num); -void G_BuildTiccmd(ticcmd_t*) {} //#define SIMULATEERRORS (RAND_MAX/3) #define SIMULATEERRORS 0 diff --git a/source/core/d_net.h b/source/core/d_net.h index 444c189bf..75aa806a4 100644 --- a/source/core/d_net.h +++ b/source/core/d_net.h @@ -72,6 +72,9 @@ extern int ticdup; extern bool nodeingame[MAXNETNODES]; // set false as nodes leave game extern bool hadlate; extern uint64_t lastglobalrecvtime; // Identify the last time a packet was received. +extern bool playeringame[MAXPLAYERS]; // as long as network isn't working - true for the first player, false for all others. +extern ticcmd_t playercmds[MAXPLAYERS]; +extern short consistancy[MAXPLAYERS][BACKUPTICS]; #endif diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 7fae461f3..bf19c2169 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -426,7 +426,6 @@ void UserConfig::ProcessOptions() C_DoCommand("stat coord"); } - } //========================================================================== @@ -939,8 +938,6 @@ void app_loop() { I_SetFrameTime(); TickSubsystems(); - twod->SetSize(screen->GetWidth(), screen->GetHeight()); - twodpsp.SetSize(screen->GetWidth(), screen->GetHeight()); handleevents(); updatePauseStatus(); diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index 8c10e090d..fee026fe7 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -13,6 +13,7 @@ extern FString currentGame; extern FString LumpFilter; class FArgs; extern bool GUICapture; +extern bool AppActive; extern FMemArena dump; // this is for memory blocks than cannot be deallocated without some huge effort. Put them in here so that they do not register on shutdown. diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h index 6e41b2edb..1e0412588 100644 --- a/source/core/gamestruct.h +++ b/source/core/gamestruct.h @@ -95,8 +95,11 @@ struct GameInterface virtual void GetInput(InputPacket* packet) {} virtual void UpdateSounds() {} virtual void ErrorCleanup() {} + virtual void Startup() {} + virtual void DrawBackground() {} virtual void Render() {} virtual void Ticker() {} + virtual int GetPlayerChecksum(int pnum) { return 0x12345678 + pnum; } }; diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index 4feaab77e..9c05abf6e 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -160,6 +160,8 @@ int32_t handleevents(void) setViewport(hud_size); setsizeneeded = false; } + twod->SetSize(screen->GetWidth(), screen->GetHeight()); + twodpsp.SetSize(screen->GetWidth(), screen->GetHeight()); I_StartFrame(); I_StartTic(); diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 1ee24e759..9f09a73db 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -33,7 +33,7 @@ */ -// For TryRunTics the following applies: +// For G_Ticker and TryRunTics the following applies: //----------------------------------------------------------------------------- // // $Id:$ @@ -72,18 +72,22 @@ #include "raze_sound.h" #include "raze_music.h" #include "vm.h" +#include "gamestate.h" +#include "screenjob.h" +#include "mmulti.h" +#include "c_console.h" +#include "menu.h" +#include "uiinput.h" +#include "v_video.h" +#include "glbackend/glbackend.h" +#include "palette.h" - - -// Forces playsim processing time to be consistent across frames. -// This improves interpolation for frames in between tics. -// -// With this cvar off the mods with a high playsim processing time will appear -// less smooth as the measured time used for interpolation will vary. - +CVAR(Bool, vid_activeinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, r_ticstability, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, cl_capfps, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +ticcmd_t playercmds[MAXPLAYERS]; + static uint64_t stabilityticduration = 0; static uint64_t stabilitystarttime = 0; @@ -94,6 +98,158 @@ int oldentertics; int gametic; + +void G_BuildTiccmd(ticcmd_t* cmd) +{ + gi->GetInput(&cmd->ucmd); + cmd->consistancy = consistancy[myconnectindex][(maketic / ticdup) % BACKUPTICS]; +} + + +void G_Ticker() +{ + int i; + + handleevents(); + +#if 0 + // Todo: Migrate state changes to here instead of doing them ad-hoc + while (gameaction != ga_nothing) + { + if (gameaction == ga_newgame2) + { + gameaction = ga_newgame; + break; + } + switch (gameaction) + { + } + C_AdjustBottom(); + } +#endif + + // get commands, check consistancy, and build new consistancy check + int buf = (gametic / ticdup) % BACKUPTICS; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + { + ticcmd_t* cmd = &playercmds[i]; + ticcmd_t* newcmd = &netcmds[i][buf]; + + if ((gametic % ticdup) == 0) + { + RunNetSpecs(i, buf); + } +#if 0 + if (demorecording) + { + G_WriteDemoTiccmd(newcmd, i, buf); + } + if (demoplayback) + { + G_ReadDemoTiccmd(cmd, i); + } + else +#endif + { + *cmd = *newcmd; + } + + + if (netgame && /*!demoplayback &&*/ (gametic % ticdup) == 0) + { +#if 0 + //players[i].inconsistant = 0; + if (gametic > BACKUPTICS * ticdup && consistancy[i][buf] != cmd->consistancy) + { + players[i].inconsistant = gametic - BACKUPTICS * ticdup; + } +#endif + consistancy[i][buf] = gi->GetPlayerChecksum(i); + } + } + } + + C_RunDelayedCommands(); + + switch (gamestate) + { + default: + case GS_STARTUP: + gi->Startup(); + break; + + case GS_MENUSCREEN: + case GS_FULLCONSOLE: + gi->DrawBackground(); + break; + + case GS_LEVEL: + gi->Ticker(); + break; + + case GS_INTERMISSION: + case GS_INTRO: + RunScreenJobFrame(); + break; + + } +} + + +//========================================================================== +// +// D_Display +// +// Draw current display, possibly wiping it from the previous +// +//========================================================================== + +void D_Display() +{ + FGameTexture* wipe = nullptr; + + if (screen == NULL) + return; // for comparative timing / profiling + + if (!AppActive && (screen->IsFullscreen() || !vid_activeinbackground)) + { + return; + } + + screen->FrameTime = I_msTimeFS(); + screen->BeginFrame(); + twod->ClearClipRect(); + if ((gamestate == GS_LEVEL) && gametic != 0) + { + // [ZZ] execute event hook that we just started the frame + //E_RenderFrame(); + // + gi->Render(); + } + + // Draw overlay elements to the 2D drawer + NetUpdate(); // send out any new accumulation + CT_Drawer(); + C_DrawConsole(); + M_Drawer(); + FStat::PrintStat(twod); + + // Handle the final 2D overlays. + if (gamestate == GS_LEVEL) DrawFullscreenBlends(); + DrawRateStuff(); + + videoShowFrame(0); +} + +// Forces playsim processing time to be consistent across frames. +// This improves interpolation for frames in between tics. +// +// With this cvar off the mods with a high playsim processing time will appear +// less smooth as the measured time used for interpolation will vary. + static void TicStabilityWait() { using namespace std::chrono; @@ -278,7 +434,7 @@ void TryRunTics (void) //if (debugfile) fprintf (debugfile, "run tic %d\n", gametic); C_Ticker (); M_Ticker (); - gi->Ticker(); + G_Ticker(); gametic++; NetUpdate (); // check for new console commands @@ -299,10 +455,7 @@ void TryRunTics (void) //========================================================================== // -// D_DoomLoop -// -// Manages timing and IO, calls all ?_Responder, ?_Ticker, and ?_Drawer, -// calls I_GetTime, I_StartFrame, and I_StartTic +// MainLoop - will never return aside from exceptions being thrown. // //========================================================================== @@ -313,8 +466,6 @@ void MainLoop () // Clamp the timer to TICRATE until the playloop has been entered. r_NoInterpolate = true; - //vid_cursor.Callback(); - for (;;) { try @@ -330,7 +481,8 @@ void MainLoop () TryRunTics (); // will run at least one tic // Update display, next frame, with current state. I_StartTic (); - gi->Render(); + + D_Display(); Mus_UpdateMusic(); // must be at the end. } catch (CRecoverableError &error) @@ -352,102 +504,3 @@ void MainLoop () } } - -//--------------------------------------------------------------------------- -// -// The one and only main loop in the entire engine. Yay! -// -//--------------------------------------------------------------------------- -#if 0 - -void _TickSubsystems() -{ - // run these on an independent timer until we got something working for the games. - static const uint64_t tickInterval = 1'000'000'000 / 30; - static uint64_t nexttick = 0; - - auto nowtick = I_nsTime(); - if (nexttick == 0) nexttick = nowtick; - int cnt = 0; - while (nexttick <= nowtick && cnt < 5) - { - nexttick += tickInterval; - C_Ticker(); - M_Ticker(); - C_RunDelayedCommands(); - cnt++; - } - // If this took too long the engine was most likely suspended so recalibrate the timer. - // Perfect precision is not needed here. - if (cnt == 5) nexttick = nowtick + tickInterval; -} - -static void _updatePauseStatus() -{ - // This must go through the network in multiplayer games. - if (M_Active() || System_WantGuiCapture()) - { - paused = 1; - } - else if (!M_Active() || !System_WantGuiCapture()) - { - if (!pausedWithKey) - { - paused = 0; - } - - if (sendPause) - { - sendPause = false; - paused = pausedWithKey ? 0 : 2; - pausedWithKey = !!paused; - } - } - - paused ? S_PauseSound(!pausedWithKey, !paused) : S_ResumeSound(paused); -} - - -void _app_loop() -{ - gamestate = GS_STARTUP; - - while (true) - { - try - { - I_SetFrameTime(); - TickSubsystems(); - twod->SetSize(screen->GetWidth(), screen->GetHeight()); - twodpsp.SetSize(screen->GetWidth(), screen->GetHeight()); - - handleevents(); - updatePauseStatus(); - D_ProcessEvents(); - - gi->RunGameFrame(); - - // Draw overlay elements to the 2D drawer - FStat::PrintStat(twod); - CT_Drawer(); - C_DrawConsole(); - M_Drawer(); - - // Handle the final 2D overlays. - if (gamestate == GS_LEVEL) DrawFullscreenBlends(); - DrawRateStuff(); - - - videoShowFrame(0); - videoSetBrightness(0); // immediately reset this so that the value doesn't stick around in the backend. - } - catch (CRecoverableError& err) - { - C_FullConsole(); - Printf(TEXTCOLOR_RED "%s\n", err.what()); - } - } -} - - -#endif \ No newline at end of file diff --git a/source/core/palette.h b/source/core/palette.h index ba6a258fa..72c3e88a9 100644 --- a/source/core/palette.h +++ b/source/core/palette.h @@ -186,5 +186,6 @@ extern glblend_t glblend[MAXBLENDTABS]; FRenderStyle GetRenderStyle(int blend, int def); extern void SetRenderStyleFromBlend(uint8_t enable, uint8_t blend, uint8_t def); float GetAlphaFromBlend(uint32_t maskprops, uint32_t blend); +void DrawFullscreenBlends(); #endif diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index 3e3d62218..6b1dcbfa2 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -495,6 +495,7 @@ void videoShowFrame(int32_t w) screen->SetSceneRenderTarget(useSSAO); twodpsp.Clear(); twod->Clear(); + videoSetBrightness(0); // immediately reset this after rendering so that the value doesn't stick around in the backend. } TMap cachemap; From 0c455acaa2790c51374cefd044d2d49a88b154ff Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 10:42:44 +0200 Subject: [PATCH 36/43] - more work to switch over to the new loop. Mainly separation of ticker and render calls --- source/build/include/build.h | 1 - source/core/d_net.h | 2 + source/core/gamecontrol.cpp | 23 ++++--- source/core/mainloop.cpp | 97 ++++++++++++++++-------------- source/games/duke/src/duke3d.h | 4 ++ source/games/duke/src/gameloop.cpp | 18 ++++++ source/games/duke/src/global.h | 1 + source/games/duke/src/types.h | 1 + source/glbackend/glbackend.h | 1 + source/sw/src/game.h | 1 - 10 files changed, 93 insertions(+), 56 deletions(-) diff --git a/source/build/include/build.h b/source/build/include/build.h index 172874b1b..1294dbf80 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -74,7 +74,6 @@ enum rendmode_t { #define MAXVOXELS 1024 #define MAXSTATUS 1024 -#define MAXPLAYERS 16 // Maximum number of component tiles in a multi-psky: #define MAXPSKYTILES 16 #define MAXSPRITESONSCREEN 2560 diff --git a/source/core/d_net.h b/source/core/d_net.h index 75aa806a4..5b72f38ef 100644 --- a/source/core/d_net.h +++ b/source/core/d_net.h @@ -53,6 +53,8 @@ void Net_SkipCommand (int type, uint8_t **stream); void Net_ClearBuffers (); +bool D_CheckNetGame(void); + // Netgame stuff (buffers and pointers, i.e. indices). diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index bf19c2169..7728dc53c 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -69,6 +69,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "screenjob.h" #include "statusbar.h" #include "uiinput.h" +#include "d_net.h" CVAR(Bool, autoloadlights, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Bool, autoloadbrightmaps, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -100,6 +101,7 @@ int lastTic; int automapMode; bool automapFollow; +extern int pauseext; CCMD(togglemap) { @@ -137,6 +139,7 @@ void I_DetectOS(void); void LoadScripts(); void app_loop(); void DrawFullscreenBlends(); +void MainLoop(); bool AppActive; @@ -280,15 +283,6 @@ void UserConfig::ProcessOptions() Printf("Build-format config files not supported and will be ignored\n"); } -#if 0 // MP disabled pending evaluation - auto v = Args->CheckValue("-port"); - if (v) netPort = strtol(v, nullptr, 0); - - netServerMode = Args->CheckParm("-server"); - netServerAddress = Args->CheckValue("-connect"); - netPassword = Args->CheckValue("-password"); -#endif - auto v = Args->CheckValue("-addon"); if (v) { @@ -866,9 +860,9 @@ int RunGame() auto exec = C_ParseCmdLineParams(nullptr); if (exec) exec->ExecCommands(); - gamestate = GS_LEVEL; SetupGameButtons(); gi->app_init(); + app_loop(); return 0; // this is never reached. app_loop only exits via exception. } @@ -1150,6 +1144,15 @@ void S_SetSoundPaused(int state) } } } + if (!netgame +#if 0 //def _DEBUG + && !demoplayback +#endif + ) + { + pauseext = !state; + } + } FString G_GetDemoPath() diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 9f09a73db..3848da8ba 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -98,6 +98,11 @@ int oldentertics; int gametic; +//========================================================================== +// +// +// +//========================================================================== void G_BuildTiccmd(ticcmd_t* cmd) { @@ -105,8 +110,13 @@ void G_BuildTiccmd(ticcmd_t* cmd) cmd->consistancy = consistancy[myconnectindex][(maketic / ticdup) % BACKUPTICS]; } +//========================================================================== +// +// +// +//========================================================================== -void G_Ticker() +static void GameTicker() { int i; @@ -116,11 +126,6 @@ void G_Ticker() // Todo: Migrate state changes to here instead of doing them ad-hoc while (gameaction != ga_nothing) { - if (gameaction == ga_newgame2) - { - gameaction = ga_newgame; - break; - } switch (gameaction) { } @@ -181,18 +186,15 @@ void G_Ticker() gi->Startup(); break; - case GS_MENUSCREEN: - case GS_FULLCONSOLE: - gi->DrawBackground(); - break; - case GS_LEVEL: gi->Ticker(); break; + case GS_MENUSCREEN: + case GS_FULLCONSOLE: case GS_INTERMISSION: case GS_INTRO: - RunScreenJobFrame(); + // These elements do not tick at game rate. break; } @@ -201,54 +203,65 @@ void G_Ticker() //========================================================================== // -// D_Display -// -// Draw current display, possibly wiping it from the previous +// Display // //========================================================================== -void D_Display() +void Display() { - FGameTexture* wipe = nullptr; - - if (screen == NULL) - return; // for comparative timing / profiling - - if (!AppActive && (screen->IsFullscreen() || !vid_activeinbackground)) + if (screen == nullptr || !AppActive && (screen->IsFullscreen() || !vid_activeinbackground)) { return; } screen->FrameTime = I_msTimeFS(); screen->BeginFrame(); + twodpsp.ClearClipRect(); twod->ClearClipRect(); - if ((gamestate == GS_LEVEL) && gametic != 0) + switch (gamestate) { - // [ZZ] execute event hook that we just started the frame - //E_RenderFrame(); - // - gi->Render(); + case GS_MENUSCREEN: + gi->DrawBackground(); + break; + + case GS_FINALE: + // screen jobs are not bound by the game ticker so they need to be ticked in the display loop. + RunScreenJobFrame(); + break; + + case GS_LEVEL: + if (gametic != 0) + { + gi->Render(); + DrawFullscreenBlends(); + } + break; + + default: + break; } - // Draw overlay elements to the 2D drawer NetUpdate(); // send out any new accumulation + + // Draw overlay elements CT_Drawer(); C_DrawConsole(); M_Drawer(); FStat::PrintStat(twod); - - // Handle the final 2D overlays. - if (gamestate == GS_LEVEL) DrawFullscreenBlends(); DrawRateStuff(); videoShowFrame(0); } +//========================================================================== +// // Forces playsim processing time to be consistent across frames. // This improves interpolation for frames in between tics. // // With this cvar off the mods with a high playsim processing time will appear // less smooth as the measured time used for interpolation will vary. +// +//========================================================================== static void TicStabilityWait() { @@ -280,9 +293,12 @@ static void TicStabilityEnd() stabilityticduration = std::min(stabilityendtime - stabilitystarttime, (uint64_t)1'000'000); } +//========================================================================== // -// TryRunTics +// The most important function in the engine. // +//========================================================================== + void TryRunTics (void) { int i; @@ -296,7 +312,7 @@ void TryRunTics (void) // will all be wasted anyway. if (pauseext) r_NoInterpolate = true; - bool doWait = cl_capfps || r_NoInterpolate /*|| netgame*/; + bool doWait = cl_capfps || r_NoInterpolate; // get real tics if (doWait) @@ -328,14 +344,7 @@ void TryRunTics (void) } } - if (ticdup == 1) - { - availabletics = lowtic - gametic; - } - else - { - availabletics = lowtic - gametic / ticdup; - } + availabletics = lowtic - gametic / ticdup; // decide how many tics to run if (realtics < availabletics-1) @@ -362,6 +371,7 @@ void TryRunTics (void) gi->Predict(myconnectindex); #endif } + gi->GetInput(nullptr); return; } @@ -431,10 +441,9 @@ void TryRunTics (void) D_DoAdvanceDemo (); } #endif - //if (debugfile) fprintf (debugfile, "run tic %d\n", gametic); C_Ticker (); M_Ticker (); - G_Ticker(); + GameTicker(); gametic++; NetUpdate (); // check for new console commands @@ -482,7 +491,7 @@ void MainLoop () // Update display, next frame, with current state. I_StartTic (); - D_Display(); + Display(); Mus_UpdateMusic(); // must be at the end. } catch (CRecoverableError &error) diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 315422fcb..d44c2c4eb 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -59,6 +59,10 @@ struct GameInterface : public ::GameInterface void ResetFollowPos(bool message) override; void GetInput(InputPacket* packet) override; void UpdateSounds() override; + void Startup() override; + void DrawBackground() override; + void Render() override; + void Ticker() override; }; diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index 0920d59a6..c0500974b 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -400,6 +400,24 @@ static void Startup() // //--------------------------------------------------------------------------- +void GameInterface::Startup() +{ + +} +void GameInterface::DrawBackground() +{ + +} +void GameInterface::Render() +{ + +} +void GameInterface::Ticker() +{ + +} + + void GameInterface::RunGameFrame() { switch (gamestate) diff --git a/source/games/duke/src/global.h b/source/games/duke/src/global.h index 41768b54e..ac6b8f58a 100644 --- a/source/games/duke/src/global.h +++ b/source/games/duke/src/global.h @@ -8,6 +8,7 @@ #include "sounds.h" #include "constants.h" #include "types.h" +#include "d_net.h" BEGIN_DUKE_NS diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index 7ab4ae0f8..685b7bcf0 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -1,6 +1,7 @@ #pragma once #include "names.h" #include "packet.h" +#include "d_net.h" BEGIN_DUKE_NS diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index 66b7f3dc0..ed91273a9 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -355,6 +355,7 @@ public: }; extern GLInstance GLInterface; +extern F2DDrawer twodpsp; void renderSetProjectionMatrix(const float* p); void renderSetViewMatrix(const float* p); diff --git a/source/sw/src/game.h b/source/sw/src/game.h index c7a1ec15c..cae06d40d 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2057,7 +2057,6 @@ extern short numplayers, myconnectindex; extern short connecthead, connectpoint2[MAXPLAYERS]; */ extern int *lastpacket2clock; -extern char username[MAXPLAYERS][50]; // save player info when moving to a new level extern USER puser[MAX_SW_PLAYERS_REG]; From d59284c96b2e863b49b0721aeeea35a55977936d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 12:02:32 +0200 Subject: [PATCH 37/43] - transitioned Duke to the new main loop. Everything compiles, but hasn't been tested. Doing a safety commit first. --- source/core/d_net.cpp | 6 + source/core/d_net.h | 2 + source/core/gamecontrol.cpp | 25 +- source/core/gamecontrol.h | 3 + source/core/gamestruct.h | 3 +- source/core/mainloop.cpp | 10 +- source/exhumed/src/exhumed.h | 1 - source/exhumed/src/gameloop.cpp | 14 -- source/games/duke/src/d_menu.cpp | 3 +- source/games/duke/src/duke3d.h | 3 - source/games/duke/src/funct.h | 2 - source/games/duke/src/game_misc.cpp | 2 +- source/games/duke/src/gameloop.cpp | 356 ++++------------------------ source/games/duke/src/premap.cpp | 2 +- source/games/duke/src/savegame.cpp | 2 +- 15 files changed, 89 insertions(+), 345 deletions(-) diff --git a/source/core/d_net.cpp b/source/core/d_net.cpp index c9d399a6d..7eee62175 100644 --- a/source/core/d_net.cpp +++ b/source/core/d_net.cpp @@ -1972,6 +1972,12 @@ void Net_SkipCommand (int type, uint8_t **stream) #endif } +void Net_ClearFifo(void) +{ + // Q: Do we need this? +} + + // This was taken out of shared_hud, because UI code shouldn't do low level calculations that may change if the backing implementation changes. int Net_GetLatency(int *ld, int *ad) { diff --git a/source/core/d_net.h b/source/core/d_net.h index 5b72f38ef..138829e91 100644 --- a/source/core/d_net.h +++ b/source/core/d_net.h @@ -55,6 +55,8 @@ void Net_ClearBuffers (); bool D_CheckNetGame(void); +void Net_ClearFifo(void); + // Netgame stuff (buffers and pointers, i.e. indices). diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 7728dc53c..d6d42d02b 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -101,7 +101,7 @@ int lastTic; int automapMode; bool automapFollow; -extern int pauseext; +extern bool pauseext; CCMD(togglemap) { @@ -863,7 +863,13 @@ int RunGame() SetupGameButtons(); gi->app_init(); - app_loop(); + // Duke has transitioned to the new main loop, the other games haven't yet. + if (g_gameType & GAMEFLAG_DUKE | GAMEFLAG_RRALL | GAMEFLAG_NAM | GAMEFLAG_NAPALM | GAMEFLAG_WW2GI) + { + D_CheckNetGame(); + MainLoop(); + } + else app_loop(); return 0; // this is never reached. app_loop only exits via exception. } @@ -1246,3 +1252,18 @@ CCMD(taunt) } } + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void startmainmenu() +{ + gamestate = GS_MENUSCREEN; + M_StartControlPanel(false); + M_SetMenu(NAME_Mainmenu); + FX_StopAllSounds(); +} + diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index fee026fe7..8162e3fcd 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -8,12 +8,14 @@ #include "tarray.h" #include "name.h" #include "memarena.h" +#include "stats.h" extern FString currentGame; extern FString LumpFilter; class FArgs; extern bool GUICapture; extern bool AppActive; +extern cycle_t drawtime, actortime, thinktime, gameupdatetime; extern FMemArena dump; // this is for memory blocks than cannot be deallocated without some huge effort. Put them in here so that they do not register on shutdown. @@ -46,6 +48,7 @@ void CONFIG_ReadCombatMacros(); int32_t CONFIG_GetMapBestTime(char const* const mapname, uint8_t const* const mapmd4); int CONFIG_SetMapBestTime(uint8_t const* const mapmd4, int32_t tm); int GameMain(); +void startmainmenu(); struct UserConfig { diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h index 1e0412588..b4226b572 100644 --- a/source/core/gamestruct.h +++ b/source/core/gamestruct.h @@ -60,7 +60,6 @@ struct GameInterface virtual ~GameInterface() {} virtual bool GenerateSavePic() { return false; } virtual void app_init() = 0; - virtual void RunGameFrame() = 0; virtual void clearlocalinputstate() {} virtual void UpdateScreenSize() {} virtual void FreeGameData() {} @@ -101,6 +100,8 @@ struct GameInterface virtual void Ticker() {} virtual int GetPlayerChecksum(int pnum) { return 0x12345678 + pnum; } + virtual void RunGameFrame() {} // this must go away once things are done. + }; diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 3848da8ba..227aed0b3 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -81,6 +81,7 @@ #include "v_video.h" #include "glbackend/glbackend.h" #include "palette.h" +#include "build.h" CVAR(Bool, vid_activeinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, r_ticstability, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -183,11 +184,15 @@ static void GameTicker() { default: case GS_STARTUP: + artClearMapArt(); gi->Startup(); break; case GS_LEVEL: + gameupdatetime.Reset(); + gameupdatetime.Clock(); gi->Ticker(); + gameupdatetime.Unclock(); break; case GS_MENUSCREEN: @@ -371,7 +376,10 @@ void TryRunTics (void) gi->Predict(myconnectindex); #endif } - gi->GetInput(nullptr); + if (!cl_syncinput) + { + gi->GetInput(nullptr); + } return; } diff --git a/source/exhumed/src/exhumed.h b/source/exhumed/src/exhumed.h index f79a2bc48..b68612191 100644 --- a/source/exhumed/src/exhumed.h +++ b/source/exhumed/src/exhumed.h @@ -89,7 +89,6 @@ void CheckKeys2(); void GameTicker(); void InitLevel(int); void InitNewGame(); -void startmainmenu(); int showmap(short nLevel, short nLevelNew, short nLevelBest); void menu_DoPlasma(); diff --git a/source/exhumed/src/gameloop.cpp b/source/exhumed/src/gameloop.cpp index 81db62bbf..4ae409ceb 100644 --- a/source/exhumed/src/gameloop.cpp +++ b/source/exhumed/src/gameloop.cpp @@ -136,20 +136,6 @@ static void GameDisplay(void) // //--------------------------------------------------------------------------- -void startmainmenu() -{ - gamestate = GS_MENUSCREEN; - M_StartControlPanel(false); - M_SetMenu(NAME_Mainmenu); - StopAllSounds(); -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - void drawmenubackground() { auto nLogoTile = EXHUMED ? kExhumedLogo : kPowerslaveLogo; diff --git a/source/games/duke/src/d_menu.cpp b/source/games/duke/src/d_menu.cpp index 43dd57d7e..a200ba41b 100644 --- a/source/games/duke/src/d_menu.cpp +++ b/source/games/duke/src/d_menu.cpp @@ -361,8 +361,7 @@ void GameInterface::DrawPlayerSprite(const DVector2& origin, bool onteam) void GameInterface::QuitToTitle() { - ps[myconnectindex].gm = MODE_DEMO; - artClearMapArt(); + gamestate = GS_STARTUP; } END_DUKE_NS diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index d44c2c4eb..ed5215f66 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -22,8 +22,6 @@ #include "stats.h" #include "binaryangle.h" -extern cycle_t drawtime, actortime, thinktime, gameupdatetime; - BEGIN_DUKE_NS extern FFont* IndexFont; @@ -33,7 +31,6 @@ struct GameInterface : public ::GameInterface { const char* Name() override { return "Duke"; } void app_init() override; - void RunGameFrame() override; void clearlocalinputstate() override; bool GenerateSavePic() override; void PlayHudSound() override; diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index a6df8ffae..4cd6c2884 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -193,7 +193,6 @@ void resetinventory(int pn); void resetplayerstats(int pn); void resetweapons(int pn); void resetprestat(int snum, int g); -void clearfifo(void); void prelevel_common(int g); void cacheit_d(); void cacheit_r(); @@ -234,7 +233,6 @@ void apply_seasick(player_struct* p, double scalefactor); void calcviewpitch(player_struct* p, double factor); void sethorizon(int snum, ESyncBits actions, double factor, fixed_t adjustment); bool movementBlocked(int snum); -void startmainmenu(); void loadcons(); void updateinterpolations(); diff --git a/source/games/duke/src/game_misc.cpp b/source/games/duke/src/game_misc.cpp index db93759a2..dd090834f 100644 --- a/source/games/duke/src/game_misc.cpp +++ b/source/games/duke/src/game_misc.cpp @@ -175,7 +175,7 @@ void FTA(int q, struct player_struct* p) // //========================================================================== -void drawbackground(void) +void GameInterface::DrawBackground() { twod->ClearScreen(); auto tex = tileGetTexture(TILE_MENUSCREEN); diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index c0500974b..d7bdae796 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -38,149 +38,14 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) BEGIN_DUKE_NS -//--------------------------------------------------------------------------- -// -// abstract the queue's implementation -// All access to the input queues should go through this function interface. -// -//--------------------------------------------------------------------------- -static InputPacket inputfifo[MOVEFIFOSIZ][MAXPLAYERS]; -static int movefifoend[MAXPLAYERS]; -static int movefifoplc; -static int bufferjitter; - -void clearfifo(void) -{ - memset(&inputfifo, 0, sizeof(inputfifo)); - memset(sync, 0, sizeof(sync)); -} - - -static inline void GetNextInput() -{ - for (int i = connecthead; i >= 0; i = connectpoint2[i]) - memcpy(&sync[i], &inputfifo[movefifoplc & (MOVEFIFOSIZ - 1)][i], sizeof(InputPacket)); - - movefifoplc++; -} - -static void advancequeue(int myconnectindex) -{ - movefifoend[myconnectindex]++; -} - -static InputPacket& nextinput(int myconnectindex) -{ - return inputfifo[movefifoend[myconnectindex] & (MOVEFIFOSIZ - 1)][myconnectindex]; -} - -bool shouldprocessinput(int myconnectindex) -{ - if (movefifoend[myconnectindex] - movefifoplc > bufferjitter) - { - int i; - for (i = connecthead; i >= 0; i = connectpoint2[i]) - if (movefifoplc == movefifoend[i]) return false; - if (i >= 0) return false; - return true; - } - return false; -} - -static void fakedomovethings() -{ - // prediction -} - -static void fakedomovethingscorrect() -{ - // unprediction -} - -void prediction() -{ -#if 0 - // We currently have no net code driving this. - if (numplayers > 1) - while (fakemovefifoplc < movefifoend[myconnectindex]) fakedomovethings(); - getpackets(); -#endif -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- -/* -void mploadsave() -{ - for(int i=connecthead;i>=0;i=connectpoint2[i]) - if( sync[i].bits&(1<<17) ) - { - multiflag = 2; - multiwhat = (sync[i].bits>>18)&1; - multipos = (unsigned) (sync[i].bits>>19)&15; - multiwho = i; - - if( multiwhat ) - { - saveplayer( multipos ); - multiflag = 0; - - if(multiwho != myconnectindex) - { - strcpy(&fta_quotes[122],&ud.user_name[multiwho][0]); - strcat(&fta_quotes[122]," SAVED A MULTIPLAYER GAME"); - FTA(122,&ps[myconnectindex]); - } - else - { - strcpy(&fta_quotes[122],"MULTIPLAYER GAME SAVED"); - FTA(122,&ps[myconnectindex]); - } - break; - } - else - { -// waitforeverybody(); - - j = loadplayer( multipos ); - - multiflag = 0; - - if(j == 0 && !isRR()) - { - if(multiwho != myconnectindex) - { - strcpy(&fta_quotes[122],&ud.user_name[multiwho][0]); - strcat(&fta_quotes[122]," LOADED A MULTIPLAYER GAME"); - FTA(122,&ps[myconnectindex]); - } - else - { - strcpy(&fta_quotes[122],"MULTIPLAYER GAME LOADED"); - FTA(122,&ps[myconnectindex]); - } - return 1; - } - } - } -} -*/ - //--------------------------------------------------------------------------- // // // //--------------------------------------------------------------------------- -int domovethings() +void GameInterface::Ticker() { - int i; - - // mplpadsave(); - ud.camerasprite = -1; if (earthquaketime > 0) earthquaketime--; @@ -192,51 +57,15 @@ int domovethings() } everyothertime++; - GetNextInput(); updateinterpolations(); -#if 0 - j = -1; - for (i = connecthead; i >= 0; i = connectpoint2[i]) - { - if (PlayerInput(i, SKB_GAMEQUIT)) - { - if (i == myconnectindex) gameexitfrommenu(); - if (screenpeek == i) - { - screenpeek = connectpoint2[i]; - if (screenpeek < 0) screenpeek = connecthead; - } - - if (i == connecthead) connecthead = connectpoint2[connecthead]; - else connectpoint2[j] = connectpoint2[i]; - - numplayers--; - ud.multimode--; - - //closedemowrite(); - - if (numplayers < 2 && !isRR()) - S_PlaySound(GENERIC_AMBIENCE17, CHAN_AUTO, CHANF_UI); - - Printf(PRINT_NOTIFY, "%s is history!", ud.user_name[i]); - - quickkill(&ps[i]); - deletesprite(ps[i].i); - } - else j = i; - } -#endif - - //if(ud.recstat == 1) record(); - if (playrunning()) { global_random = krand(); movedummyplayers();//ST 13 } - for (i = connecthead; i >= 0; i = connectpoint2[i]) + for (int i = connecthead; i >= 0; i = connectpoint2[i]) { if (playrunning()) { @@ -258,8 +87,6 @@ int domovethings() fi.think(); } - fakedomovethingscorrect(); - if ((everyothertime & 1) == 0) { fi.animatewalls(); @@ -269,80 +96,11 @@ int domovethings() if (isRR() && ud.recstat == 0 && ud.multimode < 2) dotorch(); - return 0; -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -void GameTicker() -{ - if (ps[myconnectindex].gm == MODE_DEMO) - { - M_ClearMenus(); - gamestate = GS_STARTUP; - return; - } - - //Net_GetPackets(); - - - gameupdatetime.Reset(); - gameupdatetime.Clock(); - - int const currentTic = I_GetTime(); - gameclock = I_GetBuildTime() - gameclockstart; - - while (playrunning() && currentTic - lastTic >= 1) - { - lastTic = currentTic; - auto& input = nextinput(myconnectindex); - - gi->GetInput(&input); - - advancequeue(myconnectindex); - - if (playrunning()) - { - prediction(); - - if (numplayers < 2) bufferjitter = 0; - while (shouldprocessinput(myconnectindex)) - { - if (domovethings()) break; - } - } - } - - gameupdatetime.Unclock(); - if (ps[myconnectindex].gm & (MODE_EOL | MODE_RESTART)) { exitlevel(); } - - if (!cl_syncinput) - { - gi->GetInput(nullptr); - } - - nonsharedkeys(); - gi->UpdateSounds(); - drawtime.Reset(); - drawtime.Clock(); - videoSetBrightness(thunder_brightness); - double const smoothRatio = playrunning() ? I_GetTimeFrac() * MaxSmoothRatio : MaxSmoothRatio; - displayrooms(screenpeek, smoothRatio); - drawoverlays(smoothRatio); - drawtime.Unclock(); - - if (ps[myconnectindex].gm == MODE_DEMO) - { - gamestate = GS_STARTUP; - } + nonsharedkeys(); } //--------------------------------------------------------------------------- @@ -351,14 +109,6 @@ void GameTicker() // //--------------------------------------------------------------------------- -void startmainmenu() -{ - gamestate = GS_MENUSCREEN; - M_StartControlPanel(false); - M_SetMenu(NAME_Mainmenu); - FX_StopAllSounds(); -} - void resetGameClock() { I_SetFrameTime(); @@ -367,33 +117,6 @@ void resetGameClock() cloudclock = 0; } -static void Startup() -{ - resetGameClock(); - ps[myconnectindex].ftq = 0; - - if (userConfig.CommandMap.IsNotEmpty()) - { - auto maprecord = FindMapByName(userConfig.CommandMap); - userConfig.CommandMap = ""; - if (maprecord) - { - ud.m_respawn_monsters = ud.m_player_skill == 4; - - for (int i = 0; i != -1; i = connectpoint2[i]) - { - resetweapons(i); - resetinventory(i); - } - startnewgame(maprecord, /*userConfig.skill*/2); - } - } - else - { - fi.ShowLogo([](bool) { startmainmenu(); }); - } -} - //--------------------------------------------------------------------------- // // @@ -402,47 +125,48 @@ static void Startup() void GameInterface::Startup() { + resetGameClock(); + ps[myconnectindex].ftq = 0; -} -void GameInterface::DrawBackground() -{ - -} -void GameInterface::Render() -{ - -} -void GameInterface::Ticker() -{ - -} - - -void GameInterface::RunGameFrame() -{ - switch (gamestate) + if (userConfig.CommandMap.IsNotEmpty()) { - default: - case GS_STARTUP: - Startup(); - break; - - case GS_MENUSCREEN: - case GS_FULLCONSOLE: - drawbackground(); - break; - - case GS_LEVEL: - GameTicker(); - break; - - case GS_INTERMISSION: - case GS_INTRO: - RunScreenJobFrame(); - break; + auto maprecord = FindMapByName(userConfig.CommandMap); + userConfig.CommandMap = ""; + if (maprecord) + { + ud.m_respawn_monsters = ud.m_player_skill == 4; + for (int i = 0; i != -1; i = connectpoint2[i]) + { + resetweapons(i); + resetinventory(i); + } + startnewgame(maprecord, /*userConfig.skill*/2); + } + } + else + { + fi.ShowLogo([](bool) { startmainmenu(); }); } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void GameInterface::Render() +{ + drawtime.Reset(); + drawtime.Clock(); + videoSetBrightness(thunder_brightness); + double const smoothRatio = playrunning() ? I_GetTimeFrac() * MaxSmoothRatio : MaxSmoothRatio; + displayrooms(screenpeek, smoothRatio); + drawoverlays(smoothRatio); + drawtime.Unclock(); +} + + END_DUKE_NS diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index b49b56023..53a3d1ad3 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -1013,7 +1013,7 @@ int enterlevel(MapRecord *mi, int gamemode) global_random = 0; ud.last_level = currentLevel->levelNumber; - clearfifo(); + Net_ClearFifo(); for (int i=numinterpolations-1; i>=0; i--) bakipos[i] = *curipos[i]; ps[myconnectindex].over_shoulder_on = 0; clearfrags(); diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index 01137ccf8..22f565ea5 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -520,7 +520,7 @@ void GameInterface::SerializeGameState(FSerializer& arc) recreateinterpolations(); show_shareware = 0; everyothertime = 0; - clearfifo(); + Net_ClearFifo(); // should be unnecessary with the sounds getting serialized as well. #if 0 From ffe5b114f3fc9985a252c7112568e2c68994ea61 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 12:49:21 +0200 Subject: [PATCH 38/43] - the engine starts on the new main loop and is capable of running the intros and the menu, but not the game yet. --- source/blood/src/blood.cpp | 4 ++-- source/blood/src/view.cpp | 1 - source/core/d_net.cpp | 4 ++-- source/core/gamecontrol.cpp | 9 ++++++--- source/core/mainloop.cpp | 18 +++++++++++------- source/exhumed/src/exhumed.cpp | 21 ++++----------------- source/exhumed/src/exhumed.h | 2 -- source/exhumed/src/sequence.cpp | 2 ++ source/games/duke/src/game.cpp | 18 +----------------- source/sw/src/game.cpp | 2 -- 10 files changed, 28 insertions(+), 53 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index a8336a6d8..f9874c995 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -389,7 +389,6 @@ void StartLevel(MapRecord *level) } } bVanilla = false; - enginecompatibility_mode = ENGINECOMPATIBILITY_19960925;//bVanilla; memset(xsprite,0,sizeof(xsprite)); memset(sprite,0,kMaxSprites*sizeof(spritetype)); //drawLoadingScreen(); @@ -704,13 +703,14 @@ void GameInterface::app_init() Printf(PRINT_NONOTIFY, "Initializing network users\n"); netInitialize(true); - videoInit(); Printf(PRINT_NONOTIFY, "Initializing sound system\n"); sndInit(); registerosdcommands(); gChoke.sub_83ff0(518, sub_84230); UpdateDacs(0, true); + + enginecompatibility_mode = ENGINECOMPATIBILITY_19960925;//bVanilla; } static void gameInit() diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index 6160c986d..0e253e7f0 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -322,7 +322,6 @@ void viewInit(void) FontSet(2, 4288, 1); FontSet(3, 4384, 1); FontSet(4, 4480, 0); - enginePostInit(); // This must not be done earlier! lensdata = fileSystem.LoadFile("lens.dat"); dassert(lensdata.Size() == kLensSize * kLensSize * sizeof(int)); diff --git a/source/core/d_net.cpp b/source/core/d_net.cpp index 7eee62175..ae879ce35 100644 --- a/source/core/d_net.cpp +++ b/source/core/d_net.cpp @@ -1745,10 +1745,10 @@ bool D_CheckNetGame (void) if (myconnectindex != Net_Arbitrator && doomcom.numnodes > 1) { - Printf("Arbitrator selected " TEXTCOLOR_BLUE "%s" TEXTCOLOR_NORMAL " networking mode.\n", NetMode == NET_PeerToPeer ? "peer to peer" : "packet server"); + Printf(PRINT_NONOTIFY, "Arbitrator selected " TEXTCOLOR_BLUE "%s" TEXTCOLOR_NORMAL " networking mode.\n", NetMode == NET_PeerToPeer ? "peer to peer" : "packet server"); } - if (!batchrun) Printf ("player %i of %i (%i nodes)\n", + if (!batchrun) Printf (PRINT_NONOTIFY, "player %i of %i (%i nodes)\n", myconnectindex+1, doomcom.numplayers, doomcom.numnodes); return true; diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index d6d42d02b..8bf083cc4 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -142,7 +142,7 @@ void DrawFullscreenBlends(); void MainLoop(); -bool AppActive; +bool AppActive = true; FString currentGame; FString LumpFilter; @@ -862,9 +862,11 @@ int RunGame() SetupGameButtons(); gi->app_init(); + enginePostInit(); // This must not be done earlier! + videoInit(); // Duke has transitioned to the new main loop, the other games haven't yet. - if (g_gameType & GAMEFLAG_DUKE | GAMEFLAG_RRALL | GAMEFLAG_NAM | GAMEFLAG_NAPALM | GAMEFLAG_WW2GI) + if (g_gameType & (GAMEFLAG_DUKE | GAMEFLAG_RRALL | GAMEFLAG_NAM | GAMEFLAG_NAPALM | GAMEFLAG_WW2GI)) { D_CheckNetGame(); MainLoop(); @@ -1150,6 +1152,7 @@ void S_SetSoundPaused(int state) } } } +#if 0 if (!netgame #if 0 //def _DEBUG && !demoplayback @@ -1158,7 +1161,7 @@ void S_SetSoundPaused(int state) { pauseext = !state; } - +#endif } FString G_GetDemoPath() diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 227aed0b3..9b7ab160e 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -229,7 +229,8 @@ void Display() gi->DrawBackground(); break; - case GS_FINALE: + case GS_INTRO: + case GS_INTERMISSION: // screen jobs are not bound by the game ticker so they need to be ticked in the display loop. RunScreenJobFrame(); break; @@ -248,12 +249,15 @@ void Display() NetUpdate(); // send out any new accumulation - // Draw overlay elements - CT_Drawer(); - C_DrawConsole(); - M_Drawer(); - FStat::PrintStat(twod); - DrawRateStuff(); + if (gamestate != GS_INTRO) // do not draw overlays on the intros + { + // Draw overlay elements + CT_Drawer(); + C_DrawConsole(); + M_Drawer(); + FStat::PrintStat(twod); + DrawRateStuff(); + } videoShowFrame(0); } diff --git a/source/exhumed/src/exhumed.cpp b/source/exhumed/src/exhumed.cpp index 1176f3be3..5f86d8b7a 100644 --- a/source/exhumed/src/exhumed.cpp +++ b/source/exhumed/src/exhumed.cpp @@ -61,7 +61,6 @@ void uploadCinemaPalettes(); int32_t registerosdcommands(void); void InitFonts(); -int htimer = 0; int EndLevel = false; @@ -86,9 +85,6 @@ void InstallEngine() uploadCinemaPalettes(); LoadPaletteLookups(); InitFonts(); - videoInit(); - - enginecompatibility_mode = ENGINECOMPATIBILITY_19950829; } void RemoveEngine() @@ -628,11 +624,6 @@ void ExitGame() throw CExitEvent(0); } -void InitTimer() -{ - htimer = 1; -} - void GameInterface::app_init() { int i; @@ -673,22 +664,18 @@ void GameInterface::app_init() Printf(PRINT_NONOTIFY, "Definitions file \"%s\" loaded in %d ms.\n", defsfile, etime - stime); } - - enginePostInit(); - InitView(); InitFX(); seq_LoadSequences(); InitStatus(); - InitTimer(); - + for (i = 0; i < kMaxPlayers; i++) { nPlayerLives[i] = kDefaultLives; } - - ResetEngine(); - ResetView(); + resettiming(); GrabPalette(); + + enginecompatibility_mode = ENGINECOMPATIBILITY_19950829; } void mychangespritesect(int nSprite, int nSector) diff --git a/source/exhumed/src/exhumed.h b/source/exhumed/src/exhumed.h index b68612191..12aaabf6e 100644 --- a/source/exhumed/src/exhumed.h +++ b/source/exhumed/src/exhumed.h @@ -106,8 +106,6 @@ extern int GameAction; extern int nNetPlayerCount; -extern int htimer; - extern int nNetTime; extern short nTotalPlayers; diff --git a/source/exhumed/src/sequence.cpp b/source/exhumed/src/sequence.cpp index 10f4b1574..579ed3213 100644 --- a/source/exhumed/src/sequence.cpp +++ b/source/exhumed/src/sequence.cpp @@ -310,6 +310,7 @@ void seq_LoadSequences() } } +#if 0 FILE* f = fopen("seq.dump", "wb"); fwrite(SeqBase, 1, sizeof(SeqBase), f); @@ -326,6 +327,7 @@ void seq_LoadSequences() fwrite(ChunkPict, 1, sizeof(ChunkPict), f); fwrite(ChunkFlag, 1, sizeof(ChunkFlag), f); fclose(f); +#endif nShadowPic = seq_GetFirstSeqPicnum(kSeqShadow); nShadowWidth = tilesiz[nShadowPic].x; diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index 6ffba1433..ae071be8c 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -272,7 +272,7 @@ static void initTiles() // //--------------------------------------------------------------------------- -static void Startup(void) +void GameInterface::app_init() { if (isRR()) C_SetNotifyFontScale(0.5); ud.god = 0; @@ -313,8 +313,6 @@ static void Startup(void) OnEvent(EVENT_INIT); - enginecompatibility_mode = ENGINECOMPATIBILITY_19961112; - if (engineInit()) G_FatalEngineError(); @@ -348,21 +346,7 @@ static void Startup(void) } ud.last_level = -1; -} - -//--------------------------------------------------------------------------- -// -// main entry point, sets up the game module and the engine, then enters the main loop -// -//--------------------------------------------------------------------------- - -void GameInterface::app_init() -{ - Startup(); - enginePostInit(); - videoInit(); enginecompatibility_mode = ENGINECOMPATIBILITY_19961112;//bVanilla; } - END_DUKE_NS diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 083bfd86f..7dc9ddbad 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -237,8 +237,6 @@ void GameInterface::app_init() if (!loaddefinitionsfile(G_DefFile())) Printf(PRINT_NONOTIFY, "Definitions file loaded.\n"); userConfig.AddDefs.reset(); - enginePostInit(); - videoInit(); InitFX(); } From 38d10cc59108dc53fccf7a898193ff03e0ecbb1b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 13:04:07 +0200 Subject: [PATCH 39/43] - game input works, but still no 3D scene rendered. --- source/games/duke/src/gameloop.cpp | 5 +++++ source/games/duke/src/inlines.h | 5 +++++ source/games/duke/src/player_d.cpp | 4 +--- source/games/duke/src/player_r.cpp | 4 +--- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index d7bdae796..3b12abd07 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -46,6 +46,11 @@ BEGIN_DUKE_NS void GameInterface::Ticker() { + // Make copies so that the originals do not have to be modified. + for (int i = 0; i < MAXPLAYERS; i++) + { + sync[i] = playercmds[i].ucmd; + } ud.camerasprite = -1; if (earthquaketime > 0) earthquaketime--; diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index a4f8fae52..0b7732a28 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -162,6 +162,11 @@ inline fixed_t PlayerInputAngVel(int pl) return sync[pl].q16avel; } +inline fixed_t PlayerHorizon(int pl) +{ + return sync[pl].q16horz; +} + inline void clearfriction() { for (int i = 0; i != -1; i = connectpoint2[i]) diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 34eef0d52..4b7f919fb 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -1339,8 +1339,6 @@ int doincrements_d(struct player_struct* p) int snum; snum = sprite[p->i].yvel; - // j = sync[snum].avel; - // p->weapon_ang = -(j/5); p->player_par++; @@ -3039,7 +3037,7 @@ HORIZONLY: if (cl_syncinput) { - sethorizon(snum, actions, 1, sync[snum].q16horz); + sethorizon(snum, actions, 1, PlayerHorizon(snum)); } checkhardlanding(p); diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index c3ae51519..dc35de734 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -1207,8 +1207,6 @@ int doincrements_r(struct player_struct* p) } snum = sprite[p->i].yvel; - // j = sync[snum].avel; - // p->weapon_ang = -(j/5); p->player_par++; if (p->yehaa_timer) @@ -4085,7 +4083,7 @@ HORIZONLY: if (cl_syncinput) { - sethorizon(snum, actions, 1, sync[snum].q16horz); + sethorizon(snum, actions, 1, PlayerHorizon(snum)); } checkhardlanding(p); From 765f211e0500da020f231e30b93fc24f8862e2ce Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 19:59:46 +0200 Subject: [PATCH 40/43] - things are mostly working again. Rendering produces an image again, input gets properly processed, but unsynchronised mouse input isn't properly applied yet. --- source/core/gamecontrol.cpp | 3 +-- source/core/gamecontrol.h | 2 ++ source/core/inputstate.cpp | 1 + source/core/mainloop.cpp | 10 +++++++++- source/games/duke/src/gameloop.cpp | 2 ++ source/glbackend/glbackend.cpp | 16 ++++++++++------ 6 files changed, 25 insertions(+), 9 deletions(-) diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 8bf083cc4..04222dff2 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -138,7 +138,6 @@ void S_ParseSndInfo(); void I_DetectOS(void); void LoadScripts(); void app_loop(); -void DrawFullscreenBlends(); void MainLoop(); @@ -904,7 +903,7 @@ void TickSubsystems() if (cnt == 5) nexttick = nowtick + tickInterval; } -static void updatePauseStatus() +void updatePauseStatus() { // This must go through the network in multiplayer games. if (M_Active() || System_WantGuiCapture()) diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index 8162e3fcd..a448a2675 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -16,6 +16,7 @@ class FArgs; extern bool GUICapture; extern bool AppActive; extern cycle_t drawtime, actortime, thinktime, gameupdatetime; +extern bool r_NoInterpolate; extern FMemArena dump; // this is for memory blocks than cannot be deallocated without some huge effort. Put them in here so that they do not register on shutdown. @@ -49,6 +50,7 @@ int32_t CONFIG_GetMapBestTime(char const* const mapname, uint8_t const* const ma int CONFIG_SetMapBestTime(uint8_t const* const mapmd4, int32_t tm); int GameMain(); void startmainmenu(); +void updatePauseStatus(); struct UserConfig { diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index 9c05abf6e..ec42d328f 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -160,6 +160,7 @@ int32_t handleevents(void) setViewport(hud_size); setsizeneeded = false; } +#pragma message ("only for old game loop") twod->SetSize(screen->GetWidth(), screen->GetHeight()); twodpsp.SetSize(screen->GetWidth(), screen->GetHeight()); diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 9b7ab160e..3bffcd060 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -179,6 +179,7 @@ static void GameTicker() } C_RunDelayedCommands(); + updatePauseStatus(); switch (gamestate) { @@ -191,6 +192,7 @@ static void GameTicker() case GS_LEVEL: gameupdatetime.Reset(); gameupdatetime.Clock(); + gameclock += 120 / GameTicRate; gi->Ticker(); gameupdatetime.Unclock(); break; @@ -238,6 +240,12 @@ void Display() case GS_LEVEL: if (gametic != 0) { + screen->BeginFrame(); + screen->SetSceneRenderTarget(gl_ssao != 0); + twodpsp.Clear(); + twod->Clear(); + twod->SetSize(screen->GetWidth(), screen->GetHeight()); + twodpsp.SetSize(screen->GetWidth(), screen->GetHeight()); gi->Render(); DrawFullscreenBlends(); } @@ -259,7 +267,7 @@ void Display() DrawRateStuff(); } - videoShowFrame(0); + videoShowFrame(1); } //========================================================================== diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index 3b12abd07..3d379af00 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -68,7 +68,9 @@ void GameInterface::Ticker() { global_random = krand(); movedummyplayers();//ST 13 + r_NoInterpolate = false; } + else r_NoInterpolate = true; for (int i = connecthead; i >= 0; i = connectpoint2[i]) { diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index 6b1dcbfa2..ec4012843 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -489,13 +489,17 @@ void videoShowFrame(int32_t w) }); screen->Update(); screen->mVertexData->Reset(); - // After finishing the frame, reset everything for the next frame. This needs to be done better. - screen->BeginFrame(); - bool useSSAO = (gl_ssao != 0); - screen->SetSceneRenderTarget(useSSAO); - twodpsp.Clear(); - twod->Clear(); videoSetBrightness(0); // immediately reset this after rendering so that the value doesn't stick around in the backend. + + // After finishing the frame, reset everything for the next frame. This needs to be done better. + if (!w) + { + screen->BeginFrame(); + bool useSSAO = (gl_ssao != 0); + screen->SetSceneRenderTarget(useSSAO); + twodpsp.Clear(); + twod->Clear(); + } } TMap cachemap; From 5daaa1fc06861b6bbf67508140ebbd2d906b81fe Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Mon, 31 Aug 2020 05:24:29 +1000 Subject: [PATCH 41/43] - fix issues with `cl_syncinput 0`. --- source/core/mainloop.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 3bffcd060..4244326e0 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -507,9 +507,9 @@ void MainLoop () } I_SetFrameTime(); + I_StartTic (); TryRunTics (); // will run at least one tic // Update display, next frame, with current state. - I_StartTic (); Display(); Mus_UpdateMusic(); // must be at the end. From 98557947dae6722d08a4465b861ee7355a4bbfeb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 22:52:20 +0200 Subject: [PATCH 42/43] - gameclock must also be set before calling gi->Render. This runs at the display's frame rate so the timer value from the Ticker call is not precise enough to do all the work. --- source/core/mainloop.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 4244326e0..5c799fe48 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -82,6 +82,7 @@ #include "glbackend/glbackend.h" #include "palette.h" #include "build.h" +#include "g_input.h" CVAR(Bool, vid_activeinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, r_ticstability, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -107,6 +108,7 @@ int gametic; void G_BuildTiccmd(ticcmd_t* cmd) { + I_GetEvent(); gi->GetInput(&cmd->ucmd); cmd->consistancy = consistancy[myconnectindex][(maketic / ticdup) % BACKUPTICS]; } @@ -192,7 +194,7 @@ static void GameTicker() case GS_LEVEL: gameupdatetime.Reset(); gameupdatetime.Clock(); - gameclock += 120 / GameTicRate; + gameclock = I_GetBuildTime() - gameclockstart; gi->Ticker(); gameupdatetime.Unclock(); break; @@ -246,6 +248,7 @@ void Display() twod->Clear(); twod->SetSize(screen->GetWidth(), screen->GetHeight()); twodpsp.SetSize(screen->GetWidth(), screen->GetHeight()); + gameclock = I_GetBuildTime() - gameclockstart; gi->Render(); DrawFullscreenBlends(); } @@ -390,6 +393,7 @@ void TryRunTics (void) } if (!cl_syncinput) { + I_GetEvent(); gi->GetInput(nullptr); } return; @@ -507,9 +511,9 @@ void MainLoop () } I_SetFrameTime(); - I_StartTic (); TryRunTics (); // will run at least one tic // Update display, next frame, with current state. + I_StartTic(); Display(); Mus_UpdateMusic(); // must be at the end. From 00d35bc42ca9c846de17697fa26bdf765d2ffa8c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Aug 2020 22:52:50 +0200 Subject: [PATCH 43/43] - fixed the number pulsing on Duke's and RR's HUD. --- source/games/duke/src/sbar_d.cpp | 7 +++---- source/games/duke/src/sbar_r.cpp | 9 +++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/games/duke/src/sbar_d.cpp b/source/games/duke/src/sbar_d.cpp index d5acf5e62..b97b1485b 100644 --- a/source/games/duke/src/sbar_d.cpp +++ b/source/games/duke/src/sbar_d.cpp @@ -133,11 +133,10 @@ public: { int s = -8; if (althud_flashing && p->last_extra > max_player_health) - s += (sintable[(gameclock << 5) & 2047] >> 10); - int intens = clamp(255 - 4 * s, 0, 255); - auto pe = PalEntry(255, intens, intens, intens); + s += (sintable[(gameclock << 6) & 2047] >> 10); + int intens = clamp(255 - 6 * s, 0, 255); format.Format("%d", p->last_extra); - SBar_DrawString(this, &numberFont, format, 25, texty, DI_TEXT_ALIGN_LEFT, CR_UNTRANSLATED, 1, 0, 0, 1, 1); + SBar_DrawString(this, &numberFont, format, 25, texty, DI_TEXT_ALIGN_LEFT, CR_UNTRANSLATED, intens / 255., 0, 0, 1, 1); } // diff --git a/source/games/duke/src/sbar_r.cpp b/source/games/duke/src/sbar_r.cpp index e7f322bd9..69287258b 100644 --- a/source/games/duke/src/sbar_r.cpp +++ b/source/games/duke/src/sbar_r.cpp @@ -106,15 +106,16 @@ public: imgScale = baseScale / img->GetDisplayHeight(); DrawGraphic(img, 2, -2, DI_ITEM_LEFT_BOTTOM, 1, 0, 0, imgScale, imgScale); + int gameclock = I_GetBuildTime(); + if (!althud_flashing || p->last_extra > (max_player_health >> 2) || (gameclock & 32) || (sprite[p->i].pal == 1 && p->last_extra < 2)) { int s = -8; if (althud_flashing && p->last_extra > max_player_health) - s += (sintable[(gameclock << 5) & 2047] >> 10); - int intens = clamp(255 - 4 * s, 0, 255); - auto pe = PalEntry(255, intens, intens, intens); + s += (sintable[(gameclock << 6) & 2047] >> 10); + int intens = clamp(255 - 6 * s, 0, 255); format.Format("%d", p->last_extra); - SBar_DrawString(this, &numberFont, format, 26.5, -numberFont.mFont->GetHeight() * scale + 4, DI_TEXT_ALIGN_LEFT, CR_UNTRANSLATED, 1, 0, 0, scale, scale); + SBar_DrawString(this, &numberFont, format, 26.5, -numberFont.mFont->GetHeight() * scale + 4, DI_TEXT_ALIGN_LEFT, CR_UNTRANSLATED, intens / 255., 0, 0, scale, scale); } //