From fe3f15ad33db691fd3a721f625dfe09534398d5b Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 6 Mar 2023 22:38:12 +0100 Subject: [PATCH] engine: input: psvita: reimplement OSK manually --- engine/platform/platform.h | 1 + engine/platform/psvita/in_psvita.c | 115 +++++++++++++++++++++++++++++ engine/platform/sdl/events.c | 4 + engine/platform/sdl/in_sdl.c | 4 + 4 files changed, 124 insertions(+) create mode 100644 engine/platform/psvita/in_psvita.c diff --git a/engine/platform/platform.h b/engine/platform/platform.h index cd51a95a..76805fa4 100644 --- a/engine/platform/platform.h +++ b/engine/platform/platform.h @@ -60,6 +60,7 @@ void NSwitch_Shutdown( void ); void PSVita_Init( void ); void PSVita_Shutdown( void ); qboolean PSVita_GetBasePath( char *buf, const size_t buflen ); +void PSVita_InputUpdate( void ); #endif /* diff --git a/engine/platform/psvita/in_psvita.c b/engine/platform/psvita/in_psvita.c new file mode 100644 index 00000000..3d14ade2 --- /dev/null +++ b/engine/platform/psvita/in_psvita.c @@ -0,0 +1,115 @@ +/* +in_psvita.h - psvita-specific input code +Copyright (C) 2021-2023 fgsfds + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +/* +the SDL fork that we use sometimes fails to call sceImeUpdate, +which leads to input being consumed forever without ever showing the keyboard, +so we just reimplement the whole thing here using SceCommonDialog +*/ + +#include "platform/platform.h" +#include +#include + +extern int SDL_SendKeyboardText( const char *text ); + +static qboolean ime_enabled; +static SceWChar16 ime_string[SCE_IME_MAX_TEXT_LENGTH + 1]; + +/* this is dumb but will probably work fine enough */ +static inline void utf2ascii( char *dst, const SceWChar16 *src, unsigned dstsize ) +{ + if ( !src || !dst || !dstsize ) + return; + while ( *src && ( dstsize-- > 0 ) ) + *(dst++) = (*(src++)) & 0xFF; + *dst = 0x00; +} + +static void IME_Open( void ) +{ + SceInt32 res; + SceImeDialogParam param; + + memset( ime_string, 0, sizeof( ime_string ) ); + + sceImeDialogParamInit( ¶m ); + param.supportedLanguages = SCE_IME_LANGUAGE_ENGLISH; + param.languagesForced = SCE_TRUE; + param.type = SCE_IME_TYPE_BASIC_LATIN; + param.title = u"Input text"; + param.maxTextLength = SCE_IME_MAX_TEXT_LENGTH; + param.initialText = (SceWChar16 *)u""; + param.inputTextBuffer = ime_string; + + res = sceImeDialogInit( ¶m ); + if ( res < 0 ) + { + Con_Reportf( S_WARN "Could not open IME keyboard: %d\n", res ); + } + else + { + ime_enabled = true; + } +} + +static void IME_Close( void ) +{ + if ( ime_enabled ) + { + ime_enabled = false; + sceImeDialogTerm( ); + } +} + +static void IME_Update( void ) +{ + char ascii_string[SCE_IME_MAX_TEXT_LENGTH + 2] = { 0 }; + SceImeDialogResult result; + SceCommonDialogStatus status = sceImeDialogGetStatus( ); + if( status == 2 ) + { + memset( &result, 0, sizeof( SceImeDialogResult ) ); + sceImeDialogGetResult( &result ); + if( result.button == SCE_IME_DIALOG_BUTTON_ENTER ) + { + utf2ascii( ascii_string, ime_string, SCE_IME_MAX_TEXT_LENGTH ); + SDL_SendKeyboardText( ascii_string ); + } + IME_Close(); + } +} + +void Platform_EnableTextInput( qboolean enable ) +{ + if ( enable ) + { + if ( ime_enabled ) + IME_Close(); + IME_Open(); + SDL_EventState( SDL_TEXTINPUT, SDL_ENABLE ); + } + else + { + SDL_EventState( SDL_TEXTINPUT, SDL_DISABLE ); + IME_Close(); + } +} + +void PSVita_InputUpdate( void ) +{ + if ( ime_enabled ) + IME_Update(); +} diff --git a/engine/platform/sdl/events.c b/engine/platform/sdl/events.c index bd45bb9d..a71added 100644 --- a/engine/platform/sdl/events.c +++ b/engine/platform/sdl/events.c @@ -671,6 +671,10 @@ void Platform_RunEvents( void ) while( !host.crashed && !host.shutdown_issued && SDL_PollEvent( &event ) ) SDLash_EventFilter( &event ); + +#if XASH_PSVITA + PSVita_InputUpdate(); +#endif } void* Platform_GetNativeObject( const char *name ) diff --git a/engine/platform/sdl/in_sdl.c b/engine/platform/sdl/in_sdl.c index 0603a421..22c32af0 100644 --- a/engine/platform/sdl/in_sdl.c +++ b/engine/platform/sdl/in_sdl.c @@ -126,6 +126,8 @@ void Platform_Vibrate( float time, char flags ) SDL_JoystickRumble( g_joy, 0xFFFF, 0xFFFF, time * 1000.0f ); } +#if !XASH_PSVITA + /* ============= SDLash_EnableTextInput @@ -139,6 +141,8 @@ void Platform_EnableTextInput( qboolean enable ) #endif // SDL_VERSION_ATLEAST( 2, 0, 0 ) } +#endif // !XASH_PSVITA + /* ============= SDLash_JoyInit_Old