Browse Source

Add virtual keyboard support on Switch

pull/497/head
rsn8887 7 years ago committed by Anders Jenbo
parent
commit
d63c61e27c
  1. 1
      CMakeLists.txt
  2. 8
      SourceX/DiabloUI/diabloui.cpp
  3. 79
      SourceX/platform/switch/keyboard.cpp
  4. 3
      SourceX/platform/switch/keyboard.h

1
CMakeLists.txt

@ -283,6 +283,7 @@ set(BIN_TARGET devilutionx)
if(SWITCH)
list(APPEND devilutionx_SRCS
SourceX/platform/switch/keyboard.cpp
SourceX/platform/switch/docking.cpp)
set(BIN_TARGET devilutionx.elf)
endif()

8
SourceX/DiabloUI/diabloui.cpp

@ -16,6 +16,11 @@
#include "DiabloUI/button.h"
#include "DiabloUI/dialogs.h"
#ifdef __SWITCH__
// for virtual keyboard on Switch
#include "platform/switch/keyboard.h"
#endif
namespace dvl {
int SelectedItemMin = 1;
@ -80,6 +85,9 @@ void UiInitList(int min, int max, void (*fnFocus)(int value), void (*fnSelect)(i
SDL_StopTextInput(); // input is enabled by default
for (int i = 0; i < itemCnt; i++) {
if (items[i].type == UI_EDIT) {
#ifdef __SWITCH__
switch_start_text_input(items[i - 1].art_text.text, items[i].edit.value, /*multiline=*/0);
#endif
SDL_StartTextInput();
UiTextInput = items[i].edit.value;
UiTextInputLen = items[i].edit.max_length;

79
SourceX/platform/switch/keyboard.cpp

@ -0,0 +1,79 @@
#include <string.h>
#include <stdbool.h>
#include <switch.h>
#include <SDL.h>
#include "platform/switch/keyboard.h"
static void switch_keyboard_get(const char *guide_text, char *initial_text, int max_len, int multiline, char *buf)
{
Result rc = 0;
SwkbdConfig kbd;
rc = swkbdCreate(&kbd, 0);
if (R_SUCCEEDED(rc)) {
swkbdConfigMakePresetDefault(&kbd);
swkbdConfigSetGuideText(&kbd, guide_text);
swkbdConfigSetInitialText(&kbd, initial_text);
swkbdConfigSetStringLenMax(&kbd, max_len);
rc = swkbdShow(&kbd, buf, max_len);
swkbdClose(&kbd);
}
}
static int get_utf8_character_bytes(const uint8_t *uc)
{
if (uc[0] < 0x80) {
return 1;
} else if ((uc[0] & 0xe0) == 0xc0 && (uc[1] & 0xc0) == 0x80) {
return 2;
} else if ((uc[0] & 0xf0) == 0xe0 && (uc[1] & 0xc0) == 0x80 && (uc[2] & 0xc0) == 0x80) {
return 3;
} else if ((uc[0] & 0xf8) == 0xf0 && (uc[1] & 0xc0) == 0x80 && (uc[2] & 0xc0) == 0x80 && (uc[3] & 0xc0) == 0x80) {
return 4;
} else {
return 1;
}
}
static void switch_create_and_push_sdlkey_event(uint32_t event_type, SDL_Scancode scan, SDL_Keycode key)
{
SDL_Event event;
event.type = event_type;
event.key.keysym.scancode = scan;
event.key.keysym.sym = key;
event.key.keysym.mod = 0;
SDL_PushEvent(&event);
}
void switch_start_text_input(const char *guide_text, char *initial_text, int multiline)
{
char text[65] = {'\0'};
switch_keyboard_get(guide_text, initial_text, 64, multiline, text);
for (int i = 0; i < 600; i++) {
switch_create_and_push_sdlkey_event(SDL_KEYDOWN, SDL_SCANCODE_BACKSPACE, SDLK_BACKSPACE);
switch_create_and_push_sdlkey_event(SDL_KEYUP, SDL_SCANCODE_BACKSPACE, SDLK_BACKSPACE);
}
for (int i = 0; i < 600; i++) {
switch_create_and_push_sdlkey_event(SDL_KEYDOWN, SDL_SCANCODE_DELETE, SDLK_DELETE);
switch_create_and_push_sdlkey_event(SDL_KEYUP, SDL_SCANCODE_DELETE, SDLK_DELETE);
}
if (text[0] == '\0') {
strncpy(text, initial_text, 63);
text[64] = {'\0'};
}
const uint8_t *utf8_text = (uint8_t*) text;
for (int i = 0; i < 599 && utf8_text[i];) {
int bytes_in_char = get_utf8_character_bytes(&utf8_text[i]);
SDL_Event textinput_event;
textinput_event.type = SDL_TEXTINPUT;
for (int n = 0; n < bytes_in_char; n++) {
textinput_event.text.text[n] = text[i + n];
}
textinput_event.text.text[bytes_in_char] = 0;
SDL_PushEvent(&textinput_event);
i += bytes_in_char;
}
}

3
SourceX/platform/switch/keyboard.h

@ -0,0 +1,3 @@
#pragma once
void switch_start_text_input(const char *guide_text, char *initial_text, int multiline);
Loading…
Cancel
Save