mirror of
https://github.com/Oibaf66/fbzx-wii.git
synced 2024-11-28 02:54:15 +01:00
Added extended mode key, new sdl menus controlled by joysticks
This commit is contained in:
parent
31aa295ee2
commit
93249b29bf
BIN
FreeMono.ttf
Normal file
BIN
FreeMono.ttf
Normal file
Binary file not shown.
3
Makefile
3
Makefile
@ -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
|
||||
|
@ -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>
|
@ -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>
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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
679
src/gui_sdl.c
Normal 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
976
src/menu_sdl.c
Normal 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
62
src/menu_sdl.h
Normal 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__ */
|
Loading…
Reference in New Issue
Block a user