forked from Ports/perfect_dark
port: simplify the keyboard input a bit and match it to port-net's
backspace key now repeats properly TYPE WITH KEYBOARD changes into a tooltip when typing players with controllers are allowed to type, because that seems more convenient players 2, 3 and 4 are allowed to type too if they hit the button, but only one player can have keyboard focus at a time
This commit is contained in:
1 parent
a05c4290f5
commit
5084b4be39
5 files changed
+242
-245
No files matched your search
+37
-17
@@ -19,10 +19,29 @@
|
||||
enum virtkey {
|
||||
/* same order as SDL scancodes */
|
||||
VK_KEYBOARD_BEGIN = 0,
|
||||
VK_A = 4,
|
||||
VK_Z = 29,
|
||||
VK_1 = 30,
|
||||
VK_9 = 38,
|
||||
VK_0 = 39,
|
||||
VK_RETURN = 40,
|
||||
VK_ESCAPE = 41,
|
||||
VK_BACKSPACE = 42,
|
||||
VK_SPACE = 44,
|
||||
VK_MINUS = 45,
|
||||
VK_LEFTBRACKET = 47,
|
||||
VK_RIGHTBRACKET = 48,
|
||||
VK_SEMICOLON = 51,
|
||||
VK_GRAVE = 53,
|
||||
VK_COMMA = 54,
|
||||
VK_PERIOD = 55,
|
||||
VK_F1 = 58,
|
||||
VK_F9 = 66,
|
||||
VK_DELETE = 76,
|
||||
VK_LCTRL = 224,
|
||||
VK_LSHIFT = 225,
|
||||
VK_RCTRL = 228,
|
||||
VK_RSHIFT = 229,
|
||||
|
||||
/* same order as SDL mouse buttons */
|
||||
VK_MOUSE_BEGIN = 512,
|
||||
@@ -46,6 +65,17 @@ enum virtkey {
|
||||
VK_TOTAL_COUNT = VK_JOY_BEGIN + INPUT_MAX_CONTROLLERS * INPUT_MAX_CONTROLLER_BUTTONS,
|
||||
};
|
||||
|
||||
enum keymod {
|
||||
/* same order as SDL keymods */
|
||||
KM_LSHIFT = 0x0001,
|
||||
KM_RSHIFT = 0x0002,
|
||||
KM_LCTRL = 0x0040,
|
||||
KM_RCTRL = 0x0080,
|
||||
KM_CAPS = 0x2000,
|
||||
KM_CTRL = KM_LCTRL | KM_RCTRL,
|
||||
KM_SHIFT = KM_LSHIFT | KM_RSHIFT
|
||||
};
|
||||
|
||||
enum contkey {
|
||||
CK_C_R,
|
||||
CK_C_L,
|
||||
@@ -88,14 +118,6 @@ enum mouselockmode {
|
||||
MLOCK_AUTO = 2
|
||||
};
|
||||
|
||||
enum keymod {
|
||||
/* same order as SDL keymods */
|
||||
KM_LSHIFT = 0x0001,
|
||||
KM_RSHIFT = 0x0002,
|
||||
KM_CAPS = 0x2000,
|
||||
KM_SHIFT = KM_LSHIFT | KM_RSHIFT
|
||||
};
|
||||
|
||||
// returns bitmask of connected controllers or -1 if failed
|
||||
s32 inputInit(void);
|
||||
|
||||
@@ -149,9 +171,6 @@ s32 inputAssignController(s32 cidx, s32 id);
|
||||
s32 inputKeyPressed(u32 vk);
|
||||
s32 inputKeyJustPressed(u32 vk);
|
||||
|
||||
// same as inputKeyJustPressed but returns true again if key repeat activates
|
||||
s32 inputKeyJustPressedWithRepeat(u32 vk);
|
||||
|
||||
// idx is controller index, contbtn is one of the CONT_ constants
|
||||
s32 inputButtonPressed(s32 idx, u32 contbtn);
|
||||
|
||||
@@ -229,18 +248,19 @@ s32 inputAutoLockMouse(s32 wantlock);
|
||||
// show/hide mouse cursor; if mouse lock is on the cursor is always hidden
|
||||
void inputMouseShowCursor(s32 show);
|
||||
|
||||
// enables/disables/queries text input event processing, respectively
|
||||
void inputStartTextInput(void);
|
||||
void inputStopTextInput(void);
|
||||
s32 inputIsTextInputActive(void);
|
||||
|
||||
// fills textInputBuffer with textInput chars
|
||||
void inputSetTextInput(char *textInput);
|
||||
void inputClearLastTextChar(void);
|
||||
char inputGetLastTextChar(void);
|
||||
|
||||
// returns pointer to textInputBuffer
|
||||
char *inputGetTextInput(void);
|
||||
s32 inputTextHandler(char *out, const u32 outSize, s32 *curCol, s32 oskCharsOnly);
|
||||
|
||||
void inputClearClipboard(void);
|
||||
const char *inputGetClipboard(void);
|
||||
|
||||
// returns keymod values
|
||||
u32 inputGetModState(void);
|
||||
u32 inputGetKeyModState(void);
|
||||
|
||||
#endif
|
||||
+107
-33
@@ -87,10 +87,10 @@ static f32 mouseSensX = 1.5f;
|
||||
static f32 mouseSensY = 1.5f;
|
||||
|
||||
static s32 lastKey = 0;
|
||||
static s32 keyRepeat = 0;
|
||||
static char lastChar = 0;
|
||||
static s32 textInput = 0;
|
||||
|
||||
// buffer used to store text input during a text input event
|
||||
static char textInputBuffer[11] = {0};
|
||||
static char *clipboardText = NULL;
|
||||
|
||||
static const char *ckNames[CK_TOTAL_COUNT] = {
|
||||
"R_CBUTTONS",
|
||||
@@ -500,7 +500,6 @@ static int inputEventFilter(void *data, SDL_Event *event)
|
||||
if (!lastKey) {
|
||||
lastKey = VK_KEYBOARD_BEGIN + event->key.keysym.scancode;
|
||||
}
|
||||
keyRepeat = event->key.repeat;
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
@@ -526,8 +525,11 @@ static int inputEventFilter(void *data, SDL_Event *event)
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
inputSetTextInput(event->text.text);
|
||||
if (!lastChar && event->text.text[0] && (u8)event->text.text[0] < 0x80) {
|
||||
lastChar = event->text.text[0];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -666,9 +668,6 @@ s32 inputInit(void)
|
||||
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC);
|
||||
}
|
||||
|
||||
// SDL enables text input event handling by default
|
||||
inputStopTextInput();
|
||||
|
||||
// try to load controller db from an external file in the save folder
|
||||
if (fsFileSize("$S/" CONTROLLERDB_FNAME)) {
|
||||
const char *dbpath = fsFullPath("$S/" CONTROLLERDB_FNAME);
|
||||
@@ -742,6 +741,14 @@ s32 inputReadController(s32 idx, OSContPad *npad)
|
||||
|
||||
npad->button = 0;
|
||||
|
||||
if (textInput) {
|
||||
npad->stick_x = 0;
|
||||
npad->stick_y = 0;
|
||||
npad->rstick_x = 0;
|
||||
npad->rstick_y = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < CONT_NUM_BUTTONS; ++i) {
|
||||
if (inputBindPressed(idx, i)) {
|
||||
npad->button |= 1U << i;
|
||||
@@ -1125,11 +1132,6 @@ s32 inputKeyJustPressed(u32 vk)
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 inputKeyJustPressedWithRepeat(u32 vk)
|
||||
{
|
||||
return inputKeyJustPressed(vk) || (keyRepeat && inputKeyPressed(vk));
|
||||
}
|
||||
|
||||
static inline u32 inputContToContKey(const u32 cont)
|
||||
{
|
||||
if (cont == 0) {
|
||||
@@ -1334,38 +1336,110 @@ s32 inputGetLastKey(void)
|
||||
|
||||
void inputStartTextInput(void)
|
||||
{
|
||||
lastChar = 0;
|
||||
lastKey = 0;
|
||||
textInput = 1;
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
|
||||
void inputClearLastTextChar(void)
|
||||
{
|
||||
lastChar = 0;
|
||||
}
|
||||
|
||||
char inputGetLastTextChar(void)
|
||||
{
|
||||
return lastChar;
|
||||
}
|
||||
|
||||
static inline s32 filterChar(const char ch)
|
||||
{
|
||||
return isalnum(ch) || ch == ' ' || ch == '?' || ch == '!' || ch == '.';
|
||||
}
|
||||
|
||||
s32 inputTextHandler(char *out, const u32 outSize, s32 *curCol, s32 oskCharsOnly)
|
||||
{
|
||||
const s32 ctrlHeld = inputGetKeyModState() & KM_CTRL;
|
||||
|
||||
if (!ctrlHeld) {
|
||||
const char chr = inputGetLastTextChar();
|
||||
inputClearLastTextChar();
|
||||
const s32 valid = chr && (oskCharsOnly ? filterChar(chr) : isprint(chr));
|
||||
if (valid) {
|
||||
if (*curCol < outSize - 1) {
|
||||
out[(*curCol)++] = chr;
|
||||
out[*curCol] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const s32 key = inputGetLastKey();
|
||||
inputClearLastKey();
|
||||
if (ctrlHeld && (key == VK_A + ('v' - 'a'))) {
|
||||
// CTRL+V; paste from clipboard
|
||||
const char *clip = inputGetClipboard();
|
||||
if (clip) {
|
||||
const s32 remain = outSize - *curCol - 1;
|
||||
inputClearClipboard();
|
||||
*curCol += snprintf(out + *curCol, remain, "%s", clip);
|
||||
if (*curCol > outSize) {
|
||||
*curCol = outSize;
|
||||
}
|
||||
}
|
||||
} else if (key == VK_BACKSPACE) {
|
||||
if (*curCol) {
|
||||
out[--*curCol] = '\0';
|
||||
} else {
|
||||
out[0] = '\0';
|
||||
}
|
||||
} else if (key == VK_RETURN) {
|
||||
if (out[0] && *curCol) {
|
||||
return 1;
|
||||
}
|
||||
} else if (key == VK_ESCAPE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inputClearClipboard(void)
|
||||
{
|
||||
if (clipboardText) {
|
||||
SDL_free(clipboardText);
|
||||
clipboardText = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char *inputGetClipboard(void)
|
||||
{
|
||||
if (!clipboardText) {
|
||||
char *text = SDL_GetClipboardText();
|
||||
if (text) {
|
||||
clipboardText = text;
|
||||
// remove non-printable and multibyte chars
|
||||
for (; *text; ++text) {
|
||||
if ((u8)*text < 0x20 || (u8)*text >= 0x7F) {
|
||||
*text = '?';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return clipboardText;
|
||||
}
|
||||
|
||||
void inputStopTextInput(void)
|
||||
{
|
||||
SDL_StopTextInput();
|
||||
textInputBuffer[0] = '\0';
|
||||
textInput = 0;
|
||||
}
|
||||
|
||||
s32 inputIsTextInputActive(void)
|
||||
{
|
||||
return SDL_IsTextInputActive();
|
||||
return textInput;
|
||||
}
|
||||
|
||||
void inputSetTextInput(char *textInput)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof textInputBuffer - 1; ++i) {
|
||||
if (textInput && i < strlen(textInput)) {
|
||||
textInputBuffer[i] = textInput[i];
|
||||
} else {
|
||||
textInputBuffer[i] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *inputGetTextInput(void)
|
||||
{
|
||||
return textInputBuffer;
|
||||
}
|
||||
|
||||
|
||||
u32 inputGetModState(void)
|
||||
u32 inputGetKeyModState(void)
|
||||
{
|
||||
return SDL_GetModState();
|
||||
}
|
||||
|
||||
+7
-23
@@ -141,8 +141,7 @@ s32 g_MpPlayerNum = 0;
|
||||
#ifndef PLATFORM_N64
|
||||
s32 g_MenuMouseControl = true;
|
||||
s32 g_MenuUsingMouse = false;
|
||||
s32 g_MenuTypeWithKeyboard = false;
|
||||
s32 g_MenuTypeBackspace = false;
|
||||
s32 g_MenuKeyboardPlayer = -1;
|
||||
#endif
|
||||
|
||||
void menuPlaySound(s32 menusound)
|
||||
@@ -605,7 +604,7 @@ void menuCalculateItemSize(struct menuitem *item, s16 *width, s16 *height, struc
|
||||
case MENUITEMTYPE_KEYBOARD:
|
||||
*width = 130;
|
||||
#ifndef PLATFORM_N64
|
||||
*height = inputGetAssignedControllerId(g_MpPlayerNum) == -1 ? 84 : 73;
|
||||
*height = 84;
|
||||
#else
|
||||
*height = 73;
|
||||
#endif
|
||||
@@ -4701,8 +4700,6 @@ void menuProcessInput(void)
|
||||
inputs.back2 = 0;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
s32 usingcontroller = inputGetAssignedControllerId(g_MpPlayerNum) != -1;
|
||||
|
||||
inputs.mousemoved = false;
|
||||
inputs.mousescroll = 0;
|
||||
inputs.mousex = 0;
|
||||
@@ -4711,11 +4708,6 @@ void menuProcessInput(void)
|
||||
if (menu->playernum == 0) {
|
||||
// ESC always acts as back
|
||||
inputs.back = inputKeyJustPressed(VK_ESCAPE);
|
||||
if (inputs.back && g_MenuTypeWithKeyboard) {
|
||||
if (inputIsTextInputActive()) {
|
||||
inputStopTextInput();
|
||||
}
|
||||
}
|
||||
if (inputMouseIsEnabled() && !inputMouseIsLocked() && g_MenuMouseControl) {
|
||||
inputs.mousemoved = inputMouseGetPosition(&inputs.mousex, &inputs.mousey);
|
||||
inputs.mousescroll = inputKeyPressed(VK_MOUSE_WHEEL_DN) - inputKeyPressed(VK_MOUSE_WHEEL_UP);
|
||||
@@ -4726,11 +4718,11 @@ void menuProcessInput(void)
|
||||
if (dialog && inputs.mousemoved) {
|
||||
g_MenuUsingMouse = true;
|
||||
}
|
||||
g_MenuTypeBackspace = inputKeyJustPressedWithRepeat(VK_BACKSPACE);
|
||||
|
||||
if (usingcontroller && g_MenuTypeWithKeyboard) {
|
||||
g_MenuTypeWithKeyboard = false;
|
||||
if (inputIsTextInputActive()) {
|
||||
if (inputs.back && g_MenuKeyboardPlayer != -1) {
|
||||
// eat the back input so that other menus don't quit when we hit ESC
|
||||
inputs.back = false;
|
||||
if (g_MenuKeyboardPlayer == menu->playernum) {
|
||||
g_MenuKeyboardPlayer = -1;
|
||||
inputStopTextInput();
|
||||
}
|
||||
}
|
||||
@@ -4804,11 +4796,7 @@ void menuProcessInput(void)
|
||||
#endif
|
||||
|
||||
if (buttonsnow & B_BUTTON) {
|
||||
#ifndef PLATFORM_N64
|
||||
inputs.back = inputIsTextInputActive() && !usingcontroller ? 0 : 1;
|
||||
#else
|
||||
inputs.back = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (buttonsnow & Z_TRIG) {
|
||||
@@ -4820,11 +4808,7 @@ void menuProcessInput(void)
|
||||
}
|
||||
|
||||
if (buttons & R_TRIG) {
|
||||
#ifndef PLATFORM_N64
|
||||
inputs.shoulder = inputIsTextInputActive() && !usingcontroller ? 0 : 1;
|
||||
#else
|
||||
inputs.shoulder = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((stickx < 0 ? -stickx : stickx) < (thisstickx < 0 ? -thisstickx : thisstickx)) {
|
||||
|
||||
+90
-170
@@ -24,6 +24,9 @@
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "input.h"
|
||||
#define MENU_KEYBOARD_ROWS 6
|
||||
#else
|
||||
#define MENU_KEYBOARD_ROWS 5
|
||||
#endif
|
||||
|
||||
u8 g_MpSelectedPlayersForStats[MAX_PLAYERS];
|
||||
@@ -1062,15 +1065,6 @@ Gfx *menuitemDropdownOverlay(Gfx *gdl, s16 x, s16 y, s16 x2, s16 y2, struct menu
|
||||
return gdl;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
static s32 menuitemKeyboardGetNumRows(s32 rows, s32 usingcontroller)
|
||||
{
|
||||
return rows + !usingcontroller;
|
||||
}
|
||||
#else
|
||||
#define menuitemKeyboardGetNumRows(rows, usingcontroller) (rows)
|
||||
#endif
|
||||
|
||||
bool menuitemKeyboardIsStringEmptyOrSpaces(char *text)
|
||||
{
|
||||
s32 i;
|
||||
@@ -1122,9 +1116,6 @@ Gfx *menuitemKeyboardRender(Gfx *gdl, struct menurendercontext *context)
|
||||
u32 alpha;
|
||||
s32 textheight;
|
||||
s32 textwidth;
|
||||
#ifndef PLATFORM_N64
|
||||
s32 usingcontroller = inputGetAssignedControllerId(g_MpPlayerNum) != -1;
|
||||
#endif
|
||||
|
||||
label[1] = '\n';
|
||||
label[2] = '\0';
|
||||
@@ -1179,7 +1170,7 @@ Gfx *menuitemKeyboardRender(Gfx *gdl, struct menurendercontext *context)
|
||||
gdl = text0f153838(gdl);
|
||||
|
||||
// Render horizontal grid lines
|
||||
for (row = 0; row < menuitemKeyboardGetNumRows(6, usingcontroller); row++) {
|
||||
for (row = 0; row < MENU_KEYBOARD_ROWS + 1; row++) {
|
||||
gdl = menugfxDrawFilledRect(gdl, context->x + 4, context->y + row * 11 + 13,
|
||||
context->x + 124, context->y + row * 11 + 14, 0x00ffff7f, 0x00ffff7f);
|
||||
}
|
||||
@@ -1192,23 +1183,24 @@ Gfx *menuitemKeyboardRender(Gfx *gdl, struct menurendercontext *context)
|
||||
rowspan = 4;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (!usingcontroller && (col == 0 || col == 10)) {
|
||||
rowspan = 6;
|
||||
}
|
||||
#endif
|
||||
|
||||
gdl = menugfxDrawFilledRect(gdl, context->x + col * 12 + 4, context->y + 13,
|
||||
context->x + col * 12 + 5, context->y + rowspan * 11 + 14, 0x00ffff7f, 0x00ffff7f);
|
||||
}
|
||||
|
||||
#if MENU_KEYBOARD_ROWS > 5
|
||||
gdl = menugfxDrawFilledRect(gdl, context->x + 4, context->y + 5 * 11 + 13,
|
||||
context->x + 5, context->y + 6 * 11 + 14, 0x00ffff7f, 0x00ffff7f);
|
||||
gdl = menugfxDrawFilledRect(gdl, context->x + 10 * 12 + 4, context->y + 5 * 11 + 13,
|
||||
context->x + 10 * 12 + 5, context->y + 6 * 11 + 14, 0x00ffff7f, 0x00ffff7f);
|
||||
#endif
|
||||
|
||||
gdl = text0f153628(gdl);
|
||||
|
||||
x = context->x + 10;
|
||||
y = context->y + 2;
|
||||
|
||||
for (col = 0; col < 10; col++) {
|
||||
for (row = 0; row < menuitemKeyboardGetNumRows(5, usingcontroller); row++) {
|
||||
for (row = 0; row < MENU_KEYBOARD_ROWS; row++) {
|
||||
if (context->dialog->transitionfrac < 0) {
|
||||
textcolour = g_MenuColours[context->dialog->type].item_unfocused;
|
||||
} else {
|
||||
@@ -1227,12 +1219,6 @@ Gfx *menuitemKeyboardRender(Gfx *gdl, struct menurendercontext *context)
|
||||
textcolour = (textcolour & 0xff) | 0xffff0000;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_MenuTypeWithKeyboard && !usingcontroller && col == 0 && row == 5) {
|
||||
textcolour = (textcolour & 0xff) | 0xffff0000;
|
||||
}
|
||||
#endif
|
||||
|
||||
// If this button is the focused one, set highlighted colour
|
||||
if (col == data->col && row == data->row) {
|
||||
alpha = menuGetSinOscFrac(40) * 255;
|
||||
@@ -1289,33 +1275,6 @@ Gfx *menuitemKeyboardRender(Gfx *gdl, struct menurendercontext *context)
|
||||
textMeasure(&textheight, &textwidth, langGet(labels[index]), g_CharsHandelGothicXs, g_FontHandelGothicXs, 0);
|
||||
x = (buttonwidth - textwidth) / 2 + x;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// Dim the CAPSLOCK button if typing with keyboard
|
||||
if (index == 1 && g_MenuTypeWithKeyboard && !usingcontroller) {
|
||||
if (data->capseffective) {
|
||||
// CAPS button - make it yellow
|
||||
textcolour = (textcolour & 0xff) | 0x7f7f0000;
|
||||
} else {
|
||||
if (context->dialog->transitionfrac < 0) {
|
||||
textcolour = g_MenuColours[context->dialog->type].item_disabled;
|
||||
} else {
|
||||
textcolour = colourBlend(
|
||||
g_MenuColours[context->dialog->type2].item_disabled,
|
||||
g_MenuColours[context->dialog->type].item_disabled,
|
||||
context->dialog->colourweight);
|
||||
}
|
||||
|
||||
if (context->dialog->dimmed) {
|
||||
textcolour = (colourBlend(textcolour, 0, 127) & 0xffffff00) | (textcolour & 0xff);
|
||||
}
|
||||
|
||||
textSetWaveColours(
|
||||
g_MenuWave2Colours[context->dialog->type].item_disabled,
|
||||
g_MenuWave1Colours[context->dialog->type].item_disabled);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Dim the OK button if string is empty
|
||||
if (index == 3 && menuitemKeyboardIsStringEmptyOrSpaces(data->string)) {
|
||||
if (context->dialog->transitionfrac < 0) {
|
||||
@@ -1336,31 +1295,45 @@ Gfx *menuitemKeyboardRender(Gfx *gdl, struct menurendercontext *context)
|
||||
g_MenuWave1Colours[context->dialog->type].item_disabled);
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
// Dim the Caps button if keyboard typing is enabled
|
||||
if (index == 1 && g_MenuKeyboardPlayer == g_MpPlayerNum) {
|
||||
textcolour = colourBlend(
|
||||
g_MenuColours[context->dialog->type2].item_disabled,
|
||||
g_MenuColours[context->dialog->type].item_disabled,
|
||||
context->dialog->colourweight);
|
||||
textSetWaveColours(
|
||||
g_MenuWave2Colours[context->dialog->type].item_disabled,
|
||||
g_MenuWave1Colours[context->dialog->type].item_disabled);
|
||||
}
|
||||
#endif
|
||||
|
||||
gdl = textRenderProjected(gdl, &x, &y, langGet(labels[index]), g_CharsHandelGothicXs, g_FontHandelGothicXs, textcolour, context->width, context->height, 0, 0);
|
||||
|
||||
if ((index == 3 && menuitemKeyboardIsStringEmptyOrSpaces(data->string))
|
||||
#ifndef PLATFORM_N64
|
||||
|| (index == 1 && !usingcontroller && g_MenuTypeWithKeyboard)
|
||||
#endif
|
||||
) {
|
||||
if (index == 3 && menuitemKeyboardIsStringEmptyOrSpaces(data->string)) {
|
||||
textSetWaveColours(
|
||||
g_MenuWave2Colours[context->dialog->type].item_unfocused,
|
||||
g_MenuWave1Colours[context->dialog->type].item_unfocused);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (row == 5) {
|
||||
#ifndef PLATFORM_N64
|
||||
else if (row == 5) {
|
||||
static char *kbtext = "TYPE WITH KEYBOARD";
|
||||
if (col == 0) {
|
||||
char *kbtext;
|
||||
// make the button yellow if it's active
|
||||
if (g_MenuKeyboardPlayer == g_MpPlayerNum) {
|
||||
textcolour = (textcolour & 0xff) | 0xffff0000;
|
||||
kbtext = (char *)"ESC: CANCEL ENTER: OK";
|
||||
} else {
|
||||
kbtext = (char *)"TYPE WITH KEYBOARD";
|
||||
}
|
||||
++y;
|
||||
textMeasure(&textheight, &textwidth, kbtext, g_CharsHandelGothicXs, g_FontHandelGothicXs, 0);
|
||||
x = context->x + (context->width - textwidth) / 2;
|
||||
gdl = textRenderProjected(gdl, &x, &y, kbtext, g_CharsHandelGothicXs, g_FontHandelGothicXs, textcolour, context->width, context->height, 0, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
} else {
|
||||
// Alpha-numeric cell
|
||||
label[0] = g_KeyboardKeys[row][col];
|
||||
|
||||
@@ -1401,16 +1374,10 @@ Gfx *menuitemKeyboardRender(Gfx *gdl, struct menurendercontext *context)
|
||||
if (data->col == 0) {
|
||||
x2 += 12;
|
||||
}
|
||||
} else if (data->row == 5) {
|
||||
x2 = context->x + 9 * 12 + 16;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (data->row == 5 && !usingcontroller) {
|
||||
if (data->col == 0) {
|
||||
x2 += 108;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
gdl = menugfxDrawLine(gdl, x1, y1, x2, y1 + 1, -1, -1); // top
|
||||
gdl = menugfxDrawLine(gdl, x2, y1, x2 + 1, y2 + 1, -1, -1); // right
|
||||
gdl = menugfxDrawLine(gdl, x1, y2, x2, y2 + 1, -1, -1); // bottom
|
||||
@@ -1439,9 +1406,6 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
struct menuitemdata_keyboard *kb = &data->keyboard;
|
||||
union handlerdata handlerdata;
|
||||
s32 delete = false;
|
||||
#ifndef PLATFORM_N64
|
||||
s32 usingcontroller = inputGetAssignedControllerId(g_MpPlayerNum) != -1;
|
||||
#endif
|
||||
|
||||
if (tickflags & MENUTICKFLAG_ITEMISFOCUSED) {
|
||||
s16 prevcol = kb->col;
|
||||
@@ -1454,7 +1418,7 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
const s32 dleft = dialog->x + 4;
|
||||
const s32 dright = dleft + 12 * 10;
|
||||
const s32 dtop = menuitemGetTop(item, dialog) + 12;
|
||||
const s32 dbottom = dtop + 11 * (5 + !usingcontroller);
|
||||
const s32 dbottom = dtop + 11 * 6;
|
||||
const s32 mx = inputs->mousex;
|
||||
const s32 my = inputs->mousey;
|
||||
if (mx > dleft && mx < dright && my > dtop && my < dbottom) {
|
||||
@@ -1470,23 +1434,13 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
} else {
|
||||
kb->col = 8;
|
||||
}
|
||||
}
|
||||
if (kb->row == 5 && !usingcontroller) {
|
||||
} else if (kb->row == 5) {
|
||||
kb->col = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (usingcontroller && kb->row == 5) {
|
||||
kb->row = 4;
|
||||
kb->col = 0;
|
||||
}
|
||||
|
||||
if (g_MenuTypeWithKeyboard && !usingcontroller) {
|
||||
inputStartTextInput();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
||||
// Handle left/right movement
|
||||
// In most cases the loop only runs once, but on row 4 the buttons span
|
||||
// across multiple columns so the loop will run again until the column
|
||||
@@ -1502,11 +1456,7 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
if (kb->col > 9) {
|
||||
kb->col = 0;
|
||||
}
|
||||
} while ((kb->row == 4 && kb->col != 0 && kb->col != 2 && kb->col != 5 && kb->col != 8)
|
||||
#ifndef PLATFORM_N64
|
||||
|| (!usingcontroller && kb->row == 5 && kb->col != 0)
|
||||
#endif
|
||||
);
|
||||
} while (kb->row == 4 && kb->col != 0 && kb->col != 2 && kb->col != 5 && kb->col != 8);
|
||||
}
|
||||
|
||||
// Handle up/down movement
|
||||
@@ -1514,10 +1464,10 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
kb->row += inputs->updown;
|
||||
|
||||
if (kb->row < 0) {
|
||||
kb->row = menuitemKeyboardGetNumRows(4, usingcontroller);
|
||||
kb->row = 5;
|
||||
}
|
||||
|
||||
if (kb->row > menuitemKeyboardGetNumRows(4, usingcontroller)) {
|
||||
if (kb->row > MENU_KEYBOARD_ROWS - 1) {
|
||||
kb->row = 0;
|
||||
}
|
||||
|
||||
@@ -1539,14 +1489,11 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
kb->col = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (kb->row == 5 && !usingcontroller) {
|
||||
if (kb->row == 5) {
|
||||
kb->col = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (prevcol != kb->col || prevrow != kb->row) {
|
||||
menuPlaySound(MENUSOUND_KEYBOARDFOCUS);
|
||||
@@ -1566,15 +1513,42 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
menuPopDialog();
|
||||
|
||||
item->handler(MENUOP_SET, item, &handlerdata);
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
inputStopTextInput();
|
||||
#endif
|
||||
}
|
||||
|
||||
inputs->start = false;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_MenuKeyboardPlayer == g_MpPlayerNum) {
|
||||
// match caps state to keyboard shift/caps if typing with keyboard
|
||||
const u32 kmod = inputGetKeyModState();
|
||||
kb->capslock = (kmod & KM_CAPS) != 0;
|
||||
if (kmod & KM_SHIFT) {
|
||||
kb->capslock = !kb->capslock;
|
||||
}
|
||||
// handle text input
|
||||
s32 prevpos = strlen(kb->string);
|
||||
s32 pos = prevpos;
|
||||
s32 result = inputTextHandler(kb->string, sizeof(kb->string), &pos, true);
|
||||
if (result == -1) {
|
||||
// cancel
|
||||
kb->row = 5;
|
||||
kb->col = 0;
|
||||
inputs->select = true;
|
||||
} else if (result == 1) {
|
||||
// accept
|
||||
kb->row = 4;
|
||||
kb->col = 8;
|
||||
inputs->select = true;
|
||||
g_MenuKeyboardPlayer = -1;
|
||||
inputStopTextInput();
|
||||
} else if (prevpos < pos) {
|
||||
// added char
|
||||
menuPlaySound(MENUSOUND_FOCUS);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (inputs->select) {
|
||||
if (kb->row == 4) {
|
||||
// DEL
|
||||
@@ -1583,12 +1557,7 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
}
|
||||
|
||||
// CAPS
|
||||
|
||||
if (kb->col == 2
|
||||
#ifndef PLATFORM_N64
|
||||
&& (!g_MenuTypeWithKeyboard || usingcontroller)
|
||||
#endif
|
||||
) {
|
||||
if (kb->col == 2) {
|
||||
kb->capslock = 1 - kb->capslock;
|
||||
}
|
||||
|
||||
@@ -1615,30 +1584,22 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
}
|
||||
|
||||
inputs->select = false;
|
||||
|
||||
}
|
||||
}
|
||||
} else if (kb->row == 5) {
|
||||
#ifndef PLATFORM_N64
|
||||
inputStopTextInput();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef PLATFORM_N64
|
||||
else if (!usingcontroller && kb->row == 5 && kb->col == 0) {
|
||||
g_MenuTypeWithKeyboard ^= 1;
|
||||
|
||||
if (g_MenuTypeWithKeyboard) {
|
||||
menuPlaySound(MENUSOUND_TOGGLEON);
|
||||
if (g_MenuKeyboardPlayer == -1) {
|
||||
g_MenuKeyboardPlayer = g_MpPlayerNum;
|
||||
inputClearLastTextChar();
|
||||
inputStartTextInput();
|
||||
menuPlaySound(MENUSOUND_SELECT);
|
||||
} else {
|
||||
if (kb->capslock) {
|
||||
kb->capslock = 0;
|
||||
}
|
||||
menuPlaySound(MENUSOUND_TOGGLEOFF);
|
||||
g_MenuKeyboardPlayer = -1;
|
||||
inputStopTextInput();
|
||||
}
|
||||
menuPlaySound(MENUSOUND_KEYBOARDCANCEL);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
} else {
|
||||
// Pressed A on number or letter
|
||||
s32 appended = false;
|
||||
s32 i;
|
||||
@@ -1677,43 +1638,6 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef PLATFORM_N64
|
||||
else if (g_MenuTypeWithKeyboard && !usingcontroller) {
|
||||
delete = g_MenuTypeBackspace;
|
||||
kb->capslock = (inputGetModState() & KM_CAPS) ? 1 : 0;
|
||||
|
||||
if (strlen(inputGetTextInput())) {
|
||||
s32 textwidth, textheight, charwidth;
|
||||
size_t insertidx = strlen(kb->string);
|
||||
textMeasure(&textheight, &textwidth, kb->string, g_CharsHandelGothicSm, g_FontHandelGothicSm, 0);
|
||||
char *textinput = inputGetTextInput();
|
||||
size_t textinputlen = textinput ? strlen(textinput) : 0;
|
||||
|
||||
for (size_t j = 0; j < textinputlen && insertidx < sizeof kb->string - 1; ++j) {
|
||||
u8 key[2] = {0};
|
||||
key[0] = textinput[j];
|
||||
|
||||
if ((key[0] >= ' ' && key[0] <= '!') ||
|
||||
(key[0] == '.') ||
|
||||
(key[0] >= '0' && key[0] <= '9') ||
|
||||
(key[0] == '?') ||
|
||||
(key[0] >= 'A' && key[0] <= 'Z') ||
|
||||
(key[0] >= 'a' && key[0] <= 'z')) {
|
||||
textMeasure(&textheight, &charwidth, key, g_CharsHandelGothicSm, g_FontHandelGothicSm, 0);
|
||||
textwidth += charwidth;
|
||||
|
||||
if (textwidth <= 58) {
|
||||
kb->string[insertidx++] = key[0];
|
||||
}
|
||||
|
||||
menuPlaySound(MENUSOUND_FOCUS);
|
||||
}
|
||||
}
|
||||
|
||||
inputSetTextInput(NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Handle deleting
|
||||
if (delete && kb->string[0] != '\0') {
|
||||
@@ -1738,11 +1662,7 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
|
||||
u32 prev = kb->capseffective;
|
||||
kb->capseffective = kb->capslock;
|
||||
|
||||
if (inputs->shoulder
|
||||
#ifndef PLATFORM_N64
|
||||
|| (g_MenuTypeWithKeyboard && !usingcontroller && (inputGetModState() & KM_SHIFT))
|
||||
#endif
|
||||
) {
|
||||
if (inputs->shoulder) {
|
||||
// Invert
|
||||
kb->capseffective = 1 - kb->capseffective;
|
||||
}
|
||||
@@ -4701,7 +4621,7 @@ Gfx *menuitemOverlay(Gfx *gdl, s16 x, s16 y, s16 x2, s16 y2, struct menuitem *it
|
||||
s32 menuitemGetTop(struct menuitem *item, struct menudialog *dialog)
|
||||
{
|
||||
struct menu *menu = &g_Menus[g_MpPlayerNum];
|
||||
s32 dtop = dialog->y + LINEHEIGHT + 1 + dialog->dstscroll;
|
||||
s32 dtop = dialog->y + LINEHEIGHT + 1;
|
||||
|
||||
for (s32 i = 0; i < dialog->numcols; ++i) {
|
||||
const s32 colindex = i + dialog->colstart;
|
||||
|
||||
+1
-2
@@ -538,6 +538,7 @@ extern const struct weathercfg g_DefaultWeatherConfig;
|
||||
extern const struct weathercfg *g_CurWeatherConfig;
|
||||
|
||||
extern s32 g_MenuUsingMouse;
|
||||
extern s32 g_MenuKeyboardPlayer;
|
||||
|
||||
extern f32 g_ViShakeIntensityMult;
|
||||
extern u32 g_TexFilter2D;
|
||||
@@ -554,8 +555,6 @@ extern s32 g_TickExtraSleep;
|
||||
extern s32 g_MusicDisableMpDeath;
|
||||
extern s32 g_BgunGeMuzzleFlashes;
|
||||
extern s32 g_FileAutoSelect;
|
||||
extern s32 g_MenuTypeWithKeyboard;
|
||||
extern s32 g_MenuTypeBackspace;
|
||||
|
||||
#define PLAYER_EXTCFG() g_PlayerExtCfg[g_Vars.currentplayerstats->mpindex & 3]
|
||||
#define PLAYER_DEFAULT_FOV (PLAYER_EXTCFG().fovy)
|
||||
|
||||
Reference in new issue
Block a user