uae-wii/src/gui-sdl/VirtualKeyboard.c

237 lines
6.8 KiB
C

/*********************************************************************
*
* Copyright (C) 2009, Simon Kagstrom
* Copyright (C) 2014, Fabio Olimpieri
*
* Filename: VirtualKeyboard.c
* Author: Simon Kagstrom <simon.kagstrom@gmail.com>, Fabio Olimpieri
* Description: A virtual keyboard
*
* $Id$
*
********************************************************************/
#include <SDL.h>
#include<SDL/SDL_image.h>
#ifdef GEKKO
#include <wiiuse/wpad.h>
#endif
#include "menu.h"
#include "VirtualKeyboard.h"
#include "writelog.h"
#include "target.h"
#include "gensound.h"
/* Uncomment for debugging output */
//#define DEBUG_VK
#ifdef DEBUG_VK
#define DEBUG_LOG write_log
#else
#define DEBUG_LOG(...) do {} while(0)
#endif
static SDL_Surface *image_kbd, *tmp_surface ;
static int vkb_is_init;
//static int key_code;
static VirtualKeyboard_struct VirtualKeyboard;
int kbd_is_active;
#define K(name, sdl_code) \
{ name, "KEY_"name, sdl_code, 0 }
#define N(name, key_name, sdl_code) \
{ name, "KEY_"key_name, sdl_code, 0 }
#define D(name) \
{ name, "None", 0, 1 }
#define KNL() \
{ NULL, NULL, 0, 0 }
#define NJ(name, joy_name) \
{ name, joy_name, 0, 0 }
#define KEY_COLS 21
#define KEY_ROWS 7
static virtkey_t keys[KEY_COLS * KEY_ROWS] = {
N("Esc","ESC",27), K("F1",282),K("F2",283),K("F3",284),K("F4",285),K("F5",286),K("F6",287),K("F7",288),K("F8",289),K("F9",290),K("F10",291), KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),
N("~`","BACKQUOTE",96),K("1",49),K("2",50), K("3",51), K("4",52), K("5",53), K("6",54), K("7",55), K("8",56), K("9",57), K("0",48), N("-","SUB",45),N("=","EQUALS",61), N("\\","KEY_BACKSLASH",92),N("BS","BACKSPACE",8),N("Del", "DELETE",127),N("Help", "HELP",277),K("LEFTPAREN",278), K("RIGHTPAREN",279),K("KP_DIVIDE",267),K("KP_MULTIPLY",268),
N("Tab", "TAB", 9), K("Q",113), K("W",119), K("E",101), K("R",114), K("T",116), K("Y",121), K("U",117), K("I",105), K("O",111), K("P",112),N("[","LEFTBRACKET",91),N("]","RIGHTBRACKET",93),N("Ret","RETURN",13),KNL(), K("KP7",263), K("KP8",264), K("KP9",265), K("KP_MINUS",269),KNL(),KNL(),
N("Ctrl","CTRL",306),N("Capslock","CAPSLOCK",301), K("A",97), K("S",115), K("D",100), K("F",102), K("G",103), K("H",104), K("J",106), K("K",107), K("L",108),N(";","SEMICOLON",59),N("'","SINGLEQUOTE",96),N("Ret","RETURN",13),KNL(),N("Up","CURSOR_UP",273),KNL(),K("KP4",260), K("KP5",261), K("KP6",262),K("KP_PLUS",270),
N("Sft","SHIFT_LEFT",304),K("Z",122),K("X",120),K("C",99), K("V",118), K("B",98), K("N",110), K("M",109),N(",","COMMA",44),N(".","PERIOD",46), N("/","SLASH",47), N("Sft","SHIFT_RIGHT",303), N("Lft","CURSOR_LEFT",276), N("Dwn","CURSOR_DOWN",274), N("Rgt", "CURSOR_RIGHT",275),K("KP1",257),K("KP2",258), K("KP3",259), N("Enter","KP_ENTERENTER",271),KNL(),KNL(),
N("Alt","ALT_LEFT",308), N("Amg","AMIGA_LEFT",310),N("space", "SPACE",32),N("Amg","AMIGA_RIGHT",309),N("Alt","ALT_RIGHT",307),KNL(),K("KP0",256),N(".","KP_PERIOD",266),N("Enter","KP_ENTER",271),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),
NJ("Fire","JOY_FIRE_BUTTON"),NJ("AutoFire","JOY_AUTOFIRE_BUTTON"),NJ("Joy 2nd button","JOY_2ND_BUTTON"),NJ("Joy 3rd button","JOY_3RD_BUTTON"), NJ("Joy left","JOY_LEFT"),NJ("Joy right","JOY_RIGHT"),NJ("Joy up","JOY_UP"),NJ("Joy down","JOY_DOWN"),D("None"),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL(),KNL()};
static int rows_margins[KEY_ROWS+1] = {26, 49, 74, 98, 122, 145, 172, 198};
static int buttons_margins[KEY_ROWS][KEY_COLS+1] = {
{14,44,79,110,143,175,216,257,289,321,353,386},
{14,47,73,99,125,151,177,203,229,255,281,307,333,359,385,417,462,509,541,567,593,620},
{14,62,88,114,140,166,192,218,244,270,296,322,348,374,412,515,541,567,593,620},
{14,42,67,93,119,145,171,197,223,249,275,301,327,353,412,449,476,515,541,567,593,620},
{14,80,106,132,158,184,210,236,262,288,314,340,417,449,476,515,541,567,593,620 },
{28,63,95,329,361,396,515,567,593,620},
{14,80,146,212,278,344,411,476,543,609}};
extern int RATIO;
void VirtualKeyboard_init(SDL_Surface *screen)
{
if (vkb_is_init) return;
VirtualKeyboard.screen = screen;
VirtualKeyboard.x = 2/RATIO; //Where to print the keyboard
VirtualKeyboard.y = 100/RATIO;
char kbd_image[255];
strcpy (kbd_image, "");
#ifdef OPTIONS_IN_HOME
char *home;
home = getenv ("HOME");
if (home != NULL && strlen (home) < 240)
{
strcpy (kbd_image, home);
strcat (kbd_image, "/");
}
#endif
if (RATIO == 1) strcat (kbd_image, KBDIMAGE); else strcat (kbd_image, KBDIMAGE_SMALL);
tmp_surface=IMG_Load(kbd_image);
if (tmp_surface == NULL) {write_log("Impossible to load keyboard image\n"); return;}
image_kbd=SDL_DisplayFormat(tmp_surface);
SDL_FreeSurface (tmp_surface);
memset(VirtualKeyboard.buf, 0, sizeof(VirtualKeyboard.buf));
vkb_is_init = 1;
kbd_is_active=0;
DEBUG_LOG("Virtual keyboard is inited\n");
}
void VirtualKeyboard_fini(void)
{
if (!vkb_is_init) return;
SDL_FreeSurface (image_kbd);
vkb_is_init = 0;
kbd_is_active = 0;
DEBUG_LOG("Virtual keyboard is finished\n");
}
void draw_vk()
{
SDL_Rect dst_rect = {VirtualKeyboard.x, VirtualKeyboard.y, 0, 0};
SDL_BlitSurface(image_kbd, NULL, VirtualKeyboard.screen, &dst_rect);
}
inline void flip_VKB()
{
SDL_Flip(VirtualKeyboard.screen);
}
int get_index(int x, int y)
{
int row, col;
row=col=0;
if ((x<0)||(x> 620)) return -1;
if ((y<0)||(y> 198)) return -1;
for (row=0; (rows_margins[row]<y)&&(row<KEY_ROWS+1); row++);
if (row==0) return -1; //not valid
if (rows_margins[row]<y) return -1; //not valid
row--;
for (col=0; (buttons_margins[row][col]<x)&&(row<KEY_COLS+1); col++);
if (col==0) return -1; //not valid
if (buttons_margins[row][col]<x) return -1; //not valid
col--;
return ((col) + (row) *KEY_COLS);
}
struct virtkey *get_key_internal()
{
while(1)
{
uint32_t k;
int x,y,xm, ym, i=0;
int border_x = VirtualKeyboard.x;
int border_y = VirtualKeyboard.y;
draw_vk();
SDL_ShowCursor(SDL_ENABLE);
flip_VKB();
k = menu_wait_key_press();
SDL_ShowCursor(SDL_DISABLE);
if (k & KEY_ESCAPE) return NULL;
else if (k & KEY_SELECT)
{
SDL_GetMouseState(&xm, &ym);
x = (xm-border_x);
y = (ym-border_y);
i = get_index(x*RATIO,y*RATIO);
if (i==-1) continue;
#ifdef GEKKO
WPAD_Rumble(0, 1);
SDL_Delay(90);
WPAD_Rumble(0, 0);
#endif
virtkey_t *key = &keys[i];
return key;
}
}
return NULL;
}
struct virtkey* virtkbd_get_key()
{
virtkey_t *key;
if (!vkb_is_init) return NULL;
pause_sound();
kbd_is_active=1;
key = get_key_internal();
kbd_is_active=0;
resume_sound();
return key;
}