Implemented virtual keyboard

This commit is contained in:
simon.kagstrom 2009-01-22 20:34:33 +00:00
parent a12f84ac28
commit 7f262477fa
9 changed files with 87 additions and 47 deletions

View File

@ -1,8 +1,11 @@
version 6:
TODO: Multiple frodo versions, switch between
* Implemented a virtual keyboard which is used to select key bindings
* Don't load files with zero-size (allows .d64 files where the first file
is not a PRG to load correctly)
is not a PRG to load correctly). Thanks to Dominik Reichardt for pointing
this out
-- Simon Kagstrom <simon.kagstrom@gmail.com>,

View File

@ -63,7 +63,7 @@ export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := char_to_kc.c gcaudio.c
CPPFILES := Display.cpp main.cpp Prefs.cpp SID.cpp REU.cpp IEC.cpp 1541fs.cpp \
1541d64.cpp 1541t64.cpp 1541job.cpp SAM.cpp C64_SC.cpp CPUC64_SC.cpp VIC_SC.cpp \
CIA_SC.cpp CPU1541_SC.cpp menu.cpp CPU_common.cpp
CIA_SC.cpp CPU1541_SC.cpp menu.cpp CPU_common.cpp VirtualKeyboard.cpp
sFILES :=
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))

View File

@ -23,6 +23,7 @@
#if defined(HAVE_SDL)
/* SDL menu */
#include "menu.h"
#include "VirtualKeyboard.h"
#endif
#ifdef __BEOS__
@ -183,6 +184,7 @@ public:
#endif
#ifdef HAVE_SDL
menu_t main_menu;
VirtualKeyboard *virtual_keyboard;
TTF_Font *menu_font;
bool fake_key_sequence;

View File

@ -104,6 +104,8 @@ void C64::c64_ctor1(void)
}
menu_init(&this->main_menu, this->menu_font, main_menu_messages,
32, 32, MENU_SIZE_X, MENU_SIZE_Y);
this->virtual_keyboard = new VirtualKeyboard(real_screen, this->menu_font);
}
void C64::c64_ctor2(void)
@ -343,19 +345,17 @@ void C64::bind_keys(Prefs *np)
int opt = menu_select(real_screen, &bind_key_menu, NULL);
if (opt >= 0)
{
menu_init(&key_menu, this->menu_font, key_names,
32, 32, MENU_SIZE_X, MENU_SIZE_Y);
int key = menu_select(real_screen, &key_menu, NULL);
int key;
bool shifted;
/* Assume prefs are changed */
if (this->virtual_keyboard->get_key(&key, &shifted) != false)
{
this->prefs_changed = true;
if (key > 0)
np->JoystickKeyBinding[opt] = key_keycodes[key];
else if (key == 0)
np->JoystickKeyBinding[opt] = -1;
else
this->prefs_changed = false;
menu_fini(&key_menu);
if (shifted)
key |= 0x80;
np->JoystickKeyBinding[opt] = key;
}
}
menu_fini(&bind_key_menu);
}

View File

@ -31,7 +31,8 @@
#endif
// Display surface
SDL_Surface *screen = NULL;
static Uint8 screen[DISPLAY_X * DISPLAY_Y];
static SDL_Surface *sdl_screen;
SDL_Surface *real_screen = NULL;
// Keyboard
@ -100,9 +101,9 @@ int init_graphics(void)
// Open window
SDL_ShowCursor(SDL_DISABLE);
screen = SDL_CreateRGBSurface(SDL_SWSURFACE, DISPLAY_X, DISPLAY_Y + 17, 8,
sdl_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, DISPLAY_X, DISPLAY_Y + 17, 8,
rmask, gmask, bmask, amask);
if (!screen)
if (!sdl_screen)
{
fprintf(stderr, "Cannot allocate surface to draw on: %s\n",
SDL_GetError());
@ -177,12 +178,13 @@ void C64Display::NewPrefs(Prefs *prefs)
void C64Display::Update(void)
{
Uint8 *src_pixels = (Uint8*)screen;
const Uint16 src_pitch = DISPLAY_X;
if (ThePrefs.DisplayOption == 0) {
const int x_border = (DISPLAY_X - FULL_DISPLAY_X / 2) / 2;
const int y_border = (DISPLAY_Y - FULL_DISPLAY_Y / 2) / 2;
Uint8 *src_pixels = (Uint8*)screen->pixels;
Uint8 *dst_pixels = (Uint8*)real_screen->pixels;
const Uint16 src_pitch = screen->pitch;
const Uint16 dst_pitch = real_screen->pitch;
/* Center, double size */
@ -204,9 +206,24 @@ void C64Display::Update(void)
else {
SDL_Rect srcrect = {0, 0, DISPLAY_X, DISPLAY_Y};
SDL_Rect dstrect = {0, 0, FULL_DISPLAY_X, FULL_DISPLAY_Y};
Uint8 *dst_pixels = (Uint8*)sdl_screen->pixels;
const Uint16 dst_pitch = sdl_screen->pitch;
/* Draw 1-1 */
for (int y = 0; y < DISPLAY_Y; y++)
{
for (int x = 0; x < DISPLAY_X; x++)
{
int src_off = y * src_pitch + x;
int dst_off = src_off;
Uint8 v = src_pixels[src_off];
dst_pixels[ dst_off ] = v;
}
}
/* Stretch */
SDL_SoftStretch(screen, &srcrect, real_screen, &dstrect);
SDL_SoftStretch(sdl_screen, &srcrect, real_screen, &dstrect);
}
SDL_Flip(real_screen);
}
@ -282,7 +299,7 @@ void C64Display::Speedometer(int speed)
uint8 *C64Display::BitmapBase(void)
{
return (uint8 *)screen->pixels;
return screen;
}
@ -292,7 +309,7 @@ uint8 *C64Display::BitmapBase(void)
int C64Display::BitmapXMod(void)
{
return screen->pitch;
return DISPLAY_X;
}
void C64Display::FakeKeyPress(int kc, bool shift, uint8 *CIA_key_matrix,
@ -728,7 +745,6 @@ void C64Display::InitColors(uint8 *colors)
palette[red].g = palette[red].b = 0;
palette[green].g = 0xf0;
palette[green].r = palette[green].b = 0;
SDL_SetColors(screen, palette, 0, PALETTE_SIZE);
SDL_SetColors(real_screen, palette, 0, PALETTE_SIZE);

View File

@ -28,7 +28,8 @@ INSTALL_DATA = ${INSTALL} -m 644
## Files
GUIOBJS =
OBJS = $(GUIOBJS) main.o Prefs.o SID.o REU.o IEC.o 1541fs.o \
1541d64.o 1541t64.o 1541job.o SAM.o CmdPipe.o menu.o char_to_kc.o Network.o
1541d64.o 1541t64.o 1541job.o SAM.o CmdPipe.o menu.o char_to_kc.o Network.o \
VirtualKeyboard.o
SLOBJS = $(OBJS) C64.o CPUC64.o VIC.o CIA.o CPU1541.o Display.o
SLFLAGS = -DPRECISE_CPU_CYCLES=1 -DPRECISE_CIA_CYCLES=1 -DPC_IS_POINTER=0
SCOBJS = $(OBJS) C64_SC.o CPUC64_SC.o VIC_SC.o CIA_SC.o CPU1541_SC.o CPU_common.o Display_SC.o
@ -130,7 +131,7 @@ sysconfig.h: sysconfig.h.Host-SDL
main.o: sysdeps.h sysconfig.h main.h C64.h Display.h Prefs.h SAM.h
main.o: Basic_ROM.h Kernal_ROM.h Char_ROM.h 1541_ROM.h
Display.o: sysdeps.h sysconfig.h Display.h main.h Prefs.h
Display.o: sysdeps.h sysconfig.h Display.h main.h Prefs.h Display_SDL.h
Prefs.o: sysdeps.h sysconfig.h Prefs.h Display.h C64.h main.h
SID.o: sysdeps.h sysconfig.h SID.h Prefs.h
REU.o: sysdeps.h sysconfig.h REU.h CPUC64.h C64.h Prefs.h

View File

@ -41,16 +41,26 @@ typedef struct
{ name, MATRIX(a,b), false }
#define S(name, a,b) \
{ name, MATRIX(a,b), true }
#define N(name) \
{ name, -1, false }
#define KEY_COLS 15
#define KEY_ROWS 5
static virtkey_t keys[KEY_COLS * KEY_ROWS] = {
K("<-",7,1), K("1", 7,0), K("2", 7,3), K("3", 1,0), K("4", 1,3), K("5", 2,0), K("6", 2,3), K("7", 3,0), K("8", 3,3), K("9", 4,0), K("0", 4,3), K("+", 5,0), K("-", 5,3), K("£", 0,0), K("Hom", 6,3),
K("Ctr", 7,2), K("q", 7,6), K("w", 1,1), K("e", 1,6), K("r", 2,2), K("t", 2,6), K("y", 3,1), K("u", 3,6), K("i", 4,1), K("o", 6,6), K("p", 5,1), K("@", 5,6), K("*", 6,1), K("|^", 6,0),K("Rstr", 4,0),
K("R/Stp", 7,6), K(0, 0,0), K("a", 1,2), K("s", 1,5), K("d", 2,2), K("f", 2,5), K("g", 3,2), K("h", 3,5), K("j", 4,2), K("k", 4,5), K("l", 5,2), K(":", 5,5), K(";", 6,2), K("=", 6,5), K("Ret", 0,1),
K("C=", 7,6), S("Sh",1,7), K("z", 1,4), K("x", 2,7), K("c", 2,4), K("v", 3,7), K("b", 3,4), K("n", 4,7), K("m", 4,4), K(",", 5,7), K(".", 5,4), S("Sh",6,4), K("Dwn", 0,7),K("Rgt", 0,2),
K(0, 0,0), K(0, 0,0), K(0, 0,0), K("space", 7,4),K(0, 0,0),K(0, 0,0), K("f1", 0,4),K("f3", 0,5),K("f5", 0,6),K("f7", 0,3),K(0, 0,0), K(0, 0,0), K(0, 0,0), K(0, 0,0), K("Del", 0,0),
K("Cr", 7,2), K("q", 7,6), K("w", 1,1), K("e", 1,6), K("r", 2,2), K("t", 2,6), K("y", 3,1), K("u", 3,6), K("i", 4,1), K("o", 6,6), K("p", 5,1), K("@", 5,6), K("*", 6,1), K("Au", 6,0),K("Rstr", 4,0),
K("R/Stp", 7,7), K(0, 0,0), K("a", 1,2), K("s", 1,5), K("d", 2,2), K("f", 2,5), K("g", 3,2), K("h", 3,5), K("j", 4,2), K("k", 4,5), K("l", 5,2), K(":", 5,5), K(";", 6,2), K("=", 6,5), K("Ret", 0,1),
K("C=", 7,5), S("Sh",1,7), K("z", 1,4), K("x", 2,7), K("c", 2,4), K("v", 3,7), K("b", 3,4), K("n", 4,7), K("m", 4,4), K(",", 5,7), K(".", 5,4), K("/", 6,7), K(NULL,0,0), K("Dwn", 0,7),K("Rgt", 0,2),
N("None"), K(0, 0,0), K(0, 0,0), K("space", 7,4),K(0, 0,0),K(0, 0,0), K("f1", 0,4),K("f3", 0,5),K("f5", 0,6),K("f7", 0,3),K(0, 0,0), K(0, 0,0), K(0, 0,0), K(0, 0,0), K("Del", 0,0),
};
static const char *shifted_names[KEY_COLS * KEY_ROWS] = {
NULL, "!", "\"", "#", "$", "%", "&", "'", "(", ")", NULL, NULL, NULL, NULL, "Clr",
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "[", "]", NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "<", ">", "?", NULL, "Up", "Lft",
NULL, NULL, NULL, NULL, NULL, NULL, "f2", "f4", "f6", "f8", NULL, NULL, NULL, NULL, "Ins",
};
VirtualKeyboard::VirtualKeyboard(SDL_Surface *screen, TTF_Font *font)
@ -64,8 +74,8 @@ VirtualKeyboard::VirtualKeyboard(SDL_Surface *screen, TTF_Font *font)
void VirtualKeyboard::draw()
{
int screen_w = 640;
int screen_h = 480;
int screen_w = this->screen->w;
int screen_h = this->screen->h;
int key_w = 36;
int key_h = 36;
int border_x = (screen_w - (key_w * KEY_COLS)) / 2;
@ -78,18 +88,21 @@ void VirtualKeyboard::draw()
int which = y * KEY_COLS + x;
virtkey_t key = keys[which];
int r = 255, g = 255, b = 255;
const char *what = key.name;
/* Skip empty positions */
if (key.name == NULL)
continue;
if (this->shift_on && shifted_names[which])
what = shifted_names[which];
if ( (x == this->sel_x && y == this->sel_y) ||
(this->shift_on && key.is_shift))
b = 0;
menu_print_font(this->screen, this->font, r, g, b,
x * key_w + border_x, y * key_h + border_x,
key.name);
x * key_w + border_x, y * key_h + border_y,
what);
}
}
}

View File

@ -18,15 +18,6 @@
#include "menu.h"
#define KEY_UP 1
#define KEY_DOWN 2
#define KEY_LEFT 4
#define KEY_RIGHT 8
#define KEY_SELECT 16
#define KEY_ESCAPE 32
#define KEY_PAGEDOWN 64
#define KEY_PAGEUP 128
#define IS_SUBMENU(p_msg) ( (p_msg)[0] == '^' )
static submenu_t *find_submenu(menu_t *p_menu, int index)
@ -42,7 +33,7 @@ static submenu_t *find_submenu(menu_t *p_menu, int index)
return NULL;
}
static void print_font(SDL_Surface *screen, TTF_Font *font, int r, int g, int b,
void menu_print_font(SDL_Surface *screen, TTF_Font *font, int r, int g, int b,
int x, int y, const char *msg)
{
SDL_Surface *font_surf;
@ -97,10 +88,10 @@ static void menu_draw(SDL_Surface *screen, menu_t *p_menu)
int y = (i - p_menu->start_entry_visible) * line_height;
if (p_menu->cur_sel == i) /* Selected - color */
print_font(screen, p_menu->p_font, 255,255,0, x_start,
menu_print_font(screen, p_menu->p_font, 255,255,0, x_start,
y_start + y, msg);
else /* Otherwise white */
print_font(screen, p_menu->p_font, 255,255,255, x_start,
menu_print_font(screen, p_menu->p_font, 255,255,255, x_start,
y_start + y, msg);
if (IS_SUBMENU(msg))
{
@ -257,7 +248,7 @@ void menu_fini(menu_t *p_menu)
}
static uint32_t wait_key_press(void)
uint32_t menu_wait_key_press(void)
{
SDL_Event ev;
uint32_t keys = 0;
@ -385,7 +376,7 @@ int menu_select(SDL_Surface *screen, menu_t *p_menu,
menu_draw(screen, p_menu);
SDL_Flip(screen);
keys = wait_key_press();
keys = menu_wait_key_press();
if (keys & KEY_UP)
select_next(p_menu, 0, -1);

View File

@ -20,6 +20,15 @@
extern "C" {
#endif /* __cplusplus */
#define KEY_UP 1
#define KEY_DOWN 2
#define KEY_LEFT 4
#define KEY_RIGHT 8
#define KEY_SELECT 16
#define KEY_ESCAPE 32
#define KEY_PAGEDOWN 64
#define KEY_PAGEUP 128
typedef struct
{
int n_entries;
@ -45,6 +54,9 @@ typedef struct
int n_entries;
} menu_t;
void menu_print_font(SDL_Surface *screen, TTF_Font *font, int r, int g, int b,
int x, int y, const char *msg);
void menu_init(menu_t *p_menu, TTF_Font *p_font, const char **pp_msgs,
int16_t x1, int16_t y1, int16_t x2, int16_t y2);
void menu_fini(menu_t *p_menu);
@ -52,6 +64,8 @@ void menu_fini(menu_t *p_menu);
int menu_select(SDL_Surface *screen, menu_t *p_menu,
int *p_submenus);
uint32_t menu_wait_key_press(void);
#if defined(__cplusplus)
};
#endif /* __cplusplus */