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. FBZX CAN'T INITIALIZATE THE SDL LIBRARY.
Is possible that you don't have the '/dev/mouse' symlink, or maybe, that 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 symlink (or the device pointed by) has no access permissions for the user you
are using. Just try (as root): are using. Just try (as root):
FBZX SAYS THAT IS RUNNING WITHOUT SOUND, AND TO READ THE FAQ 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 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 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 you have a MP3 playing, without the PULSEAUDIO daemon launched, FBZX won't be
able to get access to the sound. able to get access to the sound.
WHAT SPEED DO I NEED TO USE FBZX? 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 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 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 *seems* to work even better, so maybe you could use it with an smaller
computer. computer.
FBZX CAN BE USED FROM X-WINDOWS? FBZX CAN BE USED FROM X-WINDOWS?
Since FBZX uses the SDL library, it can be used both from console and from X, 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 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 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. 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 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 FrameBuffer driver, in order to allow FBZX to change the current video mode
(see next question). (see next question).
You can use the -fb option to make FBZX work in fullscreen mode. 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... 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 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 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 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. driver. This is a VESA driver that allows to change the resolution on-the-fly.
You can find it in: You can find it in:
http://www.rastersoft.com/supervesafb.html http://www.rastersoft.com/supervesafb.html
This driver is only for 2.4 kernels. 2.6 versions have a new VESAFB driver This driver is only for 2.4 kernels. 2.6 versions have a new VESAFB driver
capable of switching the resolution. capable of switching the resolution.
MY COMPUTER DOESN'T HAVE FUNCTION KEYS (F1, F2...). HOW CAN I GET ACCESS TO MY COMPUTER DOESN'T HAVE FUNCTION KEYS (F1, F2...). HOW CAN I GET ACCESS TO
THE MENUS? THE MENUS?
Just press the TAB key and you will see the message "Function key mode on". 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', 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'). 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? 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 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, 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 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 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). than 24000 samples/sec I reduce the buffer to 2048 bytes).
THERE ARE SOME GLITCHES IN THE SOUND 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 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 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. CPU. I do this with aMule, and the glitches dissapears.
I TRIED TO LOAD A .TZX FILE, BUT THE EMULATOR SHOWS A MESSAGE THAT I TRIED TO LOAD A .TZX FILE, BUT THE EMULATOR SHOWS A MESSAGE THAT
TELLS: "Unsuported TZX. Contact FBZX autor". WHAT'S HAPPEN? TELLS: "Unsuported TZX. Contact FBZX autor". WHAT'S HAPPEN?
Just read the file README.TZX. Just read the file README.TZX.
I CHOOSE A .TZX FILE AND TYPE LOAD "", BUT NOTHING HAPPENS. 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, 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. 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 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? 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 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 for headers, and flag FF is for data blocks. A programmer can define its own
flag bytes if he wants. flag bytes if he wants.
If the program loader wants to load a block with a flag XX, but there isn't a 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 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 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 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, 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). 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, 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 IT DOESN'T WORK, AND I HAVE TO PRESS BREAK (SHIFT + SPACE) TO STOP THE
COMMAND. COMMAND.
When you create a MDR file, it is created "in blank", so you must format the 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: medium before using it. To do it, just use:
FORMAT "m";1;"name" FORMAT "m";1;"name"
changing 'name' with the name you want to give to the cartridge. 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. 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 THE SYSTEM RETURNS THE MESSAGE DRIVE 'WRITE' PROTECTED. WHAT CAN I DO TO
UNPROTECT IT? UNPROTECT IT?
Just press F7 and change the 'Write protection' status with F3. Remember that 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 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. 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? WHERE CAN I FIND INFO ABOUT HOW TO USE THE INTERFACE I AND THE MICRODRIVES?
In: In:
http://www.madhippy.com/8-bit/sinclair/zxif1micro.html http://www.madhippy.com/8-bit/sinclair/zxif1micro.html
you can find the HTML version of the original manual of the Interface I and 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. 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/tapes
mkdir -p $@/fbzx-wii/snapshots mkdir -p $@/fbzx-wii/snapshots
mkdir -p $@/fbzx-wii/microdrives mkdir -p $@/fbzx-wii/microdrives
mkdir -p $@/fbzx-wii/scr
mkdir -p $@/apps/fbzx-wii/doc mkdir -p $@/apps/fbzx-wii/doc
cp fbzx.dol $@/apps/fbzx-wii/boot.dol cp fbzx.dol $@/apps/fbzx-wii/boot.dol
cp spectrum-roms/* $@/fbzx-wii/spectrum-roms cp spectrum-roms/* $@/fbzx-wii/spectrum-roms
@ -127,6 +128,7 @@ dist: $(BUILD)
touch $@/fbzx-wii/tapes/dummy touch $@/fbzx-wii/tapes/dummy
touch $@/fbzx-wii/snapshots/dummy touch $@/fbzx-wii/snapshots/dummy
touch $@/fbzx-wii/microdrives/dummy touch $@/fbzx-wii/microdrives/dummy
touch $@/fbzx-wii/scr/dummy
cd $@ && tar -czf ../fbzx-wii-bin.tar.gz * cd $@ && tar -czf ../fbzx-wii-bin.tar.gz *
distsource: distsource:

446
README
View File

@ -1,223 +1,223 @@
FBZX FBZX
A ZX Spectrum emulator for FrameBuffer A ZX Spectrum emulator for FrameBuffer
DISCLAIMER DISCLAIMER
FBZX is distributed under the GPL license, version three or later, which means 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, that is distributed "as is", without warraty of any kind. To know more details,
read the file COPYING. read the file COPYING.
The old exception for the Z80 emulator has been removed because now FBZX uses 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 Z80FREE, a brand new, fully GPLv3, Z80 emulator. So finally FBZX is 100% free
software. software.
Amstrad have kindly given their permission for the redistribution of their Amstrad have kindly given their permission for the redistribution of their
copyrighted material (the original Spectrum ROMs) but retain that copyright. copyrighted material (the original Spectrum ROMs) but retain that copyright.
To know more details about how to distribute them, read the file AMSTRAD. To know more details about how to distribute them, read the file AMSTRAD.
WHAT IS FBZX? WHAT IS FBZX?
FBZX is a Sinclair ZX Spectrum emulator, designed to work in FrameBuffer under 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 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 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. 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. FBZX is based in Z80FREE, which you can find into the folder z80free.
To work with FBZX you need: To work with FBZX you need:
-A FrameBuffer-capable graphic card (or compatible with X-windows) -A FrameBuffer-capable graphic card (or compatible with X-windows)
-A Linux system with FrameBuffer configured (can use X too) -A Linux system with FrameBuffer configured (can use X too)
-Sound Card with ALSA or OSS drivers (optional) -Sound Card with ALSA or OSS drivers (optional)
In order to get the maximum performance, your FrameBuffer driver must allow to 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 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 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 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 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 driver, or the VESAFB driver from kernels 2.6, just don't worry: FBZX will
automagically change the graphic mode when starts. automagically change the graphic mode when starts.
WHAT CAPABILITIES HAVE FBZX? WHAT CAPABILITIES HAVE FBZX?
FBZX can emulate the original 48K spectrum (issue 2 and issue 3), the original 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. 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 screen and the sound are emulated in a very acuracy way, so nearly all
the sound and screen effects should work in this emulator. 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 128K sound is emulated too, and can be disabled in 128K mode in order to save
CPU time procesing, if your computer is slow. CPU time procesing, if your computer is slow.
It emulates the Interface I and one microdrive unit, allowing to load from and It emulates the Interface I and one microdrive unit, allowing to load from and
save to MDR files. save to MDR files.
FBZX can handle Z80 snapshots (both load and save) and SNA (only load). In a FBZX can handle Z80 snapshots (both load and save) and SNA (only load). In a
future, more snapshot formats will be supported. future, more snapshot formats will be supported.
FBZX can handle TAP files (load and save), and have a fast-load mode that allows 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 to load in milliseconds a TAP file. This fast-load mode is enabled by default, but
can be disabled. can be disabled.
FBZX can also handle TZX files (see README.TZX for details). FBZX can also handle TZX files (see README.TZX for details).
FBZX can emulate the Kempston, Cursor, Sinclair 1 and Sinclair 2 joysticks, 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 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 key, WINDOWS MENU key or WINDOWS SYSTEM right key), or with a real
JoyStick. JoyStick.
HOW DO I USE FBZX? HOW DO I USE FBZX?
To run FBZX just type To run FBZX just type
fbzx fbzx
from a console. from a console.
You can load a snapshot directly with: You can load a snapshot directly with:
fbzx game.z80 fbzx game.z80
fbzx game.sna fbzx game.sna
or assign a TAP or TZX file with: or assign a TAP or TZX file with:
fbzx game.tap fbzx game.tap
fbzx game.tzx fbzx game.tzx
(in this case you still must use LOAD ""). This allows you to asociate that (in this case you still must use LOAD ""). This allows you to asociate that
file extensions to FBZX. file extensions to FBZX.
You can use the option -fs to run it in FullScreen mode. If you use the -rotate 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) 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 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 FBZX in 480x640 mode but the screen won't be rotated, but will be half width
and height (very small). and height (very small).
You can run it without sound too, just typing: You can run it without sound too, just typing:
fbzx -nosound fbzx -nosound
You can use this if you don't have a sound card, or it hasn't OSS support. 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: You can combine theses options as you like. An example:
fbzx -nosound -fs fbzx -nosound -fs
fbzx -rotate -nosound fbzx -rotate -nosound
By default, FBZX will try to use ALSA sound; if it can't, it will try with OSS 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. sound; finally, if both fails it will use no sound and alert the user.
You can change the order with You can change the order with
fbzx -oss fbzx -oss
That way it will try firts with OSS, then with ALSA. 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 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 Window System. Fortunately this only applies to old systems. Current
computers can run FBZX under X without problem. computers can run FBZX under X without problem.
The PC keyboard works exactly like the Spectrum keyboard (but only numbers and 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 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 SHIFT is in both Control keys. Delete, ',' and '.' works too. I hope to add
'extended keys' in a near future. 'extended keys' in a near future (in FBZX it is TAB button).
Whit ESC you exit FBZX. Whit ESC you exit FBZX.
F1 shows a help page with all the available keys. F1 shows a help page with all the available keys.
F2 sends you to a menu where you can load and save snapshots. 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, 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 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. 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, 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 128K, +2, +2A or spanish 128K), the joystick, enable or disable the AY
emulation and enable or disable the Interface I. emulation and enable or disable the Interface I.
F5 stops the tape when normal speed is selected. With fast speed, it does F5 stops the tape when normal speed is selected. With fast speed, it does
nothing. nothing.
F6 plays the tape when normal speed is selected. With fast speed, it does F6 plays the tape when normal speed is selected. With fast speed, it does
nothing. nothing.
F7 allows to choose a MDR file (microdrive), protect and unprotect it, F7 allows to choose a MDR file (microdrive), protect and unprotect it,
and create a new (and empty) one. and create a new (and empty) one.
F8 allows to shows a picture with the keyboard layout, or insert POKE values F8 allows to shows a picture with the keyboard layout, or insert POKE values
F9 toggles between fullscreen/windowed mode F9 toggles between fullscreen/windowed mode (in FBZX Wii it launches LOAD "")
F10 resets the spectrum. F10 resets the spectrum.
F11 is volume down. F11 is volume down.
F12 is volume up. F12 is volume up.
If your system doesn't have function keys, you can use TAB plus keys 0 to 9 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). 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? 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 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. 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 The files are in white ink, the directories in green ink, and the upper
directory are the two red dots. directory are the two red dots.
When you choose a TAP file, it is marked as "save protected", so if you want 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 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. 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 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, 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 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. 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? 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 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 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 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. 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 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). 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 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. it again with F6 as many times you want.
When the tape ends, is automatically stoped and rewinded. You can rewind the 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). 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 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). 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 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 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. 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 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 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 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 routine. This means that, if you abort the save command, the block will be saved
in the TAP file anyway. in the TAP file anyway.
HOW WORKS THE INTERFACE I AND MICRODRIVE EMULATION? HOW WORKS THE INTERFACE I AND MICRODRIVE EMULATION?
FBZX can emulate an Interface I with one microdrive attached, but only when 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. 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 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. 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. 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 When you save something to the cartridge, the MDR file is updated as soon as
the Spectrum stops the "motor" of the drive. 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("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), 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("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) void VirtualKeyboard_init(SDL_Surface *screen, TTF_Font *font)
{ {
@ -97,7 +97,7 @@ void draw()
menu_print_font(VirtualKeyboard.screen, r, g, b, menu_print_font(VirtualKeyboard.screen, r, g, b,
x * key_w + border_x, y * key_h + border_y, 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() struct virtkey* get_key()
{ {
virtkey_t *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 + 0 ].is_done = 0; //Caps Shit
keys[3 * KEY_COLS + 8 ].is_done = 0; //Sym Shift 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; FILE *fichero;
unsigned char value,bucle; unsigned char value,bucle;
int retval; int retval;
fichero=fopen(filename,"r"); fichero=fopen(filename,"r");
if(fichero!=NULL) { if((fichero!=NULL)&&(!overwrite)) {
fclose(fichero); fclose(fichero);
return -1; // file already exists 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_z80(char *);
int load_sna(char *); int load_sna(char *);
void load_snap(struct z80snapshot *); void load_snap(struct z80snapshot *);

View File

@ -33,6 +33,10 @@
#include "microdrive.h" #include "microdrive.h"
#include "Virtualkeyboard.h" #include "Virtualkeyboard.h"
#include "gui_sdl.h" #include "gui_sdl.h"
#if defined(GEKKO)
# include <ogc/system.h>
# include <wiiuse/wpad.h>
#endif
#ifdef DEBUG #ifdef DEBUG
extern FILE *fdebug; extern FILE *fdebug;
@ -709,6 +713,10 @@ inline void read_keyboard () {
enum joystate_y {JOY_CENTER_Y, JOY_UP, JOY_DOWN}; enum joystate_y {JOY_CENTER_Y, JOY_UP, JOY_DOWN};
int joy_axis_x[2],joy_axis_y[2], joy_n, joybutton_n; int joy_axis_x[2],joy_axis_y[2], joy_n, joybutton_n;
static unsigned char joybutton_matrix[2][322]; 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.k8 = ordenador.k9 = ordenador.k10 = ordenador.k11 =
ordenador.k12 = ordenador.k13 = ordenador.k14 = 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_x[joy_n] = SDL_JoystickGetAxis(ordenador.joystick_sdl[joy_n], 0);
joy_axis_y[joy_n] = SDL_JoystickGetAxis(ordenador.joystick_sdl[joy_n], 1); 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) || if (SDL_JoystickGetButton(ordenador.joystick_sdl[joy_n], 6) ||
SDL_JoystickGetButton(ordenador.joystick_sdl[joy_n], 19)) main_menu(); //Wii button "Home" 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])] = joybutton_matrix[joy_n][(ordenador.joybuttonkey[joy_n][joybutton_n])] =
SDL_JoystickGetButton(ordenador.joystick_sdl[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 //Keyboard buffer
@ -764,8 +777,8 @@ inline void read_keyboard () {
{ {
if (countdown <5) if (countdown <5)
{ {
ordenador.key[(ordenador.keyboard_buffer[0][ordenador.kbd_buffer_pointer+1])]=0; joybutton_matrix[0][(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[1][ordenador.kbd_buffer_pointer+1])]=0;
ordenador.keyboard_buffer[0][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; ordenador.keyboard_buffer[1][ordenador.kbd_buffer_pointer+1] = 0;
} }
@ -773,11 +786,11 @@ inline void read_keyboard () {
} }
else if (ordenador.kbd_buffer_pointer) else if (ordenador.kbd_buffer_pointer)
{ {
ordenador.key[(ordenador.keyboard_buffer[0][ordenador.kbd_buffer_pointer])]=1; joybutton_matrix[0][(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[1][ordenador.kbd_buffer_pointer])]=1;
ordenador.kbd_buffer_pointer--; 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[0][1]= SDLK_F6; //F6
ordenador.keyboard_buffer[1][1]= 0; ordenador.keyboard_buffer[1][1]= 0;
ordenador.kbd_buffer_pointer=6; ordenador.kbd_buffer_pointer=6;
countdown=7; countdown=15;
break; break;
case SDLK_F10: // Reset emulator 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_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_RIGHT)ordenador.k12|= 4;
if (ordenador.joy_axis_x_state[joy_n] == JOY_LEFT) ordenador.k11|= 16; 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; break;
case 1: //Kempston 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_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_RIGHT) ordenador.jk|= 1;
if (ordenador.joy_axis_x_state[joy_n] == JOY_LEFT) ordenador.jk|= 2; 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; break;
case 2: // sinclair 1 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_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_RIGHT)ordenador.k11|= 2;
if (ordenador.joy_axis_x_state[joy_n] == JOY_LEFT) ordenador.k11|= 1; 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; break;
case 3: // sinclair 2 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_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_RIGHT)ordenador.k12|= 8;
if (ordenador.joy_axis_x_state[joy_n] == JOY_LEFT) ordenador.k12|= 16; 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; 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.s8 = (ordenador.s8 & 0xE0) | (ordenador.k8 ^ 0x1F);
ordenador.s9 = (ordenador.s9 & 0xE0) | (ordenador.k9 ^ 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.s15 = (ordenador.s15 & 0xE0)| (ordenador.k15 ^ 0x1F);
ordenador.js = ordenador.jk; 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; return;
} }

View File

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

View File

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

View File

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

View File

@ -74,7 +74,7 @@ static const char *emulation_messages[] = {
/*00*/ "Emulated machine", /*00*/ "Emulated machine",
/*01*/ "^|48k_2|48K_3|128k|+2|+2A/+3|128K_Sp", /*01*/ "^|48k_2|48K_3|128k|+2|+2A/+3|128K_Sp",
/*02*/ "Volume", /*02*/ "Volume",
/*03*/ "^|0%|25%|50%|75%|100%", /*03*/ "^|0|1|2|3|4|5|6|7|max",
/*04*/ "Tap fast speed", /*04*/ "Tap fast speed",
/*05*/ "^|on|off", /*05*/ "^|on|off",
/*06*/ "Turbo mode", /*06*/ "Turbo mode",
@ -91,31 +91,28 @@ static const char *emulation_messages[] = {
static const char *input_messages[] = { static const char *input_messages[] = {
/*00*/ "Joystick type", /*00*/ "Joystick type",
/*01*/ "^|Cursor|Kempston|Sinclair1|Sinclair2", /*01*/ "^|Cursor|Kempston|Sinclair1|Sinclair2",
/*02*/ " ", /*02*/ "Bind key to Wiimote",
/*03*/ "Bind key to Wiimote", /*03*/ "^|A|B|1|2|-",
/*04*/ "^|A|B|1|2|-", /*04*/ "Bind key to Nunchuk",
/*05*/ " ", /*05*/ "^|Z|C",
/*06*/ "Bind key to Nunchuk", /*06*/ "Bind key to Classic",
/*07*/ "^|Z|C", /*07*/ "^|a|b|x|y|L|R|Zl|Zr|-",
/*08*/ " ", /*08*/ "Bind key to Pad",
/*09*/ "Bind key to Classic", /*09*/ "^|UP|DOWN|LEFT|RIGHT",
/*10*/ "^|a|b|x|y|L|R|Zl|Zr|-", /*10*/ "Rumble",
/*11*/ " ", /*11*/ "^|On|Off",
/*12*/ "Rumble",
/*13*/ "^|On|Off",
NULL, NULL,
}; };
static const char *microdrive_messages[] = { static const char *microdrive_messages[] = {
/*00*/ "Select microdrive", /*00*/ "Microdrive",
/*01*/ " ", /*01*/ "^|Select|Create|Delete",
/*02*/ "Create microdrive file", /*02*/ " ",
/*03*/ " ", /*03*/ "Interface I",
/*04*/ "Interface I", /*04*/ "^|on|off",
/*05*/ "^|on|off", /*05*/ " ",
/*06*/ " ", /*06*/ "Write protection",
/*07*/ "Write protection", /*07*/ "^|on|off",
/*08*/ "^|on|off",
NULL NULL
}; };
@ -166,7 +163,7 @@ static void insert_tape()
if (filename==NULL) // Aborted if (filename==NULL) // Aborted
return; return;
if (strcmp(filename, "None") == 0) //TO FIX IT if (strstr(filename, "None") != NULL)
{ {
ordenador.current_tap[0] = '\0'; ordenador.current_tap[0] = '\0';
free((void *)filename); free((void *)filename);
@ -189,21 +186,22 @@ static void insert_tape()
retorno=-1; retorno=-1;
else else
retorno=0; retorno=0;
strcpy(ordenador.current_tap,filename);
free((void *)filename);
switch(retorno) { switch(retorno) {
case 0: // all right case 0: // all right
strcpy(ordenador.current_tap,filename);
strcpy(ordenador.last_selected_file,filename);
break; break;
case -1: case -1:
msgInfo("Error: Can't load that file",3000,NULL); msgInfo("Error: Can't load that file",3000,NULL);
ordenador.current_tap[0]=0; ordenador.current_tap[0]=0;
free((void *)filename);
return; return;
break; break;
} }
free((void *)filename);
retval=fread(char_id,10,1,ordenador.tap_file); // read the (maybe) TZX header 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)) { if((!strncmp(char_id,"ZXTape!",7)) && (char_id[7]==0x1A)&&(char_id[8]==1)) {
ordenador.tape_file_type = TAP_TZX; ordenador.tape_file_type = TAP_TZX;
@ -221,14 +219,9 @@ static void delete_tape()
if (filename==NULL) // Aborted if (filename==NULL) // Aborted
return; return;
if (strcmp(filename, "None") == 0) if ((ext_matches(filename, ".tap")|ext_matches(filename, ".TAP")|ext_matches(filename, ".tzx")|
{ ext_matches(filename, ".TZX"))
free((void *)filename); && (msgYesNo("Delete the file?", 0, FULL_DISPLAY_X /2-138, FULL_DISPLAY_Y /2-48))) unlink(filename);
return;
}
if (ext_matches(filename, ".tap")|ext_matches(filename, ".TAP")|ext_matches(filename, ".tzx")|
ext_matches(filename, ".TZX")) unlink(filename);
free((void *)filename); free((void *)filename);
} }
@ -243,7 +236,7 @@ static void manage_tape(int which)
break; break;
case 1: //Emulate load "" case 1: //Emulate load ""
ordenador.kbd_buffer_pointer=6; ordenador.kbd_buffer_pointer=6;
countdown=7; countdown=15;
ordenador.keyboard_buffer[0][6]= SDLK_1; //Edit ordenador.keyboard_buffer[0][6]= SDLK_1; //Edit
ordenador.keyboard_buffer[1][6]= SDLK_LSHIFT; ordenador.keyboard_buffer[1][6]= SDLK_LSHIFT;
ordenador.keyboard_buffer[0][5]= SDLK_j; //Load ordenador.keyboard_buffer[0][5]= SDLK_j; //Load
@ -275,6 +268,7 @@ static void manage_tape(int which)
break; break;
case 5: //Create case 5: //Create
// Create tape // Create tape
msgInfo("Not yet implemented",3000,NULL);
break; break;
case 6: //Delete case 6: //Delete
delete_tape(); delete_tape();
@ -336,7 +330,7 @@ static void emulation_settings(void)
memset(submenus, 0, sizeof(submenus)); memset(submenus, 0, sizeof(submenus));
submenus[0] = get_machine_model(); 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[2] = !ordenador.tape_fast_load;
submenus[3] = !ordenador.turbo; submenus[3] = !ordenador.turbo;
submenus[4] = !ordenador.dblscan; submenus[4] = !ordenador.dblscan;
@ -354,7 +348,7 @@ static void emulation_settings(void)
if (submenus[0] != submenus_old[0]) ResetComputer(); else if (submenus[0] != submenus_old[0]) ResetComputer(); else
ordenador.ay_emul = !submenus[6]; ordenador.ay_emul = !submenus[6];
ordenador.volume = submenus[1]*16; ordenador.volume = submenus[1]*8;
ordenador.tape_fast_load = !submenus[2]; ordenador.tape_fast_load = !submenus[2];
ordenador.turbo = !submenus[3]; ordenador.turbo = !submenus[3];
@ -377,7 +371,7 @@ static void setup_joystick(int joy, unsigned int sdl_key, int joy_key)
int loop; int loop;
//Cancel the previous assignement - it is not possible to assign a same sdl_key to 2 joybuttons //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; if (ordenador.joybuttonkey[joy][loop] == sdl_key) ordenador.joybuttonkey[joy][loop] =0;
ordenador.joybuttonkey[joy][joy_key] = sdl_key; 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 wiimote_to_sdl[] = {0, 1, 2, 3, 4};
const unsigned int nunchuk_to_sdl[] = {7, 8}; 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 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; int joy_key = 1;
unsigned int sdl_key; unsigned int sdl_key;
unsigned int submenus[5]; unsigned int submenus[6];
int opt; int opt;
struct virtkey *virtualkey; struct virtkey *virtualkey;
@ -399,7 +394,7 @@ static void input_options(int joy)
memset(submenus, 0, sizeof(submenus)); memset(submenus, 0, sizeof(submenus));
submenus[0] = ordenador.joystick[joy]; submenus[0] = ordenador.joystick[joy];
submenus[4] = !ordenador.rumble[joy]; submenus[5] = !ordenador.rumble[joy];
opt = menu_select_title("Input menu", opt = menu_select_title("Input menu",
input_messages, submenus); input_messages, submenus);
@ -407,9 +402,9 @@ static void input_options(int joy)
return; return;
ordenador.joystick[joy] = submenus[0]; 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; return;
virtualkey = get_key(); virtualkey = get_key();
@ -419,12 +414,14 @@ static void input_options(int joy)
switch(opt) switch(opt)
{ {
case 3: // wiimote case 2: // wiimote
joy_key = wiimote_to_sdl[submenus[1]]; break; joy_key = wiimote_to_sdl[submenus[1]]; break;
case 6: // nunchuk case 4: // nunchuk
joy_key = nunchuk_to_sdl[submenus[2]]; break; joy_key = nunchuk_to_sdl[submenus[2]]; break;
case 9: // classic case 6: // classic
joy_key = classic_to_sdl[submenus[3]]; break; joy_key = classic_to_sdl[submenus[3]]; break;
case 8: // pad
joy_key = pad_to_sdl[submenus[4]]; break;
default: default:
break; 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() static void microdrive()
{ {
unsigned int submenus[2], submenus_old[2]; unsigned int submenus[3], submenus_old[3];
int opt,retval ; int opt,retval ;
memset(submenus, 0, sizeof(submenus)); memset(submenus, 0, sizeof(submenus));
submenus[0] = !ordenador.mdr_active; submenus[1] = !ordenador.mdr_active;
submenus[1] = !ordenador.mdr_cartridge[137922]; submenus[2] = !ordenador.mdr_cartridge[137922];
submenus_old[0] = submenus[0];
submenus_old[1] = submenus[1]; submenus_old[1] = submenus[1];
submenus_old[2] = submenus[2];
opt = menu_select_title("Microdrive menu", opt = menu_select_title("Microdrive menu",
microdrive_messages, submenus); microdrive_messages, submenus);
if (opt < 0) if (opt < 0)
return; return;
ordenador.mdr_active = !submenus[0]; ordenador.mdr_active = !submenus[1];
if (submenus[0]!=submenus_old[0]) ResetComputer(); if (submenus[1]!=submenus_old[1]) ResetComputer();
if (submenus[1]!=submenus_old[1]) if (submenus[2]!=submenus_old[2])
{if(ordenador.mdr_cartridge[137922]) {if(ordenador.mdr_cartridge[137922])
ordenador.mdr_cartridge[137922]=0; ordenador.mdr_cartridge[137922]=0;
else else
@ -470,13 +523,18 @@ static void microdrive()
} }
} }
switch(opt) if (opt==0)
switch (submenus[0])
{ {
case 0: // Select microdrive case 0: // Select microdrive
//Select microdrive ; select_mdr();
break; break;
case 2: // Create microdrive file case 1: // Create microdrive file
// Create microdrive file ; // Create microdrive file ;
msgInfo("Not yet implemented",3000,NULL);
break;
case 2: // Delete microdrive file
delete_mdr();
break; break;
default: default:
break; break;
@ -506,6 +564,115 @@ void show_keyboard_layout() {
menu_wait_key_press(); 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() static void tools()
{ {
int opt ; int opt ;
@ -521,13 +688,14 @@ static void tools()
show_keyboard_layout(); show_keyboard_layout();
break; break;
case 2: // Save SCR case 2: // Save SCR
// Save SCR ; save_scr();
break; break;
case 4: // Load SCR case 4: // Load SCR
//Load SCR ; load_scr();
break; break;
case 6: // Insert poke case 6: // Insert poke
// Insert poke ; // Insert poke ;
msgInfo("Not yet implemented",3000,NULL);
break; break;
default: default:
break; break;
@ -576,7 +744,7 @@ void virtual_keyboard(void)
if (key) {key_code = key->sdl_code;} else return; if (key) {key_code = key->sdl_code;} else return;
ordenador.kbd_buffer_pointer=1; ordenador.kbd_buffer_pointer=1;
countdown=7; countdown=15;
ordenador.keyboard_buffer[0][1]= key_code; ordenador.keyboard_buffer[0][1]= key_code;
if (key->caps_on) ordenador.keyboard_buffer[1][1]= SDLK_LSHIFT; if (key->caps_on) ordenador.keyboard_buffer[1][1]= SDLK_LSHIFT;
else if (key->sym_on) ordenador.keyboard_buffer[1][1]= SDLK_LCTRL; 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) static void save_load_snapshot(int which)
{ {
const char *dir = path_snaps; const char *dir = path_snaps;
const char *tape = ordenador.current_tap; const char *tape = ordenador.last_selected_file;
char *ptr;
char db[256]; char db[256];
char fb[81]; char fb[81];
int retorno; int retorno;
@ -601,6 +768,10 @@ static void save_load_snapshot(int which)
strncpy(fb, strrchr(tape, '/') + 1, 80); strncpy(fb, strrchr(tape, '/') + 1, 80);
else else
strcpy(fb, "unknown"); strcpy(fb, "unknown");
//remove the extension
ptr = strrchr (fb, '.');
if (ptr) *ptr = 0;
switch(which) switch(which)
{ {
@ -621,6 +792,7 @@ static void save_load_snapshot(int which)
switch(retorno) { switch(retorno) {
case 0: // all right case 0: // all right
strcpy(ordenador.last_selected_file,filename);
break; break;
case -1: case -1:
msgInfo("Error: Can't load that file",3000,NULL); msgInfo("Error: Can't load that file",3000,NULL);
@ -632,21 +804,35 @@ static void save_load_snapshot(int which)
} }
} }
else // Delete snashot file 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); free((void*)filename);
} break; } break;
case 1: // Save snapshot file case 1: // Save snapshot file
snprintf(db, 255, "%s/%s.z80", dir, fb); snprintf(db, 255, "%s/%s.z80", dir, fb);
retorno=save_z80(db); retorno=save_z80(db,0);
msgInfo("Snapshot saved",3000,NULL); 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; break;
default: default:
break; break;
} }
} }
static void help(void) static void help(void)
{ {
menu_select_title("FBZX-WII help", menu_select_title("FBZX-WII help",
@ -708,6 +894,6 @@ void main_menu()
default: default:
break; 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]; char buf[255];
const char *exts[] = {".tap", ".TAP", ".tzx", ".TZX", ".z80",".Z80",".sna", ".SNA", const char *exts[] = {".tap", ".TAP", ".tzx", ".TZX", ".z80",".Z80",".sna", ".SNA",
".mdr", ".MDR", NULL}; ".mdr", ".MDR", ".scr", ".SCR", NULL};
struct stat st; struct stat st;
snprintf(buf, 255, "%s/%s", base_dir, de->d_name); snprintf(buf, 255, "%s/%s", base_dir, de->d_name);
@ -695,10 +695,10 @@ uint32_t menu_wait_key_press(void)
keys |= KEY_ESCAPE; keys |= KEY_ESCAPE;
if (SDL_JoystickGetButton(joy, 5) != 0 || /* + */ if (SDL_JoystickGetButton(joy, 5) != 0 || /* + */
SDL_JoystickGetButton(joy, 18) != 0) /* C+ */ SDL_JoystickGetButton(joy, 18) != 0) /* C+ */
keys |= KEY_PAGEUP;
if (SDL_JoystickGetButton(joy, 4) != 0 || /* + */
SDL_JoystickGetButton(joy, 17) != 0) /* C+ */
keys |= KEY_PAGEDOWN; 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_changed = keys != joy_keys_last;
joy_keys_last = keys; 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,'/'); ptr_selected_file= strrchr(selected_file,'/');
if (ptr_selected_file) ptr_selected_file++; if (ptr_selected_file) ptr_selected_file++;
else ptr_selected_file = 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); 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); 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 if(retorno==2) // abort
return; return;
retorno=save_z80(nombre2); retorno=save_z80(nombre2,0);
switch(retorno) { switch(retorno) {
case 0: case 0:
break; break;