From c1f71d5c3ee9d44e16ce4210746ef913d2f4cb78 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 5 Apr 2020 19:02:54 +0100 Subject: [PATCH] Couple of fixes - Walking/running speed config (and menu options) - Prevent weapon clipping on near Z plane so that iron sights can be used better - Stop switch from left to right handed mode messing up control of menus --- Projects/Android/jni/QzDoom/VrInputDefault.c | 12 +++- .../jni/gzdoom-g3.3mgw_mobile/src/g_game.cpp | 54 ++++-------------- .../src/gl/renderer/gl_renderer.h | 2 +- .../src/gl/stereo3d/gl_stereo_cvars.cpp | 4 +- .../wadsrc/static/menudef.txt | 5 +- assets/res/lzdoom.pk3 | Bin 3222793 -> 3222904 bytes 6 files changed, 30 insertions(+), 47 deletions(-) diff --git a/Projects/Android/jni/QzDoom/VrInputDefault.c b/Projects/Android/jni/QzDoom/VrInputDefault.c index 02f6000..afff236 100644 --- a/Projects/Android/jni/QzDoom/VrInputDefault.c +++ b/Projects/Android/jni/QzDoom/VrInputDefault.c @@ -33,16 +33,25 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, if (getGameState() != 0 || isMenuActive()) //gamestate != GS_LEVEL { Joy_GenerateButtonEvents((pOffTrackedRemoteOld->Joystick.x > 0.7f ? 1 : 0), (pOffTrackedRemoteNew->Joystick.x > 0.7f ? 1 : 0), 1, KEY_PAD_DPAD_RIGHT); + Joy_GenerateButtonEvents((pDominantTrackedRemoteOld->Joystick.x > 0.7f ? 1 : 0), (pDominantTrackedRemoteNew->Joystick.x > 0.7f ? 1 : 0), 1, KEY_PAD_DPAD_RIGHT); Joy_GenerateButtonEvents((pOffTrackedRemoteOld->Joystick.x < -0.7f ? 1 : 0), (pOffTrackedRemoteNew->Joystick.x < -0.7f ? 1 : 0), 1, KEY_PAD_DPAD_LEFT); + Joy_GenerateButtonEvents((pDominantTrackedRemoteOld->Joystick.x < -0.7f ? 1 : 0), (pDominantTrackedRemoteNew->Joystick.x < -0.7f ? 1 : 0), 1, KEY_PAD_DPAD_LEFT); Joy_GenerateButtonEvents((pOffTrackedRemoteOld->Joystick.y < -0.7f ? 1 : 0), (pOffTrackedRemoteNew->Joystick.y < -0.7f ? 1 : 0), 1, KEY_PAD_DPAD_DOWN); + Joy_GenerateButtonEvents((pDominantTrackedRemoteOld->Joystick.y < -0.7f ? 1 : 0), (pDominantTrackedRemoteNew->Joystick.y < -0.7f ? 1 : 0), 1, KEY_PAD_DPAD_DOWN); Joy_GenerateButtonEvents((pOffTrackedRemoteOld->Joystick.y > 0.7f ? 1 : 0), (pOffTrackedRemoteNew->Joystick.y > 0.7f ? 1 : 0), 1, KEY_PAD_DPAD_UP); + Joy_GenerateButtonEvents((pDominantTrackedRemoteOld->Joystick.y > 0.7f ? 1 : 0), (pDominantTrackedRemoteNew->Joystick.y > 0.7f ? 1 : 0), 1, KEY_PAD_DPAD_UP); handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton1, KEY_PAD_A); handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, ovrButton_Trigger, KEY_PAD_A); handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton2, KEY_PAD_B); + + handleTrackedControllerButton(pOffTrackedRemoteNew, pOffTrackedRemoteOld, domButton1, KEY_PAD_A); + handleTrackedControllerButton(pOffTrackedRemoteNew, pOffTrackedRemoteOld, ovrButton_Trigger, KEY_PAD_A); + handleTrackedControllerButton(pOffTrackedRemoteNew, pOffTrackedRemoteOld, domButton2, KEY_PAD_B); + handleTrackedControllerButton(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, ovrButton_Enter, KEY_PAD_B); } else @@ -98,7 +107,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, float zxDist = length(x, z); if (zxDist != 0.0f && z != 0.0f) { - VectorSet(weaponangles, -degrees(atanf(y / zxDist)), -degrees(atan2f(x, -z)), 0.0f); + VectorSet(weaponangles, -degrees(atanf(y / zxDist)), -degrees(atan2f(x, -z)), weaponangles[ROLL]); } } } @@ -162,6 +171,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, { ready_teleport = false; trigger_teleport = true; + resetDoomYaw = true; } //Apply a filter and quadratic scaler so small movements are easier to make diff --git a/Projects/Android/jni/gzdoom-g3.3mgw_mobile/src/g_game.cpp b/Projects/Android/jni/gzdoom-g3.3mgw_mobile/src/g_game.cpp index c449d49..648f2ec 100644 --- a/Projects/Android/jni/gzdoom-g3.3mgw_mobile/src/g_game.cpp +++ b/Projects/Android/jni/gzdoom-g3.3mgw_mobile/src/g_game.cpp @@ -137,6 +137,8 @@ CVAR (Bool, cl_waitforsave, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR (Bool, enablescriptscreenshot, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); EXTERN_CVAR (Float, con_midtime); EXTERN_CVAR(Bool, vr_teleport); +EXTERN_CVAR(Int, vr_move_speed); +EXTERN_CVAR(Float, vr_run_multiplier); //========================================================================== // @@ -618,9 +620,9 @@ void G_BuildTiccmd (ticcmd_t *cmd) if (strafe) { if (Button_Right.bDown) - side += sidemove[speed]; + side += (vr_move_speed * (speed ? vr_run_multiplier : 1.0)); if (Button_Left.bDown) - side -= sidemove[speed]; + side -= (vr_move_speed * (speed ? vr_run_multiplier : 1.0)); } else { @@ -663,9 +665,9 @@ void G_BuildTiccmd (ticcmd_t *cmd) else { if (Button_Forward.bDown) - forward += forwardmove[speed]; + forward += (vr_move_speed * (speed ? vr_run_multiplier : 1.0)); if (Button_Back.bDown) - forward -= forwardmove[speed]; + forward -= (vr_move_speed * (speed ? vr_run_multiplier : 1.0)); } if (Button_MoveRight.bDown) @@ -701,47 +703,13 @@ void G_BuildTiccmd (ticcmd_t *cmd) if (Button_MoveUp.bDown) cmd->ucmd.buttons |= BT_MOVEUP; if (Button_ShowScores.bDown) cmd->ucmd.buttons |= BT_SHOWSCORES; - // Handle joysticks/game controllers. - if (0) { - float joyaxes[NUM_JOYAXIS]; - I_GetAxes(joyaxes); - - // Remap some axes depending on button state. - if (Button_Strafe.bDown || (Button_Mlook.bDown && lookstrafe)) { - joyaxes[JOYAXIS_Side] = joyaxes[JOYAXIS_Yaw]; - joyaxes[JOYAXIS_Yaw] = 0; - } - if (Button_Mlook.bDown) { - joyaxes[JOYAXIS_Pitch] = joyaxes[JOYAXIS_Forward]; - joyaxes[JOYAXIS_Forward] = 0; - } - - if (joyaxes[JOYAXIS_Pitch] != 0) { - G_AddViewPitch(joyint(joyaxes[JOYAXIS_Pitch] * 2048)); - } - if (joyaxes[JOYAXIS_Yaw] != 0) { - G_AddViewAngle(joyint(-1280 * joyaxes[JOYAXIS_Yaw])); - } - - side -= joyint(sidemove[speed] * joyaxes[JOYAXIS_Side]); - forward += joyint(joyaxes[JOYAXIS_Forward] * forwardmove[speed]); - fly += joyint(joyaxes[JOYAXIS_Up] * 2048); - - // Handle mice. - if (!Button_Mlook.bDown && !freelook) - { - forward += (int)((float)mousey * m_forward); - } - } - - float joyforward=0; - float joyside=0; - float dummy=0; - if (!vr_teleport) { + float joyforward=0; + float joyside=0; + float dummy=0; VR_GetMove(&joyforward, &joyside, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy); - side += joyint(joyside * sidemove[speed]); - forward += joyint(joyforward * forwardmove[speed]); + side += joyint(joyside * (vr_move_speed * (speed ? vr_run_multiplier : 1.0))); + forward += joyint(joyforward * (vr_move_speed * (speed ? vr_run_multiplier : 1.0))); } cmd->ucmd.pitch = LocalViewPitch >> 16; diff --git a/Projects/Android/jni/gzdoom-g3.3mgw_mobile/src/gl/renderer/gl_renderer.h b/Projects/Android/jni/gzdoom-g3.3mgw_mobile/src/gl/renderer/gl_renderer.h index c45e285..c5abae7 100644 --- a/Projects/Android/jni/gzdoom-g3.3mgw_mobile/src/gl/renderer/gl_renderer.h +++ b/Projects/Android/jni/gzdoom-g3.3mgw_mobile/src/gl/renderer/gl_renderer.h @@ -243,7 +243,7 @@ public: int PTM_BestColor (const uint32_t *pal_in, int r, int g, int b, int first, int num); - static float GetZNear() { return 5.f; } + static float GetZNear() { return 0.5f; } static float GetZFar() { return 65536.f; } }; diff --git a/Projects/Android/jni/gzdoom-g3.3mgw_mobile/src/gl/stereo3d/gl_stereo_cvars.cpp b/Projects/Android/jni/gzdoom-g3.3mgw_mobile/src/gl/stereo3d/gl_stereo_cvars.cpp index 25e3bfd..2607804 100644 --- a/Projects/Android/jni/gzdoom-g3.3mgw_mobile/src/gl/stereo3d/gl_stereo_cvars.cpp +++ b/Projects/Android/jni/gzdoom-g3.3mgw_mobile/src/gl/stereo3d/gl_stereo_cvars.cpp @@ -56,7 +56,7 @@ CVAR(Float, vr_ipd, 0.064f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // METERS CVAR(Float, vr_screendist, 0.80f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // METERS // default conversion between (vertical) DOOM units and meters -CVAR(Float, vr_vunits_per_meter, 30.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // METERS +CVAR(Float, vr_vunits_per_meter, 38.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // METERS CVAR(Float, vr_height_adjust, 0.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // METERS CVAR(Int, vr_control_scheme, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, vr_move_use_offhand, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -64,6 +64,8 @@ CVAR(Bool, vr_teleport, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Float, vr_weaponRotate, -30, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Float, vr_weaponScale, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Float, vr_snapTurn, 45.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Int, vr_move_speed, 24, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Float, vr_run_multiplier, 1.6, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) //HUD control CVAR(Float, vr_hud_scale, 0.5f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) diff --git a/Projects/Android/jni/gzdoom-g3.3mgw_mobile/wadsrc/static/menudef.txt b/Projects/Android/jni/gzdoom-g3.3mgw_mobile/wadsrc/static/menudef.txt index 40cb718..94e75b4 100644 --- a/Projects/Android/jni/gzdoom-g3.3mgw_mobile/wadsrc/static/menudef.txt +++ b/Projects/Android/jni/gzdoom-g3.3mgw_mobile/wadsrc/static/menudef.txt @@ -2282,6 +2282,10 @@ OptionMenu VROptionsMenu protected Option "Use Teleport", "vr_teleport", "OnOff" Slider "Snap-turn Angle", "vr_snapTurn", 0.0, 90.0, 1.0, 2 + StaticText " " + Slider "Walking Speed", "vr_move_speed", 5, 50, 1, 2 + Slider "Run Multiplier", "vr_run_multiplier", 0.0, 4.0, 0.1, 2 + StaticText " " Slider "Weapon Pitch Adjust", "vr_weaponRotate", -45, 45, 5, 2 Slider "Weapon Scale", "vr_weaponScale", 0.1, 1.0, 0.01, 2 @@ -2611,7 +2615,6 @@ OptionMenu "OpenGLOptions" protected { Title "$GLMNU_TITLE" Submenu "$GLMNU_TEXOPT", "GLTextureGLOptions" - Submenu "$GLPREFMNU_VRMODE", "VR3DMenu" Submenu "$GLMNU_POSTPROCESS", "PostProcessMenu" StaticText " " Option "$GLPREFMNU_SECLIGHTMODE", gl_lightmode, "LightingModes" diff --git a/assets/res/lzdoom.pk3 b/assets/res/lzdoom.pk3 index 4dda8c1bd69da79d62b13eb5a1bed50bf4c4d61b..38de271107d660c9459bf4060d551a0bd38f3623 100644 GIT binary patch delta 8086 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 qQl2c?J5pIoxOC95wVFoyVTQm$p&a#tl|=5X