Added rumble, added joypad binding, added src dir, added some messages, improved virtual keyboard, some bug fixes

This commit is contained in:
fabio.olimpieri 2012-05-01 10:10:41 +00:00
parent cd1ccf8cda
commit ccad9934b7
13 changed files with 761 additions and 510 deletions

266
FAQ
View File

@ -1,133 +1,133 @@
FBZX CAN'T INITIALIZATE THE SDL LIBRARY.
Is possible that you don't have the '/dev/mouse' symlink, or maybe, that
symlink (or the device pointed by) has no access permissions for the user you
are using. Just try (as root):
FBZX SAYS THAT IS RUNNING WITHOUT SOUND, AND TO READ THE FAQ
Currently FBZX uses ALSA, OSS or PulseAudio to generate the sound, and that
means that there can be only one sound source at each time in the system. If
you have a MP3 playing, without the PULSEAUDIO daemon launched, FBZX won't be
able to get access to the sound.
WHAT SPEED DO I NEED TO USE FBZX?
I'm not sure what's exactly the minimum speed, but I used it in an AMD K6-II
runing at 450 MHz and it worked at fully speed. Now, with the new OSS sound
*seems* to work even better, so maybe you could use it with an smaller
computer.
FBZX CAN BE USED FROM X-WINDOWS?
Since FBZX uses the SDL library, it can be used both from console and from X,
but, of course, in X it will need more system resources due to the fact that it
needs to emulate an 8-bit screen. Of course this was problematic with 2003
computers, but current systems can run FBZX under X without problems.
If you use it from console, it is strongly reccomended to use a native
FrameBuffer driver, in order to allow FBZX to change the current video mode
(see next question).
You can use the -fb option to make FBZX work in fullscreen mode.
I'M USING VESAFB IN MY (16-24 bits) CONSOLE, BUT FBZX WORKS SLOW...
That's because SDL is emulating an 8-bit screen for FBZX. The solution is to
change it for a FrameBuffer specific for your graphic card. If there's no
native driver (or it doesn't work reliably), you can use the SuperVESAfb
driver. This is a VESA driver that allows to change the resolution on-the-fly.
You can find it in:
http://www.rastersoft.com/supervesafb.html
This driver is only for 2.4 kernels. 2.6 versions have a new VESAFB driver
capable of switching the resolution.
MY COMPUTER DOESN'T HAVE FUNCTION KEYS (F1, F2...). HOW CAN I GET ACCESS TO
THE MENUS?
Just press the TAB key and you will see the message "Function key mode on".
Now you can use the number keys (0-9) to emulate the functions keys (F10 is '0',
F1 is '1', and so on, F11 is 'o' and F12 is 'p').
THERE'S A DELAY IN THE SOUND. HOW CAN I ELIMINATE IT?
Unfortunately, you can't. I have to use at least two buffers of 4096 bytes each
one in order to have an stable sound, and this means, at 48000 samples/sec,
0'17 seconds, and that's a perceptible delay for the human ear (with lower
sample rates it would became even worse; to avoid it, at sample rates lower
than 24000 samples/sec I reduce the buffer to 2048 bytes).
THERE ARE SOME GLITCHES IN THE SOUND
Maybe your CPU is too slow to run FBZX at full speed. But you can see with top
the load of each program, and give less priority to the ones that uses more
CPU. I do this with aMule, and the glitches dissapears.
I TRIED TO LOAD A .TZX FILE, BUT THE EMULATOR SHOWS A MESSAGE THAT
TELLS: "Unsuported TZX. Contact FBZX autor". WHAT'S HAPPEN?
Just read the file README.TZX.
I CHOOSE A .TZX FILE AND TYPE LOAD "", BUT NOTHING HAPPENS.
Fast load is available only with TAP files. If you want to load a TZX file,
you must press F6 in order to play the tape.
I TRIED TO LOAD A .TAP FILE IN FAST MODE, BUT IT FAILS AND THE EMULATOR
SHOWS THE MESSAGE "Block with right flag not found". WHAT'S HAPPENNING?
Each Spectrum's tape block has a flag byte that identify each one. Flag 0 is
for headers, and flag FF is for data blocks. A programmer can define its own
flag bytes if he wants.
If the program loader wants to load a block with a flag XX, but there isn't a
block in the TAP file with that flag, the fast loader will stop and show that
message (and will return a "Tape error" to the program loader). If I don't do
this, the fast loader should be reading the tape again and again, trying to
find a block with that flag, and the emulator should hang up (not really hang,
but it wouldn't be able to respond to keystrokes, even to the ESC key).
I CREATED A NEW MDR FILE, BUT WHEN I TRY TO WRITE TO IT, OR DO A CAT 1,
IT DOESN'T WORK, AND I HAVE TO PRESS BREAK (SHIFT + SPACE) TO STOP THE
COMMAND.
When you create a MDR file, it is created "in blank", so you must format the
medium before using it. To do it, just use:
FORMAT "m";1;"name"
changing 'name' with the name you want to give to the cartridge.
You can format a cartridge too if you want to erase a MDR file.
THE SYSTEM RETURNS THE MESSAGE DRIVE 'WRITE' PROTECTED. WHAT CAN I DO TO
UNPROTECT IT?
Just press F7 and change the 'Write protection' status with F3. Remember that
the status is stored with the cartridge, so if you exit the emulator and load
a MDR file again, it will have the same status you left it.
WHERE CAN I FIND INFO ABOUT HOW TO USE THE INTERFACE I AND THE MICRODRIVES?
In:
http://www.madhippy.com/8-bit/sinclair/zxif1micro.html
you can find the HTML version of the original manual of the Interface I and
Microdrive. There's ALL what you shoul need to know to work with it.
FBZX CAN'T INITIALIZATE THE SDL LIBRARY.
Is possible that you don't have the '/dev/mouse' symlink, or maybe, that
symlink (or the device pointed by) has no access permissions for the user you
are using. Just try (as root):
FBZX SAYS THAT IS RUNNING WITHOUT SOUND, AND TO READ THE FAQ
Currently FBZX uses ALSA, OSS or PulseAudio to generate the sound, and that
means that there can be only one sound source at each time in the system. If
you have a MP3 playing, without the PULSEAUDIO daemon launched, FBZX won't be
able to get access to the sound.
WHAT SPEED DO I NEED TO USE FBZX?
I'm not sure what's exactly the minimum speed, but I used it in an AMD K6-II
runing at 450 MHz and it worked at fully speed. Now, with the new OSS sound
*seems* to work even better, so maybe you could use it with an smaller
computer.
FBZX CAN BE USED FROM X-WINDOWS?
Since FBZX uses the SDL library, it can be used both from console and from X,
but, of course, in X it will need more system resources due to the fact that it
needs to emulate an 8-bit screen. Of course this was problematic with 2003
computers, but current systems can run FBZX under X without problems.
If you use it from console, it is strongly reccomended to use a native
FrameBuffer driver, in order to allow FBZX to change the current video mode
(see next question).
You can use the -fb option to make FBZX work in fullscreen mode.
I'M USING VESAFB IN MY (16-24 bits) CONSOLE, BUT FBZX WORKS SLOW...
That's because SDL is emulating an 8-bit screen for FBZX. The solution is to
change it for a FrameBuffer specific for your graphic card. If there's no
native driver (or it doesn't work reliably), you can use the SuperVESAfb
driver. This is a VESA driver that allows to change the resolution on-the-fly.
You can find it in:
http://www.rastersoft.com/supervesafb.html
This driver is only for 2.4 kernels. 2.6 versions have a new VESAFB driver
capable of switching the resolution.
MY COMPUTER DOESN'T HAVE FUNCTION KEYS (F1, F2...). HOW CAN I GET ACCESS TO
THE MENUS?
Just press the TAB key and you will see the message "Function key mode on".
Now you can use the number keys (0-9) to emulate the functions keys (F10 is '0',
F1 is '1', and so on, F11 is 'o' and F12 is 'p')(In FBZX this function has been disabled).
THERE'S A DELAY IN THE SOUND. HOW CAN I ELIMINATE IT?
Unfortunately, you can't. I have to use at least two buffers of 4096 bytes each
one in order to have an stable sound, and this means, at 48000 samples/sec,
0'17 seconds, and that's a perceptible delay for the human ear (with lower
sample rates it would became even worse; to avoid it, at sample rates lower
than 24000 samples/sec I reduce the buffer to 2048 bytes).
THERE ARE SOME GLITCHES IN THE SOUND
Maybe your CPU is too slow to run FBZX at full speed. But you can see with top
the load of each program, and give less priority to the ones that uses more
CPU. I do this with aMule, and the glitches dissapears.
I TRIED TO LOAD A .TZX FILE, BUT THE EMULATOR SHOWS A MESSAGE THAT
TELLS: "Unsuported TZX. Contact FBZX autor". WHAT'S HAPPEN?
Just read the file README.TZX.
I CHOOSE A .TZX FILE AND TYPE LOAD "", BUT NOTHING HAPPENS.
Fast load is available only with TAP files. If you want to load a TZX file,
you must press F6 in order to play the tape.
I TRIED TO LOAD A .TAP FILE IN FAST MODE, BUT IT FAILS AND THE EMULATOR
SHOWS THE MESSAGE "Block with right flag not found". WHAT'S HAPPENNING?
Each Spectrum's tape block has a flag byte that identify each one. Flag 0 is
for headers, and flag FF is for data blocks. A programmer can define its own
flag bytes if he wants.
If the program loader wants to load a block with a flag XX, but there isn't a
block in the TAP file with that flag, the fast loader will stop and show that
message (and will return a "Tape error" to the program loader). If I don't do
this, the fast loader should be reading the tape again and again, trying to
find a block with that flag, and the emulator should hang up (not really hang,
but it wouldn't be able to respond to keystrokes, even to the ESC key).
I CREATED A NEW MDR FILE, BUT WHEN I TRY TO WRITE TO IT, OR DO A CAT 1,
IT DOESN'T WORK, AND I HAVE TO PRESS BREAK (SHIFT + SPACE) TO STOP THE
COMMAND.
When you create a MDR file, it is created "in blank", so you must format the
medium before using it. To do it, just use:
FORMAT "m";1;"name"
changing 'name' with the name you want to give to the cartridge.
You can format a cartridge too if you want to erase a MDR file.
THE SYSTEM RETURNS THE MESSAGE DRIVE 'WRITE' PROTECTED. WHAT CAN I DO TO
UNPROTECT IT?
Just press F7 and change the 'Write protection' status with F3. Remember that
the status is stored with the cartridge, so if you exit the emulator and load
a MDR file again, it will have the same status you left it.
WHERE CAN I FIND INFO ABOUT HOW TO USE THE INTERFACE I AND THE MICRODRIVES?
In:
http://www.madhippy.com/8-bit/sinclair/zxif1micro.html
you can find the HTML version of the original manual of the Interface I and
Microdrive. There's ALL what you shoul need to know to work with it.

View File

@ -117,6 +117,7 @@ dist: $(BUILD)
mkdir -p $@/fbzx-wii/tapes
mkdir -p $@/fbzx-wii/snapshots
mkdir -p $@/fbzx-wii/microdrives
mkdir -p $@/fbzx-wii/scr
mkdir -p $@/apps/fbzx-wii/doc
cp fbzx.dol $@/apps/fbzx-wii/boot.dol
cp spectrum-roms/* $@/fbzx-wii/spectrum-roms
@ -127,6 +128,7 @@ dist: $(BUILD)
touch $@/fbzx-wii/tapes/dummy
touch $@/fbzx-wii/snapshots/dummy
touch $@/fbzx-wii/microdrives/dummy
touch $@/fbzx-wii/scr/dummy
cd $@ && tar -czf ../fbzx-wii-bin.tar.gz *
distsource:

446
README
View File

@ -1,223 +1,223 @@
FBZX
A ZX Spectrum emulator for FrameBuffer
DISCLAIMER
FBZX is distributed under the GPL license, version three or later, which means
that is distributed "as is", without warraty of any kind. To know more details,
read the file COPYING.
The old exception for the Z80 emulator has been removed because now FBZX uses
Z80FREE, a brand new, fully GPLv3, Z80 emulator. So finally FBZX is 100% free
software.
Amstrad have kindly given their permission for the redistribution of their
copyrighted material (the original Spectrum ROMs) but retain that copyright.
To know more details about how to distribute them, read the file AMSTRAD.
WHAT IS FBZX?
FBZX is a Sinclair ZX Spectrum emulator, designed to work in FrameBuffer under
Linux, but can work under Xwindows too, both in full screen mode and in a
window. It uses the SDL library, so it should be easily ported to other
architectures. Please, read the file PORTS to know more details about this.
FBZX is based in Z80FREE, which you can find into the folder z80free.
To work with FBZX you need:
-A FrameBuffer-capable graphic card (or compatible with X-windows)
-A Linux system with FrameBuffer configured (can use X too)
-Sound Card with ALSA or OSS drivers (optional)
In order to get the maximum performance, your FrameBuffer driver must allow to
change to 640x480 or 480x640 resolution in 8 bits. Only the old VESAFB driver can
have problems with this fact, so if you use this driver, be sure to boot your
Linux box in 640x480 in 8 bits. If you don't do this, SDL will emulate that
mode, resulting in a high performance penalty. If you use an specific Framebuffer
driver, or the VESAFB driver from kernels 2.6, just don't worry: FBZX will
automagically change the graphic mode when starts.
WHAT CAPABILITIES HAVE FBZX?
FBZX can emulate the original 48K spectrum (issue 2 and issue 3), the original
128K, the Amstrad +2, the Amstrad +2A and the Spanish 128K.
The screen and the sound are emulated in a very acuracy way, so nearly all
the sound and screen effects should work in this emulator.
128K sound is emulated too, and can be disabled in 128K mode in order to save
CPU time procesing, if your computer is slow.
It emulates the Interface I and one microdrive unit, allowing to load from and
save to MDR files.
FBZX can handle Z80 snapshots (both load and save) and SNA (only load). In a
future, more snapshot formats will be supported.
FBZX can handle TAP files (load and save), and have a fast-load mode that allows
to load in milliseconds a TAP file. This fast-load mode is enabled by default, but
can be disabled.
FBZX can also handle TZX files (see README.TZX for details).
FBZX can emulate the Kempston, Cursor, Sinclair 1 and Sinclair 2 joysticks,
with the cursor keys (fire is emulated with the right ALT key, ALT-GR
key, WINDOWS MENU key or WINDOWS SYSTEM right key), or with a real
JoyStick.
HOW DO I USE FBZX?
To run FBZX just type
fbzx
from a console.
You can load a snapshot directly with:
fbzx game.z80
fbzx game.sna
or assign a TAP or TZX file with:
fbzx game.tap
fbzx game.tzx
(in this case you still must use LOAD ""). This allows you to asociate that
file extensions to FBZX.
You can use the option -fs to run it in FullScreen mode. If you use the -rotate
option, FBZX will run in 480x640 mode (needed for some PDAs like the Zaurus)
rotating the screen 90 degrees. There's another option, -mini, that will run
FBZX in 480x640 mode but the screen won't be rotated, but will be half width
and height (very small).
You can run it without sound too, just typing:
fbzx -nosound
You can use this if you don't have a sound card, or it hasn't OSS support.
You can combine theses options as you like. An example:
fbzx -nosound -fs
fbzx -rotate -nosound
By default, FBZX will try to use ALSA sound; if it can't, it will try with OSS
sound; finally, if both fails it will use no sound and alert the user.
You can change the order with
fbzx -oss
That way it will try firts with OSS, then with ALSA.
FBZX works in X too, but it would run slower due to the penalty of the X
Window System. Fortunately this only applies to old systems. Current
computers can run FBZX under X without problem.
The PC keyboard works exactly like the Spectrum keyboard (but only numbers and
letters). ENTER key is Return, CAPS SHIFT is in both Shift keys, and SYMBOL
SHIFT is in both Control keys. Delete, ',' and '.' works too. I hope to add
'extended keys' in a near future.
Whit ESC you exit FBZX.
F1 shows a help page with all the available keys.
F2 sends you to a menu where you can load and save snapshots.
F3 sends you to a menu where you can choose a TAP/TZX file, rewind it,
choose if you want normal speed or fast speed for loading, enable or
disable the write protection, and create a new (and empty) TAP file.
F4 send you to a menu where you can choose the emulation type you want (48K,
128K, +2, +2A or spanish 128K), the joystick, enable or disable the AY
emulation and enable or disable the Interface I.
F5 stops the tape when normal speed is selected. With fast speed, it does
nothing.
F6 plays the tape when normal speed is selected. With fast speed, it does
nothing.
F7 allows to choose a MDR file (microdrive), protect and unprotect it,
and create a new (and empty) one.
F8 allows to shows a picture with the keyboard layout, or insert POKE values
F9 toggles between fullscreen/windowed mode
F10 resets the spectrum.
F11 is volume down.
F12 is volume up.
If your system doesn't have function keys, you can use TAB plus keys 0 to 9
to emulate them (F11 is TAB and O, and F12 is TAB and P).
HOW DO I CHOOSE A FILE WITH THE TAP/TZX OR Z80/SNA SELECTOR?
You can choose a file just by moving the white bar with the cursor keys. You
can use also the RePag and AvPag to jump over 12 positions.
The files are in white ink, the directories in green ink, and the upper
directory are the two red dots.
When you choose a TAP file, it is marked as "save protected", so if you want
to save programs, you must enable it. If you create a new TAP file, it is
marked as "save enabled", so you can start to save directly.
The SAVE option works only with the classic ROM routine, so you will be able
to save from programs that use them (it can save programs without header, too,
since the emulator intercepts the call to SA-BYTES). Each new block is added at
the end of the file, but only if the SAVE operation is enabled for this file.
HOW WORKS THE FAST SPEED LOAD AND SAVE FOR TAP FILES?
Just type LOAD "" in the emulator (or choose the TAPE LOADER option in the 128K
menu) and the tape will automagically load. This only works with programs that
uses the ROM to load all the blocks. If you have a TAP file with a program that
uses a custom routine to load the blocks, then you must use the NORMAL SPEED.
To do this, press F3 to go to the TAP menu and choose NORMAL SPEED. Then return
to the emulation (with ESC) and use LOAD "" (or the TAPE LOADER option).
Finally, put the tape in Play with F6. You can stop the tape with F5 and start
it again with F6 as many times you want.
When the tape ends, is automatically stoped and rewinded. You can rewind the
tape when you want with the right option in the TAP menu (F3 key).
In a near future a block manager will be added, in order to allow the user to
choose a block into the TAP file (thinking in multistage games).
Remember that the Fast Speed is available only for TAP files, not in TZX. In
the last case you can go to the SETTINGS menu (F4) and change the TURBO mode
to FAST, so the tape will load faster, and then change again to NORMAL.
The FAST SPEED applies when saving too. The SAVE operation is done ALWAYS
when SA-BYTES (in the Spectrum ROM) is called. The difference between FAST and
normal SAVE is that FAST returns inmediately, and NORMAL calls the original
routine. This means that, if you abort the save command, the block will be saved
in the TAP file anyway.
HOW WORKS THE INTERFACE I AND MICRODRIVE EMULATION?
FBZX can emulate an Interface I with one microdrive attached, but only when
working as Spectrum 48K, 128K or +2, never as +2A/+3 since it's incompatible.
You just have to choose an MDR file (or create a new MDR file) using the F7
key, and you will be able to use all the Interface I commands and programs.
Remember to format your cartridge (MDR file) after creating one.
When you save something to the cartridge, the MDR file is updated as soon as
the Spectrum stops the "motor" of the drive.
FBZX
A ZX Spectrum emulator for FrameBuffer
DISCLAIMER
FBZX is distributed under the GPL license, version three or later, which means
that is distributed "as is", without warraty of any kind. To know more details,
read the file COPYING.
The old exception for the Z80 emulator has been removed because now FBZX uses
Z80FREE, a brand new, fully GPLv3, Z80 emulator. So finally FBZX is 100% free
software.
Amstrad have kindly given their permission for the redistribution of their
copyrighted material (the original Spectrum ROMs) but retain that copyright.
To know more details about how to distribute them, read the file AMSTRAD.
WHAT IS FBZX?
FBZX is a Sinclair ZX Spectrum emulator, designed to work in FrameBuffer under
Linux, but can work under Xwindows too, both in full screen mode and in a
window. It uses the SDL library, so it should be easily ported to other
architectures. Please, read the file PORTS to know more details about this.
FBZX is based in Z80FREE, which you can find into the folder z80free.
To work with FBZX you need:
-A FrameBuffer-capable graphic card (or compatible with X-windows)
-A Linux system with FrameBuffer configured (can use X too)
-Sound Card with ALSA or OSS drivers (optional)
In order to get the maximum performance, your FrameBuffer driver must allow to
change to 640x480 or 480x640 resolution in 8 bits. Only the old VESAFB driver can
have problems with this fact, so if you use this driver, be sure to boot your
Linux box in 640x480 in 8 bits. If you don't do this, SDL will emulate that
mode, resulting in a high performance penalty. If you use an specific Framebuffer
driver, or the VESAFB driver from kernels 2.6, just don't worry: FBZX will
automagically change the graphic mode when starts.
WHAT CAPABILITIES HAVE FBZX?
FBZX can emulate the original 48K spectrum (issue 2 and issue 3), the original
128K, the Amstrad +2, the Amstrad +2A and the Spanish 128K.
The screen and the sound are emulated in a very acuracy way, so nearly all
the sound and screen effects should work in this emulator.
128K sound is emulated too, and can be disabled in 128K mode in order to save
CPU time procesing, if your computer is slow.
It emulates the Interface I and one microdrive unit, allowing to load from and
save to MDR files.
FBZX can handle Z80 snapshots (both load and save) and SNA (only load). In a
future, more snapshot formats will be supported.
FBZX can handle TAP files (load and save), and have a fast-load mode that allows
to load in milliseconds a TAP file. This fast-load mode is enabled by default, but
can be disabled.
FBZX can also handle TZX files (see README.TZX for details).
FBZX can emulate the Kempston, Cursor, Sinclair 1 and Sinclair 2 joysticks,
with the cursor keys (fire is emulated with the right ALT key, ALT-GR
key, WINDOWS MENU key or WINDOWS SYSTEM right key), or with a real
JoyStick.
HOW DO I USE FBZX?
To run FBZX just type
fbzx
from a console.
You can load a snapshot directly with:
fbzx game.z80
fbzx game.sna
or assign a TAP or TZX file with:
fbzx game.tap
fbzx game.tzx
(in this case you still must use LOAD ""). This allows you to asociate that
file extensions to FBZX.
You can use the option -fs to run it in FullScreen mode. If you use the -rotate
option, FBZX will run in 480x640 mode (needed for some PDAs like the Zaurus)
rotating the screen 90 degrees. There's another option, -mini, that will run
FBZX in 480x640 mode but the screen won't be rotated, but will be half width
and height (very small).
You can run it without sound too, just typing:
fbzx -nosound
You can use this if you don't have a sound card, or it hasn't OSS support.
You can combine theses options as you like. An example:
fbzx -nosound -fs
fbzx -rotate -nosound
By default, FBZX will try to use ALSA sound; if it can't, it will try with OSS
sound; finally, if both fails it will use no sound and alert the user.
You can change the order with
fbzx -oss
That way it will try firts with OSS, then with ALSA.
FBZX works in X too, but it would run slower due to the penalty of the X
Window System. Fortunately this only applies to old systems. Current
computers can run FBZX under X without problem.
The PC keyboard works exactly like the Spectrum keyboard (but only numbers and
letters). ENTER key is Return, CAPS SHIFT is in both Shift keys, and SYMBOL
SHIFT is in both Control keys. Delete, ',' and '.' works too. I hope to add
'extended keys' in a near future (in FBZX it is TAB button).
Whit ESC you exit FBZX.
F1 shows a help page with all the available keys.
F2 sends you to a menu where you can load and save snapshots.
F3 sends you to a menu where you can choose a TAP/TZX file, rewind it,
choose if you want normal speed or fast speed for loading, enable or
disable the write protection, and create a new (and empty) TAP file.
F4 send you to a menu where you can choose the emulation type you want (48K,
128K, +2, +2A or spanish 128K), the joystick, enable or disable the AY
emulation and enable or disable the Interface I.
F5 stops the tape when normal speed is selected. With fast speed, it does
nothing.
F6 plays the tape when normal speed is selected. With fast speed, it does
nothing.
F7 allows to choose a MDR file (microdrive), protect and unprotect it,
and create a new (and empty) one.
F8 allows to shows a picture with the keyboard layout, or insert POKE values
F9 toggles between fullscreen/windowed mode (in FBZX Wii it launches LOAD "")
F10 resets the spectrum.
F11 is volume down.
F12 is volume up.
If your system doesn't have function keys, you can use TAB plus keys 0 to 9
to emulate them (F11 is TAB and O, and F12 is TAB and P)(In FBZX this function has been disabled).
HOW DO I CHOOSE A FILE WITH THE TAP/TZX OR Z80/SNA SELECTOR?
You can choose a file just by moving the white bar with the cursor keys. You
can use also the RePag and AvPag to jump over 12 positions.
The files are in white ink, the directories in green ink, and the upper
directory are the two red dots.
When you choose a TAP file, it is marked as "save protected", so if you want
to save programs, you must enable it. If you create a new TAP file, it is
marked as "save enabled", so you can start to save directly.
The SAVE option works only with the classic ROM routine, so you will be able
to save from programs that use them (it can save programs without header, too,
since the emulator intercepts the call to SA-BYTES). Each new block is added at
the end of the file, but only if the SAVE operation is enabled for this file.
HOW WORKS THE FAST SPEED LOAD AND SAVE FOR TAP FILES?
Just type LOAD "" in the emulator (or choose the TAPE LOADER option in the 128K
menu) and the tape will automagically load. This only works with programs that
uses the ROM to load all the blocks. If you have a TAP file with a program that
uses a custom routine to load the blocks, then you must use the NORMAL SPEED.
To do this, press F3 to go to the TAP menu and choose NORMAL SPEED. Then return
to the emulation (with ESC) and use LOAD "" (or the TAPE LOADER option).
Finally, put the tape in Play with F6. You can stop the tape with F5 and start
it again with F6 as many times you want.
When the tape ends, is automatically stoped and rewinded. You can rewind the
tape when you want with the right option in the TAP menu (F3 key).
In a near future a block manager will be added, in order to allow the user to
choose a block into the TAP file (thinking in multistage games).
Remember that the Fast Speed is available only for TAP files, not in TZX. In
the last case you can go to the SETTINGS menu (F4) and change the TURBO mode
to FAST, so the tape will load faster, and then change again to NORMAL.
The FAST SPEED applies when saving too. The SAVE operation is done ALWAYS
when SA-BYTES (in the Spectrum ROM) is called. The difference between FAST and
normal SAVE is that FAST returns inmediately, and NORMAL calls the original
routine. This means that, if you abort the save command, the block will be saved
in the TAP file anyway.
HOW WORKS THE INTERFACE I AND MICRODRIVE EMULATION?
FBZX can emulate an Interface I with one microdrive attached, but only when
working as Spectrum 48K, 128K or +2, never as +2A/+3 since it's incompatible.
You just have to choose an MDR file (or create a new MDR file) using the F7
key, and you will be able to use all the Interface I commands and programs.
Remember to format your cartridge (MDR file) after creating one.
When you save something to the cartridge, the MDR file is updated as soon as
the Spectrum stops the "motor" of the drive.

View File

@ -50,7 +50,7 @@ static virtkey_t keys[KEY_COLS * KEY_ROWS] = {
K("Q",113), K("W",119), K("E",101), K("R",114), K("T",116), K("Y",121), K("U",117), K("I",105), K("O",111), K("P",112),
K("A",97), K("S",115), K("D",100), K("F",102), K("G",103), K("H",104), K("J",106), K("K",107), K("L",108),N("Enter","RETURN",13),
N("Caps","LSHIFT",304),K("Z",122),K("X",120),K("C",99), K("V",118), K("B",98), K("N",110), K("M",109), N("Sym","LCTRL",306),N("Space","SPACE",32),
N("Ext","TAB",9), KNL(), N("Fire","LALT",308),KNL(), K("None",0),KNL(),KNL(), KNL(),KNL(),KNL()};
N("Ext","TAB",9), K("None",0),N("Del","BACKSPACE",8),K(",",44),K(".",46),N("Fire","LALT",308), K("UP",273),K("DOWN",274), K("LEFT",276),K("RIGHT",275)};
void VirtualKeyboard_init(SDL_Surface *screen, TTF_Font *font)
{
@ -97,7 +97,7 @@ void draw()
menu_print_font(VirtualKeyboard.screen, r, g, b,
x * key_w + border_x, y * key_h + border_y,
what, 20);
what, 16);
}
}
}
@ -170,7 +170,7 @@ struct virtkey *get_key_internal()
struct virtkey* get_key()
{
virtkey_t *key;
SDL_Rect rect = {32, 32, FULL_DISPLAY_X-64, FULL_DISPLAY_Y-96};
SDL_Rect rect = {32, 128, FULL_DISPLAY_X-64, FULL_DISPLAY_Y-272};
keys[3 * KEY_COLS + 0 ].is_done = 0; //Caps Shit
keys[3 * KEY_COLS + 8 ].is_done = 0; //Sym Shift

View File

@ -77,14 +77,14 @@ void uncompress_z80(FILE *fichero,int length,unsigned char *memo) {
}
int save_z80(char *filename) {
int save_z80(char *filename, int overwrite) {
FILE *fichero;
unsigned char value,bucle;
int retval;
fichero=fopen(filename,"r");
if(fichero!=NULL) {
if((fichero!=NULL)&&(!overwrite)) {
fclose(fichero);
return -1; // file already exists
}

View File

@ -37,7 +37,7 @@ struct z80snapshot {
};
int save_z80(char *);
int save_z80(char *, int);
int load_z80(char *);
int load_sna(char *);
void load_snap(struct z80snapshot *);

View File

@ -33,6 +33,10 @@
#include "microdrive.h"
#include "Virtualkeyboard.h"
#include "gui_sdl.h"
#if defined(GEKKO)
# include <ogc/system.h>
# include <wiiuse/wpad.h>
#endif
#ifdef DEBUG
extern FILE *fdebug;
@ -709,6 +713,10 @@ inline void read_keyboard () {
enum joystate_y {JOY_CENTER_Y, JOY_UP, JOY_DOWN};
int joy_axis_x[2],joy_axis_y[2], joy_n, joybutton_n;
static unsigned char joybutton_matrix[2][322];
unsigned char status_hat;
int fire_on[2];
fire_on[0]=0;
fire_on[1]=0;
ordenador.k8 = ordenador.k9 = ordenador.k10 = ordenador.k11 =
ordenador.k12 = ordenador.k13 = ordenador.k14 =
@ -729,7 +737,6 @@ inline void read_keyboard () {
{
joy_axis_x[joy_n] = SDL_JoystickGetAxis(ordenador.joystick_sdl[joy_n], 0);
joy_axis_y[joy_n] = SDL_JoystickGetAxis(ordenador.joystick_sdl[joy_n], 1);
//ordenador.joy_fire[joy_n] = SDL_JoystickGetButton(ordenador.joystick_sdl[joy_n], 0); //Wii button "A"
if (SDL_JoystickGetButton(ordenador.joystick_sdl[joy_n], 6) ||
SDL_JoystickGetButton(ordenador.joystick_sdl[joy_n], 19)) main_menu(); //Wii button "Home"
@ -755,7 +762,13 @@ inline void read_keyboard () {
{
joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][joybutton_n])] =
SDL_JoystickGetButton(ordenador.joystick_sdl[joy_n], joybutton_n);
}
}
//JOY HAT
status_hat = SDL_JoystickGetHat(ordenador.joystick_sdl[joy_n], 0);
joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][18])] = (status_hat & SDL_HAT_UP);
joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][19])] = (status_hat & SDL_HAT_DOWN);
joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][20])] = (status_hat & SDL_HAT_LEFT);
joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][21])] = (status_hat & SDL_HAT_RIGHT);
}
//Keyboard buffer
@ -764,8 +777,8 @@ inline void read_keyboard () {
{
if (countdown <5)
{
ordenador.key[(ordenador.keyboard_buffer[0][ordenador.kbd_buffer_pointer+1])]=0;
ordenador.key[(ordenador.keyboard_buffer[1][ordenador.kbd_buffer_pointer+1])]=0;
joybutton_matrix[0][(ordenador.keyboard_buffer[0][ordenador.kbd_buffer_pointer+1])]=0;
joybutton_matrix[0][(ordenador.keyboard_buffer[1][ordenador.kbd_buffer_pointer+1])]=0;
ordenador.keyboard_buffer[0][ordenador.kbd_buffer_pointer+1] = 0;
ordenador.keyboard_buffer[1][ordenador.kbd_buffer_pointer+1] = 0;
}
@ -773,11 +786,11 @@ inline void read_keyboard () {
}
else if (ordenador.kbd_buffer_pointer)
{
ordenador.key[(ordenador.keyboard_buffer[0][ordenador.kbd_buffer_pointer])]=1;
ordenador.key[(ordenador.keyboard_buffer[1][ordenador.kbd_buffer_pointer])]=1;
joybutton_matrix[0][(ordenador.keyboard_buffer[0][ordenador.kbd_buffer_pointer])]=1;
joybutton_matrix[0][(ordenador.keyboard_buffer[1][ordenador.kbd_buffer_pointer])]=1;
ordenador.kbd_buffer_pointer--;
countdown=7;
countdown=15;
}
@ -831,7 +844,7 @@ inline void read_keyboard () {
ordenador.keyboard_buffer[0][1]= SDLK_F6; //F6
ordenador.keyboard_buffer[1][1]= 0;
ordenador.kbd_buffer_pointer=6;
countdown=7;
countdown=15;
break;
case SDLK_F10: // Reset emulator
@ -883,7 +896,7 @@ inline void read_keyboard () {
if (ordenador.joy_axis_y_state[joy_n] == JOY_DOWN) ordenador.k12|= 16;
if (ordenador.joy_axis_x_state[joy_n] == JOY_RIGHT)ordenador.k12|= 4;
if (ordenador.joy_axis_x_state[joy_n] == JOY_LEFT) ordenador.k11|= 16;
if (joybutton_matrix[joy_n][SDLK_LALT]) ordenador.k12|= 1; //fire button
if (joybutton_matrix[joy_n][SDLK_LALT]) {ordenador.k12|= 1; fire_on[joy_n]=1;}//fire button
break;
case 1: //Kempston
@ -891,7 +904,7 @@ inline void read_keyboard () {
if (ordenador.joy_axis_y_state[joy_n] == JOY_DOWN) ordenador.jk|= 4;
if (ordenador.joy_axis_x_state[joy_n] == JOY_RIGHT) ordenador.jk|= 1;
if (ordenador.joy_axis_x_state[joy_n] == JOY_LEFT) ordenador.jk|= 2;
if (joybutton_matrix[joy_n][SDLK_LALT]) ordenador.jk |= 16; //fire button
if (joybutton_matrix[joy_n][SDLK_LALT]) {ordenador.jk |= 16; fire_on[joy_n]=1;}//fire button
break;
case 2: // sinclair 1
@ -899,7 +912,7 @@ inline void read_keyboard () {
if (ordenador.joy_axis_y_state[joy_n] == JOY_DOWN)ordenador.k11|= 4;
if (ordenador.joy_axis_x_state[joy_n] == JOY_RIGHT)ordenador.k11|= 2;
if (ordenador.joy_axis_x_state[joy_n] == JOY_LEFT) ordenador.k11|= 1;
if (joybutton_matrix[joy_n][SDLK_LALT]) ordenador.k11|= 16; //fire button
if (joybutton_matrix[joy_n][SDLK_LALT]) {ordenador.k11|= 16;fire_on[joy_n]=1;} //fire button
break;
case 3: // sinclair 2
@ -907,68 +920,113 @@ inline void read_keyboard () {
if (ordenador.joy_axis_y_state[joy_n] == JOY_DOWN)ordenador.k12|= 4;
if (ordenador.joy_axis_x_state[joy_n] == JOY_RIGHT)ordenador.k12|= 8;
if (ordenador.joy_axis_x_state[joy_n] == JOY_LEFT) ordenador.k12|= 16;
if (joybutton_matrix[joy_n][SDLK_LALT]) ordenador.k12|= 1; //fire button
if (joybutton_matrix[joy_n][SDLK_LALT]) {ordenador.k12|= 1; fire_on[joy_n]=1;}//fire button
break;
}
}
if (ordenador.key[SDLK_SPACE]) ordenador.k15|=1;
if (ordenador.key[SDLK_RCTRL]||ordenador.key[SDLK_LCTRL]) ordenador.k15|=2; //Symbol shift
if ((ordenador.key[SDLK_m] || joybutton_matrix[0][SDLK_m] || joybutton_matrix[1][SDLK_m])) ordenador.k15|=4;
if ((ordenador.key[SDLK_n] || joybutton_matrix[0][SDLK_n] || joybutton_matrix[1][SDLK_n])) ordenador.k15|=8;
if ((ordenador.key[SDLK_b] || joybutton_matrix[0][SDLK_b] || joybutton_matrix[1][SDLK_b])) ordenador.k15|=16;
if (ordenador.key[SDLK_PERIOD]) ordenador.k15|=6;
if (ordenador.key[SDLK_COMMA]) ordenador.k15|=10;
if ((ordenador.key[SDLK_RETURN] || joybutton_matrix[0][SDLK_RETURN] || joybutton_matrix[1][SDLK_RETURN])) ordenador.k14|=1;
if ((ordenador.key[SDLK_l] || joybutton_matrix[0][SDLK_l] || joybutton_matrix[1][SDLK_l])) ordenador.k14|=2;
if ((ordenador.key[SDLK_k] || joybutton_matrix[0][SDLK_k] || joybutton_matrix[1][SDLK_k])) ordenador.k14|=4;
if ((ordenador.key[SDLK_j] || joybutton_matrix[0][SDLK_j] || joybutton_matrix[1][SDLK_j])) ordenador.k14|=8;
if ((ordenador.key[SDLK_h] || joybutton_matrix[0][SDLK_h] || joybutton_matrix[1][SDLK_h])) ordenador.k14|=16;
if ((ordenador.key[SDLK_p] || joybutton_matrix[0][SDLK_p] || joybutton_matrix[1][SDLK_p])) ordenador.k13|=1;
if ((ordenador.key[SDLK_o] || joybutton_matrix[0][SDLK_o] || joybutton_matrix[1][SDLK_o])) ordenador.k13|=2;
if ((ordenador.key[SDLK_i] || joybutton_matrix[0][SDLK_i] || joybutton_matrix[1][SDLK_i])) ordenador.k13|=4;
if ((ordenador.key[SDLK_u] || joybutton_matrix[0][SDLK_u] || joybutton_matrix[1][SDLK_u])) ordenador.k13|=8;
if ((ordenador.key[SDLK_y] || joybutton_matrix[0][SDLK_y] || joybutton_matrix[1][SDLK_y])) ordenador.k13|=16;
if ((ordenador.key[SDLK_0] || joybutton_matrix[0][SDLK_0] || joybutton_matrix[1][SDLK_0])) ordenador.k12|=1;
if ((ordenador.key[SDLK_9] || joybutton_matrix[0][SDLK_9] || joybutton_matrix[1][SDLK_9])) ordenador.k12|=2;
if ((ordenador.key[SDLK_8] || joybutton_matrix[0][SDLK_8] || joybutton_matrix[1][SDLK_8])) ordenador.k12|=4;
if ((ordenador.key[SDLK_7] || joybutton_matrix[0][SDLK_7] || joybutton_matrix[1][SDLK_7])) ordenador.k12|=8;
if ((ordenador.key[SDLK_6] || joybutton_matrix[0][SDLK_6] || joybutton_matrix[1][SDLK_6])) ordenador.k12|=16;
if ((ordenador.key[SDLK_BACKSPACE] || joybutton_matrix[0][SDLK_BACKSPACE] || joybutton_matrix[1][SDLK_BACKSPACE])) {ordenador.k12|=1; ordenador.k8 |=1;}
if ((ordenador.key[SDLK_1] || joybutton_matrix[0][SDLK_1] || joybutton_matrix[1][SDLK_1])) ordenador.k11|=1;
if ((ordenador.key[SDLK_2] || joybutton_matrix[0][SDLK_2] || joybutton_matrix[1][SDLK_2])) ordenador.k11|=2;
if ((ordenador.key[SDLK_3] || joybutton_matrix[0][SDLK_3] || joybutton_matrix[1][SDLK_3])) ordenador.k11|=4;
if ((ordenador.key[SDLK_4] || joybutton_matrix[0][SDLK_4] || joybutton_matrix[1][SDLK_4])) ordenador.k11|=8;
if ((ordenador.key[SDLK_5] || joybutton_matrix[0][SDLK_5] || joybutton_matrix[1][SDLK_5])) ordenador.k11|=16;
if ((ordenador.key[SDLK_q] || joybutton_matrix[0][SDLK_q] || joybutton_matrix[1][SDLK_q])) ordenador.k10|=1;
if ((ordenador.key[SDLK_w] || joybutton_matrix[0][SDLK_w] || joybutton_matrix[1][SDLK_w])) ordenador.k10|=2;
if ((ordenador.key[SDLK_e] || joybutton_matrix[0][SDLK_e] || joybutton_matrix[1][SDLK_e])) ordenador.k10|=4;
if ((ordenador.key[SDLK_r] || joybutton_matrix[0][SDLK_r] || joybutton_matrix[1][SDLK_r])) ordenador.k10|=8;
if ((ordenador.key[SDLK_t] || joybutton_matrix[0][SDLK_t] || joybutton_matrix[1][SDLK_t])) ordenador.k10|=16;
if ((ordenador.key[SDLK_a] || joybutton_matrix[0][SDLK_a] || joybutton_matrix[1][SDLK_a])) ordenador.k9 |=1;
if ((ordenador.key[SDLK_s] || joybutton_matrix[0][SDLK_s] || joybutton_matrix[1][SDLK_s])) ordenador.k9 |=2;
if ((ordenador.key[SDLK_d] || joybutton_matrix[0][SDLK_d] || joybutton_matrix[1][SDLK_d])) ordenador.k9 |=4;
if ((ordenador.key[SDLK_f] || joybutton_matrix[0][SDLK_f] || joybutton_matrix[1][SDLK_f])) ordenador.k9 |=8;
if ((ordenador.key[SDLK_g] || joybutton_matrix[0][SDLK_g] || joybutton_matrix[1][SDLK_g])) ordenador.k9 |=16;
if ((ordenador.key[SDLK_RSHIFT]||ordenador.key[SDLK_LSHIFT])) ordenador.k8 |=1; //Caps shift
if ((ordenador.key[SDLK_z] || joybutton_matrix[0][SDLK_z] || joybutton_matrix[1][SDLK_z])) ordenador.k8 |=2;
if ((ordenador.key[SDLK_x] || joybutton_matrix[0][SDLK_x] || joybutton_matrix[1][SDLK_x])) ordenador.k8 |=4;
if ((ordenador.key[SDLK_c] || joybutton_matrix[0][SDLK_c] || joybutton_matrix[1][SDLK_c])) ordenador.k8 |=8;
if ((ordenador.key[SDLK_v] || joybutton_matrix[0][SDLK_v] || joybutton_matrix[1][SDLK_v])) ordenador.k8 |=16;
if (ordenador.key[SDLK_UP]) {ordenador.k12 |=8;ordenador.k8|=1;}
if (ordenador.key[SDLK_DOWN]) {ordenador.k12 |=16;ordenador.k8|=1;}
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
#ifdef GEKKO
//Wiimote Rumble
static Uint32 last_ticks[2];
Uint32 cur_ticks;
static int rumble_on[2];
static int fire_pressed[2];
for(joy_n=0;joy_n<ordenador.joystick_number;joy_n++)
if (ordenador.rumble[joy_n])
{
cur_ticks = SDL_GetTicks();
if (fire_on[joy_n] && !rumble_on[joy_n] && !fire_pressed[joy_n])
{
WPAD_Rumble(joy_n, 1);
last_ticks[joy_n]= cur_ticks;
rumble_on[joy_n]=1;
fire_pressed[joy_n]=1;
}
if (!fire_on[joy_n] && rumble_on[joy_n] && fire_pressed[joy_n])
{
rumble_on[joy_n]=1;
fire_pressed[joy_n]=0;
}
if (((cur_ticks - last_ticks[joy_n] > 90) && rumble_on[joy_n] && !fire_pressed[joy_n]) ||(!fire_on[joy_n] && !rumble_on[joy_n] && fire_pressed[joy_n]))
{
WPAD_Rumble(joy_n, 0);
rumble_on[joy_n]=0;
fire_pressed[joy_n]=0;
}
if ((cur_ticks - last_ticks[joy_n] > 90) && rumble_on[joy_n] && fire_pressed[joy_n])
{
WPAD_Rumble(joy_n, 0);
rumble_on[joy_n]=0;
fire_pressed[joy_n]=1;
}
}
#endif
if (ordenador.key[SDLK_SPACE]|| joybutton_matrix[0][SDLK_SPACE] || joybutton_matrix[1][SDLK_SPACE]) ordenador.k15|=1;
if (ordenador.key[SDLK_RCTRL]||ordenador.key[SDLK_LCTRL]|| joybutton_matrix[0][SDLK_LCTRL] || joybutton_matrix[1][SDLK_LCTRL]) ordenador.k15|=2; //Symbol shift
if (ordenador.key[SDLK_m] || joybutton_matrix[0][SDLK_m] || joybutton_matrix[1][SDLK_m]) ordenador.k15|=4;
if (ordenador.key[SDLK_n] || joybutton_matrix[0][SDLK_n] || joybutton_matrix[1][SDLK_n]) ordenador.k15|=8;
if (ordenador.key[SDLK_b] || joybutton_matrix[0][SDLK_b] || joybutton_matrix[1][SDLK_b]) ordenador.k15|=16;
if (ordenador.key[SDLK_PERIOD] || joybutton_matrix[0][SDLK_PERIOD] || joybutton_matrix[1][SDLK_PERIOD]) ordenador.k15|=6;
if (ordenador.key[SDLK_COMMA]|| joybutton_matrix[0][SDLK_COMMA] || joybutton_matrix[1][SDLK_COMMA]) ordenador.k15|=10;
if (ordenador.key[SDLK_RETURN] || joybutton_matrix[0][SDLK_RETURN] || joybutton_matrix[1][SDLK_RETURN]) ordenador.k14|=1;
if (ordenador.key[SDLK_l] || joybutton_matrix[0][SDLK_l] || joybutton_matrix[1][SDLK_l]) ordenador.k14|=2;
if (ordenador.key[SDLK_k] || joybutton_matrix[0][SDLK_k] || joybutton_matrix[1][SDLK_k]) ordenador.k14|=4;
if (ordenador.key[SDLK_j] || joybutton_matrix[0][SDLK_j] || joybutton_matrix[1][SDLK_j]) ordenador.k14|=8;
if (ordenador.key[SDLK_h] || joybutton_matrix[0][SDLK_h] || joybutton_matrix[1][SDLK_h]) ordenador.k14|=16;
if (ordenador.key[SDLK_p] || joybutton_matrix[0][SDLK_p] || joybutton_matrix[1][SDLK_p]) ordenador.k13|=1;
if (ordenador.key[SDLK_o] || joybutton_matrix[0][SDLK_o] || joybutton_matrix[1][SDLK_o]) ordenador.k13|=2;
if (ordenador.key[SDLK_i] || joybutton_matrix[0][SDLK_i] || joybutton_matrix[1][SDLK_i]) ordenador.k13|=4;
if (ordenador.key[SDLK_u] || joybutton_matrix[0][SDLK_u] || joybutton_matrix[1][SDLK_u]) ordenador.k13|=8;
if (ordenador.key[SDLK_y] || joybutton_matrix[0][SDLK_y] || joybutton_matrix[1][SDLK_y]) ordenador.k13|=16;
if (ordenador.key[SDLK_0] || joybutton_matrix[0][SDLK_0] || joybutton_matrix[1][SDLK_0]) ordenador.k12|=1;
if (ordenador.key[SDLK_9] || joybutton_matrix[0][SDLK_9] || joybutton_matrix[1][SDLK_9]) ordenador.k12|=2;
if (ordenador.key[SDLK_8] || joybutton_matrix[0][SDLK_8] || joybutton_matrix[1][SDLK_8]) ordenador.k12|=4;
if (ordenador.key[SDLK_7] || joybutton_matrix[0][SDLK_7] || joybutton_matrix[1][SDLK_7]) ordenador.k12|=8;
if (ordenador.key[SDLK_6] || joybutton_matrix[0][SDLK_6] || joybutton_matrix[1][SDLK_6]) ordenador.k12|=16;
if (ordenador.key[SDLK_BACKSPACE] || joybutton_matrix[0][SDLK_BACKSPACE] || joybutton_matrix[1][SDLK_BACKSPACE]) {ordenador.k12|=1; ordenador.k8 |=1;}
if (ordenador.key[SDLK_1] || joybutton_matrix[0][SDLK_1] || joybutton_matrix[1][SDLK_1]) ordenador.k11|=1;
if (ordenador.key[SDLK_2] || joybutton_matrix[0][SDLK_2] || joybutton_matrix[1][SDLK_2]) ordenador.k11|=2;
if (ordenador.key[SDLK_3] || joybutton_matrix[0][SDLK_3] || joybutton_matrix[1][SDLK_3]) ordenador.k11|=4;
if (ordenador.key[SDLK_4] || joybutton_matrix[0][SDLK_4] || joybutton_matrix[1][SDLK_4]) ordenador.k11|=8;
if (ordenador.key[SDLK_5] || joybutton_matrix[0][SDLK_5] || joybutton_matrix[1][SDLK_5]) ordenador.k11|=16;
if (ordenador.key[SDLK_q] || joybutton_matrix[0][SDLK_q] || joybutton_matrix[1][SDLK_q]) ordenador.k10|=1;
if (ordenador.key[SDLK_w] || joybutton_matrix[0][SDLK_w] || joybutton_matrix[1][SDLK_w]) ordenador.k10|=2;
if (ordenador.key[SDLK_e] || joybutton_matrix[0][SDLK_e] || joybutton_matrix[1][SDLK_e]) ordenador.k10|=4;
if (ordenador.key[SDLK_r] || joybutton_matrix[0][SDLK_r] || joybutton_matrix[1][SDLK_r]) ordenador.k10|=8;
if (ordenador.key[SDLK_t] || joybutton_matrix[0][SDLK_t] || joybutton_matrix[1][SDLK_t]) ordenador.k10|=16;
if (ordenador.key[SDLK_a] || joybutton_matrix[0][SDLK_a] || joybutton_matrix[1][SDLK_a]) ordenador.k9 |=1;
if (ordenador.key[SDLK_s] || joybutton_matrix[0][SDLK_s] || joybutton_matrix[1][SDLK_s]) ordenador.k9 |=2;
if (ordenador.key[SDLK_d] || joybutton_matrix[0][SDLK_d] || joybutton_matrix[1][SDLK_d]) ordenador.k9 |=4;
if (ordenador.key[SDLK_f] || joybutton_matrix[0][SDLK_f] || joybutton_matrix[1][SDLK_f]) ordenador.k9 |=8;
if (ordenador.key[SDLK_g] || joybutton_matrix[0][SDLK_g] || joybutton_matrix[1][SDLK_g]) ordenador.k9 |=16;
if (ordenador.key[SDLK_RSHIFT]||ordenador.key[SDLK_LSHIFT]|| joybutton_matrix[0][SDLK_LSHIFT] || joybutton_matrix[1][SDLK_LSHIFT]) ordenador.k8 |=1; //Caps shift
if (ordenador.key[SDLK_z] || joybutton_matrix[0][SDLK_z] || joybutton_matrix[1][SDLK_z]) ordenador.k8 |=2;
if (ordenador.key[SDLK_x] || joybutton_matrix[0][SDLK_x] || joybutton_matrix[1][SDLK_x]) ordenador.k8 |=4;
if (ordenador.key[SDLK_c] || joybutton_matrix[0][SDLK_c] || joybutton_matrix[1][SDLK_c]) ordenador.k8 |=8;
if (ordenador.key[SDLK_v] || joybutton_matrix[0][SDLK_v] || joybutton_matrix[1][SDLK_v]) ordenador.k8 |=16;
if (ordenador.key[SDLK_UP]|| joybutton_matrix[0][SDLK_UP] || joybutton_matrix[1][SDLK_UP]) {ordenador.k12 |=8;ordenador.k8|=1;}
if (ordenador.key[SDLK_DOWN]|| joybutton_matrix[0][SDLK_DOWN] || joybutton_matrix[1][SDLK_DOWN]) {ordenador.k12 |=16;ordenador.k8|=1;}
if (ordenador.key[SDLK_LEFT]|| joybutton_matrix[0][SDLK_LEFT] || joybutton_matrix[1][SDLK_LEFT]) {ordenador.k11 |=16;ordenador.k8|=1;}
if (ordenador.key[SDLK_RIGHT]|| joybutton_matrix[0][SDLK_RIGHT] || joybutton_matrix[1][SDLK_RIGHT]) {ordenador.k12 |=4;ordenador.k8|=1;}
if (ordenador.key[SDLK_TAB]|| joybutton_matrix[0][SDLK_TAB] || joybutton_matrix[1][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);
@ -980,6 +1038,8 @@ inline void read_keyboard () {
ordenador.s15 = (ordenador.s15 & 0xE0)| (ordenador.k15 ^ 0x1F);
ordenador.js = ordenador.jk;
if (joybutton_matrix[0][SDLK_F6] && ((ordenador.tape_fast_load == 0) || (ordenador.tape_file_type==TAP_TZX)))
ordenador.pause = 0; //Play the tape
return;
}

View File

@ -148,6 +148,7 @@ struct computer {
FILE *tap_file;
unsigned char tape_fast_load; // 0 normal load; 1 fast load
unsigned char current_tap[2049];
unsigned char last_selected_file[2049];
unsigned char tape_current_bit;
unsigned int tape_block_level;
@ -204,7 +205,7 @@ struct computer {
unsigned char joy_axis_x_state[2];
unsigned char joy_axis_y_state[2];
//unsigned char joy_fire[2];
unsigned int joybuttonkey[2][18];
unsigned int joybuttonkey[2][22];
unsigned char rumble[2];
};

View File

@ -63,6 +63,7 @@ unsigned char *sound[NUM_SNDBUF];
char path_snaps[2049];
char path_taps[2049];
char path_mdrs[2049];
char path_scr[2049];
unsigned int colors[80];
unsigned int jump_frames,curr_frames;
char *filenames[5];
@ -724,9 +725,11 @@ int main(int argc,char *argv[]) {
strcat(path_snaps,"/");
strcpy(path_taps,path_snaps);
strcpy(path_mdrs,path_snaps);
strcpy(path_scr,path_snaps);
strcat(path_snaps,"snapshots");
strcat(path_taps,"tapes");
strcat(path_mdrs,"microdrives");
strcat(path_scr,"scr");
ordenador.current_tap[0]=0;
@ -847,8 +850,6 @@ int main(int argc,char *argv[]) {
}
}
//save_config(&ordenador);
#ifdef GEKKO
fatUnmount(0);
#endif

View File

@ -35,6 +35,7 @@ extern unsigned char *sound[NUM_SNDBUF];
extern char path_snaps[2049];
extern char path_taps[2049];
extern char path_mdrs[2049];
extern char path_scr[2049];
extern unsigned int colors[80];
extern unsigned int jump_frames,curr_frames;

View File

@ -74,7 +74,7 @@ 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%",
/*03*/ "^|0|1|2|3|4|5|6|7|max",
/*04*/ "Tap fast speed",
/*05*/ "^|on|off",
/*06*/ "Turbo mode",
@ -91,31 +91,28 @@ static const char *emulation_messages[] = {
static const char *input_messages[] = {
/*00*/ "Joystick type",
/*01*/ "^|Cursor|Kempston|Sinclair1|Sinclair2",
/*02*/ " ",
/*03*/ "Bind key to Wiimote",
/*04*/ "^|A|B|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",
/*02*/ "Bind key to Wiimote",
/*03*/ "^|A|B|1|2|-",
/*04*/ "Bind key to Nunchuk",
/*05*/ "^|Z|C",
/*06*/ "Bind key to Classic",
/*07*/ "^|a|b|x|y|L|R|Zl|Zr|-",
/*08*/ "Bind key to Pad",
/*09*/ "^|UP|DOWN|LEFT|RIGHT",
/*10*/ "Rumble",
/*11*/ "^|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",
/*00*/ "Microdrive",
/*01*/ "^|Select|Create|Delete",
/*02*/ " ",
/*03*/ "Interface I",
/*04*/ "^|on|off",
/*05*/ " ",
/*06*/ "Write protection",
/*07*/ "^|on|off",
NULL
};
@ -166,7 +163,7 @@ static void insert_tape()
if (filename==NULL) // Aborted
return;
if (strcmp(filename, "None") == 0) //TO FIX IT
if (strstr(filename, "None") != NULL)
{
ordenador.current_tap[0] = '\0';
free((void *)filename);
@ -189,21 +186,22 @@ static void insert_tape()
retorno=-1;
else
retorno=0;
strcpy(ordenador.current_tap,filename);
free((void *)filename);
switch(retorno) {
case 0: // all right
strcpy(ordenador.current_tap,filename);
strcpy(ordenador.last_selected_file,filename);
break;
case -1:
msgInfo("Error: Can't load that file",3000,NULL);
ordenador.current_tap[0]=0;
free((void *)filename);
return;
break;
}
free((void *)filename);
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;
@ -221,14 +219,9 @@ static void delete_tape()
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);
if ((ext_matches(filename, ".tap")|ext_matches(filename, ".TAP")|ext_matches(filename, ".tzx")|
ext_matches(filename, ".TZX"))
&& (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138, FULL_DISPLAY_Y /2-48))) unlink(filename);
free((void *)filename);
}
@ -243,7 +236,7 @@ static void manage_tape(int which)
break;
case 1: //Emulate load ""
ordenador.kbd_buffer_pointer=6;
countdown=7;
countdown=15;
ordenador.keyboard_buffer[0][6]= SDLK_1; //Edit
ordenador.keyboard_buffer[1][6]= SDLK_LSHIFT;
ordenador.keyboard_buffer[0][5]= SDLK_j; //Load
@ -275,6 +268,7 @@ static void manage_tape(int which)
break;
case 5: //Create
// Create tape
msgInfo("Not yet implemented",3000,NULL);
break;
case 6: //Delete
delete_tape();
@ -336,7 +330,7 @@ static void emulation_settings(void)
memset(submenus, 0, sizeof(submenus));
submenus[0] = get_machine_model();
submenus[1] = (unsigned int) (ordenador.volume/16);
submenus[1] = (unsigned int) (ordenador.volume/8);
submenus[2] = !ordenador.tape_fast_load;
submenus[3] = !ordenador.turbo;
submenus[4] = !ordenador.dblscan;
@ -354,7 +348,7 @@ static void emulation_settings(void)
if (submenus[0] != submenus_old[0]) ResetComputer(); else
ordenador.ay_emul = !submenus[6];
ordenador.volume = submenus[1]*16;
ordenador.volume = submenus[1]*8;
ordenador.tape_fast_load = !submenus[2];
ordenador.turbo = !submenus[3];
@ -377,7 +371,7 @@ static void setup_joystick(int joy, unsigned int sdl_key, int joy_key)
int loop;
//Cancel the previous assignement - it is not possible to assign a same sdl_key to 2 joybuttons
for (loop=0; loop<18; loop++)
for (loop=0; loop<22; loop++)
if (ordenador.joybuttonkey[joy][loop] == sdl_key) ordenador.joybuttonkey[joy][loop] =0;
ordenador.joybuttonkey[joy][joy_key] = sdl_key;
@ -389,9 +383,10 @@ static void input_options(int joy)
const unsigned int wiimote_to_sdl[] = {0, 1, 2, 3, 4};
const unsigned int nunchuk_to_sdl[] = {7, 8};
const unsigned int classic_to_sdl[] = {9, 10, 11, 12, 13, 14, 15, 16, 17};
const unsigned int pad_to_sdl[] = {18, 19, 20, 21};
int joy_key = 1;
unsigned int sdl_key;
unsigned int submenus[5];
unsigned int submenus[6];
int opt;
struct virtkey *virtualkey;
@ -399,7 +394,7 @@ static void input_options(int joy)
memset(submenus, 0, sizeof(submenus));
submenus[0] = ordenador.joystick[joy];
submenus[4] = !ordenador.rumble[joy];
submenus[5] = !ordenador.rumble[joy];
opt = menu_select_title("Input menu",
input_messages, submenus);
@ -407,9 +402,9 @@ static void input_options(int joy)
return;
ordenador.joystick[joy] = submenus[0];
ordenador.rumble[joy] = !submenus[4];
ordenador.rumble[joy] = !submenus[5];
if (opt == 0 || opt == 12)
if (opt == 0 || opt == 10)
return;
virtualkey = get_key();
@ -419,12 +414,14 @@ static void input_options(int joy)
switch(opt)
{
case 3: // wiimote
case 2: // wiimote
joy_key = wiimote_to_sdl[submenus[1]]; break;
case 6: // nunchuk
case 4: // nunchuk
joy_key = nunchuk_to_sdl[submenus[2]]; break;
case 9: // classic
case 6: // classic
joy_key = classic_to_sdl[submenus[3]]; break;
case 8: // pad
joy_key = pad_to_sdl[submenus[4]]; break;
default:
break;
}
@ -433,30 +430,86 @@ static void input_options(int joy)
}
static void select_mdr()
{
int retorno, retval;
const char *filename = menu_select_file(path_mdrs, ordenador.mdr_current_mdr, 0);
if (filename==NULL) // Aborted
return;
if (strstr(filename, "None") != NULL)
{
ordenador.mdr_current_mdr[0] = '\0';
free((void *)filename);
return;
}
if (!(ext_matches(filename, ".mdr")|ext_matches(filename, ".MDR"))) {free((void *)filename); return;}
ordenador.mdr_file=fopen(filename,"rb"); // read
if(ordenador.mdr_file==NULL)
retorno=-1;
else {
retorno=0;
retval=fread(ordenador.mdr_cartridge,137923,1,ordenador.mdr_file); // read the cartridge in memory
ordenador.mdr_modified=0; // not modified
fclose(ordenador.mdr_file);
ordenador.mdr_tapehead=0;
}
strcpy(ordenador.mdr_current_mdr,filename);
free((void *)filename);
switch(retorno) {
case 0: // all right
break;
default:
ordenador.mdr_current_mdr[0]=0;
msgInfo("Error: Can't load that file",3000,NULL);
break;
}
}
static void delete_mdr()
{
const char *filename = menu_select_file(path_mdrs, NULL, -1);
if (filename==NULL) // Aborted
return;
if ((ext_matches(filename, ".mdr")|ext_matches(filename, ".MDR"))
&& (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138, FULL_DISPLAY_Y /2-48))) unlink(filename);
free((void *)filename);
}
static void microdrive()
{
unsigned int submenus[2], submenus_old[2];
unsigned int submenus[3], submenus_old[3];
int opt,retval ;
memset(submenus, 0, sizeof(submenus));
submenus[0] = !ordenador.mdr_active;
submenus[1] = !ordenador.mdr_cartridge[137922];
submenus[1] = !ordenador.mdr_active;
submenus[2] = !ordenador.mdr_cartridge[137922];
submenus_old[0] = submenus[0];
submenus_old[1] = submenus[1];
submenus_old[2] = submenus[2];
opt = menu_select_title("Microdrive menu",
microdrive_messages, submenus);
if (opt < 0)
return;
ordenador.mdr_active = !submenus[0];
ordenador.mdr_active = !submenus[1];
if (submenus[0]!=submenus_old[0]) ResetComputer();
if (submenus[1]!=submenus_old[1])
if (submenus[1]!=submenus_old[1]) ResetComputer();
if (submenus[2]!=submenus_old[2])
{if(ordenador.mdr_cartridge[137922])
ordenador.mdr_cartridge[137922]=0;
else
@ -470,13 +523,18 @@ static void microdrive()
}
}
switch(opt)
if (opt==0)
switch (submenus[0])
{
case 0: // Select microdrive
//Select microdrive ;
select_mdr();
break;
case 2: // Create microdrive file
case 1: // Create microdrive file
// Create microdrive file ;
msgInfo("Not yet implemented",3000,NULL);
break;
case 2: // Delete microdrive file
delete_mdr();
break;
default:
break;
@ -506,6 +564,115 @@ void show_keyboard_layout() {
menu_wait_key_press();
}
static void load_scr()
{
int retorno,loop;
unsigned char value;
FILE *fichero;
unsigned char paleta_tmp[64];
const char *filename = menu_select_file(path_scr, NULL, -1);
if (filename==NULL) // Aborted
return;
if (!(ext_matches(filename, ".scr")|ext_matches(filename, ".SCR"))) {free((void *)filename); return;}
ordenador.osd_text[0]=0;
fichero=fopen(filename,"rb");
retorno=0;
if (!fichero) {
retorno=-1;
} else {
for(loop=0;loop<6912;loop++) {
if (1==fread(&value,1,1,fichero)) {
*(ordenador.block1 + 0x04000 + loop) = value;
} else {
retorno=-1;
break;
}
}
if (1==fread(paleta_tmp,64,1,fichero)) {
memcpy(ordenador.ulaplus_palete,paleta_tmp,64);
ordenador.ulaplus=1;
} else {
ordenador.ulaplus=0;
}
fclose(fichero);
}
switch(retorno) {
case 0: // all right
break;
case -1:
msgInfo("Error: Can't load that file",3000,NULL);
break;
default:
break;
}
free((void *)filename);
}
static void save_scr()
{
const char *dir = path_scr;
const char *tape = ordenador.last_selected_file;
char *ptr;
FILE *fichero;
char db[256];
char fb[81];
int retorno,retval;
// Name (for saves) - TO CHECK
if (tape && strrchr(tape, '/'))
strncpy(fb, strrchr(tape, '/') + 1, 80);
else
strcpy(fb, "unknown");
//remove the extension
ptr = strrchr (fb, '.');
if (ptr) *ptr = 0;
// Save SCR file
snprintf(db, 255, "%s/%s.scr", dir, fb);
fichero=fopen(db,"r");
if(fichero!=NULL)
{
fclose(fichero);
if (!msgYesNo("Overwrite the exiting file?", 0, FULL_DISPLAY_X /2-160, FULL_DISPLAY_Y /2-48))
return; // file already exists
}
fichero=fopen(db,"wb"); // create for write
if(fichero==NULL)
retorno=-1;
else {
retval=fwrite(ordenador.block1+0x04000,6912,1,fichero); // save screen
if (ordenador.ulaplus!=0) {
retval=fwrite(ordenador.ulaplus_palete,64,1,fichero); // save ULAPlus palete
}
fclose(fichero);
retorno=0;
}
switch(retorno) {
case 0:
msgInfo("SCR saved",3000,NULL);
break;
case -1:
msgInfo("Can't create file",3000,NULL);
break;
default:
break;
}
}
static void tools()
{
int opt ;
@ -521,13 +688,14 @@ static void tools()
show_keyboard_layout();
break;
case 2: // Save SCR
// Save SCR ;
save_scr();
break;
case 4: // Load SCR
//Load SCR ;
load_scr();
break;
case 6: // Insert poke
// Insert poke ;
msgInfo("Not yet implemented",3000,NULL);
break;
default:
break;
@ -576,7 +744,7 @@ void virtual_keyboard(void)
if (key) {key_code = key->sdl_code;} else return;
ordenador.kbd_buffer_pointer=1;
countdown=7;
countdown=15;
ordenador.keyboard_buffer[0][1]= key_code;
if (key->caps_on) ordenador.keyboard_buffer[1][1]= SDLK_LSHIFT;
else if (key->sym_on) ordenador.keyboard_buffer[1][1]= SDLK_LCTRL;
@ -586,12 +754,11 @@ void virtual_keyboard(void)
}
static void save_load_snapshot(int which)
{
const char *dir = path_snaps;
const char *tape = ordenador.current_tap;
const char *tape = ordenador.last_selected_file;
char *ptr;
char db[256];
char fb[81];
int retorno;
@ -601,6 +768,10 @@ static void save_load_snapshot(int which)
strncpy(fb, strrchr(tape, '/') + 1, 80);
else
strcpy(fb, "unknown");
//remove the extension
ptr = strrchr (fb, '.');
if (ptr) *ptr = 0;
switch(which)
{
@ -621,6 +792,7 @@ static void save_load_snapshot(int which)
switch(retorno) {
case 0: // all right
strcpy(ordenador.last_selected_file,filename);
break;
case -1:
msgInfo("Error: Can't load that file",3000,NULL);
@ -632,21 +804,35 @@ static void save_load_snapshot(int which)
}
}
else // Delete snashot file
unlink(filename);
if (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138, FULL_DISPLAY_Y /2-48)) unlink(filename);
}
free((void*)filename);
} break;
case 1: // Save snapshot file
snprintf(db, 255, "%s/%s.z80", dir, fb);
retorno=save_z80(db);
msgInfo("Snapshot saved",3000,NULL);
retorno=save_z80(db,0);
switch(retorno)
{
case 0: //OK
msgInfo("Snapshot saved",3000,NULL);
break;
case -1:
if (msgYesNo("Overwrite the exiting file?", 0, FULL_DISPLAY_X /2-160, FULL_DISPLAY_Y /2-48))
{
save_z80(db,1); //force overwrite
msgInfo("Snapshot saved",3000,NULL);
}
break;
case -2:
msgInfo("Can't create file",3000,NULL);
break;
}
break;
default:
break;
}
}
static void help(void)
{
menu_select_title("FBZX-WII help",
@ -708,6 +894,6 @@ void main_menu()
default:
break;
}
} while (opt == 5 || opt == 7 || opt == 8 || opt == 9 || opt == 12);
} while (opt == 5 || opt == 7 || opt == 8 || opt == 12);
}

View File

@ -281,7 +281,7 @@ static const char **get_file_list(const char *base_dir)
{
char buf[255];
const char *exts[] = {".tap", ".TAP", ".tzx", ".TZX", ".z80",".Z80",".sna", ".SNA",
".mdr", ".MDR", NULL};
".mdr", ".MDR", ".scr", ".SCR", NULL};
struct stat st;
snprintf(buf, 255, "%s/%s", base_dir, de->d_name);
@ -695,10 +695,10 @@ uint32_t menu_wait_key_press(void)
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;
if (SDL_JoystickGetButton(joy, 4) != 0 || /* - */
SDL_JoystickGetButton(joy, 17) != 0) /* C- */
keys |= KEY_PAGEUP;
}
joy_keys_changed = keys != joy_keys_last;
joy_keys_last = keys;
@ -878,7 +878,7 @@ static const char *menu_select_file_internal(const char *dir_path,
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);
snprintf(buf,64,"file:%s",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);

View File

@ -1510,7 +1510,7 @@ void save_z80file() {
if(retorno==2) // abort
return;
retorno=save_z80(nombre2);
retorno=save_z80(nombre2,0);
switch(retorno) {
case 0:
break;