diff --git a/CHANGES.WII b/CHANGES.WII index 55b477a..7daaefa 100644 --- a/CHANGES.WII +++ b/CHANGES.WII @@ -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 , diff --git a/Makefile b/Makefile index 745e3a0..55f1140 100644 --- a/Makefile +++ b/Makefile @@ -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)/*.*))) diff --git a/Src/C64.h b/Src/C64.h index 86211b4..dea6fe4 100644 --- a/Src/C64.h +++ b/Src/C64.h @@ -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; diff --git a/Src/C64_SDL.h b/Src/C64_SDL.h index 3cebd5d..d707819 100644 --- a/Src/C64_SDL.h +++ b/Src/C64_SDL.h @@ -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 */ - 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 (this->virtual_keyboard->get_key(&key, &shifted) != false) + { + this->prefs_changed = true; + if (shifted) + key |= 0x80; + + np->JoystickKeyBinding[opt] = key; + } } menu_fini(&bind_key_menu); } diff --git a/Src/Display_SDL.h b/Src/Display_SDL.h index 6d55d7f..3d4958e 100644 --- a/Src/Display_SDL.h +++ b/Src/Display_SDL.h @@ -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); diff --git a/Src/Makefile b/Src/Makefile index 51d26d8..f4cbad8 100644 --- a/Src/Makefile +++ b/Src/Makefile @@ -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 diff --git a/Src/VirtualKeyboard.cpp b/Src/VirtualKeyboard.cpp index 88b57e9..945c2c9 100644 --- a/Src/VirtualKeyboard.cpp +++ b/Src/VirtualKeyboard.cpp @@ -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); } } } diff --git a/Src/menu.cpp b/Src/menu.cpp index 6c5cfa6..1542917 100644 --- a/Src/menu.cpp +++ b/Src/menu.cpp @@ -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); diff --git a/Src/menu.h b/Src/menu.h index 1a335c6..f178087 100644 --- a/Src/menu.h +++ b/Src/menu.h @@ -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 */