You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.3 KiB
119 lines
3.3 KiB
#include <cstring> |
|
|
|
#include <SDL.h> |
|
#include <psp2/types.h> |
|
#include <psp2/ime_dialog.h> |
|
#include "platform/vita/keyboard.h" |
|
|
|
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'; |
|
} |
|
|
|
static void utf8_to_utf16(const 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'; |
|
} |
|
|
|
static int vita_input_thread(void *ime_buffer) |
|
{ |
|
while (1) { |
|
// update IME status. Terminate, if finished |
|
SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); |
|
if (dialogStatus == SCE_COMMON_DIALOG_STATUS_FINISHED) { |
|
uint8_t utf8_buffer[SCE_IME_DIALOG_MAX_TEXT_LENGTH]; |
|
SceImeDialogResult result; |
|
|
|
SDL_memset(&result, 0, sizeof(SceImeDialogResult)); |
|
sceImeDialogGetResult(&result); |
|
|
|
// Convert UTF16 to UTF8 |
|
utf16_to_utf8((SceWChar16 *)ime_buffer, utf8_buffer); |
|
|
|
// send sdl event |
|
SDL_Event event; |
|
event.text.type = SDL_TEXTINPUT; |
|
SDL_utf8strlcpy(event.text.text, (const char *)utf8_buffer, SDL_arraysize(event.text.text)); |
|
SDL_PushEvent(&event); |
|
|
|
sceImeDialogTerm(); |
|
break; |
|
} |
|
} |
|
return 0; |
|
} |
|
|
|
static int vita_keyboard_get(const char *guide_text, const char *initial_text, int max_len, SceWChar16 *buf) |
|
{ |
|
SceWChar16 title[SCE_IME_DIALOG_MAX_TITLE_LENGTH]; |
|
SceWChar16 text[SCE_IME_DIALOG_MAX_TEXT_LENGTH]; |
|
SceInt32 res; |
|
|
|
SDL_memset(&title, 0, sizeof(title)); |
|
SDL_memset(&text, 0, sizeof(text)); |
|
utf8_to_utf16((const uint8_t *)guide_text, title); |
|
utf8_to_utf16((const uint8_t *)initial_text, text); |
|
|
|
SceImeDialogParam param; |
|
sceImeDialogParamInit(¶m); |
|
|
|
param.supportedLanguages = SCE_IME_LANGUAGE_ENGLISH; |
|
param.languagesForced = SCE_FALSE; |
|
param.type = SCE_IME_TYPE_DEFAULT; |
|
param.option = 0; |
|
param.textBoxMode = SCE_IME_DIALOG_TEXTBOX_MODE_WITH_CLEAR; |
|
param.maxTextLength = max_len; |
|
|
|
param.title = title; |
|
param.initialText = text; |
|
param.inputTextBuffer = buf; |
|
|
|
res = sceImeDialogInit(¶m); |
|
if (res < 0) { |
|
return 0; |
|
} |
|
|
|
return 1; |
|
} |
|
|
|
void vita_start_text_input(const char *guide_text, const char *initial_text, int max_length) |
|
{ |
|
SceWChar16 ime_buffer[SCE_IME_DIALOG_MAX_TEXT_LENGTH]; |
|
if (vita_keyboard_get(guide_text, initial_text, max_length, ime_buffer)) { |
|
SDL_CreateThread(vita_input_thread, "vita_input_thread", (void *)ime_buffer); |
|
} |
|
}
|
|
|