Skip to content

Commit

Permalink
Add PVR On Screen Keyboard Support
Browse files Browse the repository at this point in the history
  • Loading branch information
SonicMastr authored and slouken committed Sep 11, 2021
1 parent 67aacfe commit 4435543
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 55 deletions.
46 changes: 25 additions & 21 deletions src/video/vita/SDL_vitagl_pvr.c
Expand Up @@ -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
Expand All @@ -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);
}

Expand Down
3 changes: 3 additions & 0 deletions src/video/vita/SDL_vitakeyboard.c
Expand Up @@ -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);
}

Expand Down
188 changes: 154 additions & 34 deletions src/video/vita/SDL_vitavideo.c
Expand Up @@ -51,8 +51,6 @@
#define VITA_GL_DeleteContext SDL_EGL_DeleteContext
#endif

#include <psp2/ime_dialog.h>

SDL_Window *Vita_Window;

static void
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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));
Expand All @@ -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");
Expand Down Expand Up @@ -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(&param);

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(&param);
if (res < 0) {
SDL_SetError("Failed to init IME");
return;
}

#elif
SceWChar16 *title = u"";
SceWChar16 *text = u"";
SceInt32 res;

SceImeDialogParam param;
sceImeDialogParamInit(&param);
Expand All @@ -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();
Expand All @@ -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();
Expand All @@ -469,6 +588,7 @@ void VITA_PumpEvents(_THIS)
}

}
#endif
}

#endif /* SDL_VIDEO_DRIVER_VITA */
Expand Down
1 change: 1 addition & 0 deletions src/video/vita/SDL_vitavideo.h
Expand Up @@ -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
{
Expand Down

0 comments on commit 4435543

Please sign in to comment.