diff --git a/Makefile b/Makefile
index 102cde2..88a94f1 100644
--- a/Makefile
+++ b/Makefile
@@ -45,8 +45,8 @@ CFLAGS = \
-g -O1 -Wall $(MACHDEP) $(INCLUDE) \
-DNOCRYPT -DWII -DBIG_ENDIAN -DWII_BIN2O \
-Wno-format-truncation \
- -Wno-narrowing
-
+ -Wno-narrowing
+#-DWII_NETTRACE
#-DLOWTRACE -DDEBUG
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
@@ -91,6 +91,7 @@ CPPFILES := \
Cartridge.cpp \
Common.cpp \
Database.cpp \
+ ExpansionModule.cpp \
Hash.cpp \
Logger.cpp \
Maria.cpp \
@@ -106,6 +107,7 @@ CPPFILES := \
Tia.cpp \
wii_atari.cpp \
wii_atari_config.cpp \
+ wii_atari_db.cpp \
wii_atari_emulation.cpp \
wii_atari_menu.cpp \
wii_atari_sdl.cpp \
diff --git a/README.md b/README.md
index 350c728..7cf027f 100644
--- a/README.md
+++ b/README.md
@@ -5,15 +5,16 @@
Ported by raz0red
-Wii7800 is a Nintendo Wii port of the ProSystem emulator developed by Greg Stanton.
+Wii7800 is a port of the ProSystem emulator developed by Greg Stanton.
Additional changes developed by Ludovic Jacomme aka Zx-81 (PSP port), Leonis,
and gdement. Portions of the Pokey code were adapted from the MAME
implementation.
[https://gstanton.github.io/ProSystem1_3/]
-| ![](https://wiibrew.org/w/images/thumb/1/16/7800-pole.gif/189px-7800-pole.gif) | ![](https://wiibrew.org/w/images/thumb/a/a5/7800-commando.gif/189px-7800-commando.gif) | ![](https://wiibrew.org/w/images/thumb/d/dd/7800-ninja.gif/189px-7800-ninja.gif) |
-|---|---|---|
+_Wii7800 0.5 + Atari 7800 Homebrew Video_
+
+
## Current status
@@ -29,26 +30,37 @@ please visit the [Wii7800 page](http://www.wiibrew.org/wiki/Wii7800) on WiiBrew:
## Installation
To install Wii7800, simply extract the zip file directly to your SD card
-(retain the hierarchical structure exactly).
-
-Cartridge images must be placed in the roms directory (/wii7800/roms).
-(Zip files are supported)
-
-Wii7800 does support loading of the Atari 7800 BIOS, although it isn't
-necessary. If you wish to use the BIOS, simply place the NTSC and PAL BIOS
-files in the (/wii7800) directory. The NTSC file must be named, "7800.rom",
-while the PAL file must be named, "7800pal.rom".
+or USB device (retain the hierarchical structure exactly).
## Lightgun Accuracy, etc.
-The crosshair for the Wii7800 emulator is not perfect. For example you may be
-pointing at something and your shot may register to the right or left. This is
-due to the way the 7800 handles hit detection for lightgun games. It only
-checks for a hit every 7 CPU cycles. There are 330 cycles for the visible
-portion of each frame. Thus, there are only ~47 hit points for each scanline.
-So, the crosshair at best gets you in approximately the right area, and if you
-miss you need to adjust based on where the shot shows up on the screen
-(exactly how you do it when there is no crosshair).
+The crosshair for the Wii7800 emulator is not perfect. For example, you
+may be pointing at something and your shot may register slightly to the
+right or left.
+
+## Cartridge Database
+
+Wii7800 ships with a database that contains recommended settings for the
+majority of commercial and a limited number of homebrew cartridges. These
+settings cover control settings, difficulty switch settings, and
+cartridge-related settings (cartridge type, Pokey support, XM support,
+high score cart support, etc.).
+
+To view/edit the settings applied for a particular cartridge perform the
+following steps:
+
+ * Load the cartridge (via the "Load cartridge" menu item)
+ * Return to the Wii7800 menu
+ * Select the "Cartridge-specific settings" menu item
+ * View/edit the settings for the cartridge
+
+Some settings will not be applied until the settings are saved and the
+cartridge is reloaded. When one of these settings is modified, a message
+will be displayed indicating that this particular setting requires the
+cartridge to be reloaded (and the settings saved prior to loading).
+
+Other settings, such as difficulty switch and control settings may not
+be applied until the cartridge is reset (or reloaded).
## Cartridge/ROM Compatibility
@@ -152,6 +164,17 @@ This page contains a list of compatible ROMs by "hash code".
1 : Left difficulty (if enabled)
2 : Right difficulty (if enabled)
Home : Display Wii7800 menu (see above)
+
+## SMB (Network support)
+
+Wii7800 allows for loading ROMs over the network via SMB. To enable SMB
+support, you must edit the "wii7800.conf" file located in the "/wii7800"
+directory and provide values for the following:
+
+ * share_ip : IP address of the computer to connect to.
+ * share_name : Name of the share on the computer.
+ * share_user : Name of the user to connect as
+ * share_pass : Password for the user
## Wii7800 crashes, code dumps, etc.
@@ -174,6 +197,48 @@ the following locations:
## Change log
+### 03/24/20 (0.5)
+ - Partial Expansion Module (XM) support
+ - XRAM
+ - XPokey (limited to single Pokey)
+ - Added support for cartridges with sizes greater than 144k
+ - Additional bank switching modes and cartridge types
+ - Multiple bank switching fixes
+ - Reworked cartridge header detection
+ - Now properly detects bank switching, RAM, etc.
+ - Detects Expansion Module (XM)
+ - Detects High score cartridge
+ - Detects Pokey at $0450
+ - Cartridge database
+ - Added ability to edit cartridge database settings via menu
+ - Added several new cartridge properties
+ - Pokey at $0450
+ - Default difficulty switch settings
+ - Expansion Module (XM) enabled/disabled
+ - High score cartridge enabled/disabled
+ - Database content
+ - Fixed incorrect controller settings for Sirius, Crossbow,
+ and Alien Brigade
+ - Added many homebrew cartridges
+ - Display enhancements
+ - Double strike (240p)
+ - GX+VI mode
+ - 16:9 correction
+ - Full widescreen support
+ - Ability to enable/disable bilinear filter (GX mode)
+ - Color trap filter
+ - Multiple default screen sizes
+ - Hierarchical file navigation support
+ - USB Support
+ - SMB (Network support) for loading ROMs
+ - Multi-save slot support
+ - Reworked menu system (cartridge-specific settings, etc.)
+ - Support for launching via WiiFlow (and returning)
+ - Fixed VSYNC issue which caused initial stutter on PAL games
+ - Fixed issue occurring when Kangaroo and Holey were enabled (caused
+ background to be displayed, resulting in large black squares)
+ - Several audio improvements (eliminated majority of TIA and Pokey pops)
+
### 11/16/19 (0.4)
- Reworked audio integration (resolves audio clipping and popping)
- Refactored project layout. Now includes third party libraries, which
@@ -239,4 +304,3 @@ the following locations:
- Controls support for Wiimote/Nunchuk/Classic/Gamecube controllers
- Analog controls support
- Dual analog support for Gamecube/Classic controllers (Robotron)
-
\ No newline at end of file
diff --git a/res/gfx/about.png b/res/gfx/about.png
index 22e94a2..da04cd0 100644
Binary files a/res/gfx/about.png and b/res/gfx/about.png differ
diff --git a/res/gfx/layers/wii7800.png b/res/gfx/layers/wii7800.png
index 86b162d..059e74f 100644
Binary files a/res/gfx/layers/wii7800.png and b/res/gfx/layers/wii7800.png differ
diff --git a/res/layout/apps/wii7800/README.wii b/res/layout/apps/wii7800/README.wii
index 07eea10..167f8b5 100644
--- a/res/layout/apps/wii7800/README.wii
+++ b/res/layout/apps/wii7800/README.wii
@@ -1,5 +1,5 @@
--------------------------------------------
-Wii7800 v0.5-SNAPSHOT release README
+Wii7800 v0.5 release README
--------------------------------------------
Ported by raz0red [github.com/raz0red]
@@ -37,14 +37,6 @@ Installation
To install Wii7800, simply extract the zip file directly to your SD card
or USB device (retain the hierarchical structure exactly).
-Cartridge images must be placed in the roms directory (/wii7800/roms).
-(Zip files are supported)
-
-Wii7800 does support loading of the Atari 7800 BIOS, although it isn't
-necessary. If you wish to use the BIOS, simply place the NTSC and PAL BIOS
-files in the (/wii7800) directory. The NTSC file must be named, "7800.rom",
-while the PAL file must be named, "7800pal.rom".
-
--------------------------------------------
Lightgun Accuracy, etc.
--------------------------------------------
@@ -53,6 +45,32 @@ The crosshair for the Wii7800 emulator is not perfect. For example, you
may be pointing at something and your shot may register slightly to the
right or left.
+--------------------------------------------
+Cartridge Database
+--------------------------------------------
+
+Wii7800 ships with a database that contains recommended settings for the
+majority of commercial and a limited number of homebrew cartridges. These
+settings cover control settings, difficulty switch settings, and
+cartridge-related settings (cartridge type, Pokey support, XM support,
+high score cart support, etc.).
+
+To view/edit the settings applied for a particular cartridge perform the
+following steps:
+
+ * Load the cartridge (via the "Load cartridge" menu item)
+ * Return to the Wii7800 menu
+ * Select the "Cartridge-specific settings" menu item
+ * View/edit the settings for the cartridge
+
+Some settings will not be applied until the settings are saved and the
+cartridge is reloaded. When one of these settings is modified, a message
+will be displayed indicating that this particular setting requires the
+cartridge to be reloaded (and the settings saved prior to loading).
+
+Other settings, such as difficulty switch and control settings may not
+be applied until the cartridge is reset (or reloaded).
+
--------------------------------------------
Cartridge/ROM Compatibility
--------------------------------------------
@@ -180,8 +198,8 @@ Wii7800 crashes, code dumps, etc.
If you are having issues with Wii7800, please let me know about it via one of
the following locations:
+[https://github.com/raz0red/wii7800/issues]
[http://www.wiibrew.org/wiki/Talk:Wii7800]
-[http://www.twitchasylum.com/forum/viewtopic.php?t=519]
--------------------------------------------
Special thanks
@@ -200,11 +218,30 @@ Team Twiizers : For enabling homebrew
Change log
--------------------------------------------
-TBD (0.5)
+03/24/20 (0.5)
---------------------
+ - Partial Expansion Module (XM) support
+ - XRAM
+ - XPokey (limited to single Pokey)
+ - Added support for cartridges with sizes greater than 144k
+ - Additional bank switching modes and cartridge types
+ - Multiple bank switching fixes
+ - Reworked cartridge header detection
+ - Now properly detects bank switching, RAM, etc.
+ - Detects Expansion Module (XM)
+ - Detects High score cartridge
+ - Detects Pokey at $0450
- Cartridge database
- - Fixed incorrect controller settings for Sirius
- - Added several homebrew titles (Arkanoid, etc.)
+ - Added ability to edit cartridge database settings via menu
+ - Added several new cartridge properties
+ - Pokey at $0450
+ - Default difficulty switch settings
+ - Expansion Module (XM) enabled/disabled
+ - High score cartridge enabled/disabled
+ - Database content
+ - Fixed incorrect controller settings for Sirius, Crossbow,
+ and Alien Brigade
+ - Added many homebrew cartridges
- Display enhancements
- Double strike (240p)
- GX+VI mode
@@ -212,11 +249,17 @@ TBD (0.5)
- Full widescreen support
- Ability to enable/disable bilinear filter (GX mode)
- Color trap filter
+ - Multiple default screen sizes
- Hierarchical file navigation support
- USB Support
- SMB (Network support) for loading ROMs
- Multi-save slot support
+ - Reworked menu system (cartridge-specific settings, etc.)
- Support for launching via WiiFlow (and returning)
+ - Fixed VSYNC issue which caused initial stutter on PAL games
+ - Fixed issue occurring when Kangaroo and Holey were enabled (caused
+ background to be displayed, resulting in large black squares)
+ - Several audio improvements (eliminated majority of TIA and Pokey pops)
11/16/19 (0.4)
---------------------
diff --git a/res/layout/apps/wii7800/meta.xml b/res/layout/apps/wii7800/meta.xml
index 0cd804c..8c0377d 100644
--- a/res/layout/apps/wii7800/meta.xml
+++ b/res/layout/apps/wii7800/meta.xml
@@ -2,7 +2,7 @@
Wii7800
raz0red
- 0.5-SNAPSHOT
+ 0.5
000000000000
Atari 7800 Emulator
Wii7800 is a port of the ProSystem emulator developed by Greg Stanton.
diff --git a/res/layout/wii7800/ProSystem.dat b/res/layout/wii7800/ProSystem.dat
index 35a789d..630d279 100644
--- a/res/layout/wii7800/ProSystem.dat
+++ b/res/layout/wii7800/ProSystem.dat
@@ -6,6 +6,9 @@ controller1=1
controller2=1
region=0
flags=0
+pokey450=false
+xm=false
+hsc=true
[0be996d25144966d5541c9eb4919b289]
title=Ace Of Aces
type=4
@@ -26,8 +29,8 @@ flags=0
title=Alien Brigade
type=2
pokey=false
-controller1=3
-controller2=3
+controller1=2
+controller2=2
region=0
flags=0
crossx=15
@@ -36,8 +39,8 @@ crossy=15
title=Alien Brigade
type=2
pokey=false
-controller1=3
-controller2=3
+controller1=2
+controller2=2
region=1
flags=0
crossx=15
@@ -67,6 +70,7 @@ controller1=1
controller2=1
region=0
flags=0
+pokey450=true
hblank=8
[07342c78619ba6ffcc61c10e907e3b50]
title=Asteroids
@@ -76,6 +80,7 @@ controller1=1
controller2=1
region=0
flags=0
+hsc=true
[8fc3a695eaea3984912d98ed4a543376]
title=Ballblazer
type=0
@@ -97,7 +102,7 @@ hblank=28
[42682415906c21c6af80e4198403ffda]
title=Barnyard Blaster
type=1
-pokey=true
+pokey=false
controller1=2
controller2=1
region=0
@@ -107,7 +112,7 @@ crossy=10
[babe2bc2976688bafb8b23c192658126]
title=Barnyard Blaster
type=1
-pokey=true
+pokey=false
controller1=2
controller2=1
region=1
@@ -146,6 +151,7 @@ controller1=1
controller2=1
region=0
flags=0
+hsc=true
[38c056a48472d9a9e16ebda5ed91dae7]
title=Centipede
type=0
@@ -206,8 +212,8 @@ flags=0
title=Crossbow
type=2
pokey=false
-controller1=3
-controller2=3
+controller1=2
+controller2=2
region=0
flags=0
crossx=15
@@ -216,8 +222,8 @@ crossy=10
title=Crossbow
type=2
pokey=false
-controller1=3
-controller2=3
+controller1=2
+controller2=2
region=1
flags=0
crossx=15
@@ -262,6 +268,7 @@ controller1=1
controller2=1
region=0
flags=0
+hsc=true
[408dca9fc40e2b5d805f403fa0509436]
title=Dig Dug
type=0
@@ -374,6 +381,7 @@ controller1=1
controller2=1
region=0
flags=0
+hsc=true
[de0d4f5a9bf1c1bddee3ed2f7ec51209]
title=Food Fight
type=0
@@ -390,6 +398,7 @@ controller1=1
controller2=1
region=0
flags=0
+hsc=true
[f5dc7dc8e38072d3d65bd90a660148ce]
title=Galaga
type=0
@@ -478,6 +487,7 @@ controller1=1
controller2=1
region=0
flags=0
+hsc=true
[f2dae0264a4b4a73762b9d7177e989f6]
title=Joust
type=0
@@ -642,6 +652,7 @@ controller1=1
controller2=1
region=0
flags=0
+hsc=true
[56469e8c5ff8983c6cb8dadc64eb0363]
title=Ms. Pac-Man
type=0
@@ -811,6 +822,7 @@ controller2=1
region=0
flags=0
dualanalog=true
+hsc=true
[980c35ae9625773a450aa7ef51751c04]
title=Scrapyard Dog
type=4
@@ -887,6 +899,7 @@ controller1=1
controller2=1
region=0
flags=0
+rightswitch=1
[95d7c321dce8f57623a9c5b4947bb375]
title=Super Skatebordin'
type=0
@@ -895,6 +908,7 @@ controller1=1
controller2=1
region=1
flags=0
+rightswitch=1
[44f862bca77d68b56b32534eda5c198d]
title=Tank Command (Overdump)
type=1
@@ -1023,6 +1037,7 @@ controller1=1
controller2=1
region=0
flags=0
+hsc=true
[b1a9f196ce5f47ca8caf8fa7bc4ca46c]
title=Xevious
type=0
@@ -1031,3 +1046,1528 @@ controller1=1
controller2=1
region=1
flags=0
+[e1f0a708fbc107001fc49ce48151fefa]
+title=Bentley Bear's CQ Wonder Hack
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+leftswitch=0
+swapbuttons=true
+[34483432b92f565f4ced82a141119164]
+title=Bentley Bear's Crystal Quest
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=true
+xm=false
+leftswitch=0
+swapbuttons=true
+[ad35a98040a2facb10ecb120bf83bcc3]
+title=Bentley Bear's Crystal Quest
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+leftswitch=0
+swapbuttons=true
+[707e98991390a4e8874508e5ed4edeef]
+title=Bentley Bear's Crystal Quest
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=true
+leftswitch=0
+swapbuttons=true
+[ec81468e31fde04b67b5b99b7da8edb1]
+title=Bentley Bear's Crystal Quest
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=true
+leftswitch=0
+swapbuttons=true
+[87484e54ab8e45aac978dcc3efd924e5]
+title=Bentley Bear's Crystal Quest P
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=false
+xm=true
+leftswitch=0
+swapbuttons=true
+[4d0b5bf95e4cb366990dbaeecb7f706d]
+title=BentleyBear
+type=2
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=true
+leftswitch=0
+swapbuttons=true
+[ba8d0d0be821b29a0ca9a6fa031a970d]
+title=BentleyBear
+type=2
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=false
+xm=true
+leftswitch=0
+swapbuttons=true
+[1926b9b322ac0f8f36e119b524aa48bd]
+title=Bentley Bear's Crystal Quest P
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=false
+xm=true
+leftswitch=0
+swapbuttons=true
+[3e4b11a99271fd807b5c6db411dc6643]
+title=Bentley Bear's Crystal Quest P
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=false
+xm=false
+leftswitch=0
+swapbuttons=true
+[8385daccee02ccda081eed45eba1479d]
+title=Legend Of Silverpeak
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[9ea73fd07e43f61209876d33e6f6dc04]
+title=Desert Falcon HSC Support
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[90fa275f9f2a65b341796e11b2f551af]
+title=Winter Games Alternate Version
+type=3
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[299d31c8e181fdd011df2014451bdf0f]
+title=Crazy Brix (Joystick)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+leftswitch=0
+rightswitch=1
+hsc=true
+[3209039148e0b7a2b1927bd05bae4685]
+title=Tric Brix (NTSC) (Joy) (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+leftswitch=0
+rightswitch=1
+[32e937e7796db3a01e9bcf5fe93929b0]
+title=Trix Brix-NoLvl13-NTSC-Joy-Hack
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+leftswitch=0
+rightswitch=1
+[a60e4b608505d1fb201703b266f754a7]
+title=TiME Salvo
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+dualanalog=true
+[dbb493bdc4e98436dbbfd4f2e4413397]
+title=Dig Dog (No Harp) (PAL)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+[54829fb744d4cd7a794ccd2580df7c3d]
+title=Dig Dog (Harp) (PAL)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+[f2047b149e72be8f97e9671314748ec4]
+title=ReZolve
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[42fa4bd854a2813b19099da524461a64]
+title=Battlezone (PAL)
+type=7
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+[f5150c0fc1948832211e57852abb0c6e]
+title=7800 Utility Cart
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+xm=true
+hsc=true
+[a8458c510fdd71a1f9cc4c0b243b177a]
+title=Battlezone (NTSC)
+type=7
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[67ee0011090a6ada38f3eef8a3020fb4]
+title=Apple Snaffle V1.25F
+type=1
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[13f11c4e8c019ee326b571d059accea4]
+title=Froggie
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=true
+[608fa599f06f935e05d445ff236f6d7a]
+title=Asterix Quest (BBCQ Hack)
+type=2
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+swapbuttons=true
+[a65f79ad4a0bbdecd59d5f7eb3623fd7]
+title=Asteroids Deluxe (NTSC)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[3d38281ed8a8d8c7cd457a18c92c8604]
+title=Astro Blaster
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[a51e5df28a0fe8c52e9d28fb5f8e44a6]
+title=Astro Fighter
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[78b1061d651ef806becac1dd3fda29a0]
+title=Beef Drop
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[6010a398070dfacb4c0173d75d73c50a]
+title=Beef Drop (New Levels Hack)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[9fa7743a016c9b7015ee1d386326f88e]
+title=b*nQ
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[af1c8f89f0aef0d9e2e15901d6e0539a]
+title=Centipede PMI PAL
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+[2d2fe4da9f1bae102fa8ca2d8830a626]
+title=Crazy Otto (NTSC)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[40bd21c9698c6b8e71b703f860c11359]
+title=Cyb Ur
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[cf3c5a32205506af3c09e6e0c82cfa09]
+title=Donkey Kong PK-XM Concerto Demo
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=true
+hsc=true
+[c956d5ce7417cc2dab61a9afd8f372d0]
+title=Donkey Kong PK-XM Demo NTSC v1.2
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=true
+hsc=true
+[df700753d8ba9353a7045868778eef6d]
+title=Donkey Kong PK-XM Demo PAL v1.2
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=true
+[098b209aac126f2c2edbc982df09cd1b]
+title=Double Dragon GPX Hack
+type=6
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[4565867aa6e5cc710a7edaf6d434b3af]
+title=Double Dragon Sprite Hack Test 2
+type=6
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[fab1290f9a4c4f2b4d831c8a57f969f5]
+title=Draker Quest (Beta 4)
+type=1
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[a9f29004412621f20ad9f5c51cc11486]
+title=Draker Quest II
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[fa4aec407b90e9360b9cfeb41839b09a]
+title=Dual Pac-Man (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[6287727ab36391a62f728bbdee88675c]
+title=FailSafe (NTSC)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[84c4b4ed75f41417ac7cbceac71e3856]
+title=FailSafe (PAL)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+[2fb85cab6e0f0582e3057bf1ac33c74a]
+title=Fatal Run Graphics Hack RC1
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[e7d89669a7f92ec2cc99d9663a28671c]
+title=Frenzy (w-Berzerk)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+xm=true
+hsc=true
+[6053233cb59c0b4ca633623fd76c4576]
+title=Froggie
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[ee09789d61a693e387ccdc9a2f025b43]
+title=Galaxians (Hack)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[3d12489c553cb1a90c8ebd6534383fa1]
+title=Gorf
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[1e21bf1d9d7b3c0cebaac576964c9eb2]
+title=Graze Suit Alpha
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[46dbc5108151e963b120cdaedd7d6d4c]
+title=Hangly-Man (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[25ce1f5dfc909bcb46086e414d6a0f30]
+title=Hearty Manslapper
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[61809684eefd6cbb2963574ffb0a3fab]
+title=Humantron 2084
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+dualanalog=true
+[bf070f04c8fc7ec721b9506b63b48470]
+title=Impossible Mission (Blue Hack)
+type=3
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[4a811d87d1730a334a21e7bda9fe535a]
+title=Impossible Mission (Green Hack)
+type=3
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[05c21a88fd736d59d28b1d95e79840b6]
+title=Impossible Mission (Red Hack)
+type=3
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[dde5703c488c4ad5268c2696704f1c68]
+title=Impossible Mission (C64 Hack)
+type=3
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[f4216cb77cd6db15225968f315c9793f]
+title=Impossible Mission C64 GPX Hack
+type=3
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[e54edc299e72d22d0ba05d16f3393e8c]
+title=Jr. Pac-Man (NTSC)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[e274e7285bb8f97d4d9acddc8497ed9e]
+title=Jr. Pac-Man (PAL)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+[5fb805f2b69820a9b196f5fed2a23c99]
+title=Klax (Prototype) (Fixed)
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[114e215b8cfc8698bc0286a79e1cb9b2]
+title=Merry Xmas 2012 e-card v1.10F
+type=0
+pokey=true
+controller1=1
+controller2=0
+region=0
+flags=0
+[eb3c1443f4a25806de4657e106d504e8]
+title=Meteor Bath (Hack) (RC2) (NTSC)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[c3f6201d6a9388e860328c963a3301cc]
+title=Meteor Shower (NTSC)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[dc0bf52475030c05671dd187e9a99f08]
+title=Meteor Shower (PAL)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+[9ff38ea62004201d870caa8bd9463525]
+title=Moon Cresta (NTSC)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[675c5b79238eaa641f2e3fe9c5e22589]
+title=Moon Cresta (PAL)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+[89f90b661d1b79e956b10bb6a9771f78]
+title=More Beef Drop (Hack)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[d8dbb5c4d7d02e6b0627df8f657a13b4]
+title=Ms Pac-Attack (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[27c133965dfd80b3acb1ed598817aea0]
+title=Ms Pac-Man (Fast Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[cf007563fe94cacf5ea5295dc93ce9ef]
+title=Ms Pac-Man (PacManPlus' Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[cad1e733986bce1ee4c9da73de1dcff1]
+title=Ms Pac-Man Invincible Fast Hack
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[db768297985178cec034c12a41d6f1a7]
+title=Ms Pac-Man 320 Invincible NTSC
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[889fc7e7ba5c807be44e85ba7a6bd26e]
+title=Ms Pac-Man 320 (NTSC)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[bc56f803d65658f92c17e6c2b271a507]
+title=Ms. Pac-Man 320 (PAL)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+[2a17dc5a61be342dd00af719cc335852]
+title=Ms Pac-Man 320 Sound Upd NTSC
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[99055c3e627bbc17fc81cbe0b3ae176c]
+title=Ms Pac-Man 320 Sound Upd PAL
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+[a69347c8a681b8e94f79d8d848998007]
+title=Ms Pac-Man Twin
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[79202cb7d2bc150ffca0c96a4d8b42cf]
+title=Multi-Lock On
+type=1
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[04edf4f3c6b186147c1117359c8f5076]
+title=Pac Pollux (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+hsc=true
+[8338eca612eedf6ddec57d54942863e7]
+title=Pac-Man (Fast Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[575c18f77a4215332bf56d0080a234b8]
+title=Pac-Man (Ferrell's Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[72ec68627bb7d879ae35a71d7679f71e]
+title=Pac-Man (PacManPlus' Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+hsc=true
+[60982f430b762343d53e48f70acfa6d0]
+title=Pac-Man 320 (NTSC)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[180121ecb4aabc7daa945b355e15c254]
+title=Pac-Man 320 (PAL)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+[4fb119f6db26380abba03e4ce3ca04c8]
+title=Pac-Man Christmas 2018 Hack
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[0b7635d0f39ff97d1e841888e1b23b7b]
+title=Pac-Man Christmas 2018 Inv Hack
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[5013b69cb05b21a1194ce48517df7bfc]
+title=Pac-Man Collection
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=true
+[6f80cac59023a69afa26182eabbdfbad]
+title=Pac-Man Collection New Monsters
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[b1685dcbaf1b578cb1b6643666d813e4]
+title=Pac-Man Collection 2 (Hack)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[4748a62d5c628fefd28df5de5567edec]
+title=Pac-Man Handheld (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[1d7d65997d7cd0858e9bee71ded272aa]
+title=Pac-Man Plus (Ferrell's Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[791e55db03903988280388573a2fcdc1]
+title=Pac-Man Plus (PacManPlus' Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+hsc=true
+[d0bf3b841ad4bbd356e9588874749a13]
+title=Pac-Man Plus (320 Mode)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=true
+xm=true
+[1482beef7dbdb122f6bb4b03640888f2]
+title=Pac-Man Plus (320 Mode)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=true
+xm=true
+[8cb66c6ed5b379181b1420d8e4758834]
+title=Pactron 1984 (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+dualanalog=true
+[c1ac9987a9483e200c338ccbd2ee94b5]
+title=Pactron 1984 Extreme (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+dualanalog=true
+[b5c9f0bf5b5763a923b7f370376b1849]
+title=Panda Racer
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[b55e4d255173e5b2c2e620f3186a1ecc]
+title=PC-Man (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[26897ab47b8c5d3b57d3cc235d7635d8]
+title=Chomper (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[2b1f78aaa2b8de5dae3ee4b93ab678f4]
+title=Christmas Pac-Man (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[a3a4dbd27c80eff9bef51f73cd26f1d5]
+title=Invisible Maze Pac-Man (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[43a0059ff1b5bf76e0c7023fde7c33a5]
+title=Jawbreaker (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[a8e752d108efceff504ae4edc4766b75]
+title=Munchkin (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[04c985ebbd0bea4c557207e69b8cbd8f]
+title=Munchman Texas (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[bc1f56d7cc14f15ddfcba5e21e19937b]
+title=YPS Quest (Hack)
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+leftswitch=0
+rightswitch=1
+[8e0c5fc77b27422a39d86ac2e57dc73d]
+title=Xmas Time (Hack)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[f9fa5107ed213e709858d8876359309e]
+title=POKEY (Sample)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+[2370f7ce1b91fc775bce3e72454f908a]
+title=Pokey Kong (Hack)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=true
+[b4f137e85588ce42d302102ba7215437]
+title=Prickle (POKEY Utility) (v09)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=true
+[e1b01dd7e842d2b682ef48f689d5a4eb]
+title=Rider of the Night
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[43525a0405184875c2ecfd0196886a34]
+title=Rip-Off (NTSC)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+xm=true
+hsc=true
+[106b409c6f4c219b1a3b3d099ead3b2b]
+title=Rip-Off (PAL)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+xm=true
+[03daa19b7aae2d27e61f2a4dbe3b9b79]
+title=RMT POKEY Player Test (Demo)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+[03935b9a1f2561bada58fcd5d9fd27de]
+title=Robotron X (NTSC) (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+dualanalog=true
+[d27ed8f883af9b4ee3b5570f30e9ff71]
+title=Rowdytron (NTSC) (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+dualanalog=true
+[01c7bc3cd8375e353c8aa837fe1262ec]
+title=RPG Player and Map Tiles (Demo)
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[a3a85e507d6f718972b1464ce1aaf8a4]
+title=Scramble
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+xm=true
+[32f1a1b5a7e3b4493c3b7b637aeea7d8]
+title=Scrapyard Dog Graphics-Life Hack
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[6e27f73bd4a49b647bcd58bc5f8b739d]
+title=Srapyard Dog (Graphics Hack)
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[0070751edb8bbf4dd4a685f58b5b72c5]
+title=Scrapyard Dog Unlimit Lives Hack
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[9bd70c06d3386f76f8162881699a777a]
+title=Serpentine
+type=3
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=true
+[95c8a795e30640c9ec82609872c80517]
+title=Shark Attack (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+rightswitch=1
+[1c8139c584e1cf5c6afdd2f3455a2446]
+title=Sky Scraper 2115
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+[ca1c27b53fcfb9fed83bc9e92920707c]
+title=Soft Cell-Tainted Love MusicDemo
+type=4
+pokey=false
+controller1=0
+controller2=0
+region=0
+flags=0
+[771cb4609347657f63e6f0eb26036e35]
+title=Space Duel (NTSC)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[a84c1b2300fbfbf21b1c02387f613dad]
+title=Space Duel (PAL)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+[6adf79558a3d7f5beca1bb8d34337417]
+title=Space Invaders (NTSC)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[0f4bd5800359a62a5874b93dc92a47f1]
+title=Spire of the Ancients
+type=2
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+[02508e6df5e173b4063a7e6e63295817]
+title=Super Circus AA-NTSC-Joy-0450
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=true
+xm=true
+hsc=true
+[81cee326b99d6831de10a566e338bd25]
+title=Super Circus AA-NTSC-joy-4000
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+hsc=true
+[1c9b0bb028e63f83a2d1c1def675acc9]
+title=Super Circus AA-PAL-Joy-0450
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+xm=true
+[f4ad1a1d732c2c8cdbd21dabaf38a46c]
+title=Super Circus AA-PAL-Joy-4000
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[f41f651417c234104d37296477fa29eb]
+title=Super Cobra (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=true
+[7ab539bb0e99e1e5a1c89230bde64610]
+title=Super Pac-Man (NTSC)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=true
+[61aa4a074ad08c524fbee88d15e369ea]
+title=Super Pac-Man (PAL)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[3632fcc732a33591b91f0eea2c01e599]
+title=Tank Command-Color Sprite Title
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[d0b87d349d6d5e40920cc4ff95253339]
+title=Tank Command-Midnight Run Hack
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[9cb3848416e39ebf642357dbee3e5970]
+title=Tempest (BBC X-Port 1) (v1_00F)
+type=3
+pokey=false
+controller1=1
+controller2=0
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[b1ec7bd809ab3deb746c5a5eb2efaecb]
+title=UFO!
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[43f8e9cec3d9991017709f48a7aa22f6]
+title=UFO! Genesys (Hack)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[f85d506f5933427c8de664be0c5510a3]
+title=Ultra Pac-Man (PacManPlus' Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=true
+[f83849cf3f5ac95856e8f93ee90d5a8d]
+title=Upside Down Pac-Man (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+rightswitch=1
+[c62632545c91823f72f6f14b19766804]
+title=WarBirds
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[40913dcf24a623c1dc2495a1c4931b48]
+title=Water Ski - Title Color Realign
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[8b49549763f4f0e42a23942b8df6b248]
+title=Water Ski-Titl Col Reali Trained
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[7db031f1c4dc957719812fe68ee42531]
+title=Xevious X (PAL) (Hack)
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[5837c4ac8b481fb98381adfd2fe87969]
+title=Armor Attack
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=true
+hsc=false
+[05b04e9822a75ceeeaa2eb106ffe768e]
+title=Adventure Map Demo
+type=4
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[727b6d447e21af42b3767f9c2cff6012]
+title=DFHSC78.BIN
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=true
+[c3107d3e3e17d67e3a11d47a5946a4f3]
+title=DONKEY KONG XM
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=true
+[8caa29a8d9214ca02697b3357102309a]
+title=DONKEY KONG XM
+type=2
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[b3143adbbb7d7d189e918e5b29d55a72]
+title=DungeonStalker_Final
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[e547492ebd342e57c28bb235546da299]
+title=3D Demo
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[89b8b3df46733e0c4d57aeb9bb245e6f]
+title=Armor Attack II
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[7cdfbe37634e7dcd4dc67db7edbcd3ba]
+title=Baby Pac-Man
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[1ae0b27d47f19d59652168fad3966375]
+title=Crazy Otto
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[35433868dfe383ae21fd77507e5a478d]
+title=Ms. Pac-Man (320 Mode)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=true
+hsc=false
+[59f1c1e7f6653a4e66ea898ce6eab50f]
+title=Pac-Man Collection! v2
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=true
+[c2b42639718d005a6d0aefa0809f77db]
+title=Pac-Man Collection! v2
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=1
+flags=0
+pokey450=false
+xm=false
+hsc=false
+[80ffad3edb50f0970e780a727a4524dd]
+title=Pac-Man (320 Mode)
+type=0
+pokey=true
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=true
+[ff8d8283553af5d5dbdaddb5781b4896]
+title=Vector Asteroids
+type=0
+pokey=false
+controller1=1
+controller2=1
+region=0
+flags=0
+pokey450=false
+xm=false
+hsc=true
diff --git a/src/Cartridge.cpp b/src/Cartridge.cpp
index da0086e..e3cf992 100644
--- a/src/Cartridge.cpp
+++ b/src/Cartridge.cpp
@@ -28,6 +28,11 @@
#include "wii_atari.h"
#include "wii_app.h"
+#ifdef WII_NETTRACE
+#include
+#include "net_print.h"
+#endif
+
#include
#define CARTRIDGE_SOURCE "Cartridge.cpp"
@@ -40,13 +45,20 @@ std::string cartridge_filename;
byte cartridge_type;
byte cartridge_region;
bool cartridge_pokey;
-byte cartridge_controller[2];
+bool cartridge_pokey450;
+byte cartridge_controller[2] = {1, 1};
byte cartridge_bank;
uint cartridge_flags;
int cartridge_crosshair_x;
int cartridge_crosshair_y;
bool cartridge_dualanalog = false;
+bool cartridge_xm = false;
+bool cartridge_disable_bios = false;
uint cartridge_hblank = 34;
+byte cartridge_left_switch = 1;
+byte cartridge_right_switch = 0;
+bool cartridge_swap_buttons = false;
+bool cartridge_hsc_enabled = false;
// Whether the cartridge has accessed the high score ROM (indicates that the
// SRAM should be persisted when the cartridge is unloaded)
@@ -86,22 +98,33 @@ static bool cartridge_CC2(const byte* header) {
}
// ----------------------------------------------------------------------------
-// GetBankOffset
+// GetBank
// ----------------------------------------------------------------------------
-static uint cartridge_GetBankOffset(byte bank) {
+static uint cartridge_GetBank(byte bank) {
if ((cartridge_type == CARTRIDGE_TYPE_SUPERCART || cartridge_type == CARTRIDGE_TYPE_SUPERCART_ROM || cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM) && cartridge_size <= 65536) {
// for some of these carts, there are only 4 banks. in this case we ignore bit 3
// previously, games of this type had to be doubled. The first 4 banks needed to be duplicated at the end of the ROM
- return (bank & 3) * 16384;
+ return (bank & 3);
}
- return bank * 16384;
+ return bank;
+}
+
+// ----------------------------------------------------------------------------
+// GetBankOffset
+// ----------------------------------------------------------------------------
+static uint cartridge_GetBankOffset(byte bank) {
+ return cartridge_GetBank(bank) * 16384;
}
// ----------------------------------------------------------------------------
// WriteBank
// ----------------------------------------------------------------------------
static void cartridge_WriteBank(word address, byte bank) {
+#ifdef TRACE_BANK_SWITCH
+ net_print_string(NULL, 0, "Bank switch: %d, %d, max:%d\n",
+ address, cartridge_GetBank(bank), cartridge_size / 16384);
+#endif
uint offset = cartridge_GetBankOffset(bank);
if(offset < cartridge_size) {
memory_WriteROM(address, 16384, cartridge_buffer + offset);
@@ -109,15 +132,43 @@ static void cartridge_WriteBank(word address, byte bank) {
}
}
+static void cartridge_SetTypeBySize(uint size) {
+ if (size <= 0x10000) {
+ int old_type = cartridge_type;
+ cartridge_type = CARTRIDGE_TYPE_NORMAL;
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Update: no bits and <= 64k: %d, %d\n", old_type, cartridge_type);
+#endif
+ } else if (size == 0x24000 ) {
+ int old_type = cartridge_type;
+ cartridge_type = CARTRIDGE_TYPE_SUPERCART_LARGE;
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Update: size == 144k: %d, %d\n", old_type, cartridge_type);
+#endif
+ } else if (size == 0x20000 ) {
+
+ int old_type = cartridge_type;
+ cartridge_type = CARTRIDGE_TYPE_SUPERCART_ROM;
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Update: size == 128k: %d, %d\n", old_type, cartridge_type);
+#endif
+ } else {
+ int old_type = cartridge_type;
+ cartridge_type = CARTRIDGE_TYPE_SUPERCART;
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Update: default for > 64k: %d, %d\n", old_type, cartridge_type);
+#endif
+ }
+}
+
// ----------------------------------------------------------------------------
// ReadHeader
// ----------------------------------------------------------------------------
static void cartridge_ReadHeader(const byte* header) {
- if( wii_debug )
- {
- fprintf( stderr, "reading cartridge header:\n" );
- }
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Reading cartridge header\n");
+#endif
char temp[33] = {0};
for(int index = 0; index < 32; index++) {
@@ -148,10 +199,10 @@ static void cartridge_ReadHeader(const byte* header) {
}
}
else {
- if(header[53] == 1) {
+ if(header[53] == 2 /*1*/) { // Wii: Abs and Act were swapped
cartridge_type = CARTRIDGE_TYPE_ABSOLUTE;
}
- else if(header[53] == 2) {
+ else if(header[53] == 1 /*2*/) { // Wii: Abs and Act were swapped
cartridge_type = CARTRIDGE_TYPE_ACTIVISION;
}
else {
@@ -159,11 +210,97 @@ static void cartridge_ReadHeader(const byte* header) {
}
}
- cartridge_pokey = (header[54] & 1)? true: false;
+ cartridge_pokey = (header[54]&1)? true: false;
+ cartridge_pokey450 = (header[54]&0x40)? true : false;
+ if (cartridge_pokey450) {
+ cartridge_pokey = true;
+ }
cartridge_controller[0] = header[55];
cartridge_controller[1] = header[56];
cartridge_region = header[57];
cartridge_flags = 0;
+ cartridge_xm = (header[63] & 1)? true: false;
+ cartridge_hsc_enabled = header[58]&0x01;
+
+ // Wii: Updates to header interpretation
+ byte ct1 = header[54];
+ if(header[53] == 0) {
+ if ((ct1&0x0a)==0x0a) { // BIT1 and BIT3 (Supercart Large: 2) rom at $4000
+ int old_type = cartridge_type;
+ cartridge_type = CARTRIDGE_TYPE_SUPERCART_LARGE;
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Update: (0x10) bit1 & bit3: %d, %d\n", old_type, cartridge_type);
+#endif
+ } else if ((ct1&0x12)==0x12) { // BIT1 and BIT4 (Supercart ROM: 4) bank6 at $4000
+ int old_type = cartridge_type;
+ cartridge_type = CARTRIDGE_TYPE_SUPERCART_ROM;
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Update: (0x12) bit1 & bit4: %d, %d\n", old_type, cartridge_type);
+#endif
+ } else if ((ct1&0x06)==0x06) { // BIT1 and BIT2 (Supercart RAM: 3) ram at $4000
+ int old_type = cartridge_type;
+ cartridge_type = CARTRIDGE_TYPE_SUPERCART_RAM;
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Update: (0x06) bit1 & bit2: %d, %d\n", old_type, cartridge_type);
+#endif
+ } else if ((ct1&0x02)==0x02) { // BIT1 (Supercart) bank switched
+ int old_type = cartridge_type;
+ cartridge_type = CARTRIDGE_TYPE_SUPERCART;
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Update: (0x01) bit1: %d, %d\n", old_type, cartridge_type);
+#endif
+ } else if (cartridge_size <= 0x10000 && ((ct1&0x04)==0x04)) { // Size < 64k && BIT2 (Normal RAM: ?) ram at $4000 )
+ int old_type = cartridge_type;
+ cartridge_type = CARTRIDGE_TYPE_NORMAL_RAM;
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Update: (0x04) bit2: %d, %d\n", old_type, cartridge_type);
+#endif
+ } else {
+ // Attempt to determine the cartridge type based on its size
+ cartridge_SetTypeBySize(cartridge_size);
+ }
+ }
+
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Header info:\n");
+ if (ct1&0x01) {
+ net_print_string(NULL, 0, " bit0: pokey at $4000\n");
+ }
+ if (ct1&0x02) {
+ net_print_string(NULL, 0, " bit1: supergame bank switched\n");
+ }
+ if (ct1&0x04) {
+ net_print_string(NULL, 0, " bit2: supergame ram at $4000\n");
+ }
+ if (ct1&0x08) {
+ net_print_string(NULL, 0, " bit3: rom at $4000\n");
+ }
+ if (ct1&0x10) {
+ net_print_string(NULL, 0, " bit4: bank 6 at $4000\n");
+ }
+ if (ct1&0x20) {
+ net_print_string(NULL, 0, " bit5: supergame banked ram\n");
+ }
+ if (ct1&0x40) {
+ net_print_string(NULL, 0, " bit6: pokey at $450\n");
+ }
+ if (ct1&0x80) {
+ net_print_string(NULL, 0, " bit7: mirror ram at $4000\n");
+ }
+ net_print_string(NULL, 0, " xm: %s\n", (cartridge_xm ? "1" : "0"));
+ net_print_string(NULL, 0, " pokey: %s\n", (cartridge_pokey ? "1" : "0"));
+ net_print_string(NULL, 0, " pokey450: %s\n", (cartridge_pokey450 ? "1" : "0"));
+ net_print_string(NULL, 0, " tv type: %s\n", cartridge_region ? "PAL" : "NTSC");
+ net_print_string(NULL, 0, " Save device: [%x]%s%s\n", header[58],
+ ((header[58]&0x02) ? " SaveKey/AtariVox": ""),
+ ((header[58]&0x01) ? " HSC": ""));
+ net_print_string(NULL, 0, " controller1: %d\n", cartridge_controller[0]);
+ net_print_string(NULL, 0, " controller2: %d\n", cartridge_controller[1]);
+ net_print_string(NULL, 0, " cartridge_type 53: %d\n", header[53]);
+ net_print_string(NULL, 0, " cartridge_type 54: %d\n", header[54]);
+ net_print_string(NULL, 0, " cartridge_size: %d\n", cartridge_size);
+ net_print_string(NULL, 0, "cartridge_type (from header): %d\n", cartridge_type);
+#endif
}
// ----------------------------------------------------------------------------
@@ -175,6 +312,10 @@ static bool cartridge_Load(const byte* data, uint size) {
return false;
}
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "actual cartridge_size: %d\n", size);
+#endif
+
cartridge_Release( );
byte header[128] = {0};
@@ -193,10 +334,41 @@ static bool cartridge_Load(const byte* data, uint size) {
cartridge_ReadHeader(header);
size -= 128;
offset = 128;
+
+ // Several cartridge headers do not have the proper size. So attempt to use the size
+ // of the file.
+ if (cartridge_size != size) {
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "!!! CARTRIDGE SIZE IN HEADER DOES NOT MATCH !!! : %d %d\n",
+ cartridge_size, size);
+#endif
+ // Necessary for the following roms:
+ // Impossible Mission hacks w/ C64 style graphics
+ if (size%1024 == 0) {
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "!!! ROM size is 1k multiple, using ROM size !!! : %d\n",
+ size);
+#endif
+ cartridge_size = size;
+ } else {
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "!!! ROM size is not 1k multiple, using header size !!! : %d\n",
+ cartridge_size);
+#endif
+
+ }
+ }
}
else {
cartridge_size = size;
+ // Attempt to guess the cartridge type based on its size
+ cartridge_SetTypeBySize(size);
}
+
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "cartridge_type: %d\n", cartridge_type);
+ net_print_string(NULL, 0, "cartridge_size: %d\n", cartridge_size);
+#endif
cartridge_buffer = new byte[cartridge_size];
for(int index = 0; index < cartridge_size; index++) {
@@ -381,7 +553,7 @@ static bool cartridge_LoadHighScoreSram()
*/
bool cartridge_LoadHighScoreCart() {
- if( !wii_hs_enabled || cartridge_region != REGION_NTSC )
+ if( !cartridge_hsc_enabled || cartridge_region != REGION_NTSC )
{
// Only load the cart if it is enabled and the region is NTSC
return false;
@@ -431,29 +603,37 @@ void cartridge_Store( ) {
case CARTRIDGE_TYPE_NORMAL:
memory_WriteROM(65536 - cartridge_size, cartridge_size, cartridge_buffer);
break;
- case CARTRIDGE_TYPE_SUPERCART:
- if(cartridge_GetBankOffset(7) < cartridge_size) {
- memory_WriteROM(49152, 16384, cartridge_buffer + cartridge_GetBankOffset(7));
- }
+ case CARTRIDGE_TYPE_NORMAL_RAM:
+ memory_WriteROM(65536 - cartridge_size, cartridge_size, cartridge_buffer);
+ memory_ClearROM(16384, 16384);
break;
- case CARTRIDGE_TYPE_SUPERCART_LARGE:
- if(cartridge_GetBankOffset(8) < cartridge_size) {
- memory_WriteROM(49152, 16384, cartridge_buffer + cartridge_GetBankOffset(8));
+ case CARTRIDGE_TYPE_SUPERCART: {
+ uint offset = cartridge_size - 16384;
+ if(offset < cartridge_size) {
+ memory_WriteROM(49152, 16384, cartridge_buffer + offset);
+ }
+ } break;
+ case CARTRIDGE_TYPE_SUPERCART_LARGE: {
+ uint offset = cartridge_size - 16384;
+ if(offset < cartridge_size) {
+ memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_WriteROM(16384, 16384, cartridge_buffer + cartridge_GetBankOffset(0));
}
- break;
- case CARTRIDGE_TYPE_SUPERCART_RAM:
- if(cartridge_GetBankOffset(7) < cartridge_size) {
- memory_WriteROM(49152, 16384, cartridge_buffer + cartridge_GetBankOffset(7));
+ } break;
+ case CARTRIDGE_TYPE_SUPERCART_RAM: {
+ uint offset = cartridge_size - 16384;
+ if(offset < cartridge_size) {
+ memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_ClearROM(16384, 16384);
}
- break;
- case CARTRIDGE_TYPE_SUPERCART_ROM:
- if(cartridge_GetBankOffset(7) < cartridge_size && cartridge_GetBankOffset(6) < cartridge_size) {
- memory_WriteROM(49152, 16384, cartridge_buffer + cartridge_GetBankOffset(7));
+ } break;
+ case CARTRIDGE_TYPE_SUPERCART_ROM: {
+ uint offset = cartridge_size - 16384;
+ if(offset < cartridge_size && cartridge_GetBankOffset(6) < cartridge_size) {
+ memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_WriteROM(16384, 16384, cartridge_buffer + cartridge_GetBankOffset(6));
}
- break;
+ } break;
case CARTRIDGE_TYPE_ABSOLUTE:
memory_WriteROM(16384, 16384, cartridge_buffer);
memory_WriteROM(32768, 32768, cartridge_buffer + cartridge_GetBankOffset(2));
@@ -474,19 +654,24 @@ void cartridge_Store( ) {
// Write
// ----------------------------------------------------------------------------
void cartridge_Write(word address, byte data) {
+#if 0
+ net_print_string(NULL, 0, "Cartridge write: %d, %d\n", address, data);
+#endif
switch(cartridge_type) {
case CARTRIDGE_TYPE_SUPERCART:
case CARTRIDGE_TYPE_SUPERCART_RAM:
- case CARTRIDGE_TYPE_SUPERCART_ROM:
- if(address >= 32768 && address < 49152 && data < 9) {
+ case CARTRIDGE_TYPE_SUPERCART_ROM: {
+ uint maxbank = cartridge_size / 16384;
+ if(address >= 32768 && address < 49152 && cartridge_GetBank(data) < maxbank /*9*/) {
cartridge_StoreBank(data);
}
- break;
- case CARTRIDGE_TYPE_SUPERCART_LARGE:
- if(address >= 32768 && address < 49152 && data < 9) {
+ } break;
+ case CARTRIDGE_TYPE_SUPERCART_LARGE: {
+ uint maxbank = cartridge_size / 16384;
+ if(address >= 32768 && address < 49152 && cartridge_GetBank(data) < maxbank /*9*/) {
cartridge_StoreBank(data + 1);
}
- break;
+ } break;
case CARTRIDGE_TYPE_ABSOLUTE:
if(address == 32768 && (data == 1 || data == 2)) {
cartridge_StoreBank(data - 1);
@@ -499,6 +684,7 @@ void cartridge_Write(word address, byte data) {
break;
}
+#if 0 // WIi: Moved to Memory.cpp
if(cartridge_pokey && address >= 0x4000 && address <= 0x400f) {
switch(address) {
case POKEY_AUDF1:
@@ -533,6 +719,7 @@ void cartridge_Write(word address, byte data) {
break;
}
}
+#endif
}
// ----------------------------------------------------------------------------
@@ -580,21 +767,30 @@ void cartridge_Release( ) {
cartridge_buffer = NULL;
//
- // WII
+ // Wii
//
// These values need to be reset so that moving between carts works
// consistently. This seems to be a ProSystem emulator bug.
//
+ cartridge_title = "";
cartridge_type = 0;
cartridge_region = 0;
cartridge_pokey = 0;
- memset( cartridge_controller, 0, sizeof( cartridge_controller ) );
+ cartridge_pokey450 = 0;
+ cartridge_xm = false;
+ // Default to joysticks
+ memset( cartridge_controller, 1, sizeof( cartridge_controller ) );
cartridge_bank = 0;
cartridge_flags = 0;
+ cartridge_disable_bios = false;
cartridge_crosshair_x = 0;
cartridge_crosshair_y = 0;
high_score_set = false;
- cartridge_hblank = 34;
+ cartridge_hblank = HBLANK_DEFAULT;
cartridge_dualanalog = false;
+ cartridge_left_switch = 1;
+ cartridge_right_switch = 0;
+ cartridge_swap_buttons = false;
+ cartridge_hsc_enabled = false;
}
}
diff --git a/src/Cartridge.h b/src/Cartridge.h
index e142e23..f420e58 100644
--- a/src/Cartridge.h
+++ b/src/Cartridge.h
@@ -31,6 +31,7 @@
#define CARTRIDGE_TYPE_SUPERCART_ROM 4
#define CARTRIDGE_TYPE_ABSOLUTE 5
#define CARTRIDGE_TYPE_ACTIVISION 6
+#define CARTRIDGE_TYPE_NORMAL_RAM 7
#define CARTRIDGE_CONTROLLER_NONE 0
#define CARTRIDGE_CONTROLLER_JOYSTICK 1
#define CARTRIDGE_CONTROLLER_LIGHTGUN 2
@@ -46,6 +47,8 @@
#include "Pokey.h"
#include "Archive.h"
+#define HBLANK_DEFAULT 34
+
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int uint;
@@ -66,9 +69,15 @@ extern std::string cartridge_filename;
extern byte cartridge_type;
extern byte cartridge_region;
extern bool cartridge_pokey;
+extern bool cartridge_pokey450;
+extern bool cartridge_xm;
extern byte cartridge_controller[2];
extern byte cartridge_bank;
extern uint cartridge_flags;
+extern bool cartridge_disable_bios;
+extern byte cartridge_left_switch;
+extern byte cartridge_right_switch;
+extern bool cartridge_swap_buttons;
// The x offset for the lightgun crosshair (allows per cartridge adjustments)
extern int cartridge_crosshair_x;
@@ -78,6 +87,8 @@ extern int cartridge_crosshair_y;
extern uint cartridge_hblank;
// Whether the cartridge supports dual analog
extern bool cartridge_dualanalog;
+// Whether the high score cart is enabled
+extern bool cartridge_hsc_enabled;
/*
* Loads the high score cartridge
diff --git a/src/Database.cpp b/src/Database.cpp
index 3c0f83c..c65f3e3 100644
--- a/src/Database.cpp
+++ b/src/Database.cpp
@@ -31,8 +31,14 @@
#include "wii_app_common.h"
#endif
+#ifdef WII_NETTRACE
+#include
+#include "net_print.h"
+#endif
+
#define DATABASE_SOURCE "Database.cpp"
+bool cart_in_db = false;
bool database_enabled = true;
std::string database_filename = "./prosystem.dat";
@@ -48,8 +54,15 @@ char database_loc[WII_MAX_PATH] = "";
// ----------------------------------------------------------------------------
// Load
// ----------------------------------------------------------------------------
-bool database_Load(std::string digest) {
+bool database_Load(std::string digest) {
+ cart_in_db = false;
if(database_enabled) {
+
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "attempting to find db entry with hash: [%s]\n",
+ digest.c_str());
+#endif
+
#ifndef WII
FILE* file = fopen(database_filename.c_str(), "r");
#else
@@ -63,21 +76,29 @@ bool database_Load(std::string digest) {
return false;
}
+ // max count of items in the database
+ static int count = 17;
+
bool found = false;
char buffer[256];
while (fgets(buffer, 256, file) != NULL) {
std::string line = buffer;
if (line.compare(1, 32, digest.c_str()) == 0) {
found = true;
- std::string entry[11];
- for (int index = 0; index < 11; index++) {
+ cart_in_db = true;
+ std::string entry[count];
+ for (int index = 0; index < count; index++) {
buffer[0] = '\0';
fgets(buffer, 256, file);
+ if (strchr(buffer, '[')) {
+ // Passed the current game in DB
+ break;
+ }
entry[index] = common_Remove(buffer, '\r');
entry[index] = common_Remove(entry[index], '\n');
}
- cartridge_title = database_GetValue(entry[0]);
+ cartridge_title = database_GetValue(entry[0]);
cartridge_type = common_ParseByte(database_GetValue(entry[1]));
cartridge_pokey = common_ParseBool(database_GetValue(entry[2]));
cartridge_controller[0] =
@@ -91,7 +112,7 @@ bool database_Load(std::string digest) {
// Optionally load the lightgun crosshair offsets, hblank, dual
// analog
//
- for (int index = 7; index < 11; index++) {
+ for (int index = 7; index < count; index++) {
if (entry[index].find("crossx") != std::string::npos) {
cartridge_crosshair_x =
common_ParseInt(database_GetValue(entry[index]));
@@ -108,8 +129,38 @@ bool database_Load(std::string digest) {
cartridge_dualanalog =
common_ParseBool(database_GetValue(entry[index]));
}
+ if (entry[index].find("pokey450") != std::string::npos) {
+ cartridge_pokey450 =
+ common_ParseBool(database_GetValue(entry[index]));
+ if (cartridge_pokey450) {
+ cartridge_pokey = true;
+ }
+ }
+ if (entry[index].find("xm") != std::string::npos) {
+ cartridge_xm =
+ common_ParseBool(database_GetValue(entry[index]));
+ }
+ if (entry[index].find("disablebios") != std::string::npos) {
+ cartridge_disable_bios =
+ common_ParseBool(database_GetValue(entry[index]));
+ }
+ if (entry[index].find("leftswitch") != std::string::npos) {
+ cartridge_left_switch =
+ common_ParseByte(database_GetValue(entry[index]));
+ }
+ if (entry[index].find("rightswitch") != std::string::npos) {
+ cartridge_right_switch =
+ common_ParseByte(database_GetValue(entry[index]));
+ }
+ if (entry[index].find("swapbuttons") != std::string::npos) {
+ cartridge_swap_buttons =
+ common_ParseBool(database_GetValue(entry[index]));
+ }
+ if (entry[index].find("hsc") != std::string::npos) {
+ cartridge_hsc_enabled =
+ common_ParseBool(database_GetValue(entry[index]));
+ }
}
-
break;
}
}
diff --git a/src/Database.h b/src/Database.h
index 67b3a2a..7e3c9b9 100644
--- a/src/Database.h
+++ b/src/Database.h
@@ -35,5 +35,6 @@ extern void database_Initialize( );
extern bool database_Load(std::string digest);
extern bool database_enabled;
extern std::string database_filename;
+extern bool cart_in_db;
#endif
diff --git a/src/ExpansionModule.cpp b/src/ExpansionModule.cpp
new file mode 100644
index 0000000..ea0ccf9
--- /dev/null
+++ b/src/ExpansionModule.cpp
@@ -0,0 +1,115 @@
+/*
+ Memory map:
+
+ POKEY1 $0450 $045F 16 bytes
+ POKEY2* $0460 $046F 16 bytes
+ XCTRL $0470 $047F 1 byte
+ RAM $4000 $7FFF 16384 bytes
+
+XCTRL Bit Description
+
++-------------------------------+
+| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
++-------------------------------+
+ | | | | | | | |
+ | | | | | | | +-- Bank select bit 0 \
+ | | | | | | +------ Bank select bit 1 | Totally 128 KByte in 16 KByte banks
+ | | | | | +---------- Bank select bit 3 /
+ | | | | +-------------- Enable memory bit (1 = Memory enabled, 0 after power on)
+ | | | +------------------ Enable POKEY bit** (1 = POKEY enabled, 0 after power on)
+ | | |
+ NA NA NA = Not Available or Not Used
+
+* = Can be mounted piggy back on the first POKEY. Description how to do this will come when i have tried it out.
+** This bit controls both POKEY chip select signals.
+
+
+The mapping is totally non compatible with pretty much everything.
+There is a bank select latch located at $0470 and the POKEY is located at $0450
+(There's also a chip select output ($0460) on the PLD which alows you to simply piggy back a second POKEY).
+Since the PLD is reconfigurable I could map the POKEY (or the RAM for that matter) to pretty much anything
+if you wanted to. However since the PLD is soldered under the POKEY this needs to be configured before delivery.
+*/
+
+#include
+#include "ExpansionModule.h"
+
+#ifdef WII_NETTRACE
+#include
+#include "net_print.h"
+#endif
+
+byte xm_ram[XM_RAM_SIZE] = {0};
+byte xm_reg = 0;
+byte xm_bank = 0;
+bool xm_pokey_enabled = false;
+bool xm_mem_enabled = false;
+
+void xm_Reset() {
+ memset(xm_ram, 0, XM_RAM_SIZE);
+ xm_bank = 0;
+ xm_reg = 0;
+ xm_mem_enabled = false;
+ xm_pokey_enabled = false;
+}
+
+byte xm_Read(word address) {
+ if (xm_pokey_enabled && (address >= 0x0450 && address < 0x0460)) {
+ byte b = pokey_GetRegister(0x4000 + (address - 0x0450));
+#if 0
+ net_print_string(NULL, 0, "Read from Pokey1: %x %d\n", address, b);
+#endif
+ return b;
+ } else if (xm_pokey_enabled && (address >= 0x0460 && address < 0x0470)) {
+ byte b = pokey_GetRegister(0x4000 + (address - 0x0460));
+#if 0
+ net_print_string(NULL, 0, "Read from Pokey2: %x %d\n", address, b);
+#endif
+ return b;
+ } else if (xm_mem_enabled && (address >= 0x4000 && address < 0x8000)) {
+ byte b = xm_ram[(xm_bank * 0x4000) + (address - 0x4000)];
+#if 0
+ net_print_string(NULL, 0, "Read from XM RAM: %x %d\n", address, b);
+#endif
+ return b;
+ } else if (address >= 0x0470 && address < 0x0480) {
+#if 0
+ net_print_string(NULL, 0, "Read from XCTRL 0x0470: %x\n", address);
+#endif
+ // TODO: Should the value be returned?
+ }
+ return 0;
+}
+
+void xm_Write(word address, byte data) {
+ if (xm_pokey_enabled && (address >= 0x0450 && address < 0x0460)) {
+#if 0
+ net_print_string(NULL, 0, "Wrote to Pokey1: %x %d\n", address, data);
+#endif
+ pokey_SetRegister(0x4000 + (address - 0x0450), data);
+ } else if (xm_pokey_enabled && (address >= 0x0460 && address < 0x0470)) {
+#if 0
+ net_print_string(NULL, 0, "Wrote to Pokey2: %x %d\n", address, data);
+#endif
+ pokey_SetRegister(0x4000 + (address - 0x0460), data);
+ } else if (xm_mem_enabled && (address >= 0x4000 && address < 0x8000)) {
+#if 0
+ net_print_string(NULL, 0, "Wrote to XM RAM: %x %d\n", address, data);
+#endif
+ xm_ram[(xm_bank * 0x4000) + (address - 0x4000)] = data;
+ } else if (address >= 0x0470 && address < 0x0480) {
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Wrote to XCTRL 0x0470: %x %d\n", address,
+ data);
+#endif
+ xm_reg = data;
+ xm_bank = xm_reg & 7;
+ xm_pokey_enabled = (xm_reg & 0x10);
+ xm_mem_enabled = (xm_reg & 0x08);
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "xm_reg: %d, xm_bank: %d, xm_pokey_enabled: %d, xm_mem_enabled: %d\n",
+ xm_reg, xm_bank, xm_pokey_enabled, xm_mem_enabled);
+#endif
+
+ }
+}
diff --git a/src/ExpansionModule.h b/src/ExpansionModule.h
new file mode 100644
index 0000000..ee811b0
--- /dev/null
+++ b/src/ExpansionModule.h
@@ -0,0 +1,19 @@
+#ifndef EXPANSIONMODULE_H
+#define EXPANSIONMODULE_H
+
+#include "Cartridge.h"
+#include "Memory.h"
+
+#define XM_RAM_SIZE 0x20000
+
+extern byte xm_ram[XM_RAM_SIZE];
+extern bool xm_pokey_enabled;
+extern bool xm_mem_enabled;
+extern byte xm_reg;
+extern byte xm_bank;
+
+
+void xm_Reset();
+byte xm_Read(word address);
+void xm_Write(word address, byte data);
+#endif
diff --git a/src/Maria.cpp b/src/Maria.cpp
index 9cf995a..557de89 100644
--- a/src/Maria.cpp
+++ b/src/Maria.cpp
@@ -23,6 +23,12 @@
// Maria.c
// ----------------------------------------------------------------------------
#include "Maria.h"
+
+#ifdef WII_NETTRACE
+#include
+#include "net_print.h"
+#endif
+
#define MARIA_LINERAM_SIZE 160
extern unsigned char* wii_sdl_get_blit_addr();
@@ -50,7 +56,7 @@ static byte maria_wmode;
// StoreCell
// ----------------------------------------------------------------------------
static inline void maria_StoreCell(byte data) {
- if(maria_horizontal < MARIA_LINERAM_SIZE) {
+ if(maria_horizontal < MARIA_LINERAM_SIZE) {
if(data) {
maria_lineRAM[maria_horizontal] = maria_palette | data;
}
@@ -61,13 +67,12 @@ static inline void maria_StoreCell(byte data) {
}
}
}
- maria_horizontal++;
-}
+ maria_horizontal++;}
// ----------------------------------------------------------------------------
// StoreCell
// ----------------------------------------------------------------------------
-static inline void maria_StoreCell(byte high, byte low) {
+static inline void maria_StoreCell(byte high, byte low) {
if(maria_horizontal < MARIA_LINERAM_SIZE) {
if(low || high) {
maria_lineRAM[maria_horizontal] = maria_palette & 16 | high | low;
@@ -118,8 +123,11 @@ static inline void maria_StoreGraphic( ) {
byte data = memory_ram[maria_pp.w];
if(maria_wmode) {
if(maria_IsHolyDMA( )) {
+#if 0 // Wii: disabled due to rendering in Kangaroo mode
maria_StoreCell(0, 0);
maria_StoreCell(0, 0);
+#endif
+ maria_horizontal+=2;
}
else {
maria_StoreCell((data & 12), (data & 192) >> 6);
@@ -128,17 +136,20 @@ static inline void maria_StoreGraphic( ) {
}
else {
if(maria_IsHolyDMA( )) {
+#if 0 // Wii: disabled due to rendering in Kangaroo mode
maria_StoreCell(0);
maria_StoreCell(0);
maria_StoreCell(0);
maria_StoreCell(0);
+#endif
+ maria_horizontal+=4;
}
else {
maria_StoreCell((data & 192) >> 6);
maria_StoreCell((data & 48) >> 4);
maria_StoreCell((data & 12) >> 2);
maria_StoreCell(data & 3);
- }
+ }
}
maria_pp.w++;
}
@@ -149,6 +160,7 @@ static inline void maria_StoreGraphic( ) {
static inline void maria_WriteLineRAM(byte* buffer) {
byte rmode = memory_ram[CTRL] & 3;
if(rmode == 0) {
+ // 160A/B
int pixel = 0;
for(int index = 0; index < MARIA_LINERAM_SIZE; index += 4) {
word color;
@@ -167,6 +179,7 @@ static inline void maria_WriteLineRAM(byte* buffer) {
}
}
else if(rmode == 2) {
+ // 320B/D
int pixel = 0;
for(int index = 0; index < MARIA_LINERAM_SIZE; index += 4) {
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 0] & 16) | ((maria_lineRAM[index + 0] & 8) >> 3) | ((maria_lineRAM[index + 0] & 2)));
@@ -180,6 +193,7 @@ static inline void maria_WriteLineRAM(byte* buffer) {
}
}
else if(rmode == 3) {
+ // 320A/C
int pixel = 0;
for(int index = 0; index < MARIA_LINERAM_SIZE; index += 4) {
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 0] & 30));
diff --git a/src/Memory.cpp b/src/Memory.cpp
index 551498f..535855a 100644
--- a/src/Memory.cpp
+++ b/src/Memory.cpp
@@ -25,6 +25,12 @@
#include "wii_main.h"
#include "Memory.h"
+#include "ExpansionModule.h"
+
+#ifdef WII_NETTRACE
+#include
+#include "net_print.h"
+#endif
byte memory_ram[MEMORY_SIZE] = {0};
byte memory_rom[MEMORY_SIZE] = {0};
@@ -51,11 +57,24 @@ void memory_Reset( ) {
// Read
// ----------------------------------------------------------------------------
byte memory_Read(word address) {
+#if 0
+ net_print_string(NULL, 0, "Memory read: %d\n", address);
+#endif
byte tmp_byte;
- if( cartridge_pokey && address == POKEY_RANDOM )
- {
- return pokey_GetRegister( POKEY_RANDOM );
+ if (cartridge_xm) {
+ if ((address >= 0x0470 && address < 0x0480) ||
+ (xm_pokey_enabled && (address >= 0x0450 && address < 0x0470)) ||
+ (xm_mem_enabled && (address >= 0x4000 && address < 0x8000))) {
+ return xm_Read(address);
+ }
+ }
+
+ if (cartridge_pokey && (
+ (!cartridge_pokey450 && (address >= 0x4000 && address <= 0x400f)) ||
+ (cartridge_pokey450 && (address >= 0x0450 && address < 0x0470)))) {
+ return pokey_GetRegister(
+ cartridge_pokey450 ? 0x4000 + (address - 0x0450) : address);
}
switch ( address ) {
@@ -80,6 +99,25 @@ byte memory_Read(word address) {
// Write
// ----------------------------------------------------------------------------
void memory_Write(word address, byte data) {
+#if 0
+ net_print_string(NULL, 0, "Memory write: %d, %d\n", address, data);
+#endif
+
+ if (cartridge_xm &&
+ ((address >= 0x0470 && address < 0x0480) ||
+ ((xm_pokey_enabled && (address >= 0x0450 && address < 0x0470)) ||
+ (xm_mem_enabled && (address >= 0x4000 && address < 0x8000))))) {
+ xm_Write(address, data);
+ return;
+ }
+
+ if (cartridge_pokey && (
+ (!cartridge_pokey450 && (address >= 0x4000 && address <= 0x400f)) ||
+ (cartridge_pokey450 && (address >= 0x0450 && address < 0x0470)))) {
+ pokey_SetRegister(
+ (cartridge_pokey450 ? 0x4000 + (address - 0x0450) : address), data);
+ return;
+ }
if(!memory_rom[address]) {
@@ -139,11 +177,11 @@ if( address >= 0x1000 && address <= 0x17FF )
case SWCHB:
/*gdement: Writing here actually writes to DRB inside the RIOT chip.
This value only indirectly affects output of SWCHB.*/
- riot_SetDRB(data);
- break;
+ riot_SetDRB(data);
+ break;
case SWCHA:
- riot_SetDRA(data);
+ riot_SetDRA(data);
break;
case TIM1T:
case TIM1T | 0x8:
@@ -186,7 +224,7 @@ if( address >= 0x1000 && address <= 0x17FF )
// ----------------------------------------------------------------------------
// WriteROM
// ----------------------------------------------------------------------------
-void memory_WriteROM(word address, word size, const byte* data) {
+void memory_WriteROM(word address, uint size, const byte* data) {
if((address + size) <= MEMORY_SIZE && data != NULL) {
for(uint index = 0; index < size; index++) {
memory_ram[address + index] = data[index];
@@ -198,7 +236,7 @@ void memory_WriteROM(word address, word size, const byte* data) {
// ----------------------------------------------------------------------------
// ClearROM
// ----------------------------------------------------------------------------
-void memory_ClearROM(word address, word size) {
+void memory_ClearROM(word address, uint size) {
if((address + size) <= MEMORY_SIZE) {
for(uint index = 0; index < size; index++) {
memory_ram[address + index] = 0;
diff --git a/src/Memory.h b/src/Memory.h
index fb83367..200743d 100644
--- a/src/Memory.h
+++ b/src/Memory.h
@@ -39,8 +39,8 @@ typedef unsigned int uint;
extern void memory_Reset( );
extern byte memory_Read(word address);
extern void memory_Write(word address, byte data);
-extern void memory_WriteROM(word address, word size, const byte* data);
-extern void memory_ClearROM(word address, word size);
+extern void memory_WriteROM(word address, uint size, const byte* data);
+extern void memory_ClearROM(word address, uint size);
extern byte memory_ram[MEMORY_SIZE];
extern byte memory_rom[MEMORY_SIZE];
diff --git a/src/Pokey.cpp b/src/Pokey.cpp
index 5d5b286..e43bfe1 100644
--- a/src/Pokey.cpp
+++ b/src/Pokey.cpp
@@ -38,6 +38,12 @@
// ----------------------------------------------------------------------------
// Pokey.cpp
// ----------------------------------------------------------------------------
+
+#ifdef WII_NETTRACE
+#include
+#include "net_print.h"
+#endif
+
#include
#include
#include "Pokey.h"
@@ -70,7 +76,7 @@
#define SK_RESET 0x03
byte pokey_buffer[POKEY_BUFFER_SIZE] = {0};
-uint pokey_size = 524;
+uint pokey_size = (POKEY_BUFFER_SIZE - 512); // 524
static uint pokey_frequency = 1787520;
static uint pokey_sampleRate = 31440;
@@ -101,6 +107,13 @@ static uint r17;
static byte SKCTL;
byte RANDOM;
+#ifdef WII_NETTRACE
+int pokey_debug_count = 100;
+#endif
+
+byte POT_input[8] = {228, 228, 228, 228, 228, 228, 228, 228};
+static int pot_scanline;
+
static ullong random_scanline_counter;
static ullong prev_random_scanline_counter;
@@ -129,6 +142,13 @@ void pokey_setSampleRate( uint rate ) {
// Reset
// ----------------------------------------------------------------------------
void pokey_Reset( ) {
+#ifdef WII_NETTRACE
+ pokey_debug_count = 100;
+#endif
+
+ pot_scanline = 0;
+ pokey_soundCntr = 0;
+
for(int index = 0; index < POKEY_POLY17_SIZE; index++) {
pokey_poly17[index] = rand( ) & 1;
}
@@ -153,6 +173,10 @@ void pokey_Reset( ) {
pokey_audf[channel] = 0;
}
+ for(int i = 0; i < 8; i++) {
+ POT_input[i] = 228;
+ }
+
pokey_audctl = 0;
pokey_baseMultiplier = POKEY_DIV_64;
@@ -176,12 +200,34 @@ void pokey_Frame() {
/* Called prior to each scanline */
void pokey_Scanline() {
random_scanline_counter += CYCLES_PER_SCANLINE;
+
+ if (pot_scanline < 228)
+ pot_scanline++;
}
byte pokey_GetRegister(word address) {
+#ifdef WII_NETTRACE
+ if ((pokey_debug_count--)>0)
+ net_print_string(NULL, 0, "pokey_getRegister: %d\n", address);
+#endif
byte data = 0;
+ byte addr = address & 0x0f;
+ if (addr < 8) {
+ byte b = POT_input[addr];
+ if (b <= pot_scanline)
+ return b;
+ return pot_scanline;
+ }
+
switch (address) {
+ case POKEY_ALLPOT: {
+ byte b = 0;
+ for (int i = 0; i < 8; i++)
+ if (POT_input[addr] <= pot_scanline)
+ b &= ~(1 << i); /* reset bit if pot value known */
+ return b;
+ }
case POKEY_RANDOM:
ullong curr_scanline_counter =
( random_scanline_counter + prosystem_cycles + prosystem_extra_cycles );
@@ -210,7 +256,6 @@ byte pokey_GetRegister(word address) {
RANDOM = RANDOM ^ 0xff;
data = RANDOM;
-
break;
}
@@ -221,11 +266,22 @@ byte pokey_GetRegister(word address) {
// SetRegister
// ----------------------------------------------------------------------------
void pokey_SetRegister(word address, byte value) {
+#ifdef WII_NETTRACE
+ if ((pokey_debug_count--)>0)
+ net_print_string(NULL, 0, "pokey_setRegister: %d %d\n", address, value);
+#endif
+
byte channelMask;
switch(address) {
+ case POKEY_POTGO:
+ if (!(SKCTL & 4))
+ pot_scanline = 0; /* slow pot mode */
+ return;
case POKEY_SKCTLS:
SKCTL = value;
+ if (value & 4)
+ pot_scanline = 228; /* fast pot mode - return results immediately */
return;
case POKEY_AUDF1:
@@ -372,8 +428,14 @@ void pokey_SetRegister(word address, byte value) {
for(byte channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
if(channelMask & (1 << channel)) {
- if((pokey_audc[channel] & POKEY_VOLUME_ONLY) || ((pokey_audc[channel] & POKEY_VOLUME_MASK) == 0) || (pokey_divideMax[channel] < (pokey_sampleMax >> 8))) {
+ if((pokey_audc[channel] & POKEY_VOLUME_ONLY) ||
+ ((pokey_audc[channel] & POKEY_VOLUME_MASK) == 0) ||
+ (pokey_divideMax[channel] < (pokey_sampleMax >> 8))) {
+#if 1 // WII
+ pokey_outVol[channel] = 1;
+#else
pokey_outVol[channel] = pokey_audc[channel] & POKEY_VOLUME_MASK;
+#endif
pokey_divideCount[channel] = 0x7fffffff;
pokey_divideMax[channel] = 0x7fffffff;
}
@@ -469,7 +531,6 @@ void pokey_Process(uint length)
// Clear
// ----------------------------------------------------------------------------
void pokey_Clear( ) {
- for(int index = 0; index < POKEY_BUFFER_SIZE; index++) {
- pokey_buffer[index] = 0;
- }
+ pokey_soundCntr = 0;
+ memset(pokey_buffer, 0, POKEY_BUFFER_SIZE);
}
diff --git a/src/Pokey.h b/src/Pokey.h
index bccd48b..6b92a55 100644
--- a/src/Pokey.h
+++ b/src/Pokey.h
@@ -50,28 +50,28 @@
#define POKEY_AUDC3 0x4005
#define POKEY_AUDF4 0x4006
#define POKEY_AUDC4 0x4007
-#define POKEY_AUDCTL 0x4008
-#define POKEY_STIMER 0x4009
-#define POKEY_SKRES 0x400a
-#define POKEY_POTGO 0x400b
-#define POKEY_SEROUT 0x400d
-#define POKEY_IRQEN 0x400e
-#define POKEY_SKCTLS 0x400f
-
-#define POKEY_POT0 0x4000
-#define POKEY_POT1 0x4001
-#define POKEY_POT2 0x4002
-#define POKEY_POT3 0x4003
-#define POKEY_POT4 0x4004
-#define POKEY_POT5 0x4005
-#define POKEY_POT6 0x4006
-#define POKEY_POT7 0x4007
-#define POKEY_ALLPOT 0x4008
-#define POKEY_KBCODE 0x4009
-#define POKEY_RANDOM 0x400a
-#define POKEY_SERIN 0x400d
-#define POKEY_IRQST 0x400e
-#define POKEY_SKSTAT 0x400f
+#define POKEY_AUDCTL 0x4008
+#define POKEY_STIMER 0x4009
+#define POKEY_SKRES 0x400a
+#define POKEY_POTGO 0x400b
+#define POKEY_SEROUT 0x400d
+#define POKEY_IRQEN 0x400e
+#define POKEY_SKCTLS 0x400f
+
+#define POKEY_POT0 0x4000
+#define POKEY_POT1 0x4001
+#define POKEY_POT2 0x4002
+#define POKEY_POT3 0x4003
+#define POKEY_POT4 0x4004
+#define POKEY_POT5 0x4005
+#define POKEY_POT6 0x4006
+#define POKEY_POT7 0x4007
+#define POKEY_ALLPOT 0x4008
+#define POKEY_KBCODE 0x4009
+#define POKEY_RANDOM 0x400a
+#define POKEY_SERIN 0x400d
+#define POKEY_IRQST 0x400e
+#define POKEY_SKSTAT 0x400f
typedef unsigned char byte;
diff --git a/src/ProSystem.cpp b/src/ProSystem.cpp
index 59cceb1..79cf8b5 100644
--- a/src/ProSystem.cpp
+++ b/src/ProSystem.cpp
@@ -32,6 +32,11 @@
#include "wii_sdl.h"
#include "wii_atari.h"
+#ifdef WII_NETTRACE
+#include
+#include "net_print.h"
+#endif
+
#define PRO_SYSTEM_SOURCE "ProSystem.cpp"
#define PRO_SYSTEM_STATE_HEADER "PRO-SYSTEM STATE"
@@ -63,6 +68,8 @@ void prosystem_Reset( ) {
tia_Reset( );
pokey_Clear( );
pokey_Reset( );
+ xm_Reset( );
+
memory_Reset( );
maria_Clear( );
maria_Reset( );
@@ -109,20 +116,18 @@ bool dbg_cycle_stealing;
// ExecuteFrame
// ----------------------------------------------------------------------------
+#if 0
+extern float wii_orient_roll;
+#endif
+
void prosystem_ExecuteFrame(const byte* input)
{
// Is WSYNC enabled for the current frame?
- bool wsync =
- ( ( wii_cart_wsync == CART_MODE_ENABLED ) ||
- ( ( wii_cart_wsync == CART_MODE_AUTO ) &&
- ( !( cartridge_flags & CARTRIDGE_WSYNC_MASK ) ) ) );
+ bool wsync = !( cartridge_flags & CARTRIDGE_WSYNC_MASK );
dbg_wsync = wsync;
// Is Maria cycle stealing enabled for the current frame?
- bool cycle_stealing =
- ( ( wii_cart_cycle_stealing == CART_MODE_ENABLED ) ||
- ( ( wii_cart_cycle_stealing == CART_MODE_AUTO ) &&
- ( !( cartridge_flags & CARTRIDGE_CYCLE_STEALING_MASK ) ) ) );
+ bool cycle_stealing = !( cartridge_flags & CARTRIDGE_CYCLE_STEALING_MASK );
dbg_cycle_stealing = cycle_stealing;
// Is the lightgun enabled for the current frame?
@@ -137,10 +142,18 @@ void prosystem_ExecuteFrame(const byte* input)
dbg_maria_cycles = 0; // debug
dbg_p6502_cycles = 0; // debug
- if( cartridge_pokey ) pokey_Frame();
+ if( cartridge_pokey || cartridge_xm ) pokey_Frame();
for( maria_scanline = 1; maria_scanline <= prosystem_scanlines; maria_scanline++ )
{
+#if 0
+ if ((int)wii_orient_roll == maria_scanline) {
+ memory_ram[INPT2] &= 0x7f;
+ } else {
+ memory_ram[INPT2] |= 0x80;
+ }
+#endif
+
if( maria_scanline == maria_displayArea.top )
{
memory_ram[MSTAT] = 0;
@@ -253,12 +266,12 @@ void prosystem_ExecuteFrame(const byte* input)
if( lightgun ) prosystem_FireLightGun();
tia_Process(2);
- if( cartridge_pokey )
+ if( cartridge_pokey || cartridge_xm )
{
pokey_Process(2);
}
- if( cartridge_pokey ) pokey_Scanline();
+ if( cartridge_pokey || cartridge_xm ) pokey_Scanline();
}
prosystem_frame++;
@@ -280,8 +293,8 @@ bool prosystem_Save(std::string filename, bool compress)
logger_LogError("Filename is invalid.", PRO_SYSTEM_SOURCE);
return false;
}
-
- if (! loc_buffer) loc_buffer = (byte *)malloc(33000 * sizeof(byte));
+
+ if (!loc_buffer) loc_buffer = (byte *)malloc((33000 + XM_RAM_SIZE + 4) * sizeof(byte));
logger_LogInfo("Saving game state to file " + filename + ".");
@@ -329,38 +342,47 @@ bool prosystem_Save(std::string filename, bool compress)
loc_buffer[size++] = riot_dra;
loc_buffer[size++] = riot_drb;
loc_buffer[size++] = riot_timing;
- loc_buffer[size++] = ( 0xff & ( riot_timer >> 8 ) );
- loc_buffer[size++] = ( 0xff & riot_timer );
+ loc_buffer[size++] = (0xff & (riot_timer >> 8));
+ loc_buffer[size++] = (0xff & riot_timer);
loc_buffer[size++] = riot_intervals;
- loc_buffer[size++] = ( 0xff & ( riot_clocks >> 8 ) );
- loc_buffer[size++] = ( 0xff & riot_clocks );
+ loc_buffer[size++] = (0xff & (riot_clocks >> 8));
+ loc_buffer[size++] = (0xff & riot_clocks);
+
+ // XM (if applicable)
+ if (cartridge_xm) {
+ loc_buffer[size++] = xm_reg;
+ loc_buffer[size++] = xm_bank;
+ loc_buffer[size++] = xm_pokey_enabled;
+ loc_buffer[size++] = xm_mem_enabled;
#if 0
- if(!compress) {
-#endif
- FILE* file = fopen(filename.c_str( ), "wb");
- if(file == NULL) {
- logger_LogError("Failed to open the file " + filename + " for writing.", PRO_SYSTEM_SOURCE);
- return false;
+net_print_string(NULL, 0, "Wrote XM: xm_reg: %d, xm_bank: %d, xm_pokey_enabled: %d, xm_mem_enabled: %d\n",
+ xm_reg, xm_bank, xm_pokey_enabled, xm_mem_enabled);
+#endif
+
+ for (index = 0; index < XM_RAM_SIZE; index++) {
+ loc_buffer[size + index] = xm_ram[index];
}
-
- if(fwrite(loc_buffer, 1, size, file) != size) {
+ size += XM_RAM_SIZE;
+ }
+
+ FILE* file = fopen(filename.c_str(), "wb");
+ if (file == NULL) {
+ logger_LogError("Failed to open the file " + filename + " for writing.",
+ PRO_SYSTEM_SOURCE);
+ return false;
+ }
+
+ if (fwrite(loc_buffer, 1, size, file) != size) {
fclose(file);
- logger_LogError("Failed to write the save state data to the file " + filename + ".", PRO_SYSTEM_SOURCE);
+ logger_LogError(
+ "Failed to write the save state data to the file " + filename + ".",
+ PRO_SYSTEM_SOURCE);
return false;
- }
-
- fflush(file);
- fclose(file);
-#if 0
}
- else {
- if(!archive_Compress(filename.c_str( ), "Save.sav", loc_buffer, size)) {
- logger_LogError("Failed to compress the save state data to the file " + filename + ".", PRO_SYSTEM_SOURCE);
- return false;
- }
- }
-#endif
+
+ fflush(file);
+ fclose(file);
return true;
}
@@ -375,7 +397,7 @@ bool prosystem_Load(const std::string filename) {
return false;
}
- if (! loc_buffer) loc_buffer = (byte *)malloc(33000 * sizeof(byte));
+ if (!loc_buffer) loc_buffer = (byte *)malloc((33000 + XM_RAM_SIZE + 4) * sizeof(byte));
logger_LogInfo("Loading game state from file " + filename + ".");
@@ -400,10 +422,11 @@ bool prosystem_Load(const std::string filename) {
return false;
}
- if( size != 16445 &&
- size != 32829 &&
- size != 16453 &&
- size != 32837 ) {
+ if( size != 16445 && size != 32829 && /* no RIOT */
+ size != 16453 && size != 32837 && /* with RIOT */
+ size != (16453 + 4 + XM_RAM_SIZE) && /* XM without supercart ram */
+ size != (32837 + 4 + XM_RAM_SIZE)) /* XM with supercart ram */
+ {
fclose(file);
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
return false;
@@ -416,9 +439,6 @@ bool prosystem_Load(const std::string filename) {
}
fclose(file);
}
- else if(size == 16445 || size == 32829 ) {
- archive_Uncompress(filename, loc_buffer, size);
- }
else {
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
return false;
@@ -468,28 +488,55 @@ bool prosystem_Load(const std::string filename) {
offset += 16384;
if(cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM) {
- if(size != 32829 && size != 32837) {
- logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
- return false;
- }
- for(index = 0; index < 16384; index++) {
- memory_ram[16384 + index] = loc_buffer[offset + index];
+ if (size != 32829 && /* no RIOT */
+ size != 32837 && /* with RIOT */
+ size != (32837 + 4 + XM_RAM_SIZE)) /* XM */ {
+ logger_LogError("Save state file has an invalid size.",
+ PRO_SYSTEM_SOURCE);
+ return false;
+ }
+ for (index = 0; index < 16384; index++) {
+ memory_ram[16384 + index] = loc_buffer[offset + index];
}
offset += 16384;
- }
+ }
- if( size == 16453 || size == 32837 )
- {
+ if (size == 16453 || /* no supercart ram */
+ size == 32837 || /* supercart ram */
+ size == (16453 + 4 + XM_RAM_SIZE) || /* xm, no supercart ram */
+ size == (32837 + 4 + XM_RAM_SIZE)) /* xm, supercart ram */ {
// RIOT state
riot_dra = loc_buffer[offset++];
riot_drb = loc_buffer[offset++];
riot_timing = loc_buffer[offset++];
- riot_timer = ( loc_buffer[offset++] << 8 );
+ riot_timer = (loc_buffer[offset++] << 8);
riot_timer |= loc_buffer[offset++];
riot_intervals = loc_buffer[offset++];
- riot_clocks = ( loc_buffer[offset++] << 8 );
+ riot_clocks = (loc_buffer[offset++] << 8);
riot_clocks |= loc_buffer[offset++];
+ }
+ // XM (if applicable)
+ if (cartridge_xm) {
+ if ((size != (16453 + 4 + XM_RAM_SIZE)) &&
+ (size != (32837 + 4 + XM_RAM_SIZE))) {
+ logger_LogError("Save state file has an invalid size.",
+ PRO_SYSTEM_SOURCE);
+ return false;
+ }
+ xm_reg = loc_buffer[offset++];
+ xm_bank = loc_buffer[offset++];
+ xm_pokey_enabled = loc_buffer[offset++];
+ xm_mem_enabled = loc_buffer[offset++];
+
+#if 0
+net_print_string(NULL, 0, "Read XM: xm_reg: %d, xm_bank: %d, xm_pokey_enabled: %d, xm_mem_enabled: %d\n",
+ xm_reg, xm_bank, xm_pokey_enabled, xm_mem_enabled);
+#endif
+
+ for (index = 0; index < XM_RAM_SIZE; index++) {
+ xm_ram[index] = loc_buffer[offset++];
+ }
}
return true;
diff --git a/src/ProSystem.h b/src/ProSystem.h
index 57020f3..a07fa15 100644
--- a/src/ProSystem.h
+++ b/src/ProSystem.h
@@ -38,6 +38,7 @@
#include "Archive.h"
#include "Tia.h"
#include "Pokey.h"
+#include "ExpansionModule.h"
typedef unsigned char byte;
typedef unsigned short word;
diff --git a/src/Region.cpp b/src/Region.cpp
index a3e8215..af3754a 100644
--- a/src/Region.cpp
+++ b/src/Region.cpp
@@ -189,8 +189,10 @@ void region_Reset( ) {
palette_Load(REGION_PALETTE_PAL); // Added check for default - bberlin
prosystem_frequency = REGION_FREQUENCY_PAL;
prosystem_scanlines = REGION_SCANLINES_PAL;
+#ifndef WII
tia_size = 624;
- pokey_size = 624;
+ pokey_size = 624;
+#endif
}
else {
maria_displayArea = REGION_DISPLAY_AREA_NTSC;
@@ -199,8 +201,10 @@ void region_Reset( ) {
palette_Load(REGION_PALETTE_NTSC); // Added check for default - bberlin
prosystem_frequency = REGION_FREQUENCY_NTSC;
prosystem_scanlines = REGION_SCANLINES_NTSC;
+#ifndef WII
tia_size = 524;
pokey_size = 524;
+#endif
}
- pokey_setSampleRate( ( prosystem_scanlines * prosystem_frequency ) << 1 );
+ pokey_setSampleRate((prosystem_scanlines * prosystem_frequency) << 1);
}
diff --git a/src/Sound.cpp b/src/Sound.cpp
index 1dce344..7a1f2b2 100644
--- a/src/Sound.cpp
+++ b/src/Sound.cpp
@@ -27,6 +27,11 @@
#include
#include "wii_direct_sound.h"
+#ifdef WII_NETTRACE
+#include
+#include "net_print.h"
+#endif
+
#define SOUND_SOURCE "Sound.cpp"
int wii_sound_length = 0;
@@ -77,17 +82,16 @@ static void sound_Resample(const byte* source, byte* target, int length) {
int measurement = sound_format.nSamplesPerSec;
int sourceIndex = 0;
int targetIndex = 0;
-
- int max = ( ( prosystem_frequency * prosystem_scanlines ) << 1 );
- while(targetIndex < length) {
- if(measurement >= max) {
- target[targetIndex++] = source[sourceIndex];
- measurement -= max;
- }
- else {
- sourceIndex++;
- measurement += sound_format.nSamplesPerSec;
- }
+
+ int max = ((prosystem_frequency * prosystem_scanlines) << 1);
+ while (targetIndex < length) {
+ if (measurement >= max) {
+ target[targetIndex++] = source[sourceIndex];
+ measurement -= max;
+ } else {
+ sourceIndex++;
+ measurement += sound_format.nSamplesPerSec;
+ }
}
}
@@ -112,26 +116,68 @@ bool sound_SetFormat(WAVEFORMATEX format) {
// Store
// ----------------------------------------------------------------------------
+byte sample[MAX_BUFFER_SIZE] = {0};
+byte pokeySample[MAX_BUFFER_SIZE] = {0};
+
+#ifdef TRACE_SOUND
+static int maxTia = 0, minTia = 0, maxPokey = 0, minPokey = 0;
+static u64 sumTia = 0, sumPokey = 0;
+static int scount = 0;
+static u64 stotalCount = 0;
+#endif
+
bool sound_Store( ) {
+ bool pokey = (cartridge_pokey || xm_pokey_enabled);
if( sound_muted ) sound_SetMuted( false );
-
- byte sample[MAX_BUFFER_SIZE];
memset( sample, 0, MAX_BUFFER_SIZE );
uint length = 48000 / prosystem_frequency; /* sound_GetSampleLength(sound_format.nSamplesPerSec, prosystem_frame, prosystem_frequency); */ /* 48000 / prosystem_frequency */
sound_Resample(tia_buffer, sample, length);
+ tia_Clear(); // WII
- if(cartridge_pokey) {
- byte pokeySample[MAX_BUFFER_SIZE];
+ if(pokey) {
memset( pokeySample, 0, MAX_BUFFER_SIZE );
- sound_Resample(pokey_buffer, pokeySample, length);
+ sound_Resample(pokey_buffer, pokeySample, length);
for(uint index = 0; index < length; index++) {
- sample[index] += pokeySample[index];
- sample[index] = sample[index] / 2;
+#ifdef TRACE_SOUND
+ stotalCount++;
+ if (sample[index] > maxTia) maxTia = sample[index];
+ if (sample[index] < minTia) minTia = sample[index];
+ if (pokeySample[index] > maxPokey) maxPokey = pokeySample[index];
+ if (pokeySample[index] < minPokey) minPokey = pokeySample[index];
+ sumTia += sample[index];
+ sumPokey += pokeySample[index];
+#endif
+ u32 sound = sample[index] + pokeySample[index];
+ sample[index] = sound >> 1;
}
- }
+ }
+ else {
+ for(uint index = 0; index < length; index++) {
+#ifdef TRACE_SOUND
+ stotalCount++;
+ sumTia += sample[index];
+ if (sample[index] > maxTia) maxTia = sample[index];
+ if (sample[index] < minTia) minTia = sample[index];
+#endif
+ sample[index] = sample[index] * 0.75; //>> 1;
+ }
+ }
+ pokey_Clear(); // WII
- wii_storeSound( sample, length );
+ wii_storeSound( sample, length );
+
+#ifdef TRACE_SOUND
+ if (scount++ == 60) {
+ net_print_string(NULL, 0, "Pokey: max %d, min %d, avg: %f (sum:%llu, count:%llu)\n",
+ maxPokey, minPokey, (sumPokey/(double)stotalCount), sumPokey, stotalCount);
+ net_print_string(NULL, 0, "TIA: max %d, min %d, avg: %f (sum:%llu, count:%llu)\n",
+ maxTia, minTia, (sumTia/(double)stotalCount), sumTia, stotalCount);
+ scount = stotalCount = 0;
+ maxPokey = minPokey = sumPokey = 0;
+ maxTia = minTia = sumTia = 0;
+ }
+#endif
return true;
}
@@ -139,11 +185,8 @@ bool sound_Store( ) {
// ----------------------------------------------------------------------------
// Play
// ----------------------------------------------------------------------------
-bool sound_Play( ) {
- byte sample[MAX_BUFFER_SIZE];
- memset( sample, 0, MAX_BUFFER_SIZE );
- wii_storeSound( sample, 1024 );
- //ResetAudio();
+bool sound_Play( ) {
+ ResetAudio();
return true;
}
@@ -151,10 +194,7 @@ bool sound_Play( ) {
// Stop
// ----------------------------------------------------------------------------
bool sound_Stop( ) {
- byte sample[MAX_BUFFER_SIZE];
- memset( sample, 0, MAX_BUFFER_SIZE );
- wii_storeSound( sample, 1024 );
- //StopAudio();
+ StopAudio();
return true;
}
diff --git a/src/Tia.cpp b/src/Tia.cpp
index d3e176a..b000ec1 100644
--- a/src/Tia.cpp
+++ b/src/Tia.cpp
@@ -39,12 +39,20 @@
// Tia.cpp
// ----------------------------------------------------------------------------
#include "Tia.h"
+#include
+
+
+#ifdef WII_NETTRACE
+#include
+#include "net_print.h"
+#endif
+
#define TIA_POLY4_SIZE 15
#define TIA_POLY5_SIZE 31
#define TIA_POLY9_SIZE 511
byte tia_buffer[TIA_BUFFER_SIZE] = {0};
-uint tia_size = 524;
+uint tia_size = TIA_BUFFER_SIZE;
static const byte TIA_POLY4[ ] = {1,1,0,1,1,1,0,0,0,0,1,0,1,0,0};
static const byte TIA_POLY5[ ] = {0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1};
@@ -119,9 +127,8 @@ void tia_Reset( ) {
// Clear
// ----------------------------------------------------------------------------
void tia_Clear( ) {
- for(int index = 0; index < TIA_BUFFER_SIZE; index++) {
- tia_buffer[index] = 0;
- }
+ tia_soundCntr = 0;
+ memset(tia_buffer, 0, TIA_BUFFER_SIZE);
}
// ----------------------------------------------------------------------------
diff --git a/src/wii/wii_app_common.h b/src/wii/wii_app_common.h
index 1354cd6..24fbb9c 100644
--- a/src/wii/wii_app_common.h
+++ b/src/wii/wii_app_common.h
@@ -62,7 +62,8 @@ enum NODETYPE {
NODETYPE_SPACER,
NODETYPE_RESUME,
NODETYPE_ADVANCED,
- NODETYPE_CARTRIDGE_SAVE_STATES_SPACER,
+ NODETYPE_CARTRIDGE_SETTINGS,
+ NODETYPE_CARTRIDGE_SETTINGS_SPACER,
NODETYPE_CARTRIDGE_SAVE_STATES,
NODETYPE_CARTRIDGE_SAVE_STATES_SLOT,
NODETYPE_DEBUG_MODE,
@@ -77,11 +78,6 @@ enum NODETYPE {
NODETYPE_MAX_FRAME_RATE,
NODETYPE_DIFF_SWITCH_DISPLAY,
NODETYPE_DIFF_SWITCH_ENABLED,
- NODETYPE_SWAP_BUTTONS,
- NODETYPE_HIGH_SCORE_MODE,
- NODETYPE_CARTRIDGE_SETTINGS,
- NODETYPE_CARTRIDGE_WSYNC,
- NODETYPE_CARTRIDGE_CYCLE_STEALING,
NODETYPE_DISPLAY_SETTINGS,
NODETYPE_CONTROLS_SETTINGS,
NODETYPE_LIGHTGUN_CROSSHAIR,
@@ -93,7 +89,33 @@ enum NODETYPE {
NODETYPE_FILTER,
NODETYPE_GX_VI_SCALER,
NODETYPE_DOUBLE_STRIKE,
- NODETYPE_TRAP_FILTER
+ NODETYPE_TRAP_FILTER,
+ NODETYPE_CART_SETTINGS_CART_TYPE,
+ NODETYPE_CART_SETTINGS_REGION,
+ NODETYPE_CART_SETTINGS_SAVE,
+ NODETYPE_CART_SETTINGS_DELETE,
+ NODETYPE_CART_SETTINGS_WSYNC,
+ NODETYPE_CART_SETTINGS_CYCLE_STEALING,
+ NODETYPE_CART_SETTINGS_POKEY,
+ NODETYPE_CART_SETTINGS_XM,
+ NODETYPE_CART_SETTINGS_DISABLE_BIOS,
+ NODETYPE_CART_SETTINGS_LEFT_SWITCH,
+ NODETYPE_CART_SETTINGS_RIGHT_SWITCH,
+ NODETYPE_CART_SETTINGS_CART_SETTINGS,
+ NODETYPE_CART_SETTINGS_DIFF_SWITCH_SETTINGS,
+ NODETYPE_CART_SETTINGS_CONTROLS_SETTINGS,
+ NODETYPE_CART_SETTINGS_SWAP_BUTTONS,
+ NODETYPE_CART_SETTINGS_CONTROLLER1,
+ NODETYPE_CART_SETTINGS_CONTROLLER2,
+ NODETYPE_CART_SETTINGS_DUAL_ANALOG,
+ NODETYPE_CART_SETTINGS_LIGHTGUN_OFFSET_X,
+ NODETYPE_CART_SETTINGS_LIGHTGUN_OFFSET_Y,
+ NODETYPE_CART_SETTINGS_CONTROLS_SPACER,
+ NODETYPE_CART_SETTINGS_HBLANK,
+ NODETYPE_CART_SETTINGS_HSC,
+ NODETYPE_ADVANCED_DIFF_SWITCH_SETTINGS
};
#endif
+
+
diff --git a/src/wii/wii_atari.cpp b/src/wii/wii_atari.cpp
index b43153a..4a3b88b 100644
--- a/src/wii/wii_atari.cpp
+++ b/src/wii/wii_atari.cpp
@@ -31,6 +31,7 @@
| |
\*--------------------------------------------------------------------------*/
+#include "Cartridge.h"
#include "Database.h"
#include "Sound.h"
#include "Timer.h"
@@ -57,6 +58,12 @@
#include "wii_atari_emulation.h"
#include "wii_atari_input.h"
#include "wii_atari_sdl.h"
+#include "wii_atari_db.h"
+
+#ifdef WII_NETTRACE
+#include
+#include "net_print.h"
+#endif
// The size of the crosshair
#define CROSSHAIR_SIZE 11
@@ -68,7 +75,8 @@
/** The default screen sizes */
static const screen_size default_screen_sizes[] = {
- {DEFAULT_SCREEN_X, DEFAULT_SCREEN_Y, "Atari 7800 PAR (6:7)"},
+ {DEFAULT_SCREEN_X, DEFAULT_SCREEN_Y, "0.857 PAR (6:7)"},
+ {616, DEFAULT_SCREEN_Y, "0.9625 PAR"},
{640, DEFAULT_SCREEN_Y, "Square Pixels (1:1)"}
};
@@ -82,16 +90,6 @@ byte atari_pal8[256] = {0};
BOOL wii_lightgun_flash = TRUE;
/** Whether to display a crosshair for the lightgun */
BOOL wii_lightgun_crosshair = TRUE;
-/** Whether wsync is enabled/disabled */
-u8 wii_cart_wsync = CART_MODE_AUTO;
-/** Whether cycle stealing is enabled/disabled */
-u8 wii_cart_cycle_stealing = CART_MODE_AUTO;
-/** Whether high score cart is enabled */
-BOOL wii_hs_enabled = TRUE;
-/** What mode the high score cart is in */
-BOOL wii_hs_mode = HSMODE_ENABLED_NORMAL;
-/** Whether to swap buttons */
-BOOL wii_swap_buttons = FALSE;
/** If the difficulty switches are enabled */
BOOL wii_diff_switch_enabled = FALSE;
/** When to display the difficulty switches */
@@ -126,13 +124,15 @@ static bool left_difficulty_down = false;
/** Whether the right difficulty switch is on */
static bool right_difficulty_down = false;
/** The keyboard (controls) data */
-static unsigned char keyboard_data[19];
+unsigned char keyboard_data[19];
/** The amount of time to wait before reading the difficulty switches */
static int diff_wait_count = 0;
/** The amount of time left to display the difficulty switch values */
static int diff_display_count = 0;
/** The current roms directory */
static char roms_dir[WII_MAX_PATH] = "";
+/** The current cartridge title */
+char rom_title[WII_MAX_PATH] = "";
/** The saves directory */
static char saves_dir[WII_MAX_PATH] = "";
@@ -141,6 +141,10 @@ int wii_ir_x = -100;
/** The y location of the Wiimote (IR) */
int wii_ir_y = -100;
+#if 0
+float wii_orient_roll = 0;
+#endif
+
// Forward reference
static void wii_atari_display_crosshairs(int x, int y, BOOL erase);
@@ -346,12 +350,12 @@ void wii_reset_keyboard_data() {
memset(keyboard_data, 0, sizeof(keyboard_data));
// Left difficulty switch defaults to off
- keyboard_data[15] = 1;
+ keyboard_data[15] = cartridge_left_switch;
left_difficulty_down = false;
- // Right difficulty swtich defaults to on
- keyboard_data[16] = 0;
- right_difficulty_down = true;
+ // Right difficulty switch defaults to on
+ keyboard_data[16] = cartridge_right_switch;
+ right_difficulty_down = false;
diff_wait_count = prosystem_frequency * 0.75;
diff_display_count = 0;
@@ -371,8 +375,17 @@ bool wii_atari_load_rom(char* filename, bool loadbios) {
database_Load(cartridge_digest);
+ // If no title, use the one used during loading the rom
+ if (cartridge_title.length() == 0) {
+ cartridge_title = rom_title;
+ }
+
+ // Provide opportunity to capture settings
+ wii_atari_db_after_load();
+
bios_enabled = false;
- if (loadbios) {
+#ifdef ENABLE_BIOS_SUPPORT
+ if (loadbios && !cartridge_disable_bios) {
char boot_rom[WII_MAX_PATH];
snprintf(boot_rom, WII_MAX_PATH, "%s%s", wii_get_fs_prefix(),
(cartridge_region == REGION_PAL ? WII_ROOT_BOOT_ROM_PAL
@@ -384,6 +397,20 @@ bool wii_atari_load_rom(char* filename, bool loadbios) {
bios_enabled = false;
}
}
+#endif
+
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "Final values:\n");
+ net_print_string(NULL, 0, " xm: %s\n", (cartridge_xm ? "1" : "0"));
+ net_print_string(NULL, 0, " pokey: %s\n", (cartridge_pokey ? "1" : "0"));
+ net_print_string(NULL, 0, " pokey450: %s\n", (cartridge_pokey450 ? "1" : "0"));
+ net_print_string(NULL, 0, " tv type: %s\n", cartridge_region ? "PAL" : "NTSC");
+ net_print_string(NULL, 0, " controller1: %d\n", cartridge_controller[0]);
+ net_print_string(NULL, 0, " controller2: %d\n", cartridge_controller[1]);
+ net_print_string(NULL, 0, " cartridge_type: %d\n", cartridge_type);
+ net_print_string(NULL, 0, " bios disabled: %s\n", cartridge_disable_bios ? "1" : "0");
+ net_print_string(NULL, 0, " hsc enabled: %s\n", cartridge_hsc_enabled ? "1" : "0");
+#endif
wii_reset_keyboard_data();
wii_atari_init_palette8();
@@ -473,10 +500,9 @@ static void wii_atari_display_diff_switches() {
/**
* Refreshes the Wii display
*
- * @param sync Whether vsync is available for the current frame
* @param testframes The number of testframes to run (for loading saves)
*/
-static void wii_atari_refresh_screen(bool sync, int testframes) {
+static void wii_atari_refresh_screen(int testframes) {
if (diff_wait_count > 0) {
// Reduces the number of frames remaining to display the difficulty
// switches.
@@ -496,15 +522,6 @@ static void wii_atari_refresh_screen(bool sync, int testframes) {
wii_atari_display_crosshairs(wii_ir_x, wii_ir_y, TRUE);
}
- if (sync) {
-#if 0
- wii_sync_video();
-#else
- // TODO: Evaluate how to evaluate this
- VIDEO_WaitVSync();
-#endif
- }
-
if (testframes < 0) {
wii_sdl_flip();
}
@@ -561,6 +578,36 @@ static void wii_atari_update_wiimote_ir() {
}
}
+#if 0
+static void wii_atari_update_wiimote_roll() {
+ orient_t orient;
+ WPAD_Orientation( WPAD_CHAN_0, &orient );
+
+ wii_orient_roll = orient.roll;
+
+ //-60 + 60;
+
+ int val = wii_orient_roll;
+ if (val < -60)
+ val = -60;
+ if (val > 60)
+ val = 60;
+
+ val = -val;
+
+ // 0 to 120;
+ val += 60;
+
+ float ratio = 140/120.0;//(circus)
+ //float ratio = 60/120.0; //(ark)
+ val *= ratio;
+ val += 40; //(circus)
+ //val += 20;// (ark)
+
+ wii_orient_roll = val;
+}
+#endif
+
// The number of cycles per scanline that the 7800 checks for a hit
#define LG_CYCLES_PER_SCANLINE 318
// The number of cycles indented (after HBLANK) prior to checking for a hit
@@ -672,13 +719,13 @@ static void wii_atari_update_joystick(int joyIndex,
gcHeld & GC_BUTTON_ATARI_UP || wii_analog_up(expY, gcY) ||
wii_analog_up(expRjsY, gcRjsY));
// | 04 10 | Joystick 1 2 | Button 1
- keyboard_data[wii_swap_buttons ? 4 + offset : 5 + offset] =
+ keyboard_data[cartridge_swap_buttons ? 4 + offset : 5 + offset] =
(held & (WII_BUTTON_ATARI_FIRE |
(isClassic ? WII_CLASSIC_ATARI_FIRE
: WII_NUNCHECK_ATARI_FIRE)) ||
gcHeld & GC_BUTTON_ATARI_FIRE);
// | 05 11 | Joystick 1 2 | Button 2
- keyboard_data[wii_swap_buttons ? 5 + offset : 4 + offset] =
+ keyboard_data[cartridge_swap_buttons ? 5 + offset : 4 + offset] =
(held & (WII_BUTTON_ATARI_FIRE_2 |
(isClassic ? WII_CLASSIC_ATARI_FIRE_2
: WII_NUNCHECK_ATARI_FIRE_2)) ||
@@ -748,6 +795,9 @@ static void wii_atari_update_keys(unsigned char keyboard_data[19]) {
if (lightgun_enabled) {
wii_atari_update_wiimote_ir();
}
+#if 0
+ wii_atari_update_wiimote_roll();
+#endif
wii_atari_update_joystick(0, keyboard_data);
wii_atari_update_joystick(1, keyboard_data);
}
@@ -794,12 +844,17 @@ void wii_render_callback() {
* riot_drb, memory_ram[SWCHB] */
sprintf(text,
"v: %.2f, hs: %d, %d, timer: %d, wsync: %s, %d, stl: %s, "
- "mar: %d, cpu: %d, ext: %d, rnd: %d, hb: %d",
+ "mar: %d, cpu: %d, ext: %d, rnd: %d, hb: %d, db: %s",
wii_fps_counter, high_score_set, hs_sram_write_count,
(riot_timer_count % 1000), (dbg_wsync ? "1" : "0"),
dbg_wsync_count, (dbg_cycle_stealing ? "1" : "0"),
dbg_maria_cycles, dbg_p6502_cycles, dbg_saved_cycles,
- RANDOM, cartridge_hblank);
+ RANDOM, cartridge_hblank,
+ cart_in_db ? "1" : "0");
+#if 0
+ ", roll: %f"
+ , wii_orient_roll
+#endif
}
GXColor color = (GXColor){0x0, 0x0, 0x0, 0x80};
@@ -903,7 +958,7 @@ void wii_atari_main_loop(int testframes) {
// Only enable lightgun if the cartridge supports it and we are displaying
// at 2x.
lightgun_enabled =
- (cartridge_controller[0] & CARTRIDGE_CONTROLLER_LIGHTGUN);
+ (cartridge_controller[0] == CARTRIDGE_CONTROLLER_LIGHTGUN);
float fps_counter;
u32 timerCount = 0;
@@ -917,6 +972,11 @@ void wii_atari_main_loop(int testframes) {
wii_set_video_mode(TRUE);
wii_gx_push_callback(&wii_render_callback, TRUE, NULL);
}
+
+ // Sync up timing prior to launching
+ VIDEO_WaitVSync();
+ VIDEO_WaitVSync();
+ timer_Reset();
while (!prosystem_paused) {
if (testframes < 0) {
@@ -929,13 +989,23 @@ void wii_atari_main_loop(int testframes) {
if (prosystem_active && !prosystem_paused) {
prosystem_ExecuteFrame(keyboard_data);
+ if (wii_vsync) {
+#if 0
+ wii_sync_video();
+#else
+ // TODO: Evaluate how to evaluate this
+ VIDEO_WaitVSync();
+#endif
+ }
+
while (!timer_IsTime())
;
fps_counter =
(((float)timerCount++ / (SDL_GetTicks() - start_time)) *
1000.0);
- wii_atari_refresh_screen(wii_vsync, testframes);
+
+ wii_atari_refresh_screen(testframes);
if (testframes < 0) {
sound_Store();
diff --git a/src/wii/wii_atari.h b/src/wii/wii_atari.h
index 22a851f..5cd9d90 100644
--- a/src/wii/wii_atari.h
+++ b/src/wii/wii_atari.h
@@ -35,6 +35,7 @@
#define WII_ATARI_H
#include
+#include "wii_main.h"
#include "wii_resize_screen.h"
// Dimensions of the surface that is being written to
@@ -93,16 +94,6 @@ extern bool wii_testframe;
extern BOOL wii_lightgun_flash;
/** Whether to display a crosshair for the lightgun */
extern BOOL wii_lightgun_crosshair;
-/** Whether wsync is enabled/disabled */
-extern u8 wii_cart_wsync;
-/** Whether cycle stealing is enabled/disabled */
-extern u8 wii_cart_cycle_stealing;
-/** Whether high score cart is enabled */
-extern BOOL wii_hs_enabled;
-/** What mode the high score cart is in */
-extern BOOL wii_hs_mode;
-/** Whether to swap buttons */
-extern BOOL wii_swap_buttons;
/** Whether the difficulty switches are enabled */
extern BOOL wii_diff_switch_enabled;
/** When to display the difficulty switches */
@@ -119,6 +110,8 @@ extern int wii_screen_y;
extern BOOL wii_filter;
/** Whether to use the GX/VI scaler */
extern BOOL wii_gx_vi_scaler;
+/** The current cartridge title */
+extern char rom_title[WII_MAX_PATH];
/**
* Returns the current roms directory
diff --git a/src/wii/wii_atari_config.cpp b/src/wii/wii_atari_config.cpp
index ec5bcef..228377f 100644
--- a/src/wii/wii_atari_config.cpp
+++ b/src/wii/wii_atari_config.cpp
@@ -61,14 +61,6 @@ void wii_config_handle_read_value(char* name, char* value) {
wii_diff_switch_display = Util_sscandec(value);
} else if (strcmp(name, "diff_switch_enabled") == 0) {
wii_diff_switch_enabled = Util_sscandec(value);
- } else if (strcmp(name, "swap_buttons") == 0) {
- wii_swap_buttons = Util_sscandec(value);
- } else if (strcmp(name, "high_score_cart") == 0) {
- wii_hs_mode = Util_sscandec(value);
- } else if (strcmp(name, "cart_wsync") == 0) {
- wii_cart_wsync = Util_sscandec(value);
- } else if (strcmp(name, "cart_cycle_stealing") == 0) {
- wii_cart_cycle_stealing = Util_sscandec(value);
} else if (strcmp(name, "lightgun_crosshair") == 0) {
wii_lightgun_crosshair = Util_sscandec(value);
} else if (strcmp(name, "lightgun_flash") == 0) {
@@ -115,11 +107,7 @@ void wii_config_handle_write_config(FILE* fp) {
fprintf(fp, "top_menu_exit=%d\n", wii_top_menu_exit);
fprintf(fp, "vsync=%d\n", wii_vsync);
fprintf(fp, "diff_switch_display=%d\n", wii_diff_switch_display);
- fprintf(fp, "swap_buttons=%d\n", wii_swap_buttons);
fprintf(fp, "diff_switch_enabled=%d\n", wii_diff_switch_enabled);
- fprintf(fp, "high_score_cart=%d\n", wii_hs_mode);
- fprintf(fp, "cart_wsync=%d\n", wii_cart_wsync);
- fprintf(fp, "cart_cycle_stealing=%d\n", wii_cart_cycle_stealing);
fprintf(fp, "lightgun_crosshair=%d\n", wii_lightgun_crosshair);
fprintf(fp, "lightgun_flash=%d\n", wii_lightgun_flash);
fprintf(fp, "screen_x=%d\n", wii_screen_x);
diff --git a/src/wii/wii_atari_db.cpp b/src/wii/wii_atari_db.cpp
new file mode 100644
index 0000000..82ff4b2
--- /dev/null
+++ b/src/wii/wii_atari_db.cpp
@@ -0,0 +1,807 @@
+/*--------------------------------------------------------------------------*\
+| |
+| __ __.__.___________ ______ _______ _______ |
+| / \ / \__|__\______ \/ __ \\ _ \ \ _ \ |
+| \ \/\/ / | | / /> /_\ \/ /_\ \ |
+| \ /| | | / // -- \ \_/ \ \_/ \ |
+| \__/\ / |__|__| /____/ \______ /\_____ /\_____ / |
+| \/ \/ \/ \/ |
+| |
+| Wii7800 by raz0red |
+| Wii port of the ProSystem emulator developed by Greg Stanton |
+| |
+| [github.com/raz0red/wii7800] |
+| |
++----------------------------------------------------------------------------+
+| |
+| This program is free software; you can redistribute it and/or |
+| modify it under the terms of the GNU General Public License |
+| as published by the Free Software Foundation; either version 2 |
+| of the License, or (at your option) any later version. |
+| |
+| This program is distributed in the hope that it will be useful, |
+| but WITHOUT ANY WARRANTY; without even the implied warranty of |
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+| GNU General Public License for more details. |
+| |
+| You should have received a copy of the GNU General Public License |
+| along with this program; if not, write to the Free Software |
+| Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
+| 02110-1301, USA. |
+| |
+\*--------------------------------------------------------------------------*/
+
+#include
+#include
+
+#include "Cartridge.h"
+#include "Region.h"
+
+#include "wii_app_common.h"
+#include "wii_app.h"
+#include "wii_main.h"
+#include "wii_atari_db.h"
+
+#ifdef WII_NETTRACE
+#include
+#include "net_print.h"
+#endif
+
+#define DB_FILE_PATH WII_PROSYSTEM_DB
+#define DB_TMP_FILE_PATH WII_FILES_DIR "ProSystem.dat.tmp"
+#define DB_OLD_FILE_PATH WII_FILES_DIR "ProSystem.dat.old"
+
+/**
+ * Cartridge settings.
+ *
+ * For these settings to be applied, the settings must be saved, and the
+ * cartridge must be re-loaded.
+ */
+typedef struct CartSettings {
+ /** The type of cartridge */
+ byte type;
+ /** Whether pokey is enabled */
+ bool pokey;
+ /** Whether pokey at $450 is enabled */
+ bool pokey450;
+ /** The region of the cartridge */
+ byte region;
+ /** Flags for the cartridge */
+ uint flags;
+ /** Whether the expansion module is enabled */
+ bool xm;
+ /** Whether to disable the bios loadig */
+ bool disable_bios;
+ /** The hblank */
+ int hblank;
+ /** High score cartridge */
+ bool hsc_enabled;
+} CartSettings;
+
+extern unsigned char keyboard_data[19];
+
+/** The database file */
+static char db_file[WII_MAX_PATH] = "";
+/** The database temp file */
+static char db_tmp_file[WII_MAX_PATH] = "";
+/** The database old file */
+static char db_old_file[WII_MAX_PATH] = "";
+/** The cartridge settings */
+static CartSettings cart_settings = {0};
+/** Whether the cart exists in the DB */
+static bool cart_exists_in_db = false;
+
+/**
+ * This method is invoked after a cartridge has been loaded. It provides an
+ * opportunity for the current cartridge settings to be captured, so they can be
+ * viewed and modified later.
+ */
+void wii_atari_db_after_load()
+{
+ cart_settings.type = cartridge_type;
+ cart_settings.pokey = cartridge_pokey;
+ cart_settings.pokey450 = cartridge_pokey450;
+ cart_settings.region = cartridge_region;
+ cart_settings.flags = cartridge_flags;
+ cart_settings.xm = cartridge_xm;
+ cart_settings.disable_bios = cartridge_disable_bios;
+ cart_settings.hblank = cartridge_hblank;
+ cart_settings.hsc_enabled = cartridge_hsc_enabled;
+ cart_exists_in_db = false;
+}
+
+/**
+ * Returns the path to the database file
+ *
+ * @return The path to the database file
+ */
+static char* get_db_path() {
+ if (db_file[0] == '\0') {
+ snprintf(db_file, WII_MAX_PATH, "%s%s", wii_get_fs_prefix(),
+ DB_FILE_PATH);
+ }
+ return db_file;
+}
+
+/**
+ * Returns the path to the database temporary file
+ *
+ * @return The path to the database temporary file
+ */
+static char* get_db_tmp_path() {
+ if (db_tmp_file[0] == '\0') {
+ snprintf(db_tmp_file, WII_MAX_PATH, "%s%s", wii_get_fs_prefix(),
+ DB_TMP_FILE_PATH);
+ }
+ return db_tmp_file;
+}
+
+/**
+ * Returns the path to the database old file
+ *
+ * @return The path to the database old file
+ */
+static char* get_db_old_path() {
+ if (db_old_file[0] == '\0') {
+ snprintf(db_old_file, WII_MAX_PATH, "%s%s", wii_get_fs_prefix(),
+ DB_OLD_FILE_PATH);
+ }
+ return db_old_file;
+}
+
+/**
+ * Writes the database entry to the specified file
+ *
+ * @param file The file to write the entry to
+ * @param hash The hash for the entry
+ */
+static void write_entry(FILE* file, const char* hash) {
+#ifdef WII_NETTRACE
+ net_print_string(NULL, 0, "writing db entry with hash: [%s]\n", hash);
+#endif
+ bool lightgun =
+ cartridge_controller[0] == CARTRIDGE_CONTROLLER_LIGHTGUN ||
+ cartridge_controller[1] == CARTRIDGE_CONTROLLER_LIGHTGUN;
+ bool bothJoystick =
+ cartridge_controller[0] == CARTRIDGE_CONTROLLER_JOYSTICK &&
+ cartridge_controller[1] == CARTRIDGE_CONTROLLER_JOYSTICK;
+ fprintf(file, "[%s]\n", hash);
+ fprintf(file, "title=%s\n", cartridge_title.c_str());
+ fprintf(file, "type=%d\n", cart_settings.type);
+ fprintf(file, "pokey=%s\n", cart_settings.pokey ? "true" : "false");
+ fprintf(file, "controller1=%d\n", cartridge_controller[0]);
+ fprintf(file, "controller2=%d\n", cartridge_controller[1]);
+ fprintf(file, "region=%d\n", cart_settings.region);
+ fprintf(file, "flags=%d\n", cart_settings.flags);
+ fprintf(file, "pokey450=%s\n", cart_settings.pokey450 ? "true" : "false");
+ fprintf(file, "xm=%s\n", cart_settings.xm ? "true" : "false");
+ fprintf(file, "hsc=%s\n", cart_settings.hsc_enabled ? "true" : "false");
+ if (lightgun) {
+ if (cartridge_crosshair_x) {
+ fprintf(file, "crossx=%d\n", cartridge_crosshair_x);
+ }
+ if (cartridge_crosshair_y) {
+ fprintf(file, "crossy=%d\n", cartridge_crosshair_y);
+ }
+ }
+#ifdef ENABLE_BIOS_SUPPORT
+ if (cart_settings.disable_bios) {
+ fprintf(file, "disablebios=%s\n", cart_settings.disable_bios ? "true" : "false");
+ }
+#endif
+ /*byte cartridge_left_switch = 1;*/ // Default
+ if (cartridge_left_switch != 1) {
+ fprintf(file, "leftswitch=%d\n", cartridge_left_switch);
+ }
+ /*byte cartridge_right_switch = 0;*/ // Default
+ if (cartridge_right_switch != 0) {
+ fprintf(file, "rightswitch=%d\n", cartridge_right_switch);
+ }
+ if (cartridge_swap_buttons) {
+ fprintf(file, "swapbuttons=%s\n", cartridge_swap_buttons ? "true" : "false");
+ }
+ if (bothJoystick && cartridge_dualanalog) {
+ fprintf(file, "dualanalog=%s\n", cartridge_dualanalog ? "true" : "false");
+ }
+ if (cart_settings.hblank != HBLANK_DEFAULT) {
+ fprintf(file, "hblank=%d\n", cart_settings.hblank);
+ }
+}
+
+/**
+ * Attempts to locate a hash in the specified source string. If it
+ * is found, it is copied into dest.
+ *
+ * @param source The source string
+ * @param dest The destination string
+ * @return non-zero if the hash was found and copied
+ */
+static int get_hash(char* source, char* dest) {
+ int db_hash_len = 0; // Length of the hash
+ char* end_idx; // End index of the hash
+ char* start_idx; // Start index of the hash
+
+ start_idx = source;
+ if (*start_idx == '[') {
+ ++start_idx;
+ end_idx = strrchr(start_idx, ']');
+ if (end_idx != 0) {
+ db_hash_len = end_idx - start_idx;
+ strncpy(dest, start_idx, db_hash_len);
+ dest[db_hash_len] = '\0';
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Attempts to find an entry for the specified hash
+ *
+ * @param hash The hash of the game
+ * @return Whether the entry was found
+ */
+static bool db_find_entry(const char* hash) {
+ char buff[255]; // The buffer to use when reading the file
+ char db_hash[255]; // A hash found in the file we are reading from
+ // The database file
+ FILE* db_file = fopen(get_db_path(), "r");
+
+ // A database file doesn't exist
+ if (!db_file) {
+ return false;
+ }
+
+ bool found = false;
+ while (!found && fgets(buff, sizeof(buff), db_file) != 0) {
+ // Check if we found a hash
+ if (get_hash(buff, db_hash)) {
+ if (!strcmp(hash, db_hash)) {
+ found = true;
+ }
+ }
+ }
+ fclose(db_file);
+ return found;
+}
+
+
+/**
+ * Writes the settings for the current game
+ *
+ * @param hash The hash of the game
+ * @param delete Whether to delete the entry
+ * @return Whether the write was successful
+ */
+static int db_write_entry(const char* hash, bool del) {
+ char buff[255]; // The buffer to use when reading the file
+ char db_hash[255]; // A hash found in the file we are reading from
+ int copy_mode = 0; // The current copy mode
+ FILE* tmp_file = 0; // The temp file
+ FILE* old_file = 0; // The old file
+
+ // The database file
+ FILE* db_file = fopen(get_db_path(), "r");
+
+ // A database file doesn't exist, create a new one
+ if (!db_file && !del) {
+ db_file = fopen(get_db_path(), "w");
+ if (!db_file) {
+ // Unable to create DB file
+ return 0;
+ }
+
+ // Write the entry
+ write_entry(db_file, hash);
+
+ fclose(db_file);
+ } else {
+ //
+ // A database exists, search for the appropriate hash while copying
+ // its current contents to a temp file
+ //
+
+ // Open up the temp file
+ tmp_file = fopen(get_db_tmp_path(), "w");
+ if (!tmp_file) {
+ fclose(db_file);
+
+ // Unable to create temp file
+ return 0;
+ }
+
+ //
+ // Loop and copy
+ //
+
+ while (fgets(buff, sizeof(buff), db_file) != 0) {
+ // Check if we found a hash
+ if (copy_mode < 2 && get_hash(buff, db_hash)) {
+ if (copy_mode) {
+ copy_mode++;
+ } else if (!strcmp(hash, db_hash)) {
+ // We have matching hashes, write out the new entry
+ if (!del) {
+ write_entry(tmp_file, hash);
+ }
+
+ copy_mode++;
+ }
+ }
+
+ if (copy_mode != 1) {
+ fprintf(tmp_file, "%s", buff);
+ }
+ }
+
+ if (!copy_mode) {
+ // We didn't find the hash in the database, add it
+ if (!del) {
+ write_entry(tmp_file, hash);
+ }
+ }
+
+ fclose(db_file);
+ fclose(tmp_file);
+
+ //
+ // Make sure the temporary file exists
+ // We do this due to the instability of the Wii SD card
+ //
+ tmp_file = fopen(get_db_tmp_path(), "r");
+ if (!tmp_file) {
+ // Unable to find temp file
+ return 0;
+ }
+ fclose(tmp_file);
+
+ // Delete old file (if it exists)
+ if ((old_file = fopen(get_db_old_path(), "r")) != 0) {
+ fclose(old_file);
+ if (remove(get_db_old_path()) != 0) {
+ return 0;
+ }
+ }
+
+ // Rename database file to old file
+ if (rename(get_db_path(), get_db_old_path()) != 0) {
+ return 0;
+ }
+
+ // Rename temp file to database file
+ if (rename(get_db_tmp_path(), get_db_path()) != 0) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/**
+ * Deletes the entry from the database with the specified hash
+ *
+ * @param hash The hash of the game
+ * @return Whether the delete was successful
+ */
+static int db_delete_entry(const char* hash) {
+ return db_write_entry(hash, true);
+}
+
+/**
+ * Checks to see if an entry exists in the database for the current game
+ *
+ * @return Whether an entry exists in the database for the current game
+ */
+bool wii_atari_db_check_exists() {
+ cart_exists_in_db = db_find_entry(cartridge_digest.c_str());
+ return cart_exists_in_db;
+}
+
+/**
+ * Creates the menu entries for the cartridge settings menu
+ */
+void wii_atari_db_create_menu(TREENODE* cart_settings_menu) {
+
+ //
+ // Cartridge settings
+ //
+
+ TREENODE* cart_settings = wii_create_tree_node(
+ NODETYPE_CART_SETTINGS_CART_SETTINGS, "Cartridge settings");
+ wii_add_child(cart_settings_menu, cart_settings);
+
+ TREENODE* child = wii_create_tree_node(NODETYPE_CART_SETTINGS_CART_TYPE, "Cartridge type");
+ wii_add_child(cart_settings, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_REGION, "Region");
+ wii_add_child(cart_settings, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_POKEY, "Pokey");
+ wii_add_child(cart_settings, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_HSC, "High score cartridge (HSC)");
+ wii_add_child(cart_settings, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_XM, "Expansion module (XM)");
+ wii_add_child(cart_settings, child);
+
+#ifdef ENABLE_BIOS_SUPPORT
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_DISABLE_BIOS, "BIOS");
+ wii_add_child(cart_settings, child);
+#endif
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_WSYNC, "Handle WSYNC");
+ wii_add_child(cart_settings, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_CYCLE_STEALING, "Cycle stealing");
+ wii_add_child(cart_settings, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_HBLANK, "HBlank");
+ wii_add_child(cart_settings, child);
+
+ //
+ // Controls settings
+ //
+
+ TREENODE* controls = wii_create_tree_node(
+ NODETYPE_CART_SETTINGS_CONTROLS_SETTINGS, "Control settings");
+ wii_add_child(cart_settings_menu, controls);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_CONTROLLER1,
+ "Controller 1");
+ wii_add_child(controls, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_CONTROLLER2,
+ "Controller 2");
+ wii_add_child(controls, child);
+
+ child = wii_create_tree_node(NODETYPE_SPACER, "");
+ wii_add_child(controls, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_SWAP_BUTTONS,
+ "Swap buttons");
+ wii_add_child(controls, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_CONTROLS_SPACER, "");
+ wii_add_child(controls, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_DUAL_ANALOG,
+ "Dual analog");
+ wii_add_child(controls, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_LIGHTGUN_OFFSET_X,
+ "Lightgun offset X");
+ wii_add_child(controls, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_LIGHTGUN_OFFSET_Y,
+ "Lightgun offset Y");
+ wii_add_child(controls, child);
+
+ //
+ // Difficulty switch settings
+ //
+
+ TREENODE* diff_switch_settings = wii_create_tree_node(
+ NODETYPE_CART_SETTINGS_DIFF_SWITCH_SETTINGS, "Difficulty switch settings");
+ wii_add_child(cart_settings_menu, diff_switch_settings);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_LEFT_SWITCH, "Left switch");
+ wii_add_child(diff_switch_settings, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_RIGHT_SWITCH, "Right switch");
+ wii_add_child(diff_switch_settings, child);
+
+ //
+ // Save/Delete settings
+ //
+
+ child = wii_create_tree_node(NODETYPE_SPACER, "");
+ wii_add_child(cart_settings_menu, child);
+
+ child =
+ wii_create_tree_node(NODETYPE_CART_SETTINGS_SAVE, "Save settings");
+ wii_add_child(cart_settings_menu, child);
+
+ child = wii_create_tree_node(NODETYPE_CART_SETTINGS_DELETE,
+ "Delete settings");
+ wii_add_child(cart_settings_menu, child);
+}
+
+/**
+ * Updates the buffer with the name of the specified node
+ *
+ * @param node The node
+ * @param buffer The name of the specified node
+ * @param value The value of the specified node
+ */
+void wii_atari_db_get_node_name(TREENODE* node, char* buffer, char* value) {
+ const char* strmode = "";
+ switch (node->node_type) {
+ case NODETYPE_CART_SETTINGS_CART_TYPE:
+ switch (cart_settings.type) {
+ case CARTRIDGE_TYPE_NORMAL:
+ strmode = "Normal";
+ break;
+ case CARTRIDGE_TYPE_SUPERCART:
+ strmode = "SuperGame bank switched";
+ break;
+ case CARTRIDGE_TYPE_SUPERCART_LARGE:
+ strmode = "SuperGame ROM at $4000 (bank 0)";
+ break;
+ case CARTRIDGE_TYPE_SUPERCART_RAM:
+ strmode = "SuperGame RAM at $4000";
+ break;
+ case CARTRIDGE_TYPE_SUPERCART_ROM:
+ strmode = "SuperGame ROM at $4000 (bank 6)";
+ break;
+ case CARTRIDGE_TYPE_ABSOLUTE:
+ strmode = "Absolute";
+ break;
+ case CARTRIDGE_TYPE_ACTIVISION:
+ strmode = "Activision";
+ break;
+ case CARTRIDGE_TYPE_NORMAL_RAM:
+ strmode="Normal RAM at $4000";
+ break;
+ default:
+ break;
+ }
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s", strmode);
+ break;
+ case NODETYPE_CART_SETTINGS_REGION:
+ switch (cart_settings.region) {
+ case REGION_NTSC:
+ strmode = "NTSC";
+ break;
+ case REGION_PAL:
+ strmode = "PAL";
+ break;
+ default:
+ break;
+ }
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s", strmode);
+ break;
+ case NODETYPE_CART_SETTINGS_WSYNC:
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s",
+ cart_settings.flags & CARTRIDGE_WSYNC_MASK ? "Disabled" : "Enabled");
+ break;
+ case NODETYPE_CART_SETTINGS_CYCLE_STEALING:
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s",
+ cart_settings.flags & CARTRIDGE_CYCLE_STEALING_MASK ? "Disabled" : "Enabled");
+ break;
+ case NODETYPE_CART_SETTINGS_XM:
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s", cart_settings.xm ? "Enabled" : "Disabled");
+ break;
+ case NODETYPE_CART_SETTINGS_SWAP_BUTTONS:
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s", cartridge_swap_buttons ? "Enabled" : "Disabled");
+ break;
+ case NODETYPE_CART_SETTINGS_POKEY:
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s",
+ cart_settings.pokey ?
+ (cart_settings.pokey450 ? "Pokey at $0450" : "Pokey at $4000") :
+ "Disabled");
+ break;
+ case NODETYPE_CART_SETTINGS_DISABLE_BIOS:
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s",
+ cart_settings.disable_bios ? "Disabled" : "Enabled");
+ break;
+ case NODETYPE_CART_SETTINGS_HSC:
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s",
+ cart_settings.hsc_enabled ? "Enabled" : "Disabled");
+ break;
+ case NODETYPE_CART_SETTINGS_LEFT_SWITCH:
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s",
+ cartridge_left_switch ? "B" : "A");
+ break;
+ case NODETYPE_CART_SETTINGS_RIGHT_SWITCH:
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s",
+ cartridge_right_switch ? "B" : "A");
+ break;
+ case NODETYPE_CART_SETTINGS_CONTROLLER1:
+ case NODETYPE_CART_SETTINGS_CONTROLLER2: {
+ byte controller = cartridge_controller
+ [node->node_type == NODETYPE_CART_SETTINGS_CONTROLLER1 ? 0 : 1];
+ const char* ctype = "(Unknown)";
+ switch (controller) {
+ case CARTRIDGE_CONTROLLER_JOYSTICK:
+ ctype = "Joystick";
+ break;
+ case CARTRIDGE_CONTROLLER_LIGHTGUN:
+ ctype = "Lightgun";
+ break;
+ }
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s", ctype);
+ } break;
+ case NODETYPE_CART_SETTINGS_DUAL_ANALOG:
+ snprintf(value, WII_MENU_BUFF_SIZE, "%s",
+ cartridge_dualanalog ? "Enabled" : "Disabled");
+ break;
+ case NODETYPE_CART_SETTINGS_LIGHTGUN_OFFSET_X:
+ snprintf(value, WII_MENU_BUFF_SIZE, "%d",
+ cartridge_crosshair_x);
+ break;
+ case NODETYPE_CART_SETTINGS_LIGHTGUN_OFFSET_Y:
+ snprintf(value, WII_MENU_BUFF_SIZE, "%d",
+ cartridge_crosshair_y);
+ break;
+ case NODETYPE_CART_SETTINGS_HBLANK:
+ snprintf(
+ value, WII_MENU_BUFF_SIZE, "%d %s", cart_settings.hblank,
+ (cart_settings.hblank == HBLANK_DEFAULT ? " (default)" : ""));
+ break;
+ }
+}
+
+/**
+ * React to the "select" event for the specified node
+ *
+ * @param node The node that was selected
+ */
+void wii_atari_db_select_node(TREENODE* node) {
+ switch (node->node_type) {
+ case NODETYPE_CART_SETTINGS_CART_SETTINGS:
+ case NODETYPE_CART_SETTINGS_DIFF_SWITCH_SETTINGS:
+ case NODETYPE_CART_SETTINGS_CONTROLS_SETTINGS:
+ wii_menu_push(node);
+ break;
+ case NODETYPE_CART_SETTINGS_CART_TYPE:
+ cart_settings.type++;
+ if (cart_settings.type > CARTRIDGE_TYPE_NORMAL_RAM) {
+ cart_settings.type = 0;
+ }
+ wii_set_status_message(
+ "Type changes not applied until cartridge is reloaded");
+ break;
+ case NODETYPE_CART_SETTINGS_REGION:
+ cart_settings.region++;
+ if (cart_settings.region > REGION_PAL) {
+ cart_settings.region = 0;
+ }
+ wii_set_status_message(
+ "Region changes not applied until cartridge is reloaded");
+ break;
+ case NODETYPE_CART_SETTINGS_WSYNC:
+ cart_settings.flags ^= CARTRIDGE_WSYNC_MASK;
+ wii_set_status_message(
+ "WSYNC changes not applied until cartridge is reloaded");
+ break;
+ case NODETYPE_CART_SETTINGS_CYCLE_STEALING:
+ cart_settings.flags ^= CARTRIDGE_CYCLE_STEALING_MASK;
+ wii_set_status_message(
+ "Cycle stealing changes not applied until cartridge is reloaded");
+ break;
+ case NODETYPE_CART_SETTINGS_POKEY:
+ if(cart_settings.pokey) {
+ if (!cart_settings.pokey450) {
+ cart_settings.pokey450 = true;
+ } else {
+ cart_settings.pokey = false;
+ cart_settings.pokey450 = false;
+ }
+ } else {
+ cart_settings.pokey = true;
+ }
+ wii_set_status_message(
+ "Pokey changes not applied until cartridge is reloaded");
+ break;
+ case NODETYPE_CART_SETTINGS_XM:
+ cart_settings.xm ^= 1;
+ wii_set_status_message(
+ "XM changes not applied until cartridge is reloaded");
+ break;
+ case NODETYPE_CART_SETTINGS_DISABLE_BIOS:
+ cart_settings.disable_bios ^= 1;
+ wii_set_status_message(
+ "BIOS changes not applied until cartridge is reloaded");
+ break;
+ case NODETYPE_CART_SETTINGS_LEFT_SWITCH:
+ cartridge_left_switch ^= 1;
+ keyboard_data[15] = cartridge_left_switch;
+ break;
+ case NODETYPE_CART_SETTINGS_RIGHT_SWITCH:
+ cartridge_right_switch ^= 1;
+ keyboard_data[16] = cartridge_right_switch;
+ break;
+ case NODETYPE_CART_SETTINGS_SWAP_BUTTONS:
+ cartridge_swap_buttons ^= 1;
+ break;
+ case NODETYPE_CART_SETTINGS_HSC:
+ cart_settings.hsc_enabled ^= 1;
+ wii_set_status_message(
+ "High score cart changes not applied until cartridge is reloaded");
+ break;
+ case NODETYPE_CART_SETTINGS_CONTROLLER1:
+ case NODETYPE_CART_SETTINGS_CONTROLLER2: {
+ byte index =
+ node->node_type == NODETYPE_CART_SETTINGS_CONTROLLER1 ? 0 : 1;
+ cartridge_controller[index]++;
+ if (cartridge_controller[index] > CARTRIDGE_CONTROLLER_LIGHTGUN) {
+ cartridge_controller[index] = CARTRIDGE_CONTROLLER_JOYSTICK;
+ }
+
+ } break;
+ case NODETYPE_CART_SETTINGS_DUAL_ANALOG:
+ cartridge_dualanalog ^= 1;
+ break;
+ case NODETYPE_CART_SETTINGS_LIGHTGUN_OFFSET_X:
+ cartridge_crosshair_x++;
+ if (cartridge_crosshair_x > 20) {
+ cartridge_crosshair_x = -20;
+ }
+ break;
+ case NODETYPE_CART_SETTINGS_LIGHTGUN_OFFSET_Y:
+ cartridge_crosshair_y++;
+ if (cartridge_crosshair_y > 20) {
+ cartridge_crosshair_y = -20;
+ }
+ break;
+ case NODETYPE_CART_SETTINGS_HBLANK:
+ cart_settings.hblank++;
+ if (cart_settings.hblank > 50) {
+ cart_settings.hblank = 0;
+ }
+ wii_set_status_message(
+ "HBlank changes not applied until cartridge is reloaded");
+ break;
+ case NODETYPE_CART_SETTINGS_SAVE:
+ if (db_write_entry(cartridge_digest.c_str(), false)) {
+ wii_set_status_message(
+ "Successfully saved cartridge settings.");
+ } else {
+ wii_set_status_message(
+ "An error occurred saving cartridge settings.");
+ }
+ wii_atari_db_check_exists();
+ break;
+ case NODETYPE_CART_SETTINGS_DELETE:
+ if (db_delete_entry(cartridge_digest.c_str())) {
+ wii_menu_reset_indexes();
+ wii_menu_move(wii_menu_stack[wii_menu_stack_head], 1);
+ wii_set_status_message(
+ "Successfully deleted cartridge settings.");
+ } else {
+ wii_set_status_message(
+ "An error occurred deleting cartridge settings.");
+ }
+ wii_atari_db_check_exists();
+ break;
+ }
+}
+
+/**
+ * Determines whether the node is currently visible
+ *
+ * @param node The node
+ * @return Whether the node is visible
+ */
+BOOL wii_atari_db_is_node_visible(TREENODE* node) {
+ switch (node->node_type) {
+ case NODETYPE_CART_SETTINGS_DELETE:
+ return cart_exists_in_db;
+ case NODETYPE_CART_SETTINGS_DUAL_ANALOG:
+ return cartridge_controller[0] == CARTRIDGE_CONTROLLER_JOYSTICK &&
+ cartridge_controller[1] == CARTRIDGE_CONTROLLER_JOYSTICK;
+ case NODETYPE_CART_SETTINGS_LIGHTGUN_OFFSET_X:
+ case NODETYPE_CART_SETTINGS_LIGHTGUN_OFFSET_Y:
+ return cartridge_controller[0] == CARTRIDGE_CONTROLLER_LIGHTGUN ||
+ cartridge_controller[1] == CARTRIDGE_CONTROLLER_LIGHTGUN;
+ case NODETYPE_CART_SETTINGS_CONTROLS_SPACER:
+ return cartridge_controller[0] != CARTRIDGE_CONTROLLER_JOYSTICK ||
+ cartridge_controller[1] != CARTRIDGE_CONTROLLER_JOYSTICK;
+ }
+ return TRUE;
+}
+
+/**
+ * Determines whether the node is selectable
+ *
+ * @param node The node
+ * @return Whether the node is selectable
+ */
+BOOL wii_atari_db_is_node_selectable(TREENODE* node) {
+ return node->node_type != NODETYPE_CART_SETTINGS_CONTROLS_SPACER;
+}
+
+
+
diff --git a/src/wii/wii_atari_db.h b/src/wii/wii_atari_db.h
new file mode 100644
index 0000000..740a5b8
--- /dev/null
+++ b/src/wii/wii_atari_db.h
@@ -0,0 +1,91 @@
+/*--------------------------------------------------------------------------*\
+| |
+| __ __.__.___________ ______ _______ _______ |
+| / \ / \__|__\______ \/ __ \\ _ \ \ _ \ |
+| \ \/\/ / | | / /> /_\ \/ /_\ \ |
+| \ /| | | / // -- \ \_/ \ \_/ \ |
+| \__/\ / |__|__| /____/ \______ /\_____ /\_____ / |
+| \/ \/ \/ \/ |
+| |
+| Wii7800 by raz0red |
+| Wii port of the ProSystem emulator developed by Greg Stanton |
+| |
+| [github.com/raz0red/wii7800] |
+| |
++----------------------------------------------------------------------------+
+| |
+| This program is free software; you can redistribute it and/or |
+| modify it under the terms of the GNU General Public License |
+| as published by the Free Software Foundation; either version 2 |
+| of the License, or (at your option) any later version. |
+| |
+| This program is distributed in the hope that it will be useful, |
+| but WITHOUT ANY WARRANTY; without even the implied warranty of |
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+| GNU General Public License for more details. |
+| |
+| You should have received a copy of the GNU General Public License |
+| along with this program; if not, write to the Free Software |
+| Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
+| 02110-1301, USA. |
+| |
+\*--------------------------------------------------------------------------*/
+
+#ifndef WII_ATARI_DB_H
+#define WII_ATARI_DB_H
+
+#include "wii_main.h"
+
+/**
+ * This method is invoked after a cartridge has been loaded. It provides an
+ * opportunity for the current cartridge settings to be captured, so they can be
+ * viewed and modified later.
+ */
+void wii_atari_db_after_load();
+
+
+/**
+ * Creates the menu entries for the cartridge settings menu
+ */
+void wii_atari_db_create_menu(TREENODE* cart_settings_menu);
+
+/**
+ * Updates the buffer with the name of the specified node
+ *
+ * @param node The node
+ * @param buffer The name of the specified node
+ * @param value The value of the specified node
+ */
+void wii_atari_db_get_node_name(TREENODE* node, char* buffer, char* value);
+
+/**
+ * React to the "select" event for the specified node
+ *
+ * @param node The node that was selected
+ */
+void wii_atari_db_select_node(TREENODE* node);
+
+/**
+ * Determines whether the node is currently visible
+ *
+ * @param node The node
+ * @return Whether the node is visible
+ */
+BOOL wii_atari_db_is_node_visible(TREENODE* node);
+
+/**
+ * Determines whether the node is selectable
+ *
+ * @param node The node
+ * @return Whether the node is selectable
+ */
+BOOL wii_atari_db_is_node_selectable(TREENODE* node);
+
+/**
+ * Checks to see if an entry exists in the database for the current game
+ *
+ * @return Whether an entry exists in the database for the current game
+ */
+bool wii_atari_db_check_exists();
+
+#endif
\ No newline at end of file
diff --git a/src/wii/wii_atari_emulation.cpp b/src/wii/wii_atari_emulation.cpp
index 7eb03df..08409f1 100644
--- a/src/wii/wii_atari_emulation.cpp
+++ b/src/wii/wii_atari_emulation.cpp
@@ -51,6 +51,10 @@ void WII_VideoStart();
void WII_VideoStop();
}
+#if 0
+extern u32 sound_max;
+#endif
+
/**
* Starts the emulator for the specified rom file.
*
@@ -65,9 +69,6 @@ BOOL wii_start_emulation(char* romfile,
const char* savefile,
BOOL reset,
BOOL resume) {
- // Disabled the high score cartridge
- wii_hs_enabled = (wii_hs_mode != HSMODE_DISABLED);
-
// Write out the current config
wii_write_config();
@@ -80,11 +81,6 @@ BOOL wii_start_emulation(char* romfile,
// Whether to load a save file
loadsave = (savefile != NULL && strlen(savefile) > 0);
- // Disable the high score cart for saves if applicable
- if (loadsave && (wii_hs_mode != HSMODE_ENABLED_SNAPSHOTS)) {
- wii_hs_enabled = false;
- }
-
// If we are not loading a save, reset snapshot related state
// information (current index, etc.)
if (!loadsave) {
@@ -124,6 +120,8 @@ BOOL wii_start_emulation(char* romfile,
succeeded = prosystem_Load(savefile);
if (succeeded) {
+ // Load high score cart after loading saved state
+ cartridge_LoadHighScoreCart();
wii_atari_pause(false);
} else {
wii_set_status_message(
@@ -154,6 +152,11 @@ BOOL wii_start_emulation(char* romfile,
free(old_last);
}
+ // This was a newly loaded rom, set snapshot index to latest snapshot
+ if (!loadsave && !reset && !resume) {
+ wii_snapshot_reset(TRUE);
+ }
+
if (wii_max_frame_rate != 0) {
prosystem_frequency = wii_max_frame_rate;
}
@@ -165,6 +168,10 @@ BOOL wii_start_emulation(char* romfile,
// Wait until no buttons are pressed
wii_wait_until_no_buttons(2);
+#if 0
+ sound_max = 0;
+#endif
+
wii_atari_main_loop();
if (wii_top_menu_exit) {
diff --git a/src/wii/wii_atari_menu.cpp b/src/wii/wii_atari_menu.cpp
index 4f6a6d1..abec42c 100644
--- a/src/wii/wii_atari_menu.cpp
+++ b/src/wii/wii_atari_menu.cpp
@@ -35,6 +35,7 @@
#include
#include
+#include "Cartridge.h"
#include "Region.h"
#include "wii_app_common.h"
@@ -52,6 +53,7 @@
#include "wii_atari.h"
#include "wii_atari_emulation.h"
#include "wii_atari_snapshot.h"
+#include "wii_atari_db.h"
#include "gettext.h"
@@ -123,14 +125,14 @@ void wii_atari_menu_init() {
roms_menu = child;
wii_add_child(wii_menu_root, child);
+ child =
+ wii_create_tree_node(NODETYPE_CARTRIDGE_SETTINGS_SPACER, "");
+ wii_add_child(wii_menu_root, child);
+
//
// Save state management
//
- child =
- wii_create_tree_node(NODETYPE_CARTRIDGE_SAVE_STATES_SPACER, "");
- wii_add_child(wii_menu_root, child);
-
TREENODE* states =
wii_create_tree_node(NODETYPE_CARTRIDGE_SAVE_STATES, "Save states");
wii_add_child(wii_menu_root, states);
@@ -150,6 +152,17 @@ void wii_atari_menu_init() {
child = wii_create_tree_node(NODETYPE_DELETE_STATE, "Delete state");
wii_add_child(states, child);
+ //
+ // Cartridge settings
+ //
+
+ TREENODE* cart_settings =
+ wii_create_tree_node(NODETYPE_CARTRIDGE_SETTINGS, "Cartridge-specific settings");
+ wii_add_child(wii_menu_root, cart_settings);
+
+ // Add items to the cart settings menu
+ wii_atari_db_create_menu(cart_settings);
+
//
// The advanced menu
//
@@ -208,23 +221,6 @@ void wii_atari_menu_init() {
wii_create_tree_node(NODETYPE_CONTROLS_SETTINGS, "Control settings");
wii_add_child(advanced, controls);
- child = wii_create_tree_node(NODETYPE_SWAP_BUTTONS, "Swap buttons");
- wii_add_child(controls, child);
-
- child = wii_create_tree_node(NODETYPE_SPACER, "");
- wii_add_child(controls, child);
-
- child =
- wii_create_tree_node(NODETYPE_DIFF_SWITCH_ENABLED, "Diff. switches");
- wii_add_child(controls, child);
-
- child = wii_create_tree_node(NODETYPE_DIFF_SWITCH_DISPLAY,
- "Diff. switches display");
- wii_add_child(controls, child);
-
- child = wii_create_tree_node(NODETYPE_SPACER, "");
- wii_add_child(controls, child);
-
child = wii_create_tree_node(NODETYPE_LIGHTGUN_CROSSHAIR,
"Lightgun crosshair");
wii_add_child(controls, child);
@@ -233,25 +229,21 @@ void wii_atari_menu_init() {
wii_add_child(controls, child);
//
- // The cartridge settings menu
+ // The diff switch settings
//
- TREENODE* cartridge =
- wii_create_tree_node(NODETYPE_CARTRIDGE_SETTINGS, "Cartridge settings");
- wii_add_child(advanced, cartridge);
+ TREENODE* diffswitch =
+ wii_create_tree_node(NODETYPE_ADVANCED_DIFF_SWITCH_SETTINGS, "Difficulty switch settings");
+ wii_add_child(advanced, diffswitch);
- child = wii_create_tree_node(NODETYPE_HIGH_SCORE_MODE, "High score cart.");
- wii_add_child(cartridge, child);
+ child =
+ wii_create_tree_node(NODETYPE_DIFF_SWITCH_ENABLED, "Diff. Switch buttons");
+ wii_add_child(diffswitch, child);
- child = wii_create_tree_node(NODETYPE_SPACER, "");
- wii_add_child(cartridge, child);
+ child = wii_create_tree_node(NODETYPE_DIFF_SWITCH_DISPLAY,
+ "Display switches");
+ wii_add_child(diffswitch, child);
- child = wii_create_tree_node(NODETYPE_CARTRIDGE_WSYNC, "Handle WSYNC");
- wii_add_child(cartridge, child);
-
- child = wii_create_tree_node(NODETYPE_CARTRIDGE_CYCLE_STEALING,
- "Cycle stealing");
- wii_add_child(cartridge, child);
child = wii_create_tree_node(NODETYPE_SPACER, "");
wii_add_child(advanced, child);
@@ -425,52 +417,6 @@ void wii_menu_handle_get_node_name(TREENODE* node, char* buffer, char* value) {
}
snprintf(value, WII_MENU_BUFF_SIZE, "%s", strmode);
break;
- case NODETYPE_HIGH_SCORE_MODE:
- switch (wii_hs_mode) {
- case HSMODE_ENABLED_NORMAL:
- strmode = "Enabled (excludes saved state)";
- break;
- case HSMODE_ENABLED_SNAPSHOTS:
- strmode = "Enabled (includes saved state)";
- break;
- case HSMODE_DISABLED:
- strmode = "Disabled";
- break;
- default:
- break;
- }
- snprintf(value, WII_MENU_BUFF_SIZE, "%s", strmode);
- break;
- case NODETYPE_CARTRIDGE_WSYNC:
- switch (wii_cart_wsync) {
- case CART_MODE_AUTO:
- strmode = "(auto)";
- break;
- case CART_MODE_ENABLED:
- strmode = "Enabled";
- break;
- case CART_MODE_DISABLED:
- strmode = "Disabled";
- break;
- default:
- break;
- }
- snprintf(value, WII_MENU_BUFF_SIZE, "%s", strmode);
- break;
- case NODETYPE_CARTRIDGE_CYCLE_STEALING:
- switch (wii_cart_cycle_stealing) {
- case CART_MODE_AUTO:
- strmode = "(auto)";
- break;
- case CART_MODE_ENABLED:
- strmode = "Enabled";
- break;
- case CART_MODE_DISABLED:
- strmode = "Disabled";
- break;
- }
- snprintf(value, WII_MENU_BUFF_SIZE, "%s", strmode);
- break;
case NODETYPE_MAX_FRAME_RATE:
if (wii_max_frame_rate == 0) {
snprintf(value, WII_MENU_BUFF_SIZE, "(auto)");
@@ -480,7 +426,6 @@ void wii_menu_handle_get_node_name(TREENODE* node, char* buffer, char* value) {
break;
case NODETYPE_DEBUG_MODE:
case NODETYPE_TOP_MENU_EXIT:
- case NODETYPE_SWAP_BUTTONS:
case NODETYPE_DIFF_SWITCH_ENABLED:
case NODETYPE_LIGHTGUN_CROSSHAIR:
case NODETYPE_LIGHTGUN_FLASH:
@@ -504,9 +449,6 @@ void wii_menu_handle_get_node_name(TREENODE* node, char* buffer, char* value) {
case NODETYPE_TOP_MENU_EXIT:
enabled = wii_top_menu_exit;
break;
- case NODETYPE_SWAP_BUTTONS:
- enabled = wii_swap_buttons;
- break;
case NODETYPE_DIFF_SWITCH_ENABLED:
enabled = wii_diff_switch_enabled;
break;
@@ -527,6 +469,8 @@ void wii_menu_handle_get_node_name(TREENODE* node, char* buffer, char* value) {
default:
break;
}
+
+ wii_atari_db_get_node_name(node, buffer, value);
}
/**
@@ -548,6 +492,9 @@ void wii_menu_handle_select_node(TREENODE* node) {
case NODETYPE_ROM:
snprintf(buff, sizeof(buff), "%s%s",
wii_get_roms_dir(), node->name);
+ // Default the cartridge title
+ rom_title[0] = '\0';
+ snprintf(rom_title, WII_MAX_PATH, "%s", node->name);
last_rom_index = wii_menu_get_current_index();
loading_game = TRUE;
wii_start_emulation(buff);
@@ -575,6 +522,9 @@ void wii_menu_handle_select_node(TREENODE* node) {
} else {
LOCK_RENDER_MUTEX();
+ // Allow DB to select node
+ wii_atari_db_select_node(node);
+
switch (node->node_type) {
case NODETYPE_ROOT_DRIVE:
case NODETYPE_UPDIR:
@@ -645,24 +595,6 @@ void wii_menu_handle_select_node(TREENODE* node) {
wii_diff_switch_display = 0;
}
break;
- case NODETYPE_CARTRIDGE_CYCLE_STEALING:
- wii_cart_cycle_stealing++;
- if (wii_cart_cycle_stealing > 2) {
- wii_cart_cycle_stealing = 0;
- }
- break;
- case NODETYPE_CARTRIDGE_WSYNC:
- wii_cart_wsync++;
- if (wii_cart_wsync > 2) {
- wii_cart_wsync = 0;
- }
- break;
- case NODETYPE_HIGH_SCORE_MODE:
- wii_hs_mode++;
- if (wii_hs_mode > 2) {
- wii_hs_mode = 0;
- }
- break;
case NODETYPE_VSYNC:
wii_set_vsync(wii_vsync ^ 1);
break;
@@ -701,15 +633,15 @@ void wii_menu_handle_select_node(TREENODE* node) {
case NODETYPE_WIIMOTE_MENU_ORIENT:
wii_mote_menu_vertical ^= 1;
break;
- case NODETYPE_SWAP_BUTTONS:
- wii_swap_buttons ^= 1;
- break;
case NODETYPE_DIFF_SWITCH_ENABLED:
wii_diff_switch_enabled ^= 1;
break;
+ case NODETYPE_CARTRIDGE_SETTINGS:
+ wii_atari_db_check_exists();
+ wii_menu_push(node);
+ break;
case NODETYPE_ADVANCED:
- case NODETYPE_LOAD_ROM:
- case NODETYPE_CARTRIDGE_SETTINGS:
+ case NODETYPE_LOAD_ROM:
case NODETYPE_DISPLAY_SETTINGS:
case NODETYPE_CONTROLS_SETTINGS:
wii_menu_push(node);
@@ -735,6 +667,9 @@ void wii_menu_handle_select_node(TREENODE* node) {
}
}
break;
+ case NODETYPE_ADVANCED_DIFF_SWITCH_SETTINGS:
+ wii_menu_push(node);
+ break;
default:
break;
}
@@ -760,7 +695,8 @@ BOOL wii_menu_handle_is_node_visible(TREENODE* node) {
return !wii_gx_vi_scaler && !wii_double_strike_mode;
case NODETYPE_RESET:
case NODETYPE_RESUME:
- case NODETYPE_CARTRIDGE_SAVE_STATES_SPACER:
+ case NODETYPE_CARTRIDGE_SETTINGS_SPACER:
+ case NODETYPE_CARTRIDGE_SETTINGS:
case NODETYPE_CARTRIDGE_SAVE_STATES:
return wii_last_rom != NULL;
break;
@@ -768,6 +704,10 @@ BOOL wii_menu_handle_is_node_visible(TREENODE* node) {
break;
}
+ if (!wii_atari_db_is_node_visible(node)) {
+ return FALSE;
+ }
+
return TRUE;
}
@@ -778,9 +718,14 @@ BOOL wii_menu_handle_is_node_visible(TREENODE* node) {
* @return Whether the node is selectable
*/
BOOL wii_menu_handle_is_node_selectable(TREENODE* node) {
- if (node->node_type == NODETYPE_CARTRIDGE_SAVE_STATES_SPACER) {
+ if (node->node_type == NODETYPE_CARTRIDGE_SETTINGS_SPACER) {
return FALSE;
}
+
+ if (!wii_atari_db_is_node_selectable(node)) {
+ return FALSE;
+ }
+
return TRUE;
}
diff --git a/src/wii/wii_direct_sound.cpp b/src/wii/wii_direct_sound.cpp
index 0d60116..c3dc0e8 100644
--- a/src/wii/wii_direct_sound.cpp
+++ b/src/wii/wii_direct_sound.cpp
@@ -13,13 +13,18 @@
#include
#include
+#ifdef WII_NETTRACE
+#include
+#include "net_print.h"
+#endif
+
#define SAMPLERATE 48000
-#define MIXBUFSIZE_BYTES 32000 // 16000
+#define MIXBUFSIZE_BYTES (64*1024) // 32000 16000
#define MIXBUFSIZE_SHORT (MIXBUFSIZE_BYTES / 2)
#define MIXBUFSIZE_WORDS (MIXBUFSIZE_BYTES / 4)
-#define SOUNDBUFSIZE 4096 // 2048
+#define SOUNDBUFSIZE (64*1024) // 4096 2048
static u8 soundbuffer[2][SOUNDBUFSIZE] ATTRIBUTE_ALIGN(32);
static u8 mixbuffer[MIXBUFSIZE_BYTES];
@@ -73,6 +78,7 @@ static void AudioSwitchBuffers() {
DCFlushRange(soundbuffer[whichab], len);
AUDIO_InitDMA((u32)soundbuffer[whichab], len);
+ AUDIO_StartDMA();
whichab ^= 1;
IsPlaying = 1;
}
@@ -118,13 +124,14 @@ void ResetAudio() {
* Puts incoming mono samples into mixbuffer
* Splits mono samples into two channels (stereo)
****************************************************************************/
+
void PlaySound(u8* Buffer, int count) {
u32* dst = (u32*)mixbuffer;
int i;
u16 sample;
for (i = 0; i < count; i++) {
- sample = ((Buffer[i] << 8) - 1) & 0xffff;
+ sample = ((Buffer[i] << 8) /*- 1*/) & 0xff00;
dst[mixhead++] = sample | (sample << 16);
if (mixhead == MIXBUFSIZE_WORDS)
mixhead = 0;
diff --git a/wii-emucommon b/wii-emucommon
index 5d1b886..126294c 160000
--- a/wii-emucommon
+++ b/wii-emucommon
@@ -1 +1 @@
-Subproject commit 5d1b8867e6e8c574d6f0ac54a75ebcdbbdb4d199
+Subproject commit 126294c6db505e72474a9a55ef6c2a5f72830801