From fdf2decde3bc9fc3268d0de9d30a97a416ab5f31 Mon Sep 17 00:00:00 2001 From: Lubos Date: Tue, 15 Mar 2022 16:33:17 +0100 Subject: [PATCH 1/2] Soft keyboard support added --- Makefile | 2 +- android/app/src/main/AndroidManifest.xml | 1 + android/app/src/main/cpp/code/q3_ui/ui_qmenu.c | 13 +++++++++++++ android/app/src/main/cpp/code/sdl/sdl_input.c | 2 -- android/app/src/main/cpp/code/vr/vr_input.c | 6 +++++- android/app/src/main/cpp/main.cpp | 5 +++-- .../src/main/java/org/libsdl/app/SDLActivity.java | 3 +++ 7 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index c51f81cb..a11b6665 100644 --- a/Makefile +++ b/Makefile @@ -2668,7 +2668,7 @@ Q3UIVMOBJ = $(Q3UIOBJ_:%.o=%.asm) $(B)/$(BASEGAME)/ui$(SHLIBNAME): $(Q3UIOBJ) $(echo_cmd) "LD $@" - $(Q)$(CC) $(CFLAGS) $(SHLIBLDFLAGS) -o $@ $(Q3UIOBJ) + $(Q)$(CC) $(CFLAGS) $(SHLIBLDFLAGS) -o $@ $(Q3UIOBJ) $(CLIENT_LIBS) $(B)/$(BASEGAME)/vm/ui.qvm: $(Q3UIVMOBJ) $(UIDIR)/ui_syscalls.asm $(Q3ASM) $(echo_cmd) "Q3ASM $@" diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c3e41ab0..10e1ecbb 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -5,6 +5,7 @@ android:versionCode="34" android:versionName="0.23.0"> + diff --git a/android/app/src/main/cpp/code/q3_ui/ui_qmenu.c b/android/app/src/main/cpp/code/q3_ui/ui_qmenu.c index f9df6e1c..517547af 100644 --- a/android/app/src/main/cpp/code/q3_ui/ui_qmenu.c +++ b/android/app/src/main/cpp/code/q3_ui/ui_qmenu.c @@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Quake's menu framework system. **********************************************************************/ #include "ui_local.h" +#include "SDL.h" sfxHandle_t menu_in_sound; sfxHandle_t menu_move_sound; @@ -1653,6 +1654,18 @@ sfxHandle_t Menu_DefaultKey( menuframework_s *m, int key ) case MTYPE_FIELD: sound = MenuField_Key( (menufield_s*)item, &key ); + +#if __ANDROID__ + //show virtual keyboard + menufield_s* m = (menufield_s*)item; + if ( key == 178 ) + { + //delete value on click + sprintf( m->field.buffer, "" ); + } + m->field.cursor = strlen( m->field.buffer ); + SDL_StartTextInput(); +#endif break; } diff --git a/android/app/src/main/cpp/code/sdl/sdl_input.c b/android/app/src/main/cpp/code/sdl/sdl_input.c index df1763af..611501a4 100644 --- a/android/app/src/main/cpp/code/sdl/sdl_input.c +++ b/android/app/src/main/cpp/code/sdl/sdl_input.c @@ -1246,8 +1246,6 @@ void IN_Init( void *windowData ) in_joystick = Cvar_Get( "in_joystick", "0", CVAR_ARCHIVE|CVAR_LATCH ); in_joystickThreshold = Cvar_Get( "joy_threshold", "0.15", CVAR_ARCHIVE ); - SDL_StartTextInput( ); - mouseAvailable = ( in_mouse->value != 0 ); IN_DeactivateMouse( Cvar_VariableIntegerValue( "r_fullscreen" ) != 0 ); diff --git a/android/app/src/main/cpp/code/vr/vr_input.c b/android/app/src/main/cpp/code/vr/vr_input.c index eb837aaf..08ef63e1 100644 --- a/android/app/src/main/cpp/code/vr/vr_input.c +++ b/android/app/src/main/cpp/code/vr/vr_input.c @@ -417,7 +417,11 @@ static void IN_VRController( qboolean isRightController, ovrTracking remoteTrack cl.snap.ps.pm_type == PM_INTERMISSION) { int mouse_multiplier = 10; - Com_QueueEvent(in_vrEventTime, SE_MOUSE, vr.weaponangles_delta[YAW] * mouse_multiplier, -vr.weaponangles_delta[PITCH] * mouse_multiplier, 0, NULL); + //ignore cursor jumping when e.g. showing keyboard + if ( ( fabs(vr.weaponangles_delta[ YAW ]) < 10 ) && ( fabs(vr.weaponangles_delta[ PITCH ]) < 10 ) ) + { + Com_QueueEvent(in_vrEventTime, SE_MOUSE, vr.weaponangles_delta[YAW] * mouse_multiplier, -vr.weaponangles_delta[PITCH] * mouse_multiplier, 0, NULL); + } } } else { vec3_t rotation = {0}; diff --git a/android/app/src/main/cpp/main.cpp b/android/app/src/main/cpp/main.cpp index 6de0f2ed..417a3565 100644 --- a/android/app/src/main/cpp/main.cpp +++ b/android/app/src/main/cpp/main.cpp @@ -84,7 +84,8 @@ int main(int argc, char* argv[]) { VR_EnterVR(engine, java); while (1) { - SDL_Event event; + //Polling events here breaks sdl_input keyboard! + /*SDL_Event event; while (SDL_PollEvent(&event)) { LOGI("Received SDL Event: %d", event.type); switch (event.type) @@ -97,7 +98,7 @@ int main(int argc, char* argv[]) { VR_LeaveVR(engine); break; } - } + }*/ VR_DrawFrame(engine); } diff --git a/android/app/src/main/java/org/libsdl/app/SDLActivity.java b/android/app/src/main/java/org/libsdl/app/SDLActivity.java index 8c363ed5..37d6b318 100644 --- a/android/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/android/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -264,6 +264,9 @@ public class SDLActivity extends Activity { if (SDLActivity.mBrokenLibraries) { return; } + if (mScreenKeyboardShown) { + return; + } SDLActivity.mHasFocus = hasFocus; if (hasFocus) { From 83599b76cace87068cf6f6c452448d8fa32fdea8 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 15 Mar 2022 22:38:26 +0000 Subject: [PATCH 2/2] Some changes... - Make HMD weapon wheel use angles for weapon selection, allows selection immediately before show animation is complete - Proper model scaling in the Player Setup menu --- .../app/src/main/cpp/code/cgame/cg_weapons.c | 72 +++++++++++++------ .../app/src/main/cpp/code/q3_ui/ui_players.c | 22 ++++-- 2 files changed, 68 insertions(+), 26 deletions(-) diff --git a/android/app/src/main/cpp/code/cgame/cg_weapons.c b/android/app/src/main/cpp/code/cgame/cg_weapons.c index 529c8d0b..e2a3179e 100644 --- a/android/app/src/main/cpp/code/cgame/cg_weapons.c +++ b/android/app/src/main/cpp/code/cgame/cg_weapons.c @@ -2096,9 +2096,9 @@ void CG_DrawWeaponSelector( void ) float thumbstickAxisX = 0.0f; float thumbstickAxisY = 0.0f; + float a = atan2(vr->thumbstick_location[THUMB_RIGHT][0], vr->thumbstick_location[THUMB_RIGHT][1]); if (length(vr->thumbstick_location[THUMB_RIGHT][0], vr->thumbstick_location[THUMB_RIGHT][1]) > 0.95f) { - float a = atan2(vr->thumbstick_location[THUMB_RIGHT][0], vr->thumbstick_location[THUMB_RIGHT][1]); thumbstickAxisX = sinf(a) * 0.95f; thumbstickAxisY = cosf(a) * 0.95f; } @@ -2149,22 +2149,24 @@ void CG_DrawWeaponSelector( void ) } } -#define IGNORE_ANGLE -999.0f #ifdef MISSIONPACK - float rollAngles[WP_NUM_WEAPONS] = {IGNORE_ANGLE, 30.0f, 60.0f, 90.0f, 120.0f, 150.0f, 180.0f, 210.0f, 240.0f, 270.0f, IGNORE_ANGLE, 300.0f, 330.0f, 0.0f}; + float iconAngles[WP_NUM_WEAPONS] = {0.0f, 30.0f, 60.0f, 90.0f, 120.0f, 150.0f, 180.0f, 210.0f, 240.0f, 270.0f, 300.0f, 330.0f, 360.0f, 390.0f}; #else - float rollAngles[WP_NUM_WEAPONS] = {IGNORE_ANGLE, 18.0f, 54.0f, 90.0f, 135.0f, 180.0f, 225.0f, 270.0f, 306.0f, 342.0f, IGNORE_ANGLE}; + float iconAngles[WP_NUM_WEAPONS] = {0.0f, 30.0f, 60.0f, 90.0f, 135.0f, 180.0f, 225.0f, 270.0f, 315.0f, 360.0f, 390.0f}; #endif qboolean selected = qfalse; - for (int c = 0; c < WP_NUM_WEAPONS-1; ++c) + int w = 0; + for (int index = 0; index < WP_NUM_WEAPONS-1; ++index) { - int w = c+1; - if (w == WP_GRAPPLING_HOOK) + if ((index+1) == WP_GRAPPLING_HOOK) { continue; } + //increment now we know we aren't looking at an invalid weapon id + ++w; + CG_RegisterWeapon(w); { @@ -2175,7 +2177,7 @@ void CG_DrawWeaponSelector( void ) VectorClear(angles); angles[YAW] = holsterAngles[YAW]; angles[PITCH] = holsterAngles[PITCH]; - angles[ROLL] = rollAngles[w]; + angles[ROLL] = iconAngles[w]; vec3_t forward, up; AngleVectors(angles, forward, NULL, up); @@ -2183,22 +2185,48 @@ void CG_DrawWeaponSelector( void ) VectorMA(iconOrigin, 0.2f, forward, iconBackground); VectorMA(iconOrigin, -0.2f, forward, iconForeground); - //Float sprite above selected weapon - vec3_t diff; - VectorSubtract(selectorOrigin, iconOrigin, diff); - float length = VectorLength(diff); - if (length <= 1.2f && - frac == 1.0f && - selectable) - { - if (cg.weaponSelectorSelection != w) + if (selectorMode == WS_CONTROLLER) + { + vec3_t diff; + VectorSubtract(selectorOrigin, iconOrigin, diff); + float length = VectorLength(diff); + if (length <= 1.2f && + frac == 1.0f && + selectable) { - cg.weaponSelectorSelection = w; - trap_HapticEvent("selector_icon", 0, 0, 100, 0, 0); - } + if (cg.weaponSelectorSelection != w) + { + cg.weaponSelectorSelection = w; + trap_HapticEvent("selector_icon", 0, 0, 100, 0, 0); + } - selected = qtrue; - } + selected = qtrue; + } + } + else + { + //For HMD selector, the weapon can be selected before the selector has finished + //its opening animation, use angles to identify the selected weapon, rather than + //the position of the selector pointer + float angle = AngleNormalize360(RAD2DEG(a)); + float angle360 = angle + 360; // HACK - Account for the icon at the top + + float low = ((iconAngles[w-1]+iconAngles[w])/2.0f); + float high = ((iconAngles[w]+iconAngles[w+1])/2.0f); + + if (((angle > low && angle <= high) || (angle360 > low && angle360 <= high)) && + (length(vr->thumbstick_location[THUMB_RIGHT][0], vr->thumbstick_location[THUMB_RIGHT][1]) > 0.5f) && + selectable) + { + if (cg.weaponSelectorSelection != w) + { + cg.weaponSelectorSelection = w; + trap_HapticEvent("selector_icon", 0, 0, 100, 0, 0); + } + + selected = qtrue; + } + } if (cg.weaponSelectorSelection == w) { diff --git a/android/app/src/main/cpp/code/q3_ui/ui_players.c b/android/app/src/main/cpp/code/q3_ui/ui_players.c index cf2730a7..ea726878 100644 --- a/android/app/src/main/cpp/code/q3_ui/ui_players.c +++ b/android/app/src/main/cpp/code/q3_ui/ui_players.c @@ -591,6 +591,8 @@ static void UI_PlayerAngles( playerInfo_t *pi, vec3_t legs[3], vec3_t torso[3], float dest; float adjust; + pi->viewAngles[YAW] = AngleNormalize360(uis.realtime / 50.0f); + VectorCopy( pi->viewAngles, headAngles ); headAngles[YAW] = AngleMod( headAngles[YAW] ); VectorClear( legsAngles ); @@ -705,6 +707,12 @@ float UI_MachinegunSpinAngle( playerInfo_t *pi ) { return angle; } +static void UI_ScaleModel(refEntity_t *ent) +{ + VectorScale(ent->axis[1], 1.6f, ent->axis[1]); + VectorScale(ent->axis[2], 1.4f, ent->axis[2]); + ent->nonNormalizedAxes = qtrue; +} /* =============== @@ -767,8 +775,8 @@ void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int ti // calculate distance so the player nearly fills the box len = 0.7 * ( maxs[2] - mins[2] ); - origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 ); - origin[1] = 0.5 * ( mins[1] + maxs[1] ); + origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 ) - 15; + origin[1] = 0.5 * ( mins[1] + maxs[1] ) - 10; origin[2] = -0.5 * ( mins[2] + maxs[2] ); refdef.time = dp_realtime; @@ -796,6 +804,10 @@ void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int ti legs.renderfx = renderfx; VectorCopy (legs.origin, legs.oldorigin); + UI_ScaleModel(&legs); + //UI_ScaleModel(&torso); + //UI_ScaleModel(&head); + trap_R_AddRefEntityToScene( &legs ); if (!legs.hModel) { @@ -852,7 +864,8 @@ void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int ti VectorCopy( origin, gun.lightingOrigin ); UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon"); gun.renderfx = renderfx; - trap_R_AddRefEntityToScene( &gun ); + //UI_ScaleModel(&gun); + trap_R_AddRefEntityToScene( &gun ); } // @@ -870,8 +883,9 @@ void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int ti angles[PITCH] = 0; angles[ROLL] = UI_MachinegunSpinAngle( pi ); AnglesToAxis( angles, barrel.axis ); + //UI_ScaleModel(&barrel); - UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, "tag_barrel"); + UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, "tag_barrel"); trap_R_AddRefEntityToScene( &barrel ); }