From f3d79960639a1416e0cd8d9a019883d249fbf4fc Mon Sep 17 00:00:00 2001 From: Jae Yeum Date: Wed, 12 Jan 2022 00:25:43 -0500 Subject: [PATCH 1/2] I#106 - Dark Forces: add new setting for weapon wave under "Hud" settings --- TheForceEngine/TFE_FrontEndUI/frontEndUi.cpp | 4 ++++ TheForceEngine/TFE_Settings/settings.cpp | 5 +++++ TheForceEngine/TFE_Settings/settings.h | 2 ++ 3 files changed, 11 insertions(+) diff --git a/TheForceEngine/TFE_FrontEndUI/frontEndUi.cpp b/TheForceEngine/TFE_FrontEndUI/frontEndUi.cpp index 347875d08..bb45666fb 100644 --- a/TheForceEngine/TFE_FrontEndUI/frontEndUi.cpp +++ b/TheForceEngine/TFE_FrontEndUI/frontEndUi.cpp @@ -1538,6 +1538,10 @@ namespace TFE_FrontEndUI ImGui::SetNextItemWidth(196*s_uiScale); ImGui::SliderInt("Offset Y", &hud->pixelOffset[1], -512, 512); + ImGui::Separator(); + + ImGui::Checkbox("Weapon Wave", &hud->weaponWave); + if (s_menuRetState != APP_STATE_MENU) { TFE_DarkForces::mission_render(); diff --git a/TheForceEngine/TFE_Settings/settings.cpp b/TheForceEngine/TFE_Settings/settings.cpp index 33962918a..4165e5363 100644 --- a/TheForceEngine/TFE_Settings/settings.cpp +++ b/TheForceEngine/TFE_Settings/settings.cpp @@ -297,6 +297,7 @@ namespace TFE_Settings writeHeader(settings, c_sectionNames[SECTION_HUD]); writeKeyValue_String(settings, "hudScale", c_tfeHudScaleStrings[s_hudSettings.hudScale]); writeKeyValue_String(settings, "hudPos", c_tfeHudPosStrings[s_hudSettings.hudPos]); + writeKeyValue_Bool(settings, "weaponWave", s_hudSettings.weaponWave); writeKeyValue_Float(settings, "scale", s_hudSettings.scale); writeKeyValue_Int(settings, "pixelOffsetX", s_hudSettings.pixelOffset[0]); writeKeyValue_Int(settings, "pixelOffsetY", s_hudSettings.pixelOffset[1]); @@ -582,6 +583,10 @@ namespace TFE_Settings { s_hudSettings.pixelOffset[1] = parseInt(value); } + else if (strcasecmp("weaponWave", key) == 0) + { + s_hudSettings.weaponWave = parseBool(value); + } } void parseSoundSettings(const char* key, const char* value) diff --git a/TheForceEngine/TFE_Settings/settings.h b/TheForceEngine/TFE_Settings/settings.h index ccc7c59a4..ca72621f0 100644 --- a/TheForceEngine/TFE_Settings/settings.h +++ b/TheForceEngine/TFE_Settings/settings.h @@ -69,6 +69,8 @@ struct TFE_Settings_Hud TFE_HudScale hudScale = TFE_HUDSCALE_PROPORTIONAL; // This setting determines how the left and right corners are calculated, which have an offset of (0,0). TFE_HudPosition hudPos = TFE_HUDPOS_EDGE; + // This setting determines whether the weapon will wave/bob. + bool weaponWave = true; // Scale of the HUD, ignored if HudScale is TFE_HUDSCALE_PROPORTIONAL. f32 scale = 1.0f; From 885f36bcee1d2828ff66bcdeb2534bb3dfc46628 Mon Sep 17 00:00:00 2001 From: Jae Yeum Date: Wed, 12 Jan 2022 01:18:20 -0500 Subject: [PATCH 2/2] I#106 - Dark Forces: apply new weapon wave setting to separate from head wave --- TheForceEngine/TFE_DarkForces/player.cpp | 105 ++++++++++++----------- 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/TheForceEngine/TFE_DarkForces/player.cpp b/TheForceEngine/TFE_DarkForces/player.cpp index 7299b7355..ad044b366 100644 --- a/TheForceEngine/TFE_DarkForces/player.cpp +++ b/TheForceEngine/TFE_DarkForces/player.cpp @@ -1830,69 +1830,76 @@ namespace TFE_DarkForces //s_282344 = 34 - dH; } - // Headwave + // Calculate the head and weapon wave offsets. s32 xWpnWaveOffset = 0; - s_headwaveVerticalOffset = 0; - if (s_config.headwave && (player->flags & 2)) + s32 headwaveVerticalOffset = 0; + fixed16_16 playerSpeed = distApprox(0, 0, s_playerVelX, s_playerVelZ); + if (!moved) + { + playerSpeed = 0; + } + if ((s_playerSector->flags1 & SEC_FLAGS1_ICE_FLOOR) && !s_wearingCleats) + { + playerSpeed = 0; + } + + if (playerSpeed != s_playerSpeed) { - fixed16_16 playerSpeed = distApprox(0, 0, s_playerVelX, s_playerVelZ); - if (!moved) + fixed16_16 speedDelta = playerSpeed - s_playerSpeed; + fixed16_16 maxFrameChange = mul16(FIXED(32), s_deltaTime); + + if (speedDelta > maxFrameChange) { - playerSpeed = 0; + speedDelta = maxFrameChange; } - if ((s_playerSector->flags1 & SEC_FLAGS1_ICE_FLOOR) && !s_wearingCleats) + else if (speedDelta < -maxFrameChange) { - playerSpeed = 0; + speedDelta = -maxFrameChange; } + s_playerSpeed += speedDelta; + } + sinCosFixed((s_curTick & 0xffff) << 7, &s_wpnSin, &s_wpnCos); - if (playerSpeed != s_playerSpeed) - { - fixed16_16 speedDelta = playerSpeed - s_playerSpeed; - fixed16_16 maxFrameChange = mul16(FIXED(32), s_deltaTime); - - if (speedDelta > maxFrameChange) - { - speedDelta = maxFrameChange; - } - else if (speedDelta < -maxFrameChange) - { - speedDelta = -maxFrameChange; - } - s_playerSpeed += speedDelta; - } - sinCosFixed((s_curTick & 0xffff) << 7, &s_wpnSin, &s_wpnCos); - - fixed16_16 playerSpeedFract = div16(s_playerSpeed, FIXED(32)); - s_headwaveVerticalOffset = mul16(mul16(s_wpnCos, PLAYER_HEADWAVE_VERT_SPD), playerSpeedFract); + fixed16_16 playerSpeedFract = div16(s_playerSpeed, FIXED(32)); + headwaveVerticalOffset = mul16(mul16(s_wpnCos, PLAYER_HEADWAVE_VERT_SPD), playerSpeedFract); - sinCosFixed((s_curTick & 0xffff) << 6, &s_wpnSin, &s_wpnCos); - xWpnWaveOffset = mul16(playerSpeedFract, s_wpnCos) >> 12; + sinCosFixed((s_curTick & 0xffff) << 6, &s_wpnSin, &s_wpnCos); + xWpnWaveOffset = mul16(playerSpeedFract, s_wpnCos) >> 12; - // Water... - if (s_playerSector->secHeight - 1 >= 0) + // Water... + if (s_playerSector->secHeight - 1 >= 0) + { + if (s_externalVelX || s_externalVelZ) { - if (s_externalVelX || s_externalVelZ) - { - fixed16_16 externSpd = distApprox(0, 0, s_externalVelX, s_externalVelZ); - - // Replace the fractional part with the current time fractional part. - // I think this is meant to add some "randomness" to the headwave while in water. - fixed16_16 speed = externSpd & (~0xffff); - speed |= (s_curTick & 0xffff); - // Then multiply by 16 and take the cosine - this is meant to be a small modification to the weapon motion - // (note that the base multiplier is 128). - sinCosFixed(speed << 4, &s_wpnSin, &s_wpnCos); - // Modify the headwave motion. - s_headwaveVerticalOffset += mul16(s_wpnCos, PLAYER_HEADWAVE_VERT_WATER_SPD); - } + fixed16_16 externSpd = distApprox(0, 0, s_externalVelX, s_externalVelZ); + + // Replace the fractional part with the current time fractional part. + // I think this is meant to add some "randomness" to the headwave while in water. + fixed16_16 speed = externSpd & (~0xffff); + speed |= (s_curTick & 0xffff); + // Then multiply by 16 and take the cosine - this is meant to be a small modification to the weapon motion + // (note that the base multiplier is 128). + sinCosFixed(speed << 4, &s_wpnSin, &s_wpnCos); + // Modify the headwave motion. + headwaveVerticalOffset += mul16(s_wpnCos, PLAYER_HEADWAVE_VERT_WATER_SPD); } } - setCameraOffset(0, s_headwaveVerticalOffset, 0); - // Apply the weapon motion. + if (s_config.headwave && (player->flags & 2)) + { + // If head wave is enabled, store the offset and apply it. This offset also affects projectiles fired by the player so + // we must not store it if head waving is disabled. + s_headwaveVerticalOffset = headwaveVerticalOffset; + setCameraOffset(0, s_headwaveVerticalOffset, 0); + } + PlayerWeapon* weapon = s_curPlayerWeapon; - weapon->xWaveOffset = xWpnWaveOffset; // the x offset has 4 bits of sub-texel precision. - weapon->yWaveOffset = s_headwaveVerticalOffset >> 13; // the y offset is probably the same 4 bits of precision & multiplied by half. + if (TFE_Settings::getHudSettings()->weaponWave) + { + // If weapon wave is enabled, apply the offset. + weapon->xWaveOffset = xWpnWaveOffset; // the x offset has 4 bits of sub-texel precision. + weapon->yWaveOffset = headwaveVerticalOffset >> 13; // the y offset is probably the same 4 bits of precision & multiplied by half. + } // The moves the player can make are restricted based on whether they are on the floor or not. if (s_colCurLowestFloor == player->posWS.y)