mGUI: Initial OSK support

This commit is contained in:
Vicki Pfau 2021-04-23 00:20:48 -07:00
parent 926e8fcccb
commit 4ba921ccc5
6 changed files with 127 additions and 0 deletions

View File

@ -14,6 +14,9 @@ CXX_GUARD_START
#include <mgba/core/input.h>
#include <mgba-util/vector.h>
#define MAX_KEYBOARD_LEN 256
#define MAX_KEYBOARD_TITLE_LEN 128
struct GUIFont;
enum GUIInput {
@ -40,6 +43,11 @@ enum GUICursorState {
GUI_CURSOR_DRAGGING
};
enum GUIKeyboardStatus {
GUI_KEYBOARD_DONE = 0,
GUI_KEYBOARD_CANCEL,
};
enum {
BATTERY_EMPTY = 0,
BATTERY_LOW = 25,
@ -57,6 +65,13 @@ struct GUIBackground {
void (*draw)(struct GUIBackground*, void* context);
};
struct GUIKeyboardParams {
char title[MAX_KEYBOARD_TITLE_LEN];
char result[MAX_KEYBOARD_LEN];
size_t maxLen;
bool multiline;
};
struct GUIParams {
unsigned width;
unsigned height;
@ -70,6 +85,7 @@ struct GUIParams {
int (*batteryState)(void);
void (*guiPrepare)(void);
void (*guiFinish)(void);
enum GUIKeyboardStatus (*getText)(struct GUIKeyboardParams*);
// State
struct mInputMap keyMap;
@ -87,6 +103,8 @@ void GUIPollInput(struct GUIParams* params, uint32_t* newInput, uint32_t* heldIn
enum GUICursorState GUIPollCursor(struct GUIParams* params, unsigned* x, unsigned* y);
void GUIInvalidateKeys(struct GUIParams* params);
void GUIKeyboardParamsInit(struct GUIKeyboardParams*);
CXX_GUARD_END
#endif

View File

@ -797,6 +797,22 @@ static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* rig
}
}
static enum GUIKeyboardStatus _keyboardRun(struct GUIKeyboardParams* keyboard) {
SwkbdState swkbd;
swkbdInit(&swkbd, SWKBD_TYPE_NORMAL, 2, keyboard->maxLen);
swkbdSetInitialText(&swkbd, keyboard->result);
if (keyboard->multiline) {
swkbdSetFeatures(&swkbd, SWKBD_MULTILINE);
}
SwkbdButton button = swkbdInputText(&swkbd, keyboard->result, sizeof( keyboard->result));
if (button == SWKBD_BUTTON_CONFIRM) {
return GUI_KEYBOARD_DONE;
} else {
return GUI_KEYBOARD_CANCEL;
}
}
THREAD_ENTRY _core2Test(void* context) {
UNUSED(context);
}
@ -892,6 +908,7 @@ int main() {
_pollInput, _pollCursor,
_batteryState,
_guiPrepare, _guiFinish,
_keyboardRun,
},
.keySources = (struct GUIInputKeys[]) {
{

View File

@ -22,6 +22,7 @@ set(OS_LIB -lvita2d -l${M_LIBRARY}
-lSceCtrl_stub
-lSceDisplay_stub
-lSceGxm_stub
-lSceIme_stub
-lSceMotion_stub
-lScePgf_stub
-lScePhotoExport_stub

View File

@ -11,10 +11,12 @@
#include <mgba-util/gui/font.h>
#include <mgba-util/gui/file-select.h>
#include <mgba-util/gui/menu.h>
#include <mgba-util/string.h>
#include <psp2/apputil.h>
#include <psp2/ctrl.h>
#include <psp2/display.h>
#include <psp2/ime_dialog.h>
#include <psp2/kernel/processmgr.h>
#include <psp2/kernel/threadmgr.h>
#include <psp2/power.h>
@ -36,6 +38,7 @@ static void _drawStart(void) {
static void _drawEnd(void) {
vita2d_end_drawing();
vita2d_common_dialog_update();
vita2d_swap_buffers();
}
@ -81,6 +84,66 @@ static int _batteryState(void) {
return state | charge;
}
static enum GUIKeyboardStatus _keyboardRun(struct GUIKeyboardParams* keyboard) {
SceImeDialogParam params;
sceImeDialogParamInit(&params);
params.supportedLanguages = 0x0001FFFF;
params.languagesForced = SCE_TRUE;
params.type = SCE_IME_TYPE_DEFAULT;
params.option = 0;
if (keyboard->multiline) {
params.option = SCE_IME_OPTION_MULTILINE;
}
params.dialogMode = SCE_IME_DIALOG_DIALOG_MODE_WITH_CANCEL;
params.maxTextLength = keyboard->maxLen;
params.title = calloc(sizeof(SceWChar16), MAX_KEYBOARD_TITLE_LEN + 1);
params.inputTextBuffer = calloc(sizeof(SceWChar16), keyboard->maxLen + 1);
params.initialText = calloc(sizeof(SceWChar16), keyboard->maxLen + 1);
uint16_t* utf16Buffer = params.initialText;
char* utf8Buffer = keyboard->result;
size_t i = keyboard->maxLen;
while (i > 0 && *utf8Buffer) {
uint32_t unichar = utf8Char((const char**) &utf8Buffer, &i);
utf16Buffer += toUtf16(unichar, utf16Buffer);
}
utf16Buffer = params.title;
utf8Buffer = keyboard->title;
i = MAX_KEYBOARD_TITLE_LEN;
while (i > 0 && *utf8Buffer) {
uint32_t unichar = utf8Char((const char**) &utf8Buffer, &i);
utf16Buffer += toUtf16(unichar, utf16Buffer);
}
sceImeDialogInit(&params);
SceCommonDialogStatus status = SCE_COMMON_DIALOG_STATUS_RUNNING;
while (status == SCE_COMMON_DIALOG_STATUS_RUNNING) {
_drawStart();
status = sceImeDialogGetStatus();
_drawEnd();
}
SceImeDialogResult result;
memset(&result, 0, sizeof(SceImeDialogResult));
sceImeDialogGetResult(&result);
sceImeDialogTerm();
utf16Buffer = params.inputTextBuffer;
utf8Buffer = keyboard->result;
i = keyboard->maxLen;
while (i > 0 && *utf16Buffer) {
uint32_t unichar = utf16Char((const uint16_t**) &utf16Buffer, &i);
utf8Buffer += toUtf8(unichar, utf8Buffer);
}
utf8Buffer[0] = 0;
free(params.initialText);
free(params.inputTextBuffer);
return result.button == SCE_IME_DIALOG_BUTTON_ENTER ? GUI_KEYBOARD_DONE : GUI_KEYBOARD_CANCEL;
}
int main() {
vita2d_init();
struct GUIFont* font = GUIFontCreate();
@ -92,6 +155,7 @@ int main() {
_pollInput, _pollCursor,
_batteryState,
0, 0,
_keyboardRun,
},
.configExtra = (struct GUIMenuItem[]) {
{
@ -167,6 +231,7 @@ int main() {
sceCtrlSetSamplingModeExt(SCE_CTRL_MODE_ANALOG_WIDE);
sceSysmoduleLoadModule(SCE_SYSMODULE_PHOTO_EXPORT);
sceSysmoduleLoadModule(SCE_SYSMODULE_APPUTIL);
sceSysmoduleLoadModule(SCE_SYSMODULE_IME);
mGUIInit(&runner, "psvita");

View File

@ -674,6 +674,24 @@ static void _guiFinish(void) {
GUIFontDrawSubmit(font);
}
static enum GUIKeyboardStatus _keyboardRun(struct GUIKeyboardParams* keyboard) {
SwkbdConfig swkbd;
swkbdCreate(&swkbd, 0);
swkbdConfigMakePresetDefault(&swkbd);
swkbdConfigSetStringLenMax(&swkbd, keyboard->maxLen);
swkbdConfigSetInitialText(&swkbd, keyboard->result);
swkbdConfigSetHeaderText(&swkbd, keyboard->title);
swkbdConfigSetReturnButtonFlag(&swkbd, keyboard->multiline);
Result rc = swkbdShow(&swkbd, keyboard->result, sizeof(keyboard->result));
swkbdClose(&swkbd);
if (R_SUCCEEDED(rc)) {
return GUI_KEYBOARD_DONE;
} else {
return GUI_KEYBOARD_CANCEL;
}
}
static void glInit(void) {
glViewport(0, 1080 - vheight, vwidth, vheight);
glClearColor(0.f, 0.f, 0.f, 1.f);
@ -865,6 +883,7 @@ int main(int argc, char* argv[]) {
_pollInput, _pollCursor,
_batteryState,
_guiPrepare, _guiFinish,
_keyboardRun,
},
.keySources = (struct GUIInputKeys[]) {
{

View File

@ -72,3 +72,10 @@ void GUIInvalidateKeys(struct GUIParams* params) {
params->inputHistory[i] = 0;
}
}
void GUIKeyboardParamsInit(struct GUIKeyboardParams* keyboard) {
memset(keyboard->title, 0, sizeof(keyboard->title));
memset(keyboard->result, 0, sizeof(keyboard->result));
keyboard->maxLen = sizeof(keyboard->result);
keyboard->multiline = false;
}