From 7ab4b072ef95117dcb1d88f03c9e4ae69f67e6ad Mon Sep 17 00:00:00 2001 From: rsn8887 Date: Wed, 21 Mar 2018 15:46:17 -0500 Subject: [PATCH] Vita: touch keyboard in menu, remove translations, smoother pointer --- CMakeLists.txt | 3 +- lib-src/enigma-core/ecl_video.cc | 20 ---- src/gui/MainMenu.cc | 2 - src/gui/Menu.cc | 7 +- src/gui/TextField.cc | 18 +++- src/nls.hh | 7 +- src/psp2/psp2_kbdvita.c | 168 +++++++++++++++++++++++++++++++ src/psp2/psp2_kbdvita.h | 14 +++ src/video.cc | 8 +- 9 files changed, 214 insertions(+), 33 deletions(-) create mode 100644 src/psp2/psp2_kbdvita.c create mode 100644 src/psp2/psp2_kbdvita.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 573038b0c..9e3f664ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ set(SRC_FILES src/psp2/psp2-dirent.c src/psp2/psp2_touch.c src/psp2/psp2_input.c + src/psp2/psp2_kbdvita.c src/AttributeDescriptor.cc src/DOMErrorReporter.cc src/DOMSchemaResolver.cc @@ -369,7 +370,7 @@ set(LDFLAGS vita2d xerces-c curl - SceSysmodule_stub SceDisplay_stub SceGxm_stub + SceSysmodule_stub SceDisplay_stub SceGxm_stub SceAppUtil_stub SceCtrl_stub ScePgf_stub ScePower_stub SceCommonDialog_stub SceAudio_stub SceShellSvc_stub SceHid_stub diff --git a/lib-src/enigma-core/ecl_video.cc b/lib-src/enigma-core/ecl_video.cc index a4d4c8817..f38670b79 100644 --- a/lib-src/enigma-core/ecl_video.cc +++ b/lib-src/enigma-core/ecl_video.cc @@ -30,11 +30,6 @@ #include #include -#ifdef __vita__ -#include -#include -#endif - using namespace ecl; /* -------------------- Graphics primitives -------------------- */ @@ -406,22 +401,7 @@ Surface *ecl::DisplayFormat(Surface *s) { } ecl::Screen *ecl::OpenScreen(int w, int h, int bipp) { -#ifdef __vita__ - SDL_Surface *sfc = SDL_SetVideoMode(w, h, bipp, SDL_HWSURFACE|SDL_DOUBLEBUF); - float sh = (float) 544; - float sw = (float)w*((float)544/(float)h); - int x = (960-sw)/2; - int y = (544-sh)/2; - - SDL_SetVideoModeScaling(x, y, sw, sh); - - //This requires a recent SDL-Vita branch SDL12 for example - //https://github.com/rsn8887/SDL-Vita/tree/SDL12 - //to compile - SDL_SetVideoModeBilinear(1); -#else SDL_Surface *sfc = SDL_SetVideoMode(w, h, bipp, SDL_SWSURFACE); -#endif return new Screen(sfc); } diff --git a/src/gui/MainMenu.cc b/src/gui/MainMenu.cc index c4f821149..c4ba4c3fc 100644 --- a/src/gui/MainMenu.cc +++ b/src/gui/MainMenu.cc @@ -546,8 +546,6 @@ namespace enigma { namespace gui { void MainMenu::tick(double /* dtime */) { #ifdef __vita__ -// display::RedrawAll(video::GetScreen()); -// SDL_Flip(video::GetScreen()->get_surface()->get_surface()); return; #else bool isFullScreen = app.prefs->getBool("FullScreen"); diff --git a/src/gui/Menu.cc b/src/gui/Menu.cc index 345cf7932..293ecd8cb 100644 --- a/src/gui/Menu.cc +++ b/src/gui/Menu.cc @@ -100,12 +100,11 @@ namespace enigma { namespace gui { if(key_focus_widget && (key_focus_widget != active_widget)) key_focus_widget->tick(0.01); tick(0.01); #ifdef __vita__ - static double totalTime = 0; - totalTime += 10; - if (totalTime > 16) { - totalTime = 0; + static Uint32 last_menu_draw_time = 0; + if (SDL_GetTicks() - last_menu_draw_time > 10) { PSP2_HandleJoysticks(); SDL_Flip(SCREEN->get_surface()->get_surface()); + last_menu_draw_time = SDL_GetTicks(); } #endif sound::MusicTick(0.01); diff --git a/src/gui/TextField.cc b/src/gui/TextField.cc index 69f7ab01c..cce710d8c 100644 --- a/src/gui/TextField.cc +++ b/src/gui/TextField.cc @@ -32,6 +32,10 @@ #include #include +#ifdef __vita__ +#include "psp2_kbdvita.h" +#endif + using namespace enigma::gui; using namespace ecl; using namespace std; @@ -128,9 +132,21 @@ bool TextField::on_event(const SDL_Event &e) { bool modified = false; switch (e.type) { - case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONDOWN: { // set cursor +#ifdef __vita__ + handeled = true; + std::string newText = ""; + char *imeResult = kbdvita_get("Enter Text", const_cast(getText().c_str()), 255); + if (imeResult != NULL) { + newText = imeResult; + set_text(newText); + invalidate(); + modified = true; + } +#endif break; + } case SDL_KEYDOWN: switch (e.key.keysym.sym) { case SDLK_RETURN: diff --git a/src/nls.hh b/src/nls.hh index 09871e40f..98d6f1728 100644 --- a/src/nls.hh +++ b/src/nls.hh @@ -23,7 +23,11 @@ namespace nls const char *localename; const char *flagimage; }; - + #ifdef __vita__ + const Language languages[] = { + { "default", "", "par" }, + }; +#else const Language languages[] = { { "default", "", "par" }, { "беларуская", "be_BY", "flags25x15/by" }, @@ -47,6 +51,7 @@ namespace nls { "Slovenčina", "sk_SK", "flags25x15/sk" }, { "українська", "uk_UA", "flags25x15/ua" }, }; +#endif } #endif diff --git a/src/psp2/psp2_kbdvita.c b/src/psp2/psp2_kbdvita.c new file mode 100644 index 000000000..876f9a6d0 --- /dev/null +++ b/src/psp2/psp2_kbdvita.c @@ -0,0 +1,168 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "psp2_kbdvita.h" + +#define IME_DIALOG_RESULT_NONE 0 +#define IME_DIALOG_RESULT_RUNNING 1 +#define IME_DIALOG_RESULT_FINISHED 2 +#define IME_DIALOG_RESULT_CANCELED 3 + +static int ime_dialog_running = 0; +static int ime_dialog_option = 0; +static int ime_init_apputils = 0; + +static uint16_t ime_title_utf16[SCE_IME_DIALOG_MAX_TITLE_LENGTH]; +static uint16_t ime_initial_text_utf16[SCE_IME_DIALOG_MAX_TEXT_LENGTH]; +static uint16_t ime_input_text_utf16[SCE_IME_DIALOG_MAX_TEXT_LENGTH + 1]; +static uint8_t ime_input_text_utf8[SCE_IME_DIALOG_MAX_TEXT_LENGTH + 1]; + +void utf16_to_utf8(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'; +} + +void utf8_to_utf16(uint8_t *src, uint16_t *dst) { + int i; + for (i = 0; src[i];) { + if ((src[i] & 0xE0) == 0xE0) { + *(dst++) = ((src[i] & 0x0F) << 12) | ((src[i + 1] & 0x3F) << 6) | (src[i + 2] & 0x3F); + i += 3; + } else if ((src[i] & 0xC0) == 0xC0) { + *(dst++) = ((src[i] & 0x1F) << 6) | (src[i + 1] & 0x3F); + i += 2; + } else { + *(dst++) = src[i]; + i += 1; + } + } + + *dst = '\0'; +} + +int initImeDialog(char *title, char *initial_text, int max_text_length, int type, int option) { + if (ime_dialog_running) + return -1; + + // Convert UTF8 to UTF16 + utf8_to_utf16((uint8_t *)title, ime_title_utf16); + utf8_to_utf16((uint8_t *)initial_text, ime_initial_text_utf16); + + SceImeDialogParam param; + sceImeDialogParamInit(¶m); + + param.supportedLanguages = 0x0001FFFF; + param.languagesForced = SCE_TRUE; + param.type = type; + param.option = option; + if (option == SCE_IME_OPTION_MULTILINE) + param.dialogMode = SCE_IME_DIALOG_DIALOG_MODE_WITH_CANCEL; + param.title = ime_title_utf16; + param.maxTextLength = max_text_length; + param.initialText = ime_initial_text_utf16; + param.inputTextBuffer = ime_input_text_utf16; + + int res = sceImeDialogInit(¶m); + if (res >= 0) { + ime_dialog_running = 1; + ime_dialog_option = option; + } + + return res; +} + +int isImeDialogRunning() { + return ime_dialog_running; +} + +uint16_t *getImeDialogInputTextUTF16() { + return ime_input_text_utf16; +} + +uint8_t *getImeDialogInputTextUTF8() { + return ime_input_text_utf8; +} + +int updateImeDialog() { + if (!ime_dialog_running) + return IME_DIALOG_RESULT_NONE; + + SceCommonDialogStatus status = sceImeDialogGetStatus(); + if (status == IME_DIALOG_RESULT_FINISHED) { + SceImeDialogResult result; + memset(&result, 0, sizeof(SceImeDialogResult)); + sceImeDialogGetResult(&result); + + if ((ime_dialog_option == SCE_IME_OPTION_MULTILINE && result.button == SCE_IME_DIALOG_BUTTON_CLOSE) || + (ime_dialog_option != SCE_IME_OPTION_MULTILINE && result.button == SCE_IME_DIALOG_BUTTON_ENTER)) { + // Convert UTF16 to UTF8 + utf16_to_utf8(ime_input_text_utf16, ime_input_text_utf8); + } else { + status = IME_DIALOG_RESULT_CANCELED; + } + + sceImeDialogTerm(); + + ime_dialog_running = 0; + } + + return status; +} + +char *kbdvita_get(char *title, char *initial_text, int maxLen) { + char *name = NULL; + + if (ime_init_apputils == 0) { + sceAppUtilInit(&(SceAppUtilInitParam){}, &(SceAppUtilBootParam){}); + sceCommonDialogSetConfigParam(&(SceCommonDialogConfigParam){}); + ime_init_apputils = 1; + } + + initImeDialog(title, initial_text, maxLen, SCE_IME_TYPE_BASIC_LATIN, 0); + + bool done; + do { + vita2d_start_drawing(); + vita2d_clear_screen(); + + done = true; + + int ime_result = updateImeDialog(); + if (ime_result == IME_DIALOG_RESULT_FINISHED) { + name = (char *)getImeDialogInputTextUTF8(); + } else if (ime_result != IME_DIALOG_RESULT_CANCELED) { + done = false; + } + + vita2d_end_drawing(); + vita2d_common_dialog_update(); + vita2d_swap_buffers(); + sceDisplayWaitVblankStart(); + } while (!done); + + return name; +} diff --git a/src/psp2/psp2_kbdvita.h b/src/psp2/psp2_kbdvita.h new file mode 100644 index 000000000..470d9585f --- /dev/null +++ b/src/psp2/psp2_kbdvita.h @@ -0,0 +1,14 @@ +#ifndef __KEYBOARD_VITA_H__ +#define __KEYBOARD_VITA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +char *kbdvita_get(char *title, char *initial_text, int maxLen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/video.cc b/src/video.cc index 68eb7b9b1..9407b8017 100644 --- a/src/video.cc +++ b/src/video.cc @@ -138,11 +138,11 @@ bool Video_SDL::init(int w, int h, int bpp, bool fullscreen) { SDL_SetVideoModeScaling(x, y, sw, sh); //This requires a recent SDL-Vita branch SDL12 for example - //https://github.com/rsn8887/SDL-Vita/tree/SDL12 - //to compile - SDL_SetVideoModeBilinear(1); + //https://github.com/rsn8887/SDL-Vita/tree/SDL12 + //to compile + SDL_SetVideoModeBilinear(1); - SDL_SetVideoModeSync(1); + SDL_SetVideoModeSync(1); #else sdlScreen = SDL_SetVideoMode(w, h, bpp, flags); #endif