Added extended mode key, new sdl menus controlled by joysticks

This commit is contained in:
fabio.olimpieri 2012-04-25 21:13:57 +00:00
parent 31aa295ee2
commit 93249b29bf
10 changed files with 1740 additions and 14 deletions

BIN
FreeMono.ttf Normal file

Binary file not shown.

View File

@ -33,7 +33,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lasnd -lSDL_mixer -lsmpeg -lvorbisidec -lSDL_image -lpng -ljpeg -lz -lSDL -lSDL_gfx -lfreetype -lfat -lwiiuse -lbte -logc -lm -lwiikeyboard
LIBS := -lasnd -lSDL_mixer -lsmpeg -lvorbisidec -lSDL_image -lpng -ljpeg -lz -lSDL_ttf -lSDL -lSDL_gfx -lfreetype -lfat -lwiiuse -lbte -logc -lm -lwiikeyboard
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
@ -122,6 +122,7 @@ dist: $(BUILD)
cp spectrum-roms/* $@/fbzx-wii/spectrum-roms
cp keymap.bmp $@/fbzx-wii/fbzx
cp ZXSpectrum48k.png $@/fbzx-wii/fbzx
cp FreeMono.ttf $@/fbzx-wii/fbzx
cp AMSTRAD CAPABILITIES COPYING FAQ README README.TZX VERSIONS $@/apps/fbzx-wii/doc
touch $@/fbzx-wii/tapes/dummy
touch $@/fbzx-wii/snapshots/dummy

View File

@ -1 +1 @@
<Project name="fbzx"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="src" path="src\"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="z80free" path="z80free\"><File path="COPYING"></File><File path="Makefile"></File><File path="Makefile.ori"></File><File path="README.txt"></File><File path="tests.expected"></File><File path="tests.in"></File><File path="tests.z80free"></File><File path="Z80free.c"></File><File path="Z80free.h"></File><File path="Z80free_codes.c"></File><File path="Z80free_codes.txt"></File><File path="Z80free_codesCB.c"></File><File path="Z80free_codesCB.txt"></File><File path="Z80free_codesDD.c"></File><File path="Z80free_codesDD.txt"></File><File path="Z80free_codesDDCB.c"></File><File path="Z80free_codesDDCB.txt"></File><File path="Z80free_codesED.c"></File><File path="Z80free_codesED.txt"></File><File path="Z80free_codesFD.c"></File><File path="Z80free_codesFD.txt"></File><File path="Z80free_codesFDCB.c"></File><File path="Z80free_codesFDCB.txt"></File><File path="z80free_gencode.py"></File><File path="z80free_tester.c"></File><File path="z80free_testgen.py"></File><File path="z80txt_converter.py"></File><File path="z80_test.pnproj"></File><File path="z80_test.pnps"></File></MagicFolder><File path="cargador.c"></File><File path="cargador.h"></File><File path="characters.c"></File><File path="characters.h"></File><File path="computer.c"></File><File path="computer.h"></File><File path="emulator.c"></File><File path="emulator.h"></File><File path="menus.c"></File><File path="menus.h"></File><File path="microdrive.c"></File><File path="microdrive.h"></File><File path="sound.c"></File><File path="sound.h"></File><File path="spk_ay.c"></File><File path="spk_ay.h"></File><File path="tape.c"></File><File path="tape.h"></File></MagicFolder><File path="Makefile"></File></Project>
<Project name="fbzx"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="src" path="src\"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="new" path="new\"><File path="VirtualKeyboard.cpp"></File><File path="VirtualKeyboard.h"></File></MagicFolder><MagicFolder excludeFolders="CVS;.svn" filter="*" name="z80free" path="z80free\"><File path="COPYING"></File><File path="Makefile"></File><File path="Makefile.ori"></File><File path="README.txt"></File><File path="tests.expected"></File><File path="tests.in"></File><File path="tests.z80free"></File><File path="Z80free.c"></File><File path="Z80free.h"></File><File path="Z80free_codes.c"></File><File path="Z80free_codes.txt"></File><File path="Z80free_codesCB.c"></File><File path="Z80free_codesCB.txt"></File><File path="Z80free_codesDD.c"></File><File path="Z80free_codesDD.txt"></File><File path="Z80free_codesDDCB.c"></File><File path="Z80free_codesDDCB.txt"></File><File path="Z80free_codesED.c"></File><File path="Z80free_codesED.txt"></File><File path="Z80free_codesFD.c"></File><File path="Z80free_codesFD.txt"></File><File path="Z80free_codesFDCB.c"></File><File path="Z80free_codesFDCB.txt"></File><File path="z80free_gencode.py"></File><File path="z80free_tester.c"></File><File path="z80free_testgen.py"></File><File path="z80txt_converter.py"></File><File path="z80_test.pnproj"></File><File path="z80_test.pnps"></File></MagicFolder><File path="cargador.c"></File><File path="cargador.h"></File><File path="characters.c"></File><File path="characters.h"></File><File path="computer.c"></File><File path="computer.h"></File><File path="emulator.c"></File><File path="emulator.h"></File><File path="gui_sdl.c"></File><File path="menus.c"></File><File path="menus.h"></File><File path="menu_sdl.c"></File><File path="menu_sdl.h"></File><File path="microdrive.c"></File><File path="microdrive.h"></File><File path="sound.c"></File><File path="sound.h"></File><File path="spk_ay.c"></File><File path="spk_ay.h"></File><File path="tape.c"></File><File path="tape.h"></File></MagicFolder><File path="Makefile"></File></Project>

View File

@ -1 +1 @@
<pd><ViewState><e p="fbzx" x="true"></e><e p="fbzx\src" x="true"></e><e p="fbzx\src\z80free" x="false"></e></ViewState></pd>
<pd><ViewState><e p="fbzx" x="true"></e><e p="fbzx\src" x="true"></e><e p="fbzx\src\new" x="false"></e><e p="fbzx\src\z80free" x="false"></e></ViewState></pd>

View File

@ -82,6 +82,8 @@ void computer_init () {
ordenador.mode128k = 0;
ordenador.joystick[0] = 1; //Kemposton
ordenador.joystick[1] = 0; // Cursor
ordenador.rumble[0] = 0;
ordenador.rumble[1] = 0;
ordenador.tape_readed = 0;
ordenador.pause = 1; // tape stop
@ -697,7 +699,6 @@ inline void read_keyboard () {
unsigned int temporal_io;
SDL_Event evento,*pevento;
static int countdown;
enum joystate_x {JOY_CENTER_X, JOY_LEFT, JOY_RIGHT};
enum joystate_y {JOY_CENTER_Y, JOY_UP, JOY_DOWN};
int joy_axis_x[2],joy_axis_y[2], loop;
@ -758,7 +759,7 @@ inline void read_keyboard () {
joy_axis_y[loop] = SDL_JoystickGetAxis(ordenador.joystick_sdl[loop], 1);
ordenador.joy_fire[loop] = SDL_JoystickGetButton(ordenador.joystick_sdl[loop], 0); //Wii button A
if (SDL_JoystickGetButton(ordenador.joystick_sdl[loop], 6)) help_menu (); //Wii button Home
if (SDL_JoystickGetButton(ordenador.joystick_sdl[loop], 6)) main_menu(); //Wii button Home
if (joy_axis_x[loop] > 16384) ordenador.joy_axis_x_state[loop] = JOY_RIGHT;
else if (joy_axis_x[loop] < -16384) ordenador.joy_axis_x_state[loop] = JOY_LEFT;
@ -946,8 +947,7 @@ inline void read_keyboard () {
}
if (ordenador.key[SDLK_SPACE]) ordenador.k15|=1;
if (ordenador.key[SDLK_RCTRL]) ordenador.k15|=2;
if (ordenador.key[SDLK_LCTRL]) ordenador.k15|=2;
if (ordenador.key[SDLK_RCTRL]||ordenador.key[SDLK_LCTRL]) ordenador.k15|=2; //Symbol shift
if (ordenador.key[SDLK_m]) ordenador.k15|=4;
if (ordenador.key[SDLK_n]) ordenador.k15|=8;
if (ordenador.key[SDLK_b]) ordenador.k15|=16;
@ -991,8 +991,7 @@ inline void read_keyboard () {
if (ordenador.key[SDLK_f]) ordenador.k9 |=8;
if (ordenador.key[SDLK_g]) ordenador.k9 |=16;
if (ordenador.key[SDLK_RSHIFT]) ordenador.k8 |=1;
if (ordenador.key[SDLK_LSHIFT]) ordenador.k8 |=1;
if (ordenador.key[SDLK_RSHIFT]||ordenador.key[SDLK_LSHIFT]) ordenador.k8 |=1; //Caps shift
if (ordenador.key[SDLK_z]) ordenador.k8 |=2;
if (ordenador.key[SDLK_x]) ordenador.k8 |=4;
if (ordenador.key[SDLK_c]) ordenador.k8 |=8;
@ -1003,6 +1002,8 @@ inline void read_keyboard () {
if (ordenador.key[SDLK_LEFT]) {ordenador.k11 |=16;ordenador.k8|=1;}
if (ordenador.key[SDLK_RIGHT]) {ordenador.k12 |=4;ordenador.k8|=1;}
if (ordenador.key[SDLK_TAB]) {ordenador.k15|=2;ordenador.k8|=1;} //Extended mode
ordenador.s8 = (ordenador.s8 & 0xE0) | (ordenador.k8 ^ 0x1F);
ordenador.s9 = (ordenador.s9 & 0xE0) | (ordenador.k9 ^ 0x1F);
ordenador.s10 = (ordenador.s10 & 0xE0)| (ordenador.k10 ^ 0x1F);

View File

@ -31,6 +31,8 @@ enum tapmodes {TAP_GUIDE, TAP_DATA, TAP_PAUSE, TAP_TRASH, TAP_STOP, TAP_PAUSE2,
TZX_SEQ_PULSES, TAP_FINAL_BIT, TAP_PAUSE3};
enum taptypes {TAP_TAP, TAP_TZX};
int countdown;
struct computer {
unsigned int temporal_io;
@ -200,6 +202,7 @@ struct computer {
unsigned char joy_axis_x_state[2];
unsigned char joy_axis_y_state[2];
unsigned char joy_fire[2];
unsigned char rumble[2];
};
void computer_init();

View File

@ -64,10 +64,10 @@ char path_mdrs[2049];
unsigned int colors[80];
unsigned int jump_frames,curr_frames;
char *filenames[5];
static SDL_Surface *image;
int load_zxspectrum_picture()
{
SDL_Surface *image;
image=IMG_Load("/fbzx-wii/fbzx/ZXSpectrum48k.png");
@ -707,8 +707,12 @@ int main(int argc,char *argv[]) {
ordenador.screenbuffer=ordenador.screen->pixels;
ordenador.screen_width=ordenador.screen->w;
//Init SDL Menu
menu_init(ordenador.screen);
//Load the splash screen
if (load_zxspectrum_picture()) sleep(3);
if (load_zxspectrum_picture()) {sleep(1); SDL_FreeSurface (image);}
// assign initial values for PATH variables
@ -775,7 +779,7 @@ int main(int argc,char *argv[]) {
load_main_game(gamefile);
printf("Modo: %d\n",ordenador.mode128k);
sprintf(ordenador.osd_text,"Press F1 for help");
sprintf(ordenador.osd_text,"Press Home for menu");
ordenador.osd_time=200;
printf("BPP: %d\n",ordenador.bpp);
@ -841,7 +845,7 @@ int main(int argc,char *argv[]) {
}
}
save_config(&ordenador);
//save_config(&ordenador);
#ifdef GEKKO
fatUnmount(0);

679
src/gui_sdl.c Normal file
View File

@ -0,0 +1,679 @@
/*
* UAE - The Un*x Amiga Emulator
*
* Interface to the Tcl/Tk GUI
*
* Copyright 1996 Bernd Schmidt
*/
#include <sys/types.h>
#include <sys/stat.h>
#include "menu_sdl.h"
#include "emulator.h"
//#include "VirtualKeyboard.h" per ora
#define ID_BUTTON_OFFSET 0
#define ID_AXIS_OFFSET 32
//extern int usbismount, smbismount; per ora
#ifdef DEBUG
extern FILE *fdebug;
#define printf(...) fprintf(fdebug,__VA_ARGS__)
#else
#ifdef GEKKO
#define printf(...)
#endif
#endif
extern int countdown;
static const char *main_menu_messages[] = {
/*00*/ "Tape",
/*01*/ "^|Insert|Load|Play|Stop|Rewind|Create|Delete",
/*02*/ "Snapshot",
/*03*/ "^|Load|Save|Delete",
/*04*/ "#1---------------------------------------------",
/*05*/ "Wiimote configuration",
/*06*/ "^|Wiimote1|Wiimote2",
/*07*/ "Emulation settings",
/*08*/ "Microdrive",
/*09*/ "Tools",
/*10*/ "Save confs",
/*11*/ "Reset",
/*12*/ "Help",
/*13*/ "Quit",
NULL
};
static const char *emulation_messages[] = {
/*00*/ "Emulated machine",
/*01*/ "^|48k_2|48K_3|128k|+2|+2A/+3|128K_Sp",
/*02*/ "Volume",
/*03*/ "^|0%|25%|50%|75%|100%",
/*04*/ "Tap fast speed",
/*05*/ "^|on|off",
/*06*/ "Turbo mode",
/*07*/ "^|on|off",
/*08*/ "Double scan",
/*09*/ "^|on|off",
/*10*/ "TV mode",
/*11*/ "^|Color|B&W",
/*12*/ "AY-3-8912 Emulation",
/*13*/ "^|on|off",
NULL
};
static const char *input_messages[] = {
/*00*/ "Joystick type",
/*01*/ "^|Cursor|Kempston|Sinclair1|Sinclair2",
/*02*/ " ",
/*03*/ "Bind key to Wiimote",
/*04*/ "^|1|2|-",
/*05*/ " ",
/*06*/ "Bind key to Nunchuk",
/*07*/ "^|Z|C",
/*08*/ " ",
/*09*/ "Bind key to Classic",
/*10*/ "^|a|b|x|y|L|R|Zl|Zr|-",
/*11*/ " ",
/*12*/ "Rumble",
/*13*/ "^|On|Off",
NULL,
};
static const char *microdrive_messages[] = {
/*00*/ "Select microdrive",
/*01*/ " ",
/*02*/ "Create microdrive file",
/*03*/ " ",
/*04*/ "Interface I",
/*05*/ "^|on|off",
/*06*/ " ",
/*07*/ "Write protection",
/*08*/ "^|on|off",
NULL
};
static const char *tools_messages[] = {
/*00*/ "Show keyboard",
/*01*/ " ",
/*02*/ "Save SCR",
/*03*/ " ",
/*04*/ "Load SCR",
/*05*/ " ",
/*06*/ "Insert poke",
NULL
};
static const char *help_messages[] = {
/*00*/ "#2HOME enters the menu system, where arrow keys",
/*01*/ "#2and nunchuck are used to navigate up and down.",
/*02*/ "#2You can bind keyboard keys to the wiimote",
/*03*/ "#2buttons in the 'Wiimote' menu and",
/*04*/ "#2change emulation options in the Settings menu.",
/*05*/ "#2 ",
/*06*/ "#2 ",
/*07*/ "#2 ",
/*08*/ "#2 ",
/*09*/ "#2 ",
/*10*/ "#2 ",
/*11*/ "#2More information is available on the wiki:",
/*12*/ "#2 http://wiibrew.org/wiki/FBZX_Wii",
/*13*/ "#2 ",
/*14*/ "OK",
NULL,
};
static void insert_tape()
{
unsigned char char_id[11];
int retorno, retval;
// Maybe should go after the first control??
if(ordenador.tap_file!=NULL)
rewind_tape(ordenador.tap_file,1);
ordenador.tape_current_bit=0;
ordenador.tape_current_mode=TAP_TRASH;
const char *filename = menu_select_file(path_taps, ordenador.current_tap, 0);
if (filename==NULL) // Aborted
return;
if (strcmp(filename, "None") == 0) //TO FIX IT
{
ordenador.current_tap[0] = '\0';
free((void *)filename);
return;
}
if (!(ext_matches(filename, ".tap")|ext_matches(filename, ".TAP")|ext_matches(filename, ".tzx")|
ext_matches(filename, ".TZX"))) {free((void *)filename); return;}
if(ordenador.tap_file!=NULL) {
fclose(ordenador.tap_file);
}
ordenador.tap_file=fopen(filename,"r+"); // read and write
ordenador.tape_write = 0; // by default, can't record
if(ordenador.tap_file==NULL)
retorno=-1;
else
retorno=0;
strcpy(ordenador.current_tap,filename);
free((void *)filename);
switch(retorno) {
case 0: // all right
break;
case -1:
msgInfo("Error: Can't load that file",3000,NULL);
ordenador.current_tap[0]=0;
return;
break;
}
retval=fread(char_id,10,1,ordenador.tap_file); // read the (maybe) TZX header
if((!strncmp(char_id,"ZXTape!",7)) && (char_id[7]==0x1A)&&(char_id[8]==1)) {
ordenador.tape_file_type = TAP_TZX;
rewind_tape(ordenador.tap_file,1);
} else {
ordenador.tape_file_type = TAP_TAP;
rewind_tape(ordenador.tap_file,1);
}
}
static void delete_tape()
{
const char *filename = menu_select_file(path_taps, NULL, -1);
if (filename==NULL) // Aborted
return;
if (strcmp(filename, "None") == 0)
{
free((void *)filename);
return;
}
if (ext_matches(filename, ".tap")|ext_matches(filename, ".TAP")|ext_matches(filename, ".tzx")|
ext_matches(filename, ".TZX")) unlink(filename);
free((void *)filename);
}
static void manage_tape(int which)
{
switch (which)
{
case 0: //Insert
insert_tape();
break;
case 1: //Emulate load ""
ordenador.kbd_buffer_pointer=6;
countdown=5;
break;
case 2: //Play
if ((ordenador.tape_fast_load == 0) || (ordenador.tape_file_type==TAP_TZX))
ordenador.pause = 0;
break;
case 3: //Stop
if ((ordenador.tape_fast_load == 0) || (ordenador.tape_file_type==TAP_TZX))
ordenador.pause = 1;
break;
case 4: //Rewind
ordenador.pause=1;
if(ordenador.tap_file!=NULL) {
ordenador.tape_current_mode=TAP_TRASH;
rewind_tape(ordenador.tap_file,1);
}
msgInfo("Tape rewinded",3000,NULL);
break;
case 5: //Create
// Create tape
break;
case 6: //Delete
delete_tape();
break;
default:
break;
}
}
static unsigned int get_machine_model(void)
{
return ordenador.mode128k + (ordenador.issue==3);
}
static void set_machine_model(int which)
{
switch (which)
{
case 0: //48k issue2
ordenador.issue=2;
ordenador.mode128k=0;
ordenador.ay_emul=0;
break;
case 1: //48k issue3
ordenador.issue=3;
ordenador.mode128k=0;
ordenador.ay_emul=0;
break;
case 2: //128k
ordenador.issue=3;
ordenador.mode128k=1;
ordenador.ay_emul=1;
break;
case 3: //Amstrad +2
ordenador.issue=3;
ordenador.mode128k=2;
ordenador.ay_emul=1;
break;
case 4: //Amstrad +2A/+3
ordenador.issue=3;
ordenador.mode128k=3;
ordenador.ay_emul=1;
ordenador.mdr_active=0;
break;
case 5: //128K Spanish
ordenador.issue=3;
ordenador.mode128k=4;
ordenador.ay_emul=1;
break;
}
}
static void emulation_settings(void)
{
unsigned int submenus[7],submenus_old[7];
int opt, i;
memset(submenus, 0, sizeof(submenus));
submenus[0] = get_machine_model();
submenus[1] = (unsigned int) (ordenador.volume/16);
submenus[2] = !ordenador.tape_fast_load;
submenus[3] = !ordenador.turbo;
submenus[4] = !ordenador.dblscan;
submenus[5] = ordenador.bw;
submenus[6] = !ordenador.ay_emul;
for (i=0; i<7; i++) submenus_old[i] = submenus[i];
opt = menu_select_title("Emulation settings menu",
emulation_messages, submenus);
if (opt < 0)
return;
set_machine_model(submenus[0]);
if (submenus[0] != submenus_old[0]) ResetComputer(); else
ordenador.ay_emul = !submenus[6];
ordenador.volume = submenus[1]*16;
ordenador.tape_fast_load = !submenus[2];
ordenador.turbo = !submenus[3];
if(ordenador.turbo){
ordenador.tst_sample=12000000/ordenador.freq; //5,0 MHz max emulation speed for wii at full frames
jump_frames=3;
} else {
ordenador.tst_sample=3500000/ordenador.freq;
jump_frames=0;
}
ordenador.dblscan = !submenus[4];
ordenador.bw = submenus[5];
if (submenus[5]!=submenus_old[5]) computer_set_palete();
}
static void setup_joystick(int joy, const char *key, int sdl_key)
{
/*
if (!strcmp(key, "None"))
{
changed_prefs.joystick_settings[1][joy].eventid[ID_BUTTON_OFFSET + sdl_key][0] = 0;
}
else
insert_keyboard_map(key, "input.1.joystick.%d.button.%d", joy, sdl_key);
*/
}
static void input_options(int joy)
{
const int wiimote_to_sdl[] = {2, 3, 4, 5};
const int nunchuk_to_sdl[] = {7, 8};
const int classic_to_sdl[] = {9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
int sdl_key = 1;
const char *key;
unsigned int submenus[5];
int opt;
//struct virtkey *virtualkey;
memset(submenus, 0, sizeof(submenus));
submenus[0] = ordenador.joystick[joy];
submenus[4] = !ordenador.rumble[joy];
opt = menu_select_title("Input menu",
input_messages, submenus);
if (opt < 0)
return;
ordenador.joystick[joy] = submenus[0];
ordenador.rumble[joy] = !submenus[4];
/*
virtualkey = virtkbd_get_key();
if (virtualkey == NULL)
return;
key = virtualkey->ev_name;
*/
switch(opt)
{
case 3: // wiimote
sdl_key = wiimote_to_sdl[submenus[1]]; break;
case 6: // nunchuk
sdl_key = nunchuk_to_sdl[submenus[2]]; break;
case 9: // classic
sdl_key = classic_to_sdl[submenus[3]]; break;
default:
break;
}
setup_joystick(joy, key, sdl_key);
}
static void microdrive()
{
unsigned int submenus[2], submenus_old[2];
int opt,retval ;
memset(submenus, 0, sizeof(submenus));
submenus[0] = !ordenador.mdr_active;
submenus[1] = !ordenador.mdr_cartridge[137922];
submenus_old[0] = submenus[0];
submenus_old[1] = submenus[1];
opt = menu_select_title("Microdrive menu",
microdrive_messages, submenus);
if (opt < 0)
return;
ordenador.mdr_active = !submenus[0];
if (submenus[0]!=submenus_old[0]) ResetComputer();
if (submenus[1]!=submenus_old[1])
{if(ordenador.mdr_cartridge[137922])
ordenador.mdr_cartridge[137922]=0;
else
ordenador.mdr_cartridge[137922]=1;
ordenador.mdr_file=fopen(ordenador.mdr_current_mdr,"wb"); // create for write
if(ordenador.mdr_file!=NULL) {
retval=fwrite(ordenador.mdr_cartridge,137923,1,ordenador.mdr_file); // save cartridge
fclose(ordenador.mdr_file);
ordenador.mdr_file=NULL;
ordenador.mdr_modified=0;
}
}
switch(opt)
{
case 0: // Select microdrive
//Select microdrive ;
break;
case 2: // Create microdrive file
// Create microdrive file ;
break;
default:
break;
}
}
void show_keyboard_layout() {
FILE *fichero;
int bucle1,bucle2,retval;
unsigned char *buffer,valor;
buffer=screen->pixels;
fichero=myfopen("fbzx/keymap.bmp","r");
if (fichero==NULL) {
msgInfo("Keymap picture not found",3000,NULL);
return;
}
for (bucle1=0;bucle1<344;bucle1++)
for(bucle2=0;bucle2<640;bucle2++) {
retval=fscanf(fichero,"%c",&valor);
paint_one_pixel((unsigned char *)(colors+valor),buffer);
buffer+=ordenador.bpp;
}
SDL_Flip(ordenador.screen);
menu_wait_key_press();
}
static void tools()
{
int opt ;
opt = menu_select_title("Tools menu",
tools_messages, NULL);
if (opt < 0)
return;
switch(opt)
{
case 0: // Show keyboard
show_keyboard_layout();
break;
case 2: // Save SCR
// Save SCR ;
break;
case 4: // Load SCR
//Load SCR ;
break;
case 6: // Insert poke
// Insert poke ;
break;
default:
break;
}
}
/*
static void set_Port(int which)
{
switch (which)
{
case PORT_SD:
prefs_set_attr ("floppy_path", strdup_path_expand (TARGET_FLOPPY_PATH));
changed_prefs.Port = which;
currprefs.Port = changed_prefs.Port;
break;
case PORT_USB:
if (usbismount) {
prefs_set_attr ("floppy_path", strdup_path_expand (TARGET_USB_PATH));
changed_prefs.Port = which;
currprefs.Port = changed_prefs.Port;}
else
msgInfo("USB is not mounted",3000,NULL);
break;
case PORT_SMB:
if (smbismount) {
prefs_set_attr ("floppy_path", strdup_path_expand (TARGET_SMB_PATH));
changed_prefs.Port = which;
currprefs.Port = changed_prefs.Port;}
else
msgInfo("SMB is not mounted",3000,NULL);
break;
default:
break;
}
}
static void virtual_keyboard(void)
{
int key_code;
virtkey_t *key =virtkbd_get_key();
if (key) {key_code = key->sdl_code;} else return;
SDL_Event event_key;
event_key.type=SDL_KEYDOWN;
event_key.key.keysym.sym=key_code;
SDL_PushEvent(&event_key);
DEBUG_LOG ("Push Event: keycode %d %s\n", key_code, "SDL_KEYDOWN");
event_key.type=SDL_KEYUP;
SDL_PushEvent(&event_key);
DEBUG_LOG ("Push Event: keycode %d %s\n", key_code, "SDL_KEYUP");
}
*/
static void save_load_snapshot(int which)
{
const char *dir = path_snaps;
const char *tape = ordenador.current_tap;
char db[256];
char fb[81];
int retorno;
// Name (for saves) - TO CHECK
if (tape && strrchr(tape, '/'))
strncpy(fb, strrchr(tape, '/') + 1, 80);
else
strcpy(fb, "unknown");
switch(which)
{
case 2:
case 0: // Load or delete file
{
const char *filename = menu_select_file(dir, NULL,-1);
if (!filename)
return;
if (ext_matches(filename, ".z80")|ext_matches(filename, ".Z80")|
ext_matches(filename, ".sna")|ext_matches(filename, ".SNA"))
{
if (which == 0) // Load snapshot file
{
retorno=load_z80(filename);
switch(retorno) {
case 0: // all right
break;
case -1:
msgInfo("Error: Can't load that file",3000,NULL);
break;
case -2:
case -3:
msgInfo("Error: unsuported snap file",3000,NULL);
break;
}
}
else // Delete snashot file
unlink(filename);
}
free((void*)filename);
} break;
case 1: // Save snapshot file
snprintf(db, 255, "%s/%s.z80", dir, fb);
retorno=save_z80(db);
msgInfo("State saved",3000,NULL);
break;
default:
break;
}
}
static void help(void)
{
menu_select_title("FBZX-WII help",
help_messages, NULL);
}
void main_menu()
{
int submenus[3];
int opt;
memset(submenus, 0, sizeof(submenus));
do
{
opt = menu_select_title("Main menu", main_menu_messages, submenus);
if (opt < 0)
break;
switch(opt)
{
case 0:
manage_tape(submenus[0]);
break;
case 2:
save_load_snapshot(submenus[1]);
break;
case 5:
input_options(submenus[2]);
break;
case 7:
emulation_settings();
break;
case 8:
microdrive();
break;
case 9:
tools();
break;
case 10:
save_config(&ordenador);
msgInfo("Configurations saved",3000,NULL);
break;
case 11:
ResetComputer ();
ordenador.pause = 1;
if (ordenador.tap_file != NULL) {
ordenador.tape_current_mode = TAP_TRASH;
rewind_tape (ordenador.tap_file,1);
}
break;
case 12:
help();
break;
case 13:
if (msgYesNo("Are you sure to quit?", 0, FULL_DISPLAY_X /2-138, FULL_DISPLAY_Y /2-48))
{salir = 0;}
break;
default:
break;
}
} while (opt == 5 || opt == 7 || opt == 8 || opt == 9 || opt == 12);
}

976
src/menu_sdl.c Normal file
View File

@ -0,0 +1,976 @@
/*********************************************************************
*
* Copyright (C) 2004,2008, Simon Kagstrom
*
* Filename: menu.c
* Author: Simon Kagstrom <simon.kagstrom@gmail.com>
* Description: Code for menus (originally for Mophun)
*
* $Id$
*
********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
#include "menu_sdl.h"
#include "emulator.h" //Necessary to use ordenador.joystick_number and ordenador.joystick_sdl
//#include "VirtualKeyboard.h"
typedef struct
{
int n_entries;
int index;
int sel;
} submenu_t;
typedef struct
{
char title[256];
const char **pp_msgs;
TTF_Font *p_font;
int x1,y1;
int x2,y2;
int text_w;
int text_h;
int n_submenus;
submenu_t *p_submenus;
int cur_sel; /* Main selection */
int start_entry_visible;
int n_entries;
} menu_t;
static SDL_Surface *real_screen;
#define IS_SUBMENU(p_msg) ( (p_msg)[0] == '^' )
#define IS_TEXT(p_msg) ( (p_msg)[0] == '#' || (p_msg)[0] == ' ' )
#define IS_MARKER(p_msg) ( (p_msg)[0] == '@' )
static int is_inited = 0;
static TTF_Font *menu_font16, *menu_font20;
#if defined(GEKKO)
#define FONT_PATH "/fbzx-wii/fbzx/FreeMono.ttf"
#else
#define FONT_PATH "FreeMono.ttf"
#endif
int fh, fw;
int msgInfo(char *text, int duration, SDL_Rect *irc)
{
int len = strlen(text);
int X, Y;
SDL_Rect src;
SDL_Rect rc;
SDL_Rect brc;
X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*12;
Y = (FULL_DISPLAY_Y /2) - 24;
brc.x = FULL_DISPLAY_X/2-2*12;
brc.y=Y+42;
brc.w=48;
brc.h=20;
rc.x = X;
rc.y=Y;
rc.w=12*(len + 2);
rc.h=duration > 0 ? 48 : 80;
src.x=rc.x+4;
src.y=rc.y+4;
src.w=rc.w;
src.h=rc.h;
if (irc)
{
irc->x=rc.x;
irc->y=rc.y;
irc->w=src.w;
irc->h=src.h;
}
SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 0, 96, 0));
SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 128, 128, 128));
menu_print_font(real_screen, 255,255,255, X+12, Y+12, text,20);
SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h);
SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h);
if (duration > 0)
SDL_Delay(duration);
else if (duration < 0)
{
SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 0x80, 0x00));
menu_print_font(real_screen, 0,0,0, FULL_DISPLAY_X/2-12, Y+42, "OK",20);
SDL_UpdateRect(real_screen, brc.x, brc.y, brc.w, brc.h);
while (!(KEY_SELECT & menu_wait_key_press())) {}
}
return 1;
}
/*
void msgKill(SDL_Rect *rc)
{
SDL_UpdateRect(real_screen, rc->x, rc->y, rc->w,rc->h);
}
*/
int msgYesNo(char *text, int default_opt, int x, int y)
{
int len = strlen(text);
int X, Y;
SDL_Rect src;
SDL_Rect rc;
SDL_Rect brc;
uint32_t key;
if (x < 0)
X = (FULL_DISPLAY_X /2) - (len / 2 + 1)*12;
else
X = x;
if (y < 0)
Y = (FULL_DISPLAY_Y /2) - 48;
else
Y = y;
rc.x=X;
rc.y=Y;
rc.w=12*(len + 2);
rc.h=80;
src.x=rc.x+4;
src.y=rc.y+4;
src.w=rc.w;
src.h=rc.h;
while (1)
{
SDL_FillRect(real_screen, &src, SDL_MapRGB(real_screen->format, 0, 96, 0));
SDL_FillRect(real_screen, &rc, SDL_MapRGB(real_screen->format, 128, 128, 128));
menu_print_font(real_screen, 255,255,255, X+12, Y+12, text,20);
if (default_opt)
{
brc.x=rc.x + rc.w/2-5*12;
brc.y=rc.y+42;
brc.w=12*3;
brc.h=20;
SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x00, 0x80, 0x00));
}
else
{
brc.x=rc.x + rc.w/2+5*12-2*12-6;
brc.y=rc.y+42;
brc.w=12*3;
brc.h=20;
SDL_FillRect(real_screen, &brc, SDL_MapRGB(real_screen->format, 0x80, 0x00, 0x00));
}
menu_print_font(real_screen, 255,255,255, rc.x + rc.w/2-5*12, Y+42, "YES",20);
menu_print_font(real_screen, 255,255,255, rc.x + rc.w/2-5*12+8*12, Y+42, "NO",20);
SDL_UpdateRect(real_screen, src.x, src.y, src.w, src.h);
SDL_UpdateRect(real_screen, rc.x, rc.y, rc.w,rc.h);
SDL_UpdateRect(real_screen, brc.x, brc.y, brc.w,brc.h);
//SDL_Flip(real_screen);
key = menu_wait_key_press();
if (key & KEY_SELECT)
{
return default_opt;
}
else if (key & KEY_ESCAPE)
{
return 0;
}
else if (key & KEY_LEFT)
{
default_opt = !default_opt;
}
else if (key & KEY_RIGHT)
{
default_opt = !default_opt;
}
}
}
static int cmpstringp(const void *p1, const void *p2)
{
const char *p1_s = *(const char**)p1;
const char *p2_s = *(const char**)p2;
/* Put directories first */
if (*p1_s == '[' && *p2_s != '[')
return -1;
if (*p1_s != '[' && *p2_s == '[')
return 1;
return strcmp(* (char * const *) p1, * (char * const *) p2);
}
/* Return true if name ends with ext (for filenames) */
int ext_matches(const char *name, const char *ext)
{
int len = strlen(name);
int ext_len = strlen(ext);
if (len <= ext_len)
return 0;
return (strcmp(name + len - ext_len, ext) == 0);
}
static int ext_matches_list(const char *name, const char **exts)
{
const char **p;
for (p = exts; *p; p++)
{
if (ext_matches(name, *p))
return 1;
}
return 0;
}
static const char **get_file_list(const char *base_dir)
{
DIR *d = opendir(base_dir);
const char **file_list;
int cur = 0;
struct dirent *de;
int cnt = 16;
if (!d)
return NULL;
file_list = (const char**)malloc(cnt * sizeof(char*));
file_list[cur++] = strdup("None");
file_list[cur] = NULL;
for (de = readdir(d);
de;
de = readdir(d))
{
char buf[255];
const char *exts[] = {".tap", ".TAP", ".tzx", ".TZX", ".z80",".Z80",".sna", ".SNA",
".mdr", ".MDR", NULL};
struct stat st;
snprintf(buf, 255, "%s/%s", base_dir, de->d_name);
if (stat(buf, &st) < 0)
continue;
if (S_ISDIR(st.st_mode)&&strcmp(".", de->d_name))
{
char *p;
size_t len = strlen(de->d_name) + 4;
p = (char*)malloc( len );
snprintf(p, len, "[%s]", de->d_name);
file_list[cur++] = p;
file_list[cur] = NULL;
}
else if (ext_matches_list(de->d_name, exts))
{
char *p;
p = strdup(de->d_name);
file_list[cur++] = p;
file_list[cur] = NULL;
}
if (cur > cnt - 2)
{
cnt = cnt + 32;
file_list = (const char**)realloc(file_list, cnt * sizeof(char*));
if (!file_list)
return NULL;
}
}
closedir(d);
qsort(&file_list[1], cur-1, sizeof(const char *), cmpstringp);
return file_list;
}
static submenu_t *find_submenu(menu_t *p_menu, int index)
{
int i;
for (i=0; i<p_menu->n_submenus; i++)
{
if (p_menu->p_submenus[i].index == index)
return &p_menu->p_submenus[i];
}
return NULL;
}
void menu_print_font(SDL_Surface *screen, int r, int g, int b,
int x, int y, const char *msg, int font_size)
{
#define _MAX_STRING 64
SDL_Surface *font_surf;
SDL_Rect dst = {x, y, 0, 0};
SDL_Color color = {r, g, b};
char buf[255];
unsigned int i;
memset(buf, 0, sizeof(buf));
strncpy(buf, msg, 254);
if (buf[0] != '|' && buf[0] != '^' && buf[0] != '.'
&& buf[0] != '-' && buf[0] != ' ' && !strstr(buf, " \""))
{
if (strlen(buf)>_MAX_STRING)
{
//buf[_MAX_STRING-3] = '.';
//buf[_MAX_STRING-2] = '.';
//buf[_MAX_STRING-1] = '.';
buf[_MAX_STRING] = '\0';
}
}
/* Fixup multi-menu option look */
for (i = 0; i < strlen(buf) ; i++)
{
if (buf[i] == '^' || buf[i] == '|')
buf[i] = ' ';
}
if (font_size == 16) font_surf = TTF_RenderUTF8_Blended(menu_font16, buf, color);
else font_surf = TTF_RenderUTF8_Blended(menu_font20, buf, color);
if (!font_surf)
{
fprintf(stderr, "%s\n", TTF_GetError());
exit(1);
}
SDL_BlitSurface(font_surf, NULL, screen, &dst);
SDL_FreeSurface(font_surf);
}
static void menu_draw(SDL_Surface *screen, menu_t *p_menu, int sel, int font_size)
{
int font_height = TTF_FontHeight(p_menu->p_font);
int line_height = (font_height + font_height / 4);
int x_start = p_menu->x1;
int y_start = p_menu->y1 + line_height;
SDL_Rect r;
int entries_visible = (p_menu->y2 - p_menu->y1) / line_height - 1;
int i, y;
if ( p_menu->n_entries * line_height > p_menu->y2 )
y_start = p_menu->y1 + line_height;
if (p_menu->cur_sel - p_menu->start_entry_visible > entries_visible)
{
while (p_menu->cur_sel - p_menu->start_entry_visible > entries_visible)
{
p_menu->start_entry_visible ++;
if (p_menu->start_entry_visible > p_menu->n_entries)
{
p_menu->start_entry_visible = 0;
break;
}
}
}
else if ( p_menu->cur_sel < p_menu->start_entry_visible )
p_menu->start_entry_visible = p_menu->cur_sel;
if (strlen(p_menu->title))
{
r.x = p_menu->x1;
r.y = p_menu->y1;
r.w = p_menu->x2 - p_menu->x1;
r.h = line_height-1;
if (sel < 0)
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0x40, 0x00, 0x00));
else
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0x00, 0xe7, 0xe7));
menu_print_font(screen, 0,0,0, p_menu->x1, p_menu->y1, p_menu->title, font_size);
}
for (i = p_menu->start_entry_visible; i <= p_menu->start_entry_visible + entries_visible; i++)
{
const char *msg = p_menu->pp_msgs[i];
if (i >= p_menu->n_entries)
break;
if (IS_MARKER(msg))
p_menu->cur_sel = atoi(&msg[1]);
else
{
y = (i - p_menu->start_entry_visible) * line_height;
if (sel < 0)
menu_print_font(screen, 0x40,0x40,0x40,
x_start, y_start + y, msg, font_size);
else if (p_menu->cur_sel == i) /* Selected - color */
menu_print_font(screen, 0,200,0,
x_start, y_start + y, msg, font_size);
else if (IS_SUBMENU(msg))
{
if (p_menu->cur_sel == i-1)
menu_print_font(screen, 0,200,0,
x_start, y_start + y, msg, font_size);
else
menu_print_font(screen, 0x40,0x40,0x40,
x_start, y_start + y, msg, font_size);
}
else if (msg[0] == '#')
{
switch (msg[1])
{
case '1':
menu_print_font(screen, 0,0,255,
x_start, y_start + y, msg+2, font_size);
break;
case '2':
menu_print_font(screen, 0x40,0x40,0x40,
x_start, y_start + y, msg+2, font_size);
break;
default:
menu_print_font(screen, 0x40,0x40,0x40,
x_start, y_start + y, msg, font_size);
break;
}
}
else /* Otherwise white */
menu_print_font(screen, 0x40,0x40,0x40,
x_start, y_start + y, msg, font_size);
if (IS_SUBMENU(msg))
{
submenu_t *p_submenu = find_submenu(p_menu, i);
int n_pipe = 0;
int n;
for (n=0; msg[n] != '\0'; n++)
{
/* Underline the selected entry */
if (msg[n] == '|')
{
int16_t n_chars;
for (n_chars = 1; msg[n+n_chars] && msg[n+n_chars] != '|'; n_chars++);
n_pipe++;
if (p_submenu->sel == n_pipe-1)
{
int w;
int h;
if (TTF_SizeText(p_menu->p_font, "X", &w, &h) < 0)
{
fw = w;
fh = h;
fprintf(stderr, "%s\n", TTF_GetError());
exit(1);
}
r = (SDL_Rect){ x_start + (n+1) * w-1, y_start + (i+ 1 - p_menu->start_entry_visible) * ((h + h/4)) -3, (n_chars - 1) * w, 2};
if (p_menu->cur_sel == i-1)
SDL_FillRect(screen, &r,
SDL_MapRGB(screen->format, 255,0,0));
else
SDL_FillRect(screen, &r,
SDL_MapRGB(screen->format, 0x40,0x40,0x40));
break;
}
}
}
}
}
}
}
static int get_next_seq_y(menu_t *p_menu, int v, int dy, int cicle)
{
if (v + dy < 0)
{if (cicle) return (p_menu->n_entries - 1); else return 0;}
if (v + dy > p_menu->n_entries - 1)
{if (cicle) return 0; else return (p_menu->n_entries - 1);}
return v + dy;
}
static void select_next(menu_t *p_menu, int dx, int dy, int cicle)
{
int next;
p_menu->cur_sel = get_next_seq_y(p_menu, p_menu->cur_sel, dy, cicle);
next = get_next_seq_y(p_menu, p_menu->cur_sel, dy + 1, cicle);
if (p_menu->pp_msgs[p_menu->cur_sel][0] == ' ' ||
p_menu->pp_msgs[p_menu->cur_sel][0] == '#' ||
IS_SUBMENU(p_menu->pp_msgs[p_menu->cur_sel]) )
select_next(p_menu, dx, dy, cicle);
/* If the next is a submenu */
if (dx != 0 && IS_SUBMENU(p_menu->pp_msgs[next]))
{
submenu_t *p_submenu = find_submenu(p_menu, next);
p_submenu->sel = (p_submenu->sel + dx) < 0 ? p_submenu->n_entries - 1 :
(p_submenu->sel + dx) % p_submenu->n_entries;
}
else if (dx == -1 && !strcmp(p_menu->pp_msgs[0], "[..]"))
p_menu->cur_sel = 0;
}
static void select_one(menu_t *p_menu, int sel)
{
if (sel >= p_menu->n_entries)
sel = 0;
p_menu->cur_sel = sel;
if (p_menu->pp_msgs[p_menu->cur_sel][0] == ' ' ||
p_menu->pp_msgs[p_menu->cur_sel][0] == '#' ||
IS_SUBMENU(p_menu->pp_msgs[p_menu->cur_sel]))
select_next(p_menu, 0, 1 , 1);
}
/*
static int is_submenu_title(menu_t *p_menu, int n)
{
if (n+1 >= p_menu->n_entries)
return 0;
else
return IS_SUBMENU(p_menu->pp_msgs[n+1]);
}
*/
static void menu_init_internal(menu_t *p_menu, const char *title,
TTF_Font *p_font, const char **pp_msgs,
int16_t x1, int16_t y1, int16_t x2, int16_t y2)
{
int submenu;
int j;
memset(p_menu, 0, sizeof(menu_t));
p_menu->pp_msgs = pp_msgs;
p_menu->p_font = p_font;
p_menu->x1 = x1;
p_menu->y1 = y1;
p_menu->x2 = x2;
p_menu->y2 = y2;
p_menu->text_w = 0;
p_menu->n_submenus = 0;
strcpy(p_menu->title, title);
for (p_menu->n_entries = 0; p_menu->pp_msgs[p_menu->n_entries]; p_menu->n_entries++)
{
int text_w_font;
/* Is this a submenu? */
if (IS_SUBMENU(p_menu->pp_msgs[p_menu->n_entries]))
{
p_menu->n_submenus++;
continue; /* Length of submenus is unimportant */
}
if (TTF_SizeText(p_font, p_menu->pp_msgs[p_menu->n_entries], &text_w_font, NULL) != 0)
{
fprintf(stderr, "%s\n", TTF_GetError());
exit(1);
}
if (text_w_font > p_menu->text_w)
p_menu->text_w = text_w_font;
}
if (p_menu->text_w > p_menu->x2 - p_menu->x1)
p_menu->text_w = p_menu->x2 - p_menu->x1;
if ( !(p_menu->p_submenus = (submenu_t *)malloc(sizeof(submenu_t) * p_menu->n_submenus)) )
{
perror("malloc failed!\n");
exit(1);
}
j=0;
submenu = 0;
for (; j < p_menu->n_entries; j++)
{
if (IS_SUBMENU(p_menu->pp_msgs[j]))
{
int n;
p_menu->p_submenus[submenu].index = j;
p_menu->p_submenus[submenu].sel = 0;
p_menu->p_submenus[submenu].n_entries = 0;
for (n=0; p_menu->pp_msgs[j][n] != '\0'; n++)
{
if (p_menu->pp_msgs[j][n] == '|')
p_menu->p_submenus[submenu].n_entries++;
}
submenu++;
}
}
p_menu->text_h = p_menu->n_entries * (TTF_FontHeight(p_font) + TTF_FontHeight(p_font) / 4);
}
static void menu_fini(menu_t *p_menu)
{
free(p_menu->p_submenus);
}
uint32_t menu_wait_key_press(void)
{
SDL_Event ev;
uint32_t keys = 0;
while (1)
{
int i, hats, nr;
SDL_Joystick *joy;
static int joy_keys_changed;
static int joy_keys_last;
SDL_JoystickUpdate();
/* Wii-specific, sorry */
for (nr = 0; nr < ordenador.joystick_number; nr++) {
joy = ordenador.joystick_sdl[nr];
if (!joy)
continue;
hats = SDL_JoystickNumHats (joy);
for (i = 0; i < hats; i++) {
Uint8 v = SDL_JoystickGetHat (joy, i);
if (v & SDL_HAT_UP)
keys |= KEY_UP;
if (v & SDL_HAT_DOWN)
keys |= KEY_DOWN;
if (v & SDL_HAT_LEFT)
keys |= KEY_LEFT;
if (v & SDL_HAT_RIGHT)
keys |= KEY_RIGHT;
}
Sint16 axis0 = SDL_JoystickGetAxis(joy, 0);
Sint16 axis1 = SDL_JoystickGetAxis(joy, 1);
if ( axis0 < -15000 ) keys |= KEY_LEFT;
else if (axis0 > 15000 ) keys |= KEY_RIGHT;
if (axis1 < -15000 ) keys |= KEY_UP;
else if( axis1 > 15000 ) keys |= KEY_DOWN;
if (SDL_JoystickGetButton(joy, 0) != 0 || /* A */
SDL_JoystickGetButton(joy, 3) != 0 || /* 2 */
SDL_JoystickGetButton(joy, 9) != 0 || /* CA */
SDL_JoystickGetButton(joy, 10) != 0) /* CB */
keys |= KEY_SELECT;
if (SDL_JoystickGetButton(joy, 2) != 0 || /* 1 */
SDL_JoystickGetButton(joy, 11) != 0 || /* CX */
SDL_JoystickGetButton(joy, 12) != 0) /* CY */
keys |= KEY_ESCAPE;
if (SDL_JoystickGetButton(joy, 5) != 0 || /* + */
SDL_JoystickGetButton(joy, 18) != 0) /* C+ */
keys |= KEY_PAGEUP;
if (SDL_JoystickGetButton(joy, 4) != 0 || /* + */
SDL_JoystickGetButton(joy, 17) != 0) /* C+ */
keys |= KEY_PAGEDOWN;
}
joy_keys_changed = keys != joy_keys_last;
joy_keys_last = keys;
if (!joy_keys_changed)
keys = 0;
if (SDL_PollEvent(&ev))
{
switch(ev.type)
{
case SDL_KEYDOWN:
switch (ev.key.keysym.sym)
{
case SDLK_UP:
keys |= KEY_UP;
break;
case SDLK_DOWN:
keys |= KEY_DOWN;
break;
case SDLK_LEFT:
keys |= KEY_LEFT;
break;
case SDLK_RIGHT:
keys |= KEY_RIGHT;
break;
case SDLK_PAGEDOWN:
keys |= KEY_PAGEDOWN;
break;
case SDLK_PAGEUP:
keys |= KEY_PAGEUP;
break;
case SDLK_RETURN:
case SDLK_SPACE:
keys |= KEY_SELECT;
break;
case SDLK_HOME:
case SDLK_ESCAPE:
keys |= KEY_ESCAPE;
break;
default:
break;
}
break;
case SDL_QUIT:
exit(0);
break;
default:
break;
}
break;
}
if (keys != 0)
break;
SDL_Delay(100);
}
return keys;
}
extern void PicDisplay(char *name, int off_x, int off_y, int wait);
extern const char **get_t64_list(char *t64);
extern const char **get_prg_list(char *t64);
extern char curdir[256];
static int menu_select_internal(SDL_Surface *screen,
menu_t *p_menu, int *p_submenus, int sel,
void (*select_next_cb)(menu_t *p, void *data),
void *select_next_cb_data, int font_size)
{
int ret = -1;
int i;
for (i = 0; i < p_menu->n_submenus; i++)
p_menu->p_submenus[i].sel = p_submenus[i];
while(1)
{
SDL_Rect r = {p_menu->x1, p_menu->y1,
p_menu->x2 - p_menu->x1, p_menu->y2 - p_menu->y1};
uint32_t keys;
int sel_last = p_menu->cur_sel;
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
menu_draw(screen, p_menu, 0, font_size);
SDL_Flip(screen);
keys = menu_wait_key_press();
if (keys & KEY_UP)
select_next(p_menu, 0, -1, 1);
else if (keys & KEY_DOWN)
select_next(p_menu, 0, 1, 1);
else if (keys & KEY_PAGEUP)
select_next(p_menu, 0, -18, 0);
else if (keys & KEY_PAGEDOWN)
select_next(p_menu, 0, 18, 0);
else if (keys & KEY_LEFT)
select_next(p_menu, -1, 0 ,1);
else if (keys & KEY_RIGHT)
select_next(p_menu, 1, 0 ,1);
else if (keys & KEY_ESCAPE)
break;
else if (keys & KEY_SELECT)
{
ret = p_menu->cur_sel;
int i;
for (i=0; i<p_menu->n_submenus; i++)
p_submenus[i] = p_menu->p_submenus[i].sel;
break;
}
/* Invoke the callback when an entry is selected */
if (sel_last != p_menu->cur_sel &&
select_next_cb != NULL)
select_next_cb(p_menu, select_next_cb_data);
}
SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
return ret;
}
int menu_select_sized(const char *title, const char **msgs, int *submenus, int sel,
int x, int y, int x2, int y2,
void (*select_next_cb)(menu_t *p, void *data),
void *select_next_cb_data, int font_size)
{
menu_t menu;
int out;
if (font_size == 16) menu_init_internal(&menu, title, menu_font16, msgs, x, y, x2, y2);
else menu_init_internal(&menu, title, menu_font20, msgs, x, y, x2, y2);
if (sel >= 0)
select_one(&menu, sel);
out = menu_select_internal(real_screen, &menu, submenus, sel,
select_next_cb, select_next_cb_data, font_size);
menu_fini(&menu);
return out;
}
int menu_select_title(const char *title, const char **msgs, int *submenus)
{
SDL_FillRect(real_screen, 0, SDL_MapRGB(real_screen->format, 0, 0, 0));
return menu_select_sized(title, msgs, submenus, 0,
32, 32, FULL_DISPLAY_X-32, FULL_DISPLAY_Y-32,
NULL, NULL, 20);
}
int menu_select(const char **msgs, int *submenus)
{
return menu_select_title("", msgs, submenus);
}
static const char *menu_select_file_internal(const char *dir_path,
int x, int y, int x2, int y2, const char *selected_file, int which)
{
const char **file_list = get_file_list(dir_path);
char *sel;
char *out;
const char *ptr_selected_file;
int opt;
int i;
char buf[64];
if (file_list == NULL)
return NULL;
if (selected_file)
{
ptr_selected_file= strrchr(selected_file,'/');
if (ptr_selected_file) ptr_selected_file++;
else ptr_selected_file = selected_file;
snprintf(buf,64,"tp%d:%s",which, ptr_selected_file);
opt = menu_select_sized(buf, file_list, NULL, 0, x, y, x2, y2, NULL, NULL, 16);
}
else opt = menu_select_sized("Select file", file_list, NULL, 0, x, y, x2, y2, NULL, NULL ,16);
if (opt < 0)
return NULL;
sel = strdup(file_list[opt]);
/* Cleanup everything - file_list is NULL-terminated */
for ( i = 0; file_list[i]; i++ )
free((void*)file_list[i]);
free(file_list);
if (!sel)
return NULL;
/* If this is a folder, enter it recursively */
if (sel[0] == '[')
{
char buf[255];
int len = strlen(sel);
int s;
/* Remove trailing ] */
sel[len-1] = '\0';
s = snprintf(buf, 128, "%s/%s", dir_path, sel + 1);
/* We don't need this anymore */
free((void*)sel);
/* Too deep recursion! */
if (s >= sizeof(buf))
return NULL;
return menu_select_file(buf, selected_file, which);
}
out = (char*)malloc(strlen(dir_path) + strlen(sel) + 4);
snprintf(out, strlen(dir_path) + strlen(sel) + 4,
"%s/%s", dir_path, sel);
free(sel);
return out;
}
/*
const char *menu_select_file_start(const char *dir_path, const char **d64_name)
{
const char *file = menu_select_file_internal(dir_path,
32, 32, FULL_DISPLAY_X, FULL_DISPLAY_Y - 32);
if (!file)
return NULL;
return file;
}
*/
const char *menu_select_file(const char *dir_path,const char *selected_file, int which)
{
if (dir_path == NULL)
dir_path = "";
return menu_select_file_internal(dir_path,
0, 32, FULL_DISPLAY_X, FULL_DISPLAY_Y - 32, selected_file, which);
}
static TTF_Font *read_font(const char *path, int font_size)
{
TTF_Font *out;
SDL_RWops *rw;
Uint8 *data = (Uint8*)malloc(1 * 1024*1024);
FILE *fp = fopen(path, "r");
if (!data) {
fprintf(stderr, "Malloc failed\n");
exit(1);
}
if (!fp) {
fprintf(stderr, "Could not open font\n");
exit(1);
}
fread(data, 1, 1 * 1024 * 1024, fp);
rw = SDL_RWFromMem(data, 1 * 1024 * 1024);
if (!rw)
{
fprintf(stderr, "Could not create RW: %s\n", SDL_GetError());
exit(1);
}
out = TTF_OpenFontRW(rw, 1, font_size);
if (!out)
{
fprintf(stderr, "Unable to open font %s\n", path);
exit(1);
}
fclose(fp);
return out;
}
void menu_init(SDL_Surface *screen)
{
TTF_Init();
menu_font16 = read_font(FONT_PATH, 16);
menu_font20 = read_font(FONT_PATH, 20);
real_screen = screen;
//virtkbd_init(screen, menu_font_alt16); per ora
is_inited = 1;
}
int menu_is_inited(void)
{
return is_inited;
}

62
src/menu_sdl.h Normal file
View File

@ -0,0 +1,62 @@
/*********************************************************************
*
* Copyright (C) 2004, 2008, Simon Kagstrom
*
* Filename: menu.h
* Author: Simon Kagstrom <simon.kagstrom@gmail.com>
* Description:
*
* $Id$
*
********************************************************************/
#ifndef __MENU_H__
#define __MENU_H__
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <stdint.h>
#if defined(__cplusplus)
extern "C" {
#endif
#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 KEY_HELP 256
#define FULL_DISPLAY_X 640
#define FULL_DISPLAY_Y 480
void menu_print_font(SDL_Surface *screen, int r, int g, int b, int x, int y, const char *msg, int font_size);
/* Various option selects */
int menu_select_title(const char *title, const char **pp_msgs, int *p_submenus);
int menu_select(const char **pp_msgs, int *p_submenus);
const char *menu_select_file(const char *dir_path,const char *selected_file, int which);
const char *menu_select_file_start(const char *dir_path, const char **d64_name);
uint32_t menu_wait_key_press(void);
extern void msgKill(SDL_Rect *rc);
extern int msgInfo(char *text, int duration, SDL_Rect *rc);
extern int msgYesNo(char *text, int def,int x, int y);
void menu_init(SDL_Surface *screen);
int menu_is_inited(void);
int ext_matches(const char *name, const char *ext);
#if defined(__cplusplus)
}
#endif
#endif /* !__MENU_H__ */