From 4435543db121861797666369647e2fe42b44b7bb Mon Sep 17 00:00:00 2001
From: Jaylon Gowie <[EMAIL REDACTED]>
Date: Fri, 10 Sep 2021 20:01:40 -0500
Subject: [PATCH] Add PVR On Screen Keyboard Support
---
src/video/vita/SDL_vitagl_pvr.c | 46 ++++----
src/video/vita/SDL_vitakeyboard.c | 3 +
src/video/vita/SDL_vitavideo.c | 188 ++++++++++++++++++++++++------
src/video/vita/SDL_vitavideo.h | 1 +
4 files changed, 183 insertions(+), 55 deletions(-)
diff --git a/src/video/vita/SDL_vitagl_pvr.c b/src/video/vita/SDL_vitagl_pvr.c
index e85b489668..1cc337121a 100644
--- a/src/video/vita/SDL_vitagl_pvr.c
+++ b/src/video/vita/SDL_vitagl_pvr.c
@@ -37,34 +37,34 @@
int
VITA_GL_LoadLibrary(_THIS, const char *path)
{
- PVRSRV_PSP2_APPHINT hint;
- char* override = SDL_getenv("VITA_MODULE_PATH");
- char* default_path = "app0:module";
- char target_path[MAX_PATH];
-
- if (override != NULL)
- {
- default_path = override;
- }
+ PVRSRV_PSP2_APPHINT hint;
+ char* override = SDL_getenv("VITA_MODULE_PATH");
+ char* default_path = "app0:module";
+ char target_path[MAX_PATH];
+
+ if (override != NULL)
+ {
+ default_path = override;
+ }
- sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL);
- sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL);
+ sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL);
+ sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL);
- SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx");
- sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
+ SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx");
+ sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
- SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libIMGEGL.suprx");
- sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
+ SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libIMGEGL.suprx");
+ sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
- PVRSRVInitializeAppHint(&hint);
+ PVRSRVInitializeAppHint(&hint);
- SDL_snprintf(hint.szGLES1, MAX_PATH, "%s/%s", default_path, "libGLESv1_CM.suprx");
- SDL_snprintf(hint.szGLES2, MAX_PATH, "%s/%s", default_path, "libGLESv2.suprx");
- SDL_snprintf(hint.szWindowSystem, MAX_PATH, "%s/%s", default_path, "libpvrPSP2_WSEGL.suprx");
+ SDL_snprintf(hint.szGLES1, MAX_PATH, "%s/%s", default_path, "libGLESv1_CM.suprx");
+ SDL_snprintf(hint.szGLES2, MAX_PATH, "%s/%s", default_path, "libGLESv2.suprx");
+ SDL_snprintf(hint.szWindowSystem, MAX_PATH, "%s/%s", default_path, "libpvrPSP2_WSEGL.suprx");
- PVRSRVCreateVirtualAppHint(&hint);
+ PVRSRVCreateVirtualAppHint(&hint);
- return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) 0, 0);
+ return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) 0, 0);
}
SDL_GLContext
@@ -86,6 +86,10 @@ VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
int
VITA_GL_SwapWindow(_THIS, SDL_Window * window)
{
+ SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+ if (videodata->ime_active) {
+ sceImeUpdate();
+ }
return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
}
diff --git a/src/video/vita/SDL_vitakeyboard.c b/src/video/vita/SDL_vitakeyboard.c
index 2f6679b521..a4e9e21f0a 100644
--- a/src/video/vita/SDL_vitakeyboard.c
+++ b/src/video/vita/SDL_vitakeyboard.c
@@ -42,6 +42,9 @@ Uint8 lock_key_down = 0;
void
VITA_InitKeyboard(void)
{
+#if defined(SDL_VIDEO_VITA_PVR)
+ sceSysmoduleLoadModule(SCE_SYSMODULE_IME); /** For PVR OSK Support **/
+#endif
sceHidKeyboardEnumerate(&keyboard_hid_handle, 1);
}
diff --git a/src/video/vita/SDL_vitavideo.c b/src/video/vita/SDL_vitavideo.c
index b5ece3bee7..89966cb814 100644
--- a/src/video/vita/SDL_vitavideo.c
+++ b/src/video/vita/SDL_vitavideo.c
@@ -51,8 +51,6 @@
#define VITA_GL_DeleteContext SDL_EGL_DeleteContext
#endif
-#include <psp2/ime_dialog.h>
-
SDL_Window *Vita_Window;
static void
@@ -176,11 +174,32 @@ VITA_VideoInit(_THIS)
{
SDL_VideoDisplay display;
SDL_DisplayMode current_mode;
-
+#if defined(SDL_VIDEO_VITA_PVR)
+ char* res = SDL_getenv("VITA_RESOLUTION");
+#endif
SDL_zero(current_mode);
- current_mode.w = 960;
- current_mode.h = 544;
+#if defined(SDL_VIDEO_VITA_PVR)
+ if (res) {
+ /* 1088i for PSTV (Or Sharpscale) */
+ if (!SDL_strncmp(res, "1080", 4)) {
+ current_mode.w = 1920;
+ current_mode.h = 1088;
+ }
+ /* 725p for PSTV (Or Sharpscale) */
+ else if (!SDL_strncmp(res, "720", 3)) {
+ current_mode.w = 1280;
+ current_mode.h = 725;
+ }
+ }
+ /* 544p */
+ else {
+#endif
+ current_mode.w = 960;
+ current_mode.h = 544;
+#if defined(SDL_VIDEO_VITA_PVR)
+ }
+#endif
current_mode.refresh_rate = 60;
/* 32 bpp for default */
@@ -223,6 +242,9 @@ int
VITA_CreateWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *wdata;
+#if defined(SDL_VIDEO_VITA_PVR)
+ Psp2NativeWindow win;
+#endif
/* Allocate window internal data */
wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
@@ -243,8 +265,24 @@ VITA_CreateWindow(_THIS, SDL_Window * window)
Vita_Window = window;
#if defined(SDL_VIDEO_VITA_PVR)
+ win.type = PSP2_DRAWABLE_TYPE_WINDOW;
+ win.numFlipBuffers = 2;
+ win.flipChainThrdAffinity = 0x20000;
+
+ /* 1088i for PSTV (Or Sharpscale) */
+ if (window->w == 1920) {
+ win.windowSize = PSP2_WINDOW_1920X1088;
+ }
+ /* 725p for PSTV (Or Sharpscale) */
+ else if (window->w == 1280) {
+ win.windowSize = PSP2_WINDOW_1280X725;
+ }
+ /* 544p */
+ else {
+ win.windowSize = PSP2_WINDOW_960X544;
+ }
if ((window->flags & SDL_WINDOW_OPENGL) != 0) {
- wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) 0);
+ wdata->egl_surface = SDL_EGL_CreateSurface(_this, &win);
if (wdata->egl_surface == EGL_NO_SURFACE) {
return SDL_SetError("Could not create GLES window surface");
@@ -353,13 +391,109 @@ SDL_bool VITA_HasScreenKeyboardSupport(_THIS)
#define SCE_IME_LANGUAGE_ENGLISH_US SCE_IME_LANGUAGE_ENGLISH
#endif
+static void utf16_to_utf8(const uint16_t *src, uint8_t *dst) {
+ int i;
+ for (i = 0; src[i]; i++) {
+ if ((src[i] & 0xFF80) == 0) {
+ *(dst++) = src[i] & 0xFF;
+ } else if((src[i] & 0xF800) == 0) {
+ *(dst++) = ((src[i] >> 6) & 0xFF) | 0xC0;
+ *(dst++) = (src[i] & 0x3F) | 0x80;
+ } else if((src[i] & 0xFC00) == 0xD800 && (src[i + 1] & 0xFC00) == 0xDC00) {
+ *(dst++) = (((src[i] + 64) >> 8) & 0x3) | 0xF0;
+ *(dst++) = (((src[i] >> 2) + 16) & 0x3F) | 0x80;
+ *(dst++) = ((src[i] >> 4) & 0x30) | 0x80 | ((src[i + 1] << 2) & 0xF);
+ *(dst++) = (src[i + 1] & 0x3F) | 0x80;
+ i += 1;
+ } else {
+ *(dst++) = ((src[i] >> 12) & 0xF) | 0xE0;
+ *(dst++) = ((src[i] >> 6) & 0x3F) | 0x80;
+ *(dst++) = (src[i] & 0x3F) | 0x80;
+ }
+ }
+
+ *dst = '\0';
+}
+
+#if defined (SDL_VIDEO_VITA_PVR)
+SceWChar16 libime_out[SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1];
+char libime_initval[8] = { 1 };
+SceImeCaret caret_rev;
+
+void VITA_ImeEventHandler(void *arg, const SceImeEventData *e)
+{
+ SDL_VideoData *videodata = (SDL_VideoData *)arg;
+ SDL_Scancode scancode;
+ uint8_t utf8_buffer[SCE_IME_MAX_TEXT_LENGTH];
+ switch (e->id) {
+ case SCE_IME_EVENT_UPDATE_TEXT:
+ if (e->param.text.caretIndex == 0) {
+ scancode = SDL_GetScancodeFromKey(0x08);
+ SDL_SendKeyboardKeyAutoRelease(scancode);
+ sceImeSetText((SceWChar16 *)libime_initval, 4);
+ }
+ else {
+ scancode = SDL_GetScancodeFromKey(*(SceWChar16 *)&libime_out[1]);
+ if (scancode == SDL_SCANCODE_SPACE) {
+ SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_SPACE);
+ }
+ else {
+ utf16_to_utf8((SceWChar16 *)&libime_out[1], utf8_buffer);
+ SDL_SendKeyboardText((const char*)utf8_buffer);
+ }
+ SDL_memset(&caret_rev, 0, sizeof(SceImeCaret));
+ SDL_memset(libime_out, 0, ((SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1) * sizeof(SceWChar16)));
+ caret_rev.index = 1;
+ sceImeSetCaret(&caret_rev);
+ sceImeSetText((SceWChar16 *)libime_initval, 4);
+ }
+ break;
+ case SCE_IME_EVENT_PRESS_ENTER:
+ scancode = SDL_GetScancodeFromKey(0x0D);
+ SDL_SendKeyboardKeyAutoRelease(scancode);
+ case SCE_IME_EVENT_PRESS_CLOSE:
+ sceImeClose();
+ videodata->ime_active = SDL_FALSE;
+ break;
+ }
+}
+#endif
+
void VITA_ShowScreenKeyboard(_THIS, SDL_Window *window)
{
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+ SceInt32 res;
+
+#if defined(SDL_VIDEO_VITA_PVR)
+
+ SceUInt32 libime_work[SCE_IME_WORK_BUFFER_SIZE / sizeof(SceInt32)];
+ SceImeParam param;
+ sceImeParamInit(¶m);
+
+ SDL_memset(libime_out, 0, ((SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1) * sizeof(SceWChar16)));
+
+ param.supportedLanguages = SCE_IME_LANGUAGE_ENGLISH_US;
+ param.languagesForced = SCE_FALSE;
+ param.type = SCE_IME_TYPE_DEFAULT;
+ param.option = SCE_IME_OPTION_NO_ASSISTANCE;
+ param.inputTextBuffer = libime_out;
+ param.maxTextLength = SCE_IME_MAX_TEXT_LENGTH;
+ param.handler = VITA_ImeEventHandler;
+ param.filter = NULL;
+ param.initialText = (SceWChar16 *)libime_initval;
+ param.arg = videodata;
+ param.work = libime_work;
+
+ res = sceImeOpen(¶m);
+ if (res < 0) {
+ SDL_SetError("Failed to init IME");
+ return;
+ }
+
+#elif
SceWChar16 *title = u"";
SceWChar16 *text = u"";
- SceInt32 res;
SceImeDialogParam param;
sceImeDialogParamInit(¶m);
@@ -381,11 +515,14 @@ void VITA_ShowScreenKeyboard(_THIS, SDL_Window *window)
return;
}
+#endif
+
videodata->ime_active = SDL_TRUE;
}
void VITA_HideScreenKeyboard(_THIS, SDL_Window *window)
{
+#if !defined(SDL_VIDEO_VITA_PVR)
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus();
@@ -401,48 +538,30 @@ void VITA_HideScreenKeyboard(_THIS, SDL_Window *window)
}
videodata->ime_active = SDL_FALSE;
+#endif
}
SDL_bool VITA_IsScreenKeyboardShown(_THIS, SDL_Window *window)
{
+#if defined(SDL_VIDEO_VITA_PVR)
+ SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+ return videodata->ime_active;
+#elif
SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus();
return (dialogStatus == SCE_COMMON_DIALOG_STATUS_RUNNING);
-}
-
-
-static void utf16_to_utf8(const uint16_t *src, uint8_t *dst) {
- int i;
- for (i = 0; src[i]; i++) {
- if ((src[i] & 0xFF80) == 0) {
- *(dst++) = src[i] & 0xFF;
- } else if((src[i] & 0xF800) == 0) {
- *(dst++) = ((src[i] >> 6) & 0xFF) | 0xC0;
- *(dst++) = (src[i] & 0x3F) | 0x80;
- } else if((src[i] & 0xFC00) == 0xD800 && (src[i + 1] & 0xFC00) == 0xDC00) {
- *(dst++) = (((src[i] + 64) >> 8) & 0x3) | 0xF0;
- *(dst++) = (((src[i] >> 2) + 16) & 0x3F) | 0x80;
- *(dst++) = ((src[i] >> 4) & 0x30) | 0x80 | ((src[i + 1] << 2) & 0xF);
- *(dst++) = (src[i + 1] & 0x3F) | 0x80;
- i += 1;
- } else {
- *(dst++) = ((src[i] >> 12) & 0xF) | 0xE0;
- *(dst++) = ((src[i] >> 6) & 0x3F) | 0x80;
- *(dst++) = (src[i] & 0x3F) | 0x80;
- }
- }
-
- *dst = '\0';
+#endif
}
void VITA_PumpEvents(_THIS)
{
+#if !defined(SDL_VIDEO_VITA_PVR)
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
-
-
+#endif
VITA_PollTouch();
VITA_PollKeyboard();
VITA_PollMouse();
+#if !defined(SDL_VIDEO_VITA_PVR)
if (videodata->ime_active == SDL_TRUE) {
// update IME status. Terminate, if finished
SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus();
@@ -469,6 +588,7 @@ void VITA_PumpEvents(_THIS)
}
}
+#endif
}
#endif /* SDL_VIDEO_DRIVER_VITA */
diff --git a/src/video/vita/SDL_vitavideo.h b/src/video/vita/SDL_vitavideo.h
index b63b1d8369..b2c60294b2 100644
--- a/src/video/vita/SDL_vitavideo.h
+++ b/src/video/vita/SDL_vitavideo.h
@@ -29,6 +29,7 @@
#include <psp2/types.h>
#include <psp2/display.h>
#include <psp2/ime_dialog.h>
+#include <psp2/sysmodule.h>
typedef struct SDL_VideoData
{