diff --git a/source/blood/src/actor.cpp b/source/blood/src/actor.cpp index 33ac5b4ec..c177cc7dc 100644 --- a/source/blood/src/actor.cpp +++ b/source/blood/src/actor.cpp @@ -5593,6 +5593,8 @@ void actProcessSprites(void) int t = divscale16(pXSprite->data2, nDist); gPlayer[p].flickerEffect += t; } + if (gMe->flickerEffect) + ctrlJoystickRumble(gMe->flickerEffect); #ifdef NOONE_EXTENSIONS if (gModernMap && pXSprite->data1) diff --git a/source/blood/src/config.cpp b/source/blood/src/config.cpp index 1a5382f52..196642ac9 100644 --- a/source/blood/src/config.cpp +++ b/source/blood/src/config.cpp @@ -77,6 +77,7 @@ char CommbatMacro[MAXRIDECULE][MAXRIDECULELENGTH]; char szPlayerName[MAXPLAYERNAME]; int32_t gTurnSpeed; int32_t gTurnAcceleration; +int32_t gCenterViewOnDrop; int32_t gDetail; int32_t gMouseAim; int32_t gAutoAim; @@ -307,6 +308,7 @@ void CONFIG_SetDefaults(void) #else gSetup.usejoystick = 0; #endif + gSetup.joystickrumble = 0; gSetup.forcesetup = 1; gSetup.noautoload = 1; @@ -386,6 +388,7 @@ void CONFIG_SetDefaults(void) gViewSize = 2; gTurnSpeed = 92; gTurnAcceleration = 1; + gCenterViewOnDrop = 0; gDetail = 4; gAutoRun = 0; gViewInterpolate = 1; @@ -751,6 +754,7 @@ int CONFIG_ReadSetup(void) SCRIPT_GetNumber(scripthandle, "Setup", "ForceSetup", &gSetup.forcesetup); SCRIPT_GetNumber(scripthandle, "Setup", "NoAutoLoad", &gSetup.noautoload); SCRIPT_GetNumber(scripthandle, "Setup", "InputJoystick", &gSetup.usejoystick); + SCRIPT_GetNumber(scripthandle, "Setup", "UseJoystickRumble", &gSetup.joystickrumble); SCRIPT_GetNumber(scripthandle, "Setup", "InputMouse", &gSetup.usemouse); int32_t cachesize; @@ -886,6 +890,7 @@ void CONFIG_WriteSetup(uint32_t flags) SCRIPT_PutNumber(scripthandle, "Setup", "ForceSetup", gSetup.forcesetup, FALSE, FALSE); SCRIPT_PutNumber(scripthandle, "Setup", "NoAutoLoad", gSetup.noautoload, FALSE, FALSE); SCRIPT_PutNumber(scripthandle, "Setup", "InputJoystick", gSetup.usejoystick, FALSE, FALSE); + SCRIPT_PutNumber(scripthandle, "Setup", "UseJoystickRumble", gSetup.joystickrumble, FALSE, FALSE); SCRIPT_PutNumber(scripthandle, "Setup", "InputMouse", gSetup.usemouse, FALSE, FALSE); #ifdef POLYMER diff --git a/source/blood/src/config.h b/source/blood/src/config.h index 1124484f2..db4cf237a 100644 --- a/source/blood/src/config.h +++ b/source/blood/src/config.h @@ -58,6 +58,7 @@ extern char CommbatMacro[MAXRIDECULE][MAXRIDECULELENGTH]; extern char szPlayerName[MAXPLAYERNAME]; extern int32_t gTurnSpeed; extern int32_t gTurnAcceleration; +extern int32_t gCenterViewOnDrop; extern int32_t gDetail; extern int32_t gAutoAim; extern int32_t gWeaponSwitch; diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 6f68ebb2f..02c5c9daf 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -520,6 +520,11 @@ void ctrlGetInput(void) } if (input.q16turn == 0) input.q16turn = fix16_sadd(input.q16mlook, fix16_sdiv(fix16_from_int(info.dyaw>>4), F16(32))); + if (gCenterViewOnDrop == 2) + { + gInput.keyFlags.lookCenter = 1; + gCenterViewOnDrop = 1; + } } if (!gMouseAimingFlipped) input.q16mlook = -input.q16mlook; @@ -564,3 +569,16 @@ void ctrlGetInput(void) gViewLook = fix16_clamp(gViewLook+(input.q16mlook << 3), F16(downAngle), F16(upAngle)); } } + +void ctrlJoystickRumble(int nTime) +{ + if (!CONTROL_JoystickEnabled || !joystick.hasRumble || !gSetup.joystickrumble) + return; + + const int nRumble = nTime<<9; + nTime = ClipLow(nTime, 28)<<3; + joystick.rumbleHigh = UINT16_MAX > joystick.rumbleHigh + nRumble ? joystick.rumbleHigh + nRumble : UINT16_MAX; + joystick.rumbleLow = UINT16_MAX > joystick.rumbleHigh + nRumble ? joystick.rumbleLow + nRumble : UINT16_MAX; + joystick.rumbleHigh >>= 1; + joystick.rumbleTime = nTime > joystick.rumbleTime ? nTime : joystick.rumbleTime; +} diff --git a/source/blood/src/controls.h b/source/blood/src/controls.h index edf222fde..4651434ec 100644 --- a/source/blood/src/controls.h +++ b/source/blood/src/controls.h @@ -115,4 +115,4 @@ int32_t ctrlCheckAllInput(void); void ctrlClearAllInput(void); void ctrlInit(); void ctrlGetInput(); - +void ctrlJoystickRumble(int nTime); diff --git a/source/blood/src/globals.h b/source/blood/src/globals.h index c32830291..333ff1950 100644 --- a/source/blood/src/globals.h +++ b/source/blood/src/globals.h @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. typedef struct { int32_t usejoystick; + int32_t joystickrumble; int32_t usemouse; int32_t fullscreen; int32_t xdim; diff --git a/source/blood/src/menu.cpp b/source/blood/src/menu.cpp index c961be361..b2f399e4a 100644 --- a/source/blood/src/menu.cpp +++ b/source/blood/src/menu.cpp @@ -68,6 +68,8 @@ void SetMouseSensitivity(CGameMenuItemSliderFloat *); void SetMouseAimFlipped(CGameMenuItemZBool *); void SetTurnSpeed(CGameMenuItemSlider *); void SetTurnAcceleration(CGameMenuItemZCycle *); +void SetCenterView(CGameMenuItemZBool *); +void SetJoystickRumble(CGameMenuItemZBool *pItem); void ResetKeys(CGameMenuItemChain *); void ResetKeysClassic(CGameMenuItemChain *); void SetMessages(CGameMenuItemZBool *); @@ -699,6 +701,7 @@ CGameMenu menuOptionsControlMouseButtonAssignment; CGameMenu menuOptionsControlJoystickButtonAssignment[MAXJOYSTICKBUTTONPAGES]; CGameMenu menuOptionsControlJoystickListAxes; // contains list of editable joystick axes CGameMenu menuOptionsControlJoystickAxis[MAXJOYAXES]; // options menu for each joystick axis +CGameMenu menuOptionsControlJoystickMisc; void SetupMouseMenu(CGameMenuItemChain *pItem); void SetupJoystickButtonsMenu(CGameMenuItemChain *pItem); @@ -722,6 +725,7 @@ CGameMenuItemChain itemOptionsControlKeyboard("KEYBOARD SETUP", 1, 0, 60, 320, 1 CGameMenuItemChain itemOptionsControlMouse("MOUSE SETUP", 1, 0, 80, 320, 1, &menuOptionsControlMouse, -1, SetupMouseMenu, 0); CGameMenuItemChain itemOptionsControlJoystickButtons("JOYSTICK BUTTONS SETUP", 1, 0, 120, 320, 1, &menuOptionsControlJoystickButtonAssignment[0], -1, SetupJoystickButtonsMenu, 0); CGameMenuItemChain itemOptionsControlJoystickAxes("JOYSTICK AXES SETUP", 1, 0, 140, 320, 1, &menuOptionsControlJoystickListAxes, -1, SetupJoystickAxesMenu, 0); +CGameMenuItemChain itemOptionsControlJoystickMisc("JOYSTICK MISC SETUP", 1, 0, 160, 320, 1, &menuOptionsControlJoystickMisc, -1, NULL, 0); CGameMenuItemTitle itemOptionsControlKeyboardTitle("KEYBOARD SETUP", 1, 160, 20, 2038); CGameMenuItemSlider itemOptionsControlKeyboardSliderTurnSpeed("Key Turn Speed:", 1, 18, 50, 280, &gTurnSpeed, 64, 128, 4, SetTurnSpeed, -1, -1); @@ -843,6 +847,10 @@ CGameMenuItemZCycle *pItemOptionsControlJoystickAxisDigitalNeg[MAXJOYAXES]; CGameMenuItemSlider *pItemOptionsControlJoystickAxisDeadzone[MAXJOYAXES]; CGameMenuItemSlider *pItemOptionsControlJoystickAxisSaturate[MAXJOYAXES]; +CGameMenuItemTitle itemOptionsControlJoystickMiscTitle("JOYSTICK MISC", 1, 160, 20, 2038); +CGameMenuItemZBool itemOptionsControlJoystickMiscCenterView("CENTER VIEW ON DROP:", 1, 18, 60, 280, gCenterViewOnDrop, SetCenterView, NULL, NULL); +CGameMenuItemZBool itemOptionsControlJoystickMiscRumble("RUMBLE CONTROLLER:", 1, 18, 80, 280, 0, SetJoystickRumble, NULL, NULL); + void SetupLoadingScreen(void) { menuLoading.Add(&itemLoadingText, true); @@ -1433,6 +1441,7 @@ void SetupControlsMenu(void) menuOptionsControl.Add(&itemOptionsControlMouse, false); menuOptionsControl.Add(&itemOptionsControlJoystickButtons, false); menuOptionsControl.Add(&itemOptionsControlJoystickAxes, false); + menuOptionsControl.Add(&itemOptionsControlJoystickMisc, false); menuOptionsControl.Add(&itemBloodQAV, false); menuOptionsControlKeyboard.Add(&itemOptionsControlKeyboardTitle, false); @@ -1475,9 +1484,18 @@ void SetupJoystickMenu(void) { itemOptionsControlJoystickButtons.bEnable = 0; itemOptionsControlJoystickAxes.bEnable = 0; + itemOptionsControlJoystickMisc.bEnable = 0; return; } + menuOptionsControlJoystickMisc.Add(&itemOptionsControlJoystickMiscTitle, false); + menuOptionsControlJoystickMisc.Add(&itemOptionsControlJoystickMiscCenterView, true); + menuOptionsControlJoystickMisc.Add(&itemOptionsControlJoystickMiscRumble, false); + menuOptionsControlJoystickMisc.Add(&itemBloodQAV, false); + + itemOptionsControlJoystickMiscCenterView.at20 = gCenterViewOnDrop; + itemOptionsControlJoystickMiscRumble.at20 = gSetup.joystickrumble; + int i = 0, y = 0; for (int nButton = 0; nButton < joystick.numButtons; nButton++) // store every joystick button/hat name for button list at launch { @@ -1807,6 +1825,16 @@ void SetTurnAcceleration(CGameMenuItemZCycle *pItem) gTurnAcceleration = pItem->m_nFocus; } +void SetCenterView(CGameMenuItemZBool *pItem) +{ + gCenterViewOnDrop = pItem->at20; +} + +void SetJoystickRumble(CGameMenuItemZBool *pItem) +{ + gSetup.joystickrumble = pItem->at20; +} + void SetAutoAim(CGameMenuItemZCycle *pItem) { gAutoAim = pItem->m_nFocus; @@ -2307,6 +2335,7 @@ void SetupPollJoystick(CGameMenuItemChain *pItem) { itemOptionsControlJoystickButtons.bEnable = 1; itemOptionsControlJoystickAxes.bEnable = 1; + itemOptionsControlJoystickMisc.bEnable = 1; SetupJoystickMenu(); } } diff --git a/source/blood/src/osdcmd.cpp b/source/blood/src/osdcmd.cpp index 52ecc9df2..e3ae0cdac 100644 --- a/source/blood/src/osdcmd.cpp +++ b/source/blood/src/osdcmd.cpp @@ -1023,6 +1023,7 @@ int32_t registerosdcommands(void) { "fov", "change the field of view", (void *)&gFov, CVAR_INT|CVAR_FUNCPTR, 75, 140 }, { "in_aimmode", "0: toggle, 1: hold to aim", (void *)&gMouseAiming, CVAR_BOOL, 0, 1 }, + { "in_centerviewondrop", "enable/disable recenter view when dropping down onto ground", (void *)&gCenterViewOnDrop, CVAR_BOOL, 0, 1 }, { "in_mousebias", "emulates the original mouse code's weighting of input towards whichever axis is moving the most at any given time", (void *)&MouseBias, CVAR_INT, 0, 32 diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index f721d5f7b..2b1223f01 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -2223,6 +2223,8 @@ int playerDamageSprite(int nSource, PLAYER *pPlayer, DAMAGE_TYPE nDamageType, in return 0; nDamage = playerDamageArmor(pPlayer, nDamageType, nDamage); pPlayer->painEffect = ClipHigh(pPlayer->painEffect+(nDamage>>3), 600); + if (pPlayer == gMe) + ctrlJoystickRumble(pPlayer->painEffect); spritetype *pSprite = pPlayer->pSprite; XSPRITE *pXSprite = pPlayer->pXSprite; @@ -2434,6 +2436,8 @@ void playerLandingSound(PLAYER *pPlayer) SPRITEHIT *pHit = &gSpriteHit[pSprite->extra]; if (pHit->florhit) { + if ((pPlayer == gMe) && gCenterViewOnDrop) + gCenterViewOnDrop = 2; if (!gGameOptions.bFriendlyFire && IsTargetTeammate(pPlayer, &sprite[pHit->florhit & 0x3fff])) return; char nSurf = tileGetSurfType(pHit->florhit); diff --git a/source/blood/src/weapon.cpp b/source/blood/src/weapon.cpp index 340b056c6..8075fcb43 100644 --- a/source/blood/src/weapon.cpp +++ b/source/blood/src/weapon.cpp @@ -1212,6 +1212,8 @@ void FireShotgun(int nTrigger, PLAYER *pPlayer) } UseAmmo(pPlayer, pPlayer->weaponAmmo, nTrigger); pPlayer->flashEffect = 1; + if (pPlayer == gMe && powerupCheck(pPlayer, kPwUpTwoGuns)) + ctrlJoystickRumble(n>>2); } void EjectShell(int, PLAYER *pPlayer) @@ -1254,6 +1256,8 @@ void FireTommy(int nTrigger, PLAYER *pPlayer) } UseAmmo(pPlayer, pPlayer->weaponAmmo, nTrigger); pPlayer->flashEffect = 1; + if (pPlayer == gMe && powerupCheck(pPlayer, kPwUpTwoGuns)) + ctrlJoystickRumble(nTrigger<<3); } #define kMaxSpread 14 @@ -1357,6 +1361,8 @@ void AltFireSpread2(int nTrigger, PLAYER *pPlayer) WeaponLower(pPlayer); pPlayer->weaponState = -1; } + if (pPlayer == gMe && powerupCheck(pPlayer, kPwUpTwoGuns)) + ctrlJoystickRumble(nTrigger<<3); } void FireFlare(int nTrigger, PLAYER *pPlayer)