[What Was New 004 - August 5, 2008]

- added: option to disable AA filtering 
         (snes graphics 'crisper', AA now default OFF)
- added: mapped zooming and turbo mode to classic controller
- added: preliminary usb support (loading)
- changed: sram and freezes now saved by filename, not internal romname. 
           If you have multiple versions of the same game, you can now have 
           srams and freezes for each version. A prompt to convert to the 
           new naming is provided for sram only.
- changed: by default, autoload/save sram and freeze enabled
This commit is contained in:
dborth 2008-10-16 01:52:18 +00:00
parent b6273051f8
commit 65984b9102
196 changed files with 19493 additions and 28119 deletions

View File

@ -1,8 +1,10 @@
.PHONY = all wii gc wii-clean gc-clean wii-run gc-run
.PHONY = all wii gc wii-clean gc-clean wii-run gc-run specials specials-clean specials-wii specials-gc specials-wii-clean specials-gc-clean
VERSION := 004
all: wii gc
clean: wii-clean gc-clean
clean: wii-clean gc-clean specials-clean
wii:
$(MAKE) -f Makefile.wii
@ -21,3 +23,38 @@ gc-clean:
gc-run:
$(MAKE) -f Makefile.gc run
# Custom Quicksave Versions
specials: specials-wii specials-gc
specials-clean: specials-wii-clean specials-gc-clean
specials-wii:
touch source/ngc/snes9xGX.h
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=0" "LOADTYPE:='"MCSLOTA"'" "VERSION:=$(VERSION)" -f Makefile.wii
touch source/ngc/snes9xGX.h
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=1" "LOADTYPE:='"MCSLOTB"'" "VERSION:=$(VERSION)" -f Makefile.wii
touch source/ngc/snes9xGX.h
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=3" "LOADTYPE:='"SD"'" "VERSION:=$(VERSION)" -f Makefile.wii
specials-gc:
touch source/ngc/snes9xGX.h
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=0" "LOADTYPE:='"MCSLOTA"'" "VERSION:=$(VERSION)" -f Makefile.gc
touch source/ngc/snes9xGX.h
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=1" "LOADTYPE:='"MCSLOTB"'" "VERSION:=$(VERSION)" -f Makefile.gc
touch source/ngc/snes9xGX.h
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=3" "LOADTYPE:='"SD"'" "VERSION:=$(VERSION)" -f Makefile.gc
touch source/ngc/snes9xGX.h
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=4" "LOADTYPE:='"SMB"'" "VERSION:=$(VERSION)" -f Makefile.gc
specials-wii-clean:
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=0" "LOADTYPE:='"MCSLOTA"'" "VERSION:=$(VERSION)" -f Makefile.wii clean
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=1" "LOADTYPE:='"MCSLOTB"'" "VERSION:=$(VERSION)" -f Makefile.wii clean
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=3" "LOADTYPE:='"SD"'" "VERSION:=$(VERSION)" -f Makefile.wii clean
specials-gc-clean:
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=0" "LOADTYPE:='"MCSLOTA"'" "VERSION:=$(VERSION)" -f Makefile.gc clean
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=1" "LOADTYPE:='"MCSLOTB"'" "VERSION:=$(VERSION)" -f Makefile.gc clean
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=3" "LOADTYPE:='"SD"'" "VERSION:=$(VERSION)" -f Makefile.gc clean
$(MAKE) "CUSTOMFLAGS:=-DQUICK_SAVE_SLOT=4" "LOADTYPE:='"SMB"'" "VERSION:=$(VERSION)" -f Makefile.gc clean

View File

@ -1,5 +1,3 @@
VERSION := 006
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
@ -11,32 +9,35 @@ endif
include $(DEVKITPPC)/gamecube_rules
LOADTYPE = "sd"
VERSION = "version"
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := snes9xgx-$(VERSION)-gc
TARGETDIR := executables
TARGET := executables/snes9xgx-$(VERSION)-$(LOADTYPE)-gc
BUILD := build_gc
SOURCES := source/snes9x source/ngc source/sz
SOURCES := source/snes9x source/unzip source/ngc source/smb
DATA := data
INCLUDES := source/snes9x source/ngc
INCLUDES := source/snes9x source/unzip source/ngc source/smb
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
-DNGC \
-DNO_ASM -DRIGHTSHIFT_IS_SAR \
-DCPU_SHUTDOWN -DSPC700_SHUTDOWN \
-DSPC700_C -DSDD1_DECOMP \
-DCORRECT_VRAM_READS -DNEW_COLOUR_BLENDING \
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \
-fomit-frame-pointer -fno-exceptions -Wno-unused-parameter \
#-D_DEBUG_VIDEO -pipe
CUSTOMFLAGS = -DQUICK_SAVE_SLOT=1 -DSMB_SVID='"Crunchewy"' \
-DSMB_IP='"192.168.1.111"' -DGW_IP='"192.168.1.1"'
CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) \
-DNGC -DNO_ASM -DCPU_SHUTDOWN -DSPC700C \
-DSPC700_SHUTDOWN -DNEW_COLOUR_BLENDING \
-DNO_INLINE_GET_SET -DSDD1_DECOMP -DCORRECT_VRAM_READS \
-DDETECT_NASTY_FX_INTERLEAVE -DNGC_ZOOM -DSDUSE_LFN \
-DFORCE_WII=0 $(CUSTOMFLAGS) \
-fomit-frame-pointer -fno-exceptions -Wno-unused-parameter -pipe
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
@ -44,13 +45,13 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lpngu -lpng -lmxml -lbba -ltinysmb -lfat -lz -logc -lm -lfreetype
LIBS := -lfat -lz -logc -lm -lfreetype -lbba
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(CURDIR)
LIBDIRS :=
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
@ -59,7 +60,7 @@ LIBDIRS := $(CURDIR)
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
@ -102,15 +103,13 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB)
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@[ -d $(TARGETDIR) ] || mkdir -p $(TARGETDIR)
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.gc
@rm -fr $(OUTPUT).elf
#---------------------------------------------------------------------------------
clean:
@ -119,11 +118,11 @@ clean:
#---------------------------------------------------------------------------------
run:
psoload $(OUTPUT).dol
wiiload $(OUTPUT).dol
#---------------------------------------------------------------------------------
reload:
psoload -r $(OUTPUT).dol
wiiload -r $(OUTPUT).dol
#---------------------------------------------------------------------------------

View File

@ -1,5 +1,3 @@
VERSION := 006
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
@ -11,46 +9,50 @@ endif
include $(DEVKITPPC)/wii_rules
LOADTYPE = "sd"
VERSION = "version"
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := snes9xgx-$(VERSION)-wii
TARGETDIR := executables
TARGET := executables/snes9xgx-$(VERSION)-$(LOADTYPE)-wii
BUILD := build_wii
SOURCES := source/snes9x source/ngc source/sz
SOURCES := source/snes9x source/unzip source/ngc source/smb
DATA := data
INCLUDES := source/snes9x source/ngc
INCLUDES := source/snes9x source/unzip source/ngc source/smb
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
-DNGC -DWII_DVD \
-DNO_ASM -DRIGHTSHIFT_IS_SAR \
-DCPU_SHUTDOWN -DSPC700_SHUTDOWN \
-DSPC700_C -DSDD1_DECOMP \
-DCORRECT_VRAM_READS -DNEW_COLOUR_BLENDING \
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \
-fomit-frame-pointer -fno-exceptions -Wno-unused-parameter \
#-D_DEBUG_VIDEO -pipe
CXXFLAGS = -save-temps -Xassembler -aln=$@.lst $(CFLAGS)
CUSTOMFLAGS = -DQUICK_SAVE_SLOT=3 -DSMB_SVID='"Crunchewy"' \
-DSMB_IP='"192.168.1.111"' -DGW_IP='"192.168.1.1"'
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) \
-DNGC -DHW_RVL -DNO_ASM -DCPU_SHUTDOWN -DSPC700C \
-DSPC700_SHUTDOWN -DNEW_COLOUR_BLENDING \
-DNO_INLINE_GET_SET -DSDD1_DECOMP -DCORRECT_VRAM_READS \
-DDETECT_NASTY_FX_INTERLEAVE -DNGC_ZOOM -DSDUSE_LFN \
-DFORCE_WII=1 $(CUSTOMFLAGS)\
-fomit-frame-pointer -fno-exceptions -Wno-unused-parameter -pipe
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -ldi -lpngu -lpng -lmxml -lfat -lwiiuse -lz -lbte -logc -lm -lfreetype -ltinysmb
LIBS := -lfat -lwiiuse -lz -lbte -logc -lm -lfreetype
# -logcsys
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(CURDIR)
LIBDIRS :=
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
@ -59,7 +61,7 @@ LIBDIRS := $(CURDIR)
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
@ -102,15 +104,13 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB)
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@[ -d $(TARGETDIR) ] || mkdir -p $(TARGETDIR)
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.wii
@rm -fr $(OUTPUT).elf
#---------------------------------------------------------------------------------
clean:

View File

@ -10,88 +10,12 @@
­———————————————————————————————————————————————————————————————————————•ßrK•
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· SNES9X GX 006 ·oø×O0|
| http://code.google.com/p/snes9x-gx |
| (Under GPL License) |
|0O×øo· SNES9XGX v004 ·oø×O0|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
SNES9x GX is a Super Nintendo emulator for the Wii based on the PC emulator
SNES9x 1.51 (http://snes9x.ipherswipsite.com/). SoftDev is responsible for
the original SNES9x 1.50 GameCube port, whose work was continued by crunchy2.
It was updated for the Wii by michniewski and SNES9x 1.51 was ported by
Tantric. The project is currently being maintained by michniewski and Tantric.
PLEASE NOTE: THIS DOCUMENT IS A WORK IN PROGRESS
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· FEATURES ·oø×O0|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
- Based on Snes9x 1.51 - superior ROM compatibility
- Wiimote, Nunchuk, Classic, and Gamecube controller support
- SNES Superscope, Mouse, Justifier support
- Cheat support
- Auto Load/Save Game Snapshots and SRAM
- Custom controller configurations
- SD, USB, DVD, SMB, GC Memory Card, Zip, and 7z support
- Autodetect PAL/NTSC, 16:9 widescreen support
- Open Source!
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· UPDATE HISTORY ·oø×O0|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
[What's New 006 - October 15, 2008]
Tantric
- added: 480p for GameCube
- added: Sound sync
- added: 7z support
- changed: Faster SD/USB access (readahead cache enabled)
- fixed: Video offset issues
- fixed: BS-X games work now
- fixed: Wii DVD works now
- fixed: DVD re-enabled for GameCube
- fixed: Nunchuk analog stick issues
- fixed: Many crashes, memory leaks, etc
michniewski
- added: Video shift options
- changed: Turn DVD motor off option re-enabled for GameCube
[What Was New 005 - September 23, 2008]
michniewski
- added: Superscope/mouse/justifier support, with Wii remote
- added: 3 render modes - Original, Filtered, Unfiltered
- added: widescreen compensation option
- added: DVD support on the Wii
- changed: zoom - limited range, added reset zoom option
Tantric
- added: now uses SNES 1.51 core (thanks to eke-eke for help with this)
- added: cheats menu! Loads .CHT file from /snes9x/cheats folder,
.CHT file name must match file name of ROM
- added: load/save preference selector. ROM, SRAM, Freeze, and preferences
are saved/loaded according to these
- added: preliminary Windows file share loading/saving (SMB) support on Wii:
You can input your network settings into snes9xGX.xml, or edit
s9xconfig.cpp from the source code and compile.
- added: 'Auto' settings for save/load - attempts to automatically determine
your load/save device(s) - SD, USB, Memory Card, DVD, SMB
- added: ROM Information page
- added: Game Menu - all game-specific options are here now:
SRAM save/load, Snapshot save/load, game reload, etc
- added: Credits page
- fixed: sd gecko works now
- fixed: full USB support
- changed: menu structure
- changed: preferences are now loaded and saved in XML format. You can open
snes9xGX.xml edit all settings, including some not available within
the program
- changed: if Home button is pressed when a game is running, Game Menu pops up
- changed: if preferences can't be loaded at the start and/or are reset,
preferences menu pops up - remove to save your preferences!
- changed: SRAM load - game reloaded automatically after loading SRAM
[What Was New 004 - August 5, 2008]
[What's New 004]
- added: option to disable AA filtering
(snes graphics 'crisper', AA now default OFF)
@ -103,7 +27,7 @@ Tantric
new naming is provided for sram only.
- changed: by default, autoload/save sram and freeze enabled
[What Was New 003 - July 25, 2008]
[What Was New 003]
- added: alphabetical file sorting
- added: background logo/backdrop + nicer menus
- added: scrolling in ROM selector
@ -114,13 +38,13 @@ Tantric
- fixed: precompiled dols for autosaving to various locations (see readme)
- changed: GC default quickload slot (to sd) (thanks kerframil)
- changed: default load/save dirs are now "/snes9x/roms" and
"/snes9x/saves/" (thanks kerframil)
"/snes/save/" (thanks kerframil)
- changed: Classic X and Y defaults aren't switched
- changed: if autosave is enabled, it doesn't ask to save SRAM
anymore. It is saved in the background.
- updated README
[Whats Was New 002 - July 21, 2008]
[Whats Was New 002]
- added: classic and nunchuk support
- added: all controllers can now be configured
- added: GC version (untested)
@ -130,7 +54,7 @@ Tantric
- one makefile to make all versions. (thanks to snes9x143 SVN)
[What Was New 001 - July 12, 2008]
[What Was New 001]
- compiles with latest devkitppc (r15)
- now uses libfat (can use front sd slot on wii)
- updated menu items a bit
@ -140,89 +64,102 @@ Tantric
[older update history at the bottom]
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· FEATURES ·oø×O0|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
- Based on Snes9x 1.5 - superior ROM compatibility
- Auto Load/Save Freeze States and SRAM
- Custom controller configurations
- Wiimote, Nunchuk, Classic, and Gamecube controller support
- Autodetect PAL/NTSC
- Zip Support
- Open Source!
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· SETUP & INSTALLATION ·oø×O0|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
Unzip the archive. You will find the following folders inside:
Unzip the archive into a folder. You'll find 4 variations of the dol for both
wii and gamecube versions. The variants auto save and load preferences and sram
to/from different locations as follows (you can also manually save and load
SRAM to any location).
[A default version is provided for quick install. See loading from HBC below.]
apps Contains Homebrew Channel ready files
(see Homebrew Channel instructions below)
executables Contains Gamecube / Wii DOL files
(for loading from other methods)
snes9x Contains the directory structure required for storing
roms, saves, and cheats (see below)
filename preferences/sram autoloading location
------------------------- -------------------------------------
snes9xGX-00x-sd-xxxx.dol SD card
snes9xGX-00x-mcslota-xxxx.dol Memory card in slot A
snes9xGX-00x-mcslotb-xxxx.dol Memory card in slot B
snes9xGX-00x-smb-xxxx.dol SMB share (see SMB section below)
// snes9xGX-00x-noload-xxxx.dol none - doesn't load prefs nor autosave SRAM
The last part of the filename (shown above as xxxx), denotes the wii and gamecube
versions.
----------------------------
Directory Structure Setup
----------------------------
By default, roms are loaded from "snes9x/roms/", saves and preferences are
stored in "snes9x/saves/", and cheats are loaded from "/snes9x/cheats/".
Therefore you should have the following folder structure at the root
of your load device (SD/USB/SMB):
snes9x/
roms/
saves/
cheats/
----------------------------
ROMS, Preferences, Saves, and Cheats:
ROMS, Preferences, and Saves:
----------------------------
Your SNES rom images must be in the Super Magicom (SMC) or FIG format. Generally,
all images you find will be in this format, but if you run across one that isn't
please download RTOOL which will allow you to convert the image into SMC format.
Cheats must be placed in the cheats folder and named identically to the ROM name,
except with a CHT extension.
Wii
----------
On the Wii, you can load roms from SD card (Front SD or SD Gecko), USB, DVD,
or SMB share. Note that if you are using the Homebrew Channel, to load from
USB, DVD, or SMB you will first have to load Snes9xGx from SD, and then set
your load method preference. To load roms from a Windows network share (SMB)
you will have to edit snes9xGX.xml on your SD card with your network settings,
or edit s9xconfig.cpp from the source code and compile. If you edit and compile
the source, you can use wiiload and the Homebrew Channel to load and play
Snes9xGx completely over the network, without needing an SD card.
On the Wii, you can load roms from any SD card (Front SD, SD Gecko, etc).
By default, ROMs are loaded from "snes9x/roms/" and saves and preferences are
stored in "snes9x/saves/". Therefore, on your SD card, you should have the following
folders:
snes9x/
roms/
saves/
Gamecube
------------
You can load roms from DVD or SD card. If you create a bootable
DVD of Snes9xGx you can put roms on the same DVD. You may save preferences and
game data to SD or Memory Card.
You can load roms from DVD, SD card or SMB share. If you wish to use an SD card
or SMB share, you must create the same folder tree as above. Put your roms in the
"snes9x/roms" folder. On DVD you can either place your roms at the top level, or
optionally you may have an SNESROMS folder at the top level of the DVD, in which
case the game selectorwill default to showing that folder when first entered.
If you create a bootable DVD of Snes9xGx you can put roms on the same DVD.
------------------------------
Loading / Running the Emulator:
------------------------------
Wii - Via Homebrew Channel:
Via Homebrew Channel:
--------------------
The most popular method of running homebrew on the Wii is through the Homebrew
The most popular method of running homebrew on the wii is through the Homebrew
Channel. If you already have the channel installed, just copy over the apps folder
included in the archive into the root of your SD card.
included in the archive into the root of your SD card (the SD autosaving version
for wii is included in the apps/Snes9xGX/ folder renamed to boot.dol).
Remember to also create the snes9x directory structure required. See above.
Remember to also create the snes9x/roms and snes9x/saves directories. See above.
If you wish to use a version that autosaves to other available saving locations,
just choose the appropriate dol, copy it into the apps/Snes9XGX/ folder, and
RENAME it to boot.dol (remove the other version). Then proceed to copy
the entire apps folder to your sd card and run it with the HBC.
If you haven't installed the homebrew channel yet, read about how to here:
http://hbc.hackmii.com/
If you haven't installed the Homebrew Channel yet, read about how to here:
http://hbc.hackmii.com/
Gamecube:
---------
You can load Snes9xGX via sdload and an SD card in slot A, or by streaming
it to your Gamecube, or by booting a bootable DVD with Snes9xGX on it.
This document doesn't cover how to do any of that. A good source for information
on these topics is the tehskeen forums: http://www.tehskeen.com/forums/
You can load it via sdload and an SD card in slot A, or by streaming it to your
cube, or by booting a bootable DVD (gamecube only) with it on it. This document doesn't cover
how to do any of that. A good source for information on these topics is the
tehskeen forums:
http://www.tehskeen.com/forums/
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· ABOUT SNES9X ·oø×O0|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
Welcome to the revolution in Wii/GameCube emulators! SNES9X is by far the most
Welcome to the revolution in GameCube emulators! SNES9X is by far the most
complete and accurate Super Nintendo Entertainment System emulator to date.
Taking full power of the ATi-GX chipset and packed full of features that are
to die for after playing your games you'll never want to come back to
@ -230,9 +167,10 @@ reality.
SNES9X is a very popular open source emulator mainly for the PC platform, but
has seen many ports to other consoles such as the Nintendo DS, Microsoft XBOX
,
and, thanks to SoftDev, the Nintendo GameCube. SoftDev's 1.50 port is not based
on any previous SNES emulators that have existed for the GameCube.
and now thanks to SoftDev the Nintendo GameCube! This is a straight port and
is not based on any previous SNES emulators that have existed for the
GameCube. You can get more information on SNES9X here from the below URL.
http://snes9x.ipherswipsite.com/
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· DEFAULT CONTROLLER MAPPING ·oø×O0|
@ -244,51 +182,34 @@ under the Config Controllers option.
Below are the default button mappings for supported controllers. The wiimote
configuration allows you to play with the wiimote held sideways.
Wiimote SNES Nunchuk SNES
Wiimote SNES Nunchuk SNES
--------------------- ---------------------
1 Y Z Y
2 B B B
A A A A
B X C X
- SELECT 2 SELECT
+ START 1 START
HOME Emulator menu HOME Emulator menu
LT - LT
RT + RT
1 Y Z Y
2 B B B
A A A A
B X C X
- SELECT 2 SELECT
+ START 1 START
HOME Emulator menu HOME Emulator menu
LT - LT
RT + RT
Classic SNES GC PAD SNES
Classic SNES GC PAD SNES
--------------------- ---------------------
X X Y Y
B B B B
A A A A
Y Y X X
- SELECT Z SELECT
+ START START START
X X Y Y
B B B B
A A A A
Y Y X X
- SELECT Z SELECT
+ START START START
HOME Emulator menu
LT LT LT LT
RT RT RT RT
LT LT LT LT
RT RT RT RT
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· SUPERSCOPE / MOUSE / JUSTIFIER SUPPORT ·oø×O0|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
Make sure you enable the superscope, mouse, or justifier in the controller
options menu BEFORE loading the rom. If you have already loaded the rom
and changed the setting, reset the game for the settings to take effect.
These controllers can be controlled by either the Gamecube controller analog
sticks,the Classic controller analog sticks, or by aiming at the screen
with the wiimote.
Aim Offscreen - Wiimote Minus, GameCube Z button
Fire - B button
Cursor - A button
Turbo Toggle - Wiimote D-Pad Down, GameCube Y button
These configurations cannot be changed.
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· ZIP SUPPORT ·oø×O0|
@ -316,15 +237,16 @@ To use 7-Zip compression on either linux or windows, use the following command:
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
Once the DOL file is loaded you will be presented with main menu where you can
load a ROM, set options for the emulator, set the joypad configuration, etc.
load a ROM, set options for the emulator, set the joypad configuration, save or
load freezes, manage SRAM, etc.
After loading a game the game will start running immediately. If you have the
auto-load SRAM option enabled it will automatically load SRAM (if it exists)
before starting play.
You can return to the menu at any time by pressing the Home button
(Wiimote and Classic Controller) or on the c-stick (the yellow control stick)
to the left, or by pressing L+R+X+Y (GameCube Controller).
Return to the game by selecting "Resume Game".
You can return to the main menu at any time by pressing
the c-stick (the yellow control stick) to the left, or by pressing L+R+X+Y.
Return to the game by selecting "Resume Game" or by pressing the B button until
play resumes.
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· TURBO MODE ·oø×O0|
@ -339,16 +261,23 @@ want normal playback speed to resume.
|0O×øo· IMPORTING AND EXPORTING SRAM ·oø×O0|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
Snes9xGx now includes the ability to load SRAM from Snes9x on other
platforms (Mac/PC/Linux/Etc) and to save back to those platforms.
Snes9xGx 2.0.1 now includes the ability to load SRAM from Snes9x on other
platforms (Mac/PC/Linux/Etc) and to save back to those platforms. To use this
feature simply save or load SRAM to/from SD card or an SMB share.
To load a SRAM file on the Wii or Gamecube from another platform, ensure the
name of the SRM file matches the filename of the ROM (except with an SRM
extension).
The only thing to be aware of is that Snes9xGx requires that the SRM file have a
name that is the rom name (not necessarily the same as the file name!) with .SRM
at the end. For example, the game "Super Mario All-Stars + World" has a rom name
of "ALL_STARS + WORLD", so the SRAM file should have the name "ALL_STARS +
WORLD.srm". You can see the rom name for a game by loading the game - the rom
name is shown in the information that is briefly shown at the bottom of the
screen. A perhaps easier way to find the correct name is simply to load the game
and then save SRAM to SD or SMB and look at the filename that Snes9xGx uses.
That's the name you should use when importing an SRAM from another platform.
To use a Wii/GameCube SRAM file on another platform just do the opposite:
copy the saved SRAM file to the other platform. You may have to rename the
file to be what that version of snes9x expects it to be.
To use an Snes9xGx SRAM on another platform just do the opposite: save SRAM to
SD or SMB, and then copy that saved SRAM file to the other platform. You may
have to rename the file to be what that version of snes9x expects it to be.
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· UPDATE HISTORY (old) ·oø×O0|
@ -482,7 +411,7 @@ changes to the emulator settings again and save them.
GameCube Port 2.0 WIP6 and earlier - SoftDev
Additional improvements to 2.0 WIP6 - eke-eke
GameCube 2.0.1bx enhancements - crunchy2
v00x updates - michniewski & Tantric
v00x updates - michniewski
GX - http://www.gc-linux.org
libogc - Shagkur & wintermute
@ -492,7 +421,7 @@ changes to the emulator settings again and save them.
Documentation
brakken, crunchy2, michniewski, Tantric
brakken, crunchy2, michniewski
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· ·oø×O0|

View File

@ -1,16 +1,12 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Audio RAM
*
* softdev July 2006
*
* aram.cpp
*
* Gamecube Audio RAM storage
***************************************************************************/
****************************************************************************/
#include <gccore.h>
#include <string.h>
#include "aram.h"
#define ARAM_READ 1
@ -19,11 +15,11 @@
#define TEMPSIZE 32768
static char tempbuffer[TEMPSIZE] ATTRIBUTE_ALIGN (32);
/****************************************************************************
/**
* ARAMPut
*
* Move data from MAIN memory to ARAM
***************************************************************************/
*/
void
ARAMPut (char *src, char *dst, int len)
{
@ -32,11 +28,11 @@ ARAMPut (char *src, char *dst, int len)
while (AR_GetDMAStatus());
}
/****************************************************************************
/**
* ARAMFetch
*
* This function will move data from ARAM to MAIN memory
***************************************************************************/
*/
void
ARAMFetch (char *dst, char *src, int len)
{
@ -45,11 +41,11 @@ ARAMFetch (char *dst, char *src, int len)
while (AR_GetDMAStatus ());
}
/****************************************************************************
/**
* ARAMFetchSlow
*
* Required as SNES memory may NOT be 32-byte aligned
***************************************************************************/
*/
void
ARAMFetchSlow (char *dst, char *src, int len)
{

View File

@ -1,13 +1,10 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Audio RAM
*
* softdev July 2006
*
* aram.h
*
* Gamecube Audio RAM storage
***************************************************************************/
****************************************************************************/
#ifndef _GCARAMI_
#define _GCARAMI_

View File

@ -1,20 +1,17 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Audio
*
* Audio is fixed to 32Khz/16bit/Stereo
*
* softdev July 2006
*
* audio.cpp
*
* Audio driver
* Audio is fixed to 32Khz/16bit/Stereo
***************************************************************************/
****************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "snes9x.h"
#include "memmap.h"
#include "debug.h"
@ -29,7 +26,7 @@
#include "controls.h"
#include "video.h"
#include "menudraw.h"
#include "ftfont.h"
/*** Double buffered audio ***/
#define AUDIOBUFFER 2048
@ -43,65 +40,65 @@ lwpq_t audioqueue;
lwp_t athread;
static uint8 astack[AUDIOSTACK];
/****************************************************************************
/**
* Audio Threading
***************************************************************************/
*/
static void *
AudioThread (void *arg)
{
LWP_InitQueue (&audioqueue);
LWP_InitQueue (&audioqueue);
while (1)
while (1)
{
whichab ^= 1;
if (ConfigRequested)
memset (soundbuffer[whichab], 0, AUDIOBUFFER);
else
{
whichab ^= 1;
if (ConfigRequested)
memset (soundbuffer[whichab], 0, AUDIOBUFFER);
else
{
so.samples_mixed_so_far = so.play_position = 0;
S9xMixSamples (soundbuffer[whichab], AUDIOBUFFER >> 1);
}
LWP_ThreadSleep (audioqueue);
so.samples_mixed_so_far = so.play_position = 0;
S9xMixSamples (soundbuffer[whichab], AUDIOBUFFER >> 1);
}
LWP_ThreadSleep (audioqueue);
}
return NULL;
return NULL;
}
/****************************************************************************
* MixSamples
* This continually calls S9xMixSamples On each DMA Completion
***************************************************************************/
/**
* MixSamples
* This continually calls S9xMixSamples On each DMA Completion
*/
static void
GCMixSamples ()
{
AUDIO_StopDMA ();
AUDIO_StopDMA ();
DCFlushRange (soundbuffer[whichab], AUDIOBUFFER);
AUDIO_InitDMA ((u32) soundbuffer[whichab], AUDIOBUFFER);
AUDIO_StartDMA ();
DCFlushRange (soundbuffer[whichab], AUDIOBUFFER);
AUDIO_InitDMA ((u32) soundbuffer[whichab], AUDIOBUFFER);
AUDIO_StartDMA ();
LWP_ThreadSignal (audioqueue);
LWP_ThreadSignal (audioqueue);
}
/****************************************************************************
* InitGCAudio
***************************************************************************/
/**
* InitGCAudio
*/
void
InitGCAudio ()
{
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_32KHZ);
AUDIO_RegisterDMACallback (GCMixSamples);
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_32KHZ);
AUDIO_RegisterDMACallback (GCMixSamples);
LWP_CreateThread (&athread, AudioThread, NULL, astack, AUDIOSTACK, 80);
LWP_CreateThread (&athread, AudioThread, NULL, astack, AUDIOSTACK, 80);
}
/****************************************************************************
/**
* AudioStart
*
* Called to kick off the Audio Queue
***************************************************************************/
*/
void
AudioStart ()
{
GCMixSamples ();
GCMixSamples ();
}

View File

@ -1,13 +1,12 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Audio
*
* Audio is fixed to 32Khz/16bit/Stereo
*
* softdev July 2006
*
* audio.h
*
* Audio driver
* Audio is fixed to 32Khz/16bit/Stereo
***************************************************************************/
****************************************************************************/
void InitGCAudio ();
void AudioStart ();

View File

@ -1,117 +1,168 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* michniewski August 2008
*
* button_mapping.c
*
* Controller button mapping
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ogcsys.h>
#include <unistd.h>
#include <wiiuse/wpad.h>
#include "button_mapping.h"
/****************************************************************************
* Controller Button Descriptions:
* used for identifying which buttons have been pressed when configuring
* and for displaying the name of said button
***************************************************************************/
/***
* Controller Button Descriptions:
* used for identifying which buttons have been pressed when configuring
* and for displaying the name of said button
***/
//CtrlrMap ctrlr_def[4];
CtrlrMap ctrlr_def[4] = {
CtrlrMap ctrlr_def[4] = {
// Nunchuk btn def
{
CTRLR_NUNCHUK,
13,
{
{WPAD_BUTTON_DOWN, "DOWN"},
{WPAD_BUTTON_UP, "UP"},
{WPAD_BUTTON_LEFT, "LEFT"},
{WPAD_BUTTON_RIGHT, "RIGHT"},
{WPAD_BUTTON_A, "A"},
{WPAD_BUTTON_B, "B"},
{WPAD_BUTTON_1, "1"},
{WPAD_BUTTON_2, "2"},
{WPAD_BUTTON_PLUS, "PLUS"},
{WPAD_BUTTON_MINUS, "MINUS"},
{WPAD_BUTTON_HOME, "HOME"},
{WPAD_NUNCHUK_BUTTON_Z, "Z"},
{WPAD_NUNCHUK_BUTTON_C, "C"},
{0, ""},
{0, ""}
}
},
CTRLR_NUNCHUK,
13,
WPAD_BUTTON_DOWN, "DOWN",
WPAD_BUTTON_UP, "UP",
WPAD_BUTTON_LEFT, "LEFT",
WPAD_BUTTON_RIGHT, "RIGHT",
WPAD_BUTTON_A, "A",
WPAD_BUTTON_B, "B",
WPAD_BUTTON_1, "1",
WPAD_BUTTON_2, "2",
WPAD_BUTTON_PLUS, "PLUS",
WPAD_BUTTON_MINUS, "MINUS",
WPAD_BUTTON_HOME, "HOME",
WPAD_NUNCHUK_BUTTON_Z, "Z",
WPAD_NUNCHUK_BUTTON_C, "C",
0, "",
0, "",
// Classic btn def
{
CTRLR_CLASSIC,
15,
{
{WPAD_CLASSIC_BUTTON_DOWN, "DOWN"},
{WPAD_CLASSIC_BUTTON_UP, "UP"},
{WPAD_CLASSIC_BUTTON_LEFT, "LEFT"},
{WPAD_CLASSIC_BUTTON_RIGHT, "RIGHT"},
{WPAD_CLASSIC_BUTTON_A, "A"},
{WPAD_CLASSIC_BUTTON_B, "B"},
{WPAD_CLASSIC_BUTTON_X, "X"},
{WPAD_CLASSIC_BUTTON_Y, "Y"},
{WPAD_CLASSIC_BUTTON_PLUS, "PLUS"},
{WPAD_CLASSIC_BUTTON_MINUS, "MINUS"},
{WPAD_CLASSIC_BUTTON_HOME, "HOME"},
{WPAD_CLASSIC_BUTTON_FULL_L, "L TRIG"},
{WPAD_CLASSIC_BUTTON_FULL_R, "R TRIG"},
{WPAD_CLASSIC_BUTTON_ZL, "ZL"},
{WPAD_CLASSIC_BUTTON_ZR, "ZR"}
}
},
// Gamecube controller btn def
{
CTRLR_GCPAD,
13,
{
{PAD_BUTTON_DOWN, "DOWN"},
{PAD_BUTTON_UP, "UP"},
{PAD_BUTTON_LEFT, "LEFT"},
{PAD_BUTTON_RIGHT, "RIGHT"},
{PAD_BUTTON_A, "A"},
{PAD_BUTTON_B, "B"},
{PAD_BUTTON_X, "X"},
{PAD_BUTTON_Y, "Y"},
{PAD_BUTTON_MENU, "MENU"},
{PAD_BUTTON_START, "START"},
{PAD_TRIGGER_L, "L TRIG"},
{PAD_TRIGGER_R, "R TRIG"},
{PAD_TRIGGER_Z, "Z"},
{0, ""},
{0, ""}
}
},
CTRLR_CLASSIC,
15,
WPAD_CLASSIC_BUTTON_DOWN, "DOWN",
WPAD_CLASSIC_BUTTON_UP, "UP",
WPAD_CLASSIC_BUTTON_LEFT, "LEFT",
WPAD_CLASSIC_BUTTON_RIGHT, "RIGHT",
WPAD_CLASSIC_BUTTON_A, "A",
WPAD_CLASSIC_BUTTON_B, "B",
WPAD_CLASSIC_BUTTON_X, "X",
WPAD_CLASSIC_BUTTON_Y, "Y",
WPAD_CLASSIC_BUTTON_PLUS, "PLUS",
WPAD_CLASSIC_BUTTON_MINUS, "MINUS",
WPAD_CLASSIC_BUTTON_HOME, "HOME",
WPAD_CLASSIC_BUTTON_FULL_L, "L TRIG",
WPAD_CLASSIC_BUTTON_FULL_R, "R TRIG",
WPAD_CLASSIC_BUTTON_ZL, "ZL",
WPAD_CLASSIC_BUTTON_ZR, "ZR",
// Gamecube controller btn def
CTRLR_GCPAD,
13,
PAD_BUTTON_DOWN, "DOWN",
PAD_BUTTON_UP, "UP",
PAD_BUTTON_LEFT, "LEFT",
PAD_BUTTON_RIGHT, "RIGHT",
PAD_BUTTON_A, "A",
PAD_BUTTON_B, "B",
PAD_BUTTON_X, "X",
PAD_BUTTON_Y, "Y",
PAD_BUTTON_MENU, "MENU",
PAD_BUTTON_START, "START",
PAD_TRIGGER_L, "L TRIG",
PAD_TRIGGER_R, "R TRIG",
PAD_TRIGGER_Z, "Z",
0, "",
0, "",
// Wiimote btn def
{
CTRLR_WIIMOTE,
11,
{
{WPAD_BUTTON_DOWN, "DOWN"},
{WPAD_BUTTON_UP, "UP"},
{WPAD_BUTTON_LEFT, "LEFT"},
{WPAD_BUTTON_RIGHT, "RIGHT"},
{WPAD_BUTTON_A, "A"},
{WPAD_BUTTON_B, "B"},
{WPAD_BUTTON_1, "1"},
{WPAD_BUTTON_2, "2"},
{WPAD_BUTTON_PLUS, "PLUS"},
{WPAD_BUTTON_MINUS, "MINUS"},
{WPAD_BUTTON_HOME, "HOME"},
{0, ""},
{0, ""},
{0, ""},
{0, ""}
}
}
CTRLR_WIIMOTE,
11,
WPAD_BUTTON_DOWN, "DOWN",
WPAD_BUTTON_UP, "UP",
WPAD_BUTTON_LEFT, "LEFT",
WPAD_BUTTON_RIGHT, "RIGHT",
WPAD_BUTTON_A, "A",
WPAD_BUTTON_B, "B",
WPAD_BUTTON_1, "1",
WPAD_BUTTON_2, "2",
WPAD_BUTTON_PLUS, "PLUS",
WPAD_BUTTON_MINUS, "MINUS",
WPAD_BUTTON_HOME, "HOME",
0, "",
0, "",
0, "",
0, ""
};
/***
* Default controller maps
* button press on left, and corresponding snes button on right
* arguably some data is unnecessary here but lets stick to one struct type ok?
CtrlrMap defaultmap[4];
// Nunchuk Default
defaultmap[0].type = CTRLR_NUNCHUK;
defaultmap[0].num_btns = 12;
defaultmap[0].map[] = { WPAD_BUTTON_A, "A",
WPAD_BUTTON_B, "B",
WPAD_NUNCHUK_BUTTON_C, "X",
WPAD_NUNCHUK_BUTTON_Z, "Y",
WPAD_BUTTON_MINUS, "L",
WPAD_BUTTON_PLUS, "R",
WPAD_BUTTON_2, "SELECT",
WPAD_BUTTON_1, "START",
WPAD_BUTTON_UP, "UP",
WPAD_BUTTON_DOWN, "DOWN",
WPAD_BUTTON_LEFT, "LEFT",
WPAD_BUTTON_RIGHT, "RIGHT"
};
// Classic Default
defaultmap[1].type = CTRLR_CLASSIC;
defaultmap[1].num_btns = 12;
defaultmap[1].map[] = { WPAD_CLASSIC_BUTTON_A, "A",
WPAD_CLASSIC_BUTTON_B, "B",
WPAD_CLASSIC_BUTTON_Y, "X",
WPAD_CLASSIC_BUTTON_X, "Y",
WPAD_CLASSIC_BUTTON_FULL_L, "L",
WPAD_CLASSIC_BUTTON_FULL_R, "R",
WPAD_CLASSIC_BUTTON_MINUS, "SELECT",
WPAD_CLASSIC_BUTTON_PLUS, "START",
WPAD_CLASSIC_BUTTON_UP, "UP",
WPAD_CLASSIC_BUTTON_DOWN, "DOWN",
WPAD_CLASSIC_BUTTON_LEFT, "LEFT",
WPAD_CLASSIC_BUTTON_RIGHT, "RIGHT"
};
// Gamecube Controller Default
defaultmap[2].type = CTRLR_GCPAD;
defaultmap[2].num_btns = 12;
defaultmap[2].map[] = {PAD_BUTTON_A, "A",
PAD_BUTTON_B, "B",
PAD_BUTTON_X, "X",
PAD_BUTTON_Y, "Y",
PAD_TRIGGER_L, "L",
PAD_TRIGGER_R, "R",
PAD_TRIGGER_Z, "SELECT",
PAD_BUTTON_START, "START",
PAD_BUTTON_UP, "UP",
PAD_BUTTON_DOWN, "DOWN",
PAD_BUTTON_LEFT, "LEFT",
PAD_BUTTON_RIGHT, "RIGHT"
};
// Wiimote Default
defaultmap[3].type = CTRLR_WIIMOTE;
defaultmap[3].num_btns = 12;
defaultmap[3].map[] = { WPAD_BUTTON_B, "A",
WPAD_BUTTON_2, "B",
WPAD_BUTTON_1, "X",
WPAD_BUTTON_A, "Y",
0x0000, "L",
0x0000, "R",
WPAD_BUTTON_MINUS, "SELECT",
WPAD_BUTTON_PLUS, "START",
WPAD_BUTTON_RIGHT, "UP",
WPAD_BUTTON_LEFT, "DOWN",
WPAD_BUTTON_UP, "LEFT",
WPAD_BUTTON_DOWN, "RIGHT"
};
// end default padmaps
***/
// eof

View File

@ -1,13 +1,3 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* michniewski August 2008
*
* button_mapping.h
*
* Controller button mapping
***************************************************************************/
#ifndef BTN_MAP_H
#define BTN_MAP_H

View File

@ -1,104 +0,0 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* Tantric August 2008
*
* cheatmgr.cpp
*
* Cheat handling
***************************************************************************/
#include "memmap.h"
#include "cheats.h"
#include "snes9xGX.h"
#include "fileop.h"
#include "filesel.h"
#include "smbop.h"
#include "menudraw.h"
extern SCheatData Cheat;
/****************************************************************************
* NGCLoadCheatFile
*
* Loads cheat file from save buffer
* Custom version of S9xLoadCheatFile()
***************************************************************************/
bool NGCLoadCheatFile (int length)
{
Cheat.num_cheats = 0;
uint8 data [28];
int offset = 0;
while (offset < length)
{
if(Cheat.num_cheats < MAX_CHEATS)
{
memcpy (data, savebuffer+offset, 28);
offset += 28;
Cheat.c [Cheat.num_cheats].enabled = (data [0] & 4) == 0;
Cheat.c [Cheat.num_cheats].byte = data [1];
Cheat.c [Cheat.num_cheats].address = data [2] | (data [3] << 8) | (data [4] << 16);
Cheat.c [Cheat.num_cheats].saved_byte = data [5];
Cheat.c [Cheat.num_cheats].saved = (data [0] & 8) != 0;
memmove (Cheat.c [Cheat.num_cheats].name, &data [8], 20);
Cheat.c [Cheat.num_cheats++].name [20] = 0;
}
}
return true;
}
/****************************************************************************
* SetupCheats
*
* Erases any prexisting cheats, loads cheats from a cheat file
* Called when a ROM is first loaded
***************************************************************************/
void
SetupCheats()
{
char filepath[1024];
int offset = 0;
S9xInitCheatData ();
S9xDeleteCheats ();
int method = GCSettings.SaveMethod;
if(method == METHOD_AUTO)
method = autoSaveMethod();
AllocSaveBuffer();
if(method == METHOD_SD || method == METHOD_USB)
{
if(ChangeFATInterface(method, NOTSILENT))
{
sprintf (filepath, "%s/%s/%s.cht", ROOTFATDIR, GCSettings.CheatFolder, Memory.ROMFilename);
offset = LoadBufferFromFAT (filepath, SILENT);
}
}
else if(method == METHOD_SMB)
{
sprintf (filepath, "%s/%s.cht", GCSettings.CheatFolder, Memory.ROMFilename);
offset = LoadBufferFromSMB (filepath, SILENT);
}
// load cheat file if present
if(offset > 0)
{
if(NGCLoadCheatFile (offset))
{
// disable all cheats loaded from the file
for (uint16 i = 0; i < Cheat.num_cheats; i++)
S9xDisableCheat(i);
}
}
FreeSaveBuffer ();
}

877
source/ngc/dkpro.h Normal file
View File

@ -0,0 +1,877 @@
/*******************************************************************
* Image File : /public/dkpro.bmp
* Width : 218
* Height : 65
*
* This header contains a compressed Zip image.
* Use zlib1.2.3 uncompress function to restore.
*******************************************************************/
#define dkpro_RAW 28340
#define dkpro_COMPRESSED 6887
#define dkpro_WIDTH 218
#define dkpro_HEIGHT 65
unsigned char dkpro[6887] = {
0x78, 0xda, 0xed, 0x9c, 0x67, 0x70, 0x54, 0x57, 0x96, 0xc7, 0xf9, 0xb8,
0xb5, 0x55, 0xbb, 0x55,
0x53, 0xb5, 0xb5, 0xb3, 0x9e, 0x31, 0xc6, 0x98, 0x20, 0x31, 0xf6, 0x38,
0x7b, 0xc6, 0x33, 0x0e,
0xe3, 0x34, 0x60, 0x03, 0x36, 0xc9, 0x80, 0x49, 0xb6, 0x41, 0x42, 0x59,
0x42, 0x39, 0x20, 0x75,
0xbf, 0xd3, 0x92, 0x90, 0x84, 0x32, 0x41, 0x02, 0x11, 0xd4, 0x48, 0xe4,
0x60, 0x72, 0x0e, 0x22,
0x98, 0x8c, 0x8d, 0x04, 0x26, 0x83, 0x31, 0xe0, 0xec, 0x71, 0x06, 0xe7,
0xa0, 0xfd, 0xdd, 0xdb,
0xdd, 0xaf, 0x5f, 0xb7, 0xba, 0x07, 0x30, 0xc6, 0xf6, 0x87, 0xd6, 0xbf,
0x1e, 0xb4, 0x6e, 0x38,
0xf7, 0xe4, 0x7b, 0xee, 0x7b, 0x4f, 0xdd, 0x4e, 0xda, 0x5d, 0x1d, 0xaa,
0xc3, 0x52, 0xba, 0x38,
0x3b, 0x46, 0x75, 0x70, 0xb6, 0x8f, 0xbd, 0xb1, 0xfe, 0xc6, 0xf8, 0x3f,
0x3a, 0x6f, 0x8c, 0x6f,
0xef, 0xbc, 0x29, 0xb6, 0xa3, 0xb3, 0x53, 0x74, 0x57, 0x67, 0xb7, 0x88,
0x76, 0x12, 0xc2, 0x6f,
0x06, 0x55, 0xe1, 0xd8, 0xea, 0xe6, 0xa8, 0x3f, 0x38, 0xc3, 0x62, 0xfa,
0xd5, 0x94, 0xc4, 0x2f,
0x28, 0xdd, 0x91, 0x71, 0x74, 0xdc, 0xf9, 0xdc, 0x0b, 0x85, 0xa7, 0x72,
0x0f, 0x8c, 0x5f, 0x95,
0x59, 0x37, 0x29, 0x32, 0xf1, 0xfe, 0xfa, 0x3f, 0xc4, 0xb4, 0x77, 0x76,
0x8a, 0x09, 0x9b, 0x15,
0xb2, 0xdd, 0xaf, 0x6f, 0xaf, 0xb0, 0x94, 0x9b, 0x89, 0xa3, 0xbe, 0x93,
0x9d, 0x09, 0xef, 0x39,
0x5a, 0xed, 0xad, 0x12, 0x0c, 0x3f, 0xca, 0x8e, 0xca, 0x84, 0x94, 0xdb,
0x9d, 0xed, 0xa3, 0xba,
0x84, 0xec, 0xf6, 0x6b, 0xda, 0x2b, 0xf5, 0x26, 0x67, 0x58, 0x74, 0xe5,
0xf8, 0x7f, 0x65, 0x6a,
0xab, 0x18, 0xdf, 0x49, 0x50, 0x18, 0x3f, 0xb8, 0x6c, 0x37, 0x6e, 0x5d,
0xee, 0xd3, 0x33, 0x6e,
0x88, 0xeb, 0xec, 0xec, 0x16, 0x19, 0xd2, 0xe0, 0x2f, 0x9f, 0x0f, 0x3b,
0xd4, 0xdf, 0x1b, 0x35,
0xaf, 0xa8, 0x75, 0x6c, 0x2b, 0xf6, 0xf8, 0xc6, 0xf8, 0x46, 0x3c, 0xf8,
0x9e, 0x98, 0xf2, 0x46,
0xd7, 0x0f, 0xf2, 0xad, 0x78, 0xfb, 0xbe, 0x33, 0x68, 0xcd, 0x3f, 0x69,
0x1b, 0x36, 0xfd, 0xa6,
0xd8, 0x2e, 0xd5, 0xed, 0x52, 0x43, 0x9a, 0xfc, 0x85, 0x50, 0xdd, 0x2d,
0xa5, 0xb3, 0xb3, 0x43,
0x74, 0x69, 0x49, 0x6b, 0x76, 0xab, 0xf1, 0xb5, 0x7c, 0xa5, 0xa1, 0x6c,
0xe5, 0xb2, 0xd3, 0x27,
0x72, 0x52, 0xf6, 0xcb, 0x36, 0x69, 0x92, 0x5d, 0x72, 0x48, 0xde, 0x96,
0x1f, 0xdc, 0xd6, 0xfb,
0x56, 0xdc, 0x63, 0x0d, 0x6c, 0x5a, 0xb0, 0x3b, 0xef, 0xfe, 0xfa, 0x9b,
0xa2, 0xc3, 0xab, 0xda,
0xa5, 0x84, 0x34, 0x7a, 0xfd, 0xd1, 0xcd, 0xd9, 0x61, 0x74, 0x8f, 0xca,
0x8f, 0x53, 0x5b, 0x8d,
0xaf, 0xe4, 0x4b, 0x8d, 0x6f, 0xb0, 0xc9, 0xb7, 0x72, 0x5c, 0xe6, 0x48,
0x86, 0x3c, 0x2b, 0x4f,
0x4b, 0x5f, 0xe9, 0x2f, 0x03, 0x40, 0x7f, 0xe9, 0x27, 0x7d, 0xf8, 0x3d,
0x5a, 0x2a, 0x65, 0x27,
0xb6, 0x6c, 0xc5, 0xae, 0xae, 0x19, 0x5f, 0x2a, 0xbb, 0x95, 0x8c, 0xcf,
0xea, 0xe8, 0x0c, 0x8b,
0x0a, 0x69, 0xf4, 0x7a, 0xc7, 0x58, 0x58, 0xca, 0x1f, 0xa7, 0x94, 0x24,
0xfd, 0x68, 0xff, 0x46,
0x2e, 0x6a, 0x7c, 0x85, 0x25, 0x3e, 0x90, 0x06, 0x19, 0x8d, 0xb5, 0x06,
0xcb, 0x70, 0x79, 0x41,
0x5e, 0x6c, 0x83, 0x11, 0x32, 0x84, 0xde, 0x61, 0x32, 0x4e, 0x5e, 0xd5,
0xd6, 0xbd, 0xa4, 0x67,
0x5e, 0x22, 0x4f, 0x1e, 0x9a, 0x78, 0x4b, 0xca, 0xef, 0x9d, 0x37, 0x24,
0xdd, 0xe0, 0xbc, 0x21,
0x31, 0x74, 0x5d, 0xdb, 0xd5, 0xa1, 0xaa, 0x5d, 0x7a, 0x20, 0x9b, 0x85,
0xcd, 0xea, 0x34, 0x7a,
0x4d, 0x61, 0x6b, 0xee, 0xe7, 0xc6, 0x67, 0xf2, 0x99, 0x7c, 0x4e, 0xdc,
0x9c, 0x93, 0x72, 0xe2,
0x69, 0x08, 0x96, 0x19, 0x75, 0x19, 0x8c, 0xc4, 0x76, 0x03, 0x24, 0x81,
0xac, 0xf9, 0x9d, 0x7c,
0x21, 0x9f, 0x69, 0x7c, 0x65, 0x04, 0xaf, 0x34, 0x43, 0xb8, 0x3a, 0xac,
0x99, 0xdc, 0x21, 0xb9,
0x6d, 0xdd, 0xd1, 0x35, 0xb5, 0xc3, 0xc4, 0xe6, 0x94, 0xef, 0xed, 0x9f,
0x88, 0xc2, 0x25, 0x62,
0xac, 0x51, 0x86, 0x62, 0x89, 0xc8, 0xab, 0xc0, 0x48, 0x79, 0x4e, 0xc6,
0xca, 0x19, 0xec, 0xf6,
0xa9, 0x7c, 0x12, 0xc2, 0xcf, 0x05, 0xea, 0x8a, 0x39, 0x35, 0x1d, 0x92,
0xda, 0xc6, 0x58, 0x97,
0xc8, 0x23, 0xf2, 0x95, 0xfd, 0x43, 0x51, 0xf8, 0x42, 0x8e, 0x92, 0x0f,
0x87, 0x73, 0x45, 0x5d,
0x35, 0x46, 0x92, 0x45, 0x17, 0x90, 0x1d, 0x3f, 0x96, 0x0f, 0x43, 0xf8,
0x79, 0x60, 0x7c, 0x21,
0x8d, 0x35, 0x37, 0x27, 0xf9, 0xd7, 0xf6, 0xed, 0x27, 0xee, 0x4e, 0xbd,
0x64, 0x7f, 0x5f, 0xde,
0x67, 0xff, 0xfa, 0x5a, 0x56, 0x90, 0x0d, 0x47, 0x4b, 0xec, 0x4f, 0x44,
0x8c, 0x3c, 0x2f, 0x42,
0xa4, 0xaa, 0x5a, 0x32, 0x84, 0x6b, 0xc3, 0x87, 0x58, 0xe4, 0x7d, 0xe3,
0x73, 0x69, 0xf0, 0xb3,
0x99, 0xaa, 0x15, 0xe7, 0x17, 0x7c, 0x99, 0xf7, 0xae, 0xbc, 0x2b, 0xef,
0x11, 0x8b, 0x33, 0x89,
0xb0, 0x38, 0x89, 0xbf, 0x26, 0x44, 0x63, 0x37, 0xb5, 0xcb, 0x85, 0x70,
0x2d, 0x18, 0x28, 0x47,
0x88, 0xa1, 0x77, 0x8d, 0x4f, 0xc5, 0xe9, 0x67, 0xb3, 0x9b, 0xa7, 0x66,
0xc4, 0x7d, 0x61, 0x7f,
0xdb, 0xf1, 0x16, 0xe7, 0xad, 0xcf, 0x64, 0xaa, 0x44, 0x48, 0xa2, 0x24,
0x5d, 0x33, 0x12, 0x43,
0xb8, 0x66, 0x8c, 0x94, 0x63, 0xc4, 0xd1, 0x5b, 0xc6, 0x47, 0x52, 0x6f,
0xb5, 0x59, 0x75, 0x97,
0xd4, 0xbf, 0x95, 0x5f, 0x4c, 0xbf, 0x60, 0x9c, 0x97, 0xf3, 0xd8, 0x74,
0x16, 0x95, 0x44, 0x4a,
0x08, 0xbf, 0x11, 0x44, 0xc9, 0x6b, 0xf2, 0x96, 0x9c, 0x37, 0x3e, 0x90,
0xe9, 0x35, 0x1d, 0x4d,
0x9b, 0x85, 0x3b, 0x3b, 0x8e, 0xde, 0xe6, 0x78, 0xdb, 0x7e, 0x56, 0xce,
0x62, 0xd1, 0xd5, 0xec,
0x46, 0x69, 0x57, 0x81, 0x74, 0x13, 0x69, 0xd7, 0x1d, 0xe9, 0x57, 0xb9,
0x5a, 0xaa, 0xbe, 0x52,
0xaf, 0x61, 0x95, 0xf4, 0x5f, 0x54, 0xbe, 0x40, 0x88, 0x91, 0x43, 0x44,
0xd2, 0x59, 0xe3, 0x5d,
0x99, 0x66, 0xb1, 0xd9, 0x2d, 0x75, 0xa9, 0x71, 0x1f, 0xd8, 0x4f, 0x3b,
0x4e, 0xcb, 0x1b, 0xd2,
0xcc, 0xf9, 0x2a, 0x53, 0xb2, 0xae, 0x10, 0x99, 0x3e, 0x92, 0xa4, 0x4b,
0xc6, 0x15, 0xcf, 0xbc,
0x7a, 0x64, 0xfa, 0x69, 0x2d, 0xfd, 0xdf, 0xf2, 0x99, 0x89, 0xa5, 0xd4,
0x8e, 0xea, 0xaa, 0x63,
0xa3, 0xf1, 0xc3, 0x64, 0x66, 0x5c, 0xfd, 0x2a, 0x69, 0x7e, 0xf2, 0x65,
0x5e, 0x47, 0x09, 0x03,
0x23, 0x41, 0x0e, 0x12, 0x4b, 0xa7, 0x8d, 0x37, 0x65, 0xaa, 0xc7, 0x66,
0xd4, 0x8b, 0xb7, 0x54,
0x9d, 0x4d, 0x3f, 0x65, 0x9c, 0x90, 0x93, 0xf4, 0x8d, 0x83, 0xab, 0xb1,
0x57, 0x88, 0x2c, 0x19,
0x23, 0x2f, 0xc8, 0x30, 0xce, 0xdb, 0x0a, 0xc3, 0xa9, 0x33, 0xd3, 0x25,
0xfb, 0x8a, 0x67, 0x5f,
0x1d, 0x72, 0xd0, 0x57, 0x2c, 0x27, 0xc5, 0xa1, 0xe6, 0x6a, 0xa3, 0x69,
0xc9, 0x09, 0x3a, 0x3e,
0x93, 0x9d, 0x40, 0x5d, 0xb1, 0x54, 0x52, 0xb1, 0x58, 0x2f, 0x8d, 0x2c,
0x93, 0xa6, 0xc7, 0xe7,
0xc0, 0xa3, 0xb2, 0x4d, 0x86, 0x86, 0xb2, 0x81, 0x97, 0xe7, 0x6c, 0x2c,
0xfd, 0xa2, 0x29, 0x91,
0x15, 0x43, 0x59, 0xf1, 0x79, 0xf6, 0x0c, 0x65, 0xfb, 0x8c, 0xeb, 0x26,
0x65, 0x20, 0x24, 0xcb,
0x2b, 0x72, 0x5a, 0x4e, 0xb0, 0x6f, 0xd5, 0xd6, 0xba, 0x6c, 0xd6, 0x6d,
0x56, 0xc7, 0x48, 0x5b,
0xd1, 0xf9, 0x9c, 0x23, 0x54, 0x27, 0xa7, 0x39, 0x53, 0x65, 0x88, 0xed,
0x8a, 0xa1, 0xfc, 0x6e,
0xbf, 0x6c, 0x91, 0xcd, 0x1a, 0x4d, 0xf2, 0x2a, 0x3a, 0xcd, 0x11, 0xfb,
0x55, 0x50, 0xb8, 0x72,
0xe4, 0xa2, 0x77, 0xa7, 0xec, 0x34, 0x57, 0xdb, 0x2e, 0x6b, 0xa9, 0x93,
0xc6, 0x06, 0x1d, 0x9f,
0x49, 0x74, 0xf9, 0xde, 0x45, 0xa8, 0x46, 0xe3, 0x36, 0xb8, 0xcb, 0xc1,
0xd3, 0x46, 0x70, 0xee,
0x1f, 0xa4, 0x31, 0x84, 0x3d, 0x3e, 0x03, 0xea, 0x36, 0xdd, 0x97, 0xc9,
0x2a, 0x07, 0x90, 0x64,
0x73, 0x1b, 0x34, 0xc9, 0x4a, 0x99, 0x27, 0xe5, 0xd8, 0x7d, 0x04, 0x67,
0xcf, 0x04, 0x2c, 0x9d,
0x7b, 0x5d, 0xe4, 0x0c, 0xa4, 0xe5, 0xfd, 0x72, 0x5c, 0x8e, 0x18, 0x67,
0x64, 0xb2, 0x3b, 0xce,
0xc2, 0x9d, 0x5d, 0x22, 0x0f, 0x18, 0x47, 0x8c, 0x43, 0x72, 0x98, 0xbd,
0x6e, 0xac, 0x18, 0x72,
0xa5, 0x3f, 0x06, 0x3e, 0x99, 0xe2, 0xa7, 0x97, 0xdb, 0xd0, 0xc8, 0xf5,
0xf9, 0xb1, 0xa1, 0xdb,
0x26, 0x9f, 0xb5, 0xde, 0x94, 0x87, 0xd0, 0x72, 0xb0, 0x9f, 0x4c, 0xa2,
0xe2, 0x0b, 0xf9, 0xc1,
0x7c, 0xbe, 0xd7, 0x0a, 0xb7, 0x23, 0x34, 0xd7, 0x69, 0x52, 0x88, 0x77,
0x36, 0xbb, 0x71, 0x48,
0x5a, 0x88, 0x44, 0x97, 0xdc, 0x06, 0xd6, 0x7b, 0xfe, 0xb2, 0x77, 0x90,
0xbe, 0xc6, 0xaa, 0xd1,
0xc4, 0x62, 0x16, 0x3c, 0xfd, 0x12, 0x3f, 0x59, 0xb2, 0x07, 0xcb, 0x1c,
0x32, 0x4e, 0xca, 0xc4,
0x9a, 0x8e, 0x89, 0xca, 0x66, 0x9d, 0xa7, 0x45, 0xc4, 0xbe, 0x6e, 0x6f,
0x76, 0x34, 0x13, 0x67,
0x0d, 0x70, 0x5d, 0x70, 0x85, 0x28, 0xe4, 0x4a, 0xc3, 0x2b, 0x5b, 0x3d,
0xf7, 0xf1, 0x41, 0xab,
0xfc, 0x51, 0xf2, 0xe8, 0x29, 0xbc, 0x62, 0x2a, 0x57, 0xbe, 0x9a, 0x90,
0xb3, 0x56, 0xc9, 0x8f,
0xe6, 0x5a, 0xdf, 0xc9, 0x51, 0xb9, 0x5b, 0xf2, 0x03, 0xae, 0xa5, 0xda,
0x72, 0xb0, 0xd0, 0xa7,
0xe8, 0xd7, 0xcb, 0x9b, 0xca, 0xe3, 0xaa, 0x27, 0x85, 0x59, 0xea, 0xf9,
0x83, 0x0b, 0xad, 0x9c,
0xfb, 0x9f, 0xc0, 0x66, 0x8a, 0xeb, 0x7c, 0xf4, 0x33, 0xd8, 0x47, 0xa2,
0x40, 0xf8, 0x5a, 0x3f,
0x7b, 0x9a, 0x43, 0x8c, 0x8e, 0x15, 0xc7, 0xcf, 0x2e, 0x69, 0x5b, 0xe4,
0xc9, 0x6e, 0xfc, 0xaa,
0xd9, 0x38, 0x26, 0xd5, 0x6e, 0x9b, 0xdd, 0x34, 0x71, 0x69, 0x6a, 0x8b,
0x71, 0x80, 0x9c, 0xb9,
0x5f, 0x8a, 0xd8, 0xcd, 0x8a, 0x2e, 0x8b, 0x62, 0xa0, 0xfe, 0x1d, 0xa7,
0x33, 0x49, 0xab, 0x7c,
0x6e, 0xa2, 0x55, 0xda, 0xe3, 0xf9, 0x81, 0x66, 0x78, 0xe7, 0xfd, 0x34,
0x14, 0xc3, 0xfb, 0x48,
0x59, 0x21, 0xdf, 0x9a, 0x6b, 0x7d, 0x45, 0x5e, 0xb8, 0x87, 0xd6, 0x60,
0x34, 0xf3, 0xc8, 0x9c,
0x1f, 0x11, 0x69, 0x17, 0xdd, 0x50, 0x36, 0x8b, 0xd0, 0x12, 0xa6, 0xd0,
0xe7, 0xe5, 0xfa, 0x12,
0x67, 0x9b, 0xfb, 0x89, 0x98, 0x22, 0xdd, 0x97, 0x43, 0xae, 0xb4, 0x4a,
0x14, 0x1c, 0xad, 0x64,
0xea, 0x61, 0x78, 0xd2, 0xb8, 0x9f, 0x20, 0x4b, 0xb1, 0x45, 0x2b, 0x97,
0x87, 0x21, 0x3b, 0xd8,
0x75, 0x0e, 0x18, 0x87, 0xa5, 0xb2, 0x16, 0x9b, 0x55, 0x87, 0xa5, 0xdc,
0x56, 0x71, 0x32, 0x75,
0xaf, 0xec, 0x25, 0xde, 0x97, 0xb2, 0x7e, 0x69, 0x50, 0x94, 0x81, 0x52,
0x19, 0x2f, 0x25, 0x7a,
0xad, 0x12, 0x3e, 0x95, 0x92, 0xd1, 0x93, 0xd0, 0xa2, 0xf7, 0x9e, 0x58,
0xab, 0x74, 0x44, 0x8b,
0xae, 0x91, 0xbe, 0x33, 0xc6, 0xb9, 0x65, 0x73, 0xcd, 0xf3, 0x8c, 0x08,
0xbe, 0x8e, 0xff, 0x88,
0x32, 0x68, 0x44, 0xc1, 0xe1, 0x25, 0x73, 0xad, 0xcf, 0x90, 0xe3, 0x7e,
0xe8, 0x05, 0xa3, 0x95,
0x0f, 0x6f, 0xff, 0x72, 0x3f, 0x13, 0x72, 0xd9, 0x4c, 0xd5, 0x91, 0x6a,
0x6c, 0x06, 0x36, 0xfb,
0xc6, 0xa4, 0xf3, 0x09, 0x67, 0x9f, 0x07, 0xd0, 0xbd, 0x8b, 0x8a, 0x8d,
0x4a, 0xe3, 0xfb, 0x2b,
0xbc, 0x03, 0xf8, 0x23, 0xd6, 0xcf, 0x80, 0x83, 0xc0, 0x72, 0x28, 0xb9,
0x95, 0xb4, 0xe3, 0x03,
0x68, 0xa3, 0xc8, 0xad, 0x8f, 0x62, 0xb7, 0x36, 0x4a, 0xff, 0x8d, 0x3e,
0x4a, 0x89, 0xff, 0x6d,
0xb2, 0x4f, 0xf6, 0x1a, 0xcd, 0x52, 0xae, 0x6a, 0x90, 0xea, 0xce, 0xa9,
0x11, 0x25, 0xcd, 0x59,
0x3b, 0xd9, 0xdb, 0xf7, 0x4b, 0x0d, 0x3b, 0x6c, 0x45, 0x10, 0x54, 0x72,
0x95, 0xb3, 0x82, 0x50,
0x31, 0x25, 0xe3, 0xb1, 0x69, 0xd8, 0xab, 0x10, 0xaf, 0x4c, 0x42, 0x2b,
0xef, 0x9a, 0xf8, 0x5e,
0x6e, 0x81, 0x97, 0x4a, 0x0d, 0x35, 0xab, 0x4c, 0x7b, 0x49, 0x26, 0xe3,
0xe3, 0x75, 0xed, 0x36,
0x86, 0xdc, 0x63, 0xc0, 0x69, 0x99, 0x9b, 0x66, 0x39, 0x1c, 0x15, 0x61,
0xe5, 0x7c, 0x33, 0xa7,
0x95, 0x68, 0x1e, 0x5c, 0xab, 0x95, 0x40, 0xcb, 0xd3, 0x33, 0x8e, 0xbe,
0x18, 0x59, 0x2c, 0x1f,
0x9b, 0x6b, 0x7d, 0x88, 0x9f, 0xfd, 0x4d, 0x53, 0x2a, 0x63, 0x64, 0xa1,
0x39, 0x32, 0x9f, 0xb1,
0xc5, 0x9a, 0xd7, 0x6c, 0xe9, 0x21, 0x37, 0x49, 0x07, 0x8d, 0x9b, 0xc1,
0x7d, 0xd8, 0x4a, 0x71,
0xa4, 0xb8, 0xb8, 0x68, 0xd2, 0x79, 0x5f, 0xce, 0xc9, 0x5f, 0x90, 0x64,
0x9c, 0x5e, 0x5b, 0xd8,
0xcf, 0xbe, 0xb4, 0x48, 0xa4, 0x70, 0xc9, 0x8d, 0x4f, 0xf1, 0x01, 0x6b,
0xfb, 0x47, 0xb2, 0x4b,
0x06, 0x6a, 0x69, 0x8a, 0xcd, 0xf5, 0x0b, 0xa1, 0x5f, 0xaa, 0xa5, 0xb2,
0xe9, 0x3a, 0x3d, 0x9f,
0xcf, 0x15, 0xa6, 0x36, 0x4a, 0xdc, 0xfa, 0x8b, 0xd7, 0x77, 0x64, 0x93,
0xa8, 0x2e, 0x6c, 0x3a,
0x4e, 0xca, 0x4d, 0x8d, 0x05, 0x42, 0x09, 0x75, 0xd7, 0x2e, 0xd9, 0x49,
0x2e, 0x2c, 0xad, 0xb9,
0x25, 0x91, 0x9a, 0x71, 0x74, 0x4d, 0xc1, 0xee, 0xbc, 0xed, 0x54, 0x61,
0x5b, 0x99, 0x39, 0x31,
0x28, 0x26, 0x40, 0x73, 0x1c, 0xd2, 0xa6, 0xf0, 0x79, 0x31, 0x15, 0x54,
0x23, 0xdc, 0xc4, 0xea,
0x3a, 0xfa, 0x23, 0x64, 0xf6, 0xe0, 0x92, 0x74, 0x41, 0x57, 0xae, 0xf1,
0x55, 0x7c, 0xca, 0x65,
0x44, 0x3a, 0xf5, 0xda, 0x22, 0xd9, 0x48, 0xfd, 0xb0, 0x89, 0x99, 0x55,
0x50, 0x88, 0x25, 0x7f,
0x96, 0xd2, 0xaa, 0xc6, 0x14, 0xf3, 0x39, 0x85, 0x2a, 0x4c, 0x21, 0x09,
0xaf, 0x55, 0x3d, 0x13,
0x98, 0x5f, 0x05, 0xa7, 0x79, 0xcc, 0x4d, 0xd4, 0x3d, 0x63, 0xb0, 0xbb,
0xb0, 0xef, 0x2f, 0x40,
0x53, 0x9e, 0xb5, 0xde, 0x26, 0x63, 0x3c, 0xc4, 0xb8, 0x4a, 0xf4, 0x94,
0x61, 0xd2, 0x48, 0xe4,
0xd3, 0x58, 0xb4, 0x53, 0xae, 0xf5, 0x1f, 0x47, 0x75, 0x38, 0x50, 0x9e,
0x05, 0x83, 0xb0, 0x45,
0xaa, 0xf6, 0xef, 0x5c, 0x72, 0x6c, 0x16, 0xda, 0xf7, 0xd0, 0xb9, 0xc0,
0x09, 0xe7, 0x2f, 0xd0,
0xce, 0x40, 0xa2, 0x32, 0x68, 0x8d, 0xc4, 0x2f, 0xce, 0x59, 0xf0, 0x31,
0x19, 0x55, 0xdd, 0x8d,
0x48, 0x86, 0xaf, 0x3d, 0x96, 0x79, 0x0a, 0x5f, 0xca, 0x3f, 0xb1, 0x93,
0xb2, 0x4f, 0xaa, 0x7b,
0xfd, 0x64, 0x5d, 0x83, 0xd9, 0xb0, 0x4a, 0xae, 0x4c, 0x41, 0xee, 0x32,
0x56, 0x74, 0xc9, 0x53,
0x8a, 0xb7, 0xc6, 0xe1, 0xeb, 0x65, 0x48, 0xb1, 0x01, 0x2b, 0x6c, 0x95,
0x97, 0x64, 0x2a, 0x72,
0xc5, 0x60, 0xc5, 0x12, 0xfa, 0x27, 0x04, 0xd5, 0x7d, 0x05, 0x9a, 0xdb,
0x21, 0xdb, 0x8d, 0xbd,
0x52, 0x8c, 0xcd, 0xc2, 0x67, 0x75, 0x89, 0x58, 0x23, 0x5b, 0xed, 0x8a,
0xc2, 0x32, 0x66, 0xd5,
0x04, 0xc5, 0x04, 0x38, 0x8b, 0xa6, 0xd6, 0x3d, 0x8f, 0xae, 0x2e, 0xf0,
0xef, 0x9b, 0x68, 0xaf,
0x45, 0xd7, 0xcc, 0xef, 0x51, 0x83, 0x79, 0xf0, 0xb1, 0x84, 0xa1, 0x2b,
0xd7, 0xf8, 0xf1, 0xe8,
0xcf, 0x4e, 0x2c, 0xbc, 0xa9, 0x67, 0x78, 0xf4, 0xa3, 0x3e, 0x6f, 0xd5,
0xf7, 0x26, 0xca, 0xe0,
0xa6, 0x1a, 0xc9, 0x8e, 0xa0, 0xb3, 0xe3, 0x6e, 0xbc, 0x41, 0x6b, 0x1e,
0xed, 0x35, 0xf4, 0xe4,
0xc9, 0x5c, 0x79, 0xdd, 0xec, 0x39, 0x2f, 0x93, 0xc8, 0x5a, 0xf3, 0x98,
0xed, 0x59, 0xeb, 0x1c,
0x72, 0x3f, 0xcc, 0xb8, 0x12, 0x7c, 0x60, 0xbb, 0x9c, 0x32, 0x47, 0x9e,
0x24, 0x72, 0xd4, 0xee,
0x57, 0x01, 0x85, 0x63, 0x8c, 0x3b, 0xe5, 0xc6, 0x05, 0xc6, 0xaa, 0x13,
0x65, 0x33, 0x23, 0x4e,
0xca, 0x19, 0x0b, 0xd7, 0x67, 0x98, 0x75, 0x02, 0x7a, 0x55, 0x68, 0xb5,
0x08, 0x0b, 0x59, 0x25,
0x3a, 0xcd, 0xce, 0xd5, 0x0e, 0xdf, 0x78, 0x4c, 0x1e, 0x91, 0xbb, 0xe4,
0x77, 0xe8, 0xf9, 0xbc,
0xa5, 0xef, 0x7d, 0xe4, 0xcf, 0x46, 0xef, 0xfb, 0x2d, 0xeb, 0xbf, 0x23,
0x3d, 0xb1, 0xcd, 0x7e,
0xfe, 0x7f, 0x0b, 0x7f, 0xce, 0xa3, 0x77, 0x32, 0x12, 0x95, 0xe9, 0xfb,
0x28, 0x4d, 0x70, 0xf1,
0x8e, 0xa9, 0x8d, 0xf3, 0xa2, 0xee, 0xed, 0x1e, 0x84, 0xdb, 0x18, 0xae,
0x6a, 0xc6, 0x05, 0xd3,
0xfd, 0x7a, 0x66, 0x6e, 0x31, 0x76, 0xca, 0x38, 0x6c, 0x16, 0xe6, 0xbc,
0x3b, 0x62, 0x9b, 0x7d,
0x23, 0x51, 0xb0, 0x59, 0x66, 0xe3, 0x17, 0x53, 0x03, 0xa0, 0x8e, 0xab,
0x16, 0x2f, 0x89, 0x23,
0x7f, 0xbe, 0x4e, 0xad, 0x76, 0xc4, 0xc4, 0x71, 0xd6, 0x2c, 0x83, 0x73,
0x6f, 0xcb, 0x3b, 0xf2,
0x27, 0x24, 0xaf, 0x63, 0x1d, 0x65, 0xb1, 0x25, 0x70, 0x75, 0xdc, 0xd2,
0xeb, 0xc1, 0x09, 0xe6,
0x4d, 0xc2, 0x27, 0x2b, 0x91, 0x25, 0x4b, 0x66, 0xa0, 0xb3, 0xa3, 0x6e,
0xa8, 0xf3, 0xe1, 0x08,
0x78, 0x9f, 0x8a, 0x04, 0xf1, 0xd8, 0xfb, 0x84, 0xbb, 0xfd, 0x18, 0x2b,
0xdf, 0x43, 0x04, 0xcc,
0x46, 0x37, 0x5e, 0x2a, 0xeb, 0xd0, 0x63, 0x29, 0xe3, 0x96, 0x6b, 0xbe,
0x5c, 0x38, 0x8e, 0x1e,
0x9f, 0x64, 0x9f, 0xab, 0x86, 0x7a, 0x32, 0xf6, 0x39, 0x6e, 0xf6, 0x9c,
0x47, 0x02, 0x75, 0xd7,
0x7b, 0xbf, 0xa6, 0xea, 0xcb, 0xd1, 0x31, 0xdd, 0x1f, 0x8f, 0x56, 0xcb,
0xd8, 0x35, 0xcf, 0xf9,
0xf4, 0x29, 0x99, 0xaa, 0x65, 0x1a, 0x98, 0x04, 0xb7, 0xd1, 0xf8, 0x95,
0xb7, 0xef, 0x0d, 0xe8,
0x25, 0x43, 0x75, 0xa7, 0xc9, 0xe9, 0x51, 0xc6, 0x77, 0x14, 0x75, 0x77,
0x42, 0xf5, 0x9f, 0xe3,
0xdc, 0x9f, 0x8a, 0xf6, 0x14, 0x2f, 0x53, 0x91, 0xfa, 0x44, 0x00, 0x6d,
0x28, 0x7f, 0x5c, 0xcf,
0xb8, 0x12, 0xb4, 0xe6, 0xd2, 0xb6, 0x3f, 0x6a, 0x64, 0x0d, 0x16, 0xda,
0x68, 0x6c, 0x93, 0x82,
0xda, 0x5b, 0x92, 0xba, 0xce, 0x78, 0x2a, 0xea, 0x65, 0xfb, 0x5a, 0xc7,
0x5a, 0x66, 0xcd, 0x42,
0x7b, 0x33, 0x03, 0x62, 0x06, 0x5a, 0xcc, 0x90, 0x85, 0xf0, 0xf3, 0x6a,
0x1b, 0xbc, 0xe6, 0xf3,
0xdb, 0x59, 0xf9, 0x33, 0x63, 0xa7, 0x63, 0x8b, 0x64, 0xe2, 0xf6, 0xb8,
0xd9, 0x7e, 0x90, 0x1a,
0xef, 0x08, 0xd7, 0x41, 0xb3, 0xe5, 0x04, 0xde, 0x93, 0x8e, 0x16, 0x4a,
0xd0, 0xd1, 0x29, 0xb3,
0xb5, 0x19, 0xe9, 0xfb, 0x41, 0x61, 0x06, 0x51, 0x92, 0x80, 0xdc, 0x9e,
0xf6, 0xc3, 0x64, 0xd5,
0x3f, 0x21, 0xbd, 0xd3, 0xb2, 0xde, 0x21, 0x32, 0xf4, 0xc3, 0x5a, 0x23,
0x27, 0x2c, 0xf3, 0xcf,
0xb1, 0x87, 0x75, 0x25, 0x5a, 0x66, 0x42, 0x7f, 0x0c, 0xb9, 0xac, 0xd9,
0xec, 0x3b, 0xc9, 0x89,
0x5a, 0x69, 0x78, 0xbb, 0xa5, 0xcd, 0x8a, 0x13, 0xf4, 0x67, 0xe1, 0x71,
0xb1, 0x16, 0x7a, 0x2e,
0x99, 0x6e, 0x83, 0x4f, 0xa5, 0x85, 0x5a, 0xb2, 0x5e, 0x86, 0x45, 0x2a,
0x45, 0x33, 0x8a, 0xac,
0x99, 0x44, 0xc4, 0xb7, 0x98, 0x6d, 0xc7, 0x90, 0xeb, 0x84, 0x65, 0xcd,
0x74, 0xe4, 0xc9, 0xc1,
0xe2, 0xc7, 0x03, 0xae, 0xea, 0xc2, 0x51, 0x59, 0x8b, 0x37, 0x4c, 0x64,
0x54, 0x20, 0xfd, 0x4f,
0xe3, 0x8c, 0xb3, 0x4e, 0xd6, 0x1a, 0x9b, 0xc5, 0x51, 0xd3, 0x29, 0xb1,
0xcb, 0xb4, 0x11, 0xb1,
0x9b, 0xed, 0x2b, 0x45, 0x61, 0x56, 0x10, 0x34, 0x60, 0x03, 0x55, 0x85,
0x1d, 0x64, 0x1f, 0xbc,
0x1c, 0x8e, 0xca, 0xed, 0x44, 0xeb, 0x34, 0x4e, 0x2d, 0xb5, 0x68, 0xc6,
0xd3, 0xba, 0x1b, 0xfd,
0x2e, 0x20, 0x67, 0xce, 0x87, 0xc6, 0x6e, 0xcb, 0xd8, 0x24, 0x72, 0xfd,
0x64, 0x4e, 0x5d, 0x9b,
0xd0, 0xad, 0xa7, 0xf5, 0x90, 0x0c, 0x65, 0xb5, 0xe9, 0x7a, 0x27, 0x7f,
0xc5, 0x6c, 0x6d, 0x61,
0x37, 0x7a, 0x8e, 0x5d, 0x62, 0x1a, 0x51, 0xe2, 0x69, 0xdb, 0x47, 0x1c,
0xdf, 0x81, 0xcd, 0x5b,
0x2c, 0xeb, 0x9c, 0x90, 0x07, 0xa5, 0x1b, 0x51, 0xd1, 0x08, 0xdf, 0x93,
0xb1, 0xcf, 0x56, 0xcb,
0x7a, 0x2d, 0xc4, 0x69, 0x2a, 0xb9, 0x78, 0x17, 0xda, 0x3b, 0xe4, 0xc3,
0xf5, 0x1e, 0x1d, 0x1f,
0xe7, 0xf4, 0x3e, 0x3b, 0x91, 0x68, 0x6b, 0xf6, 0xe9, 0x3d, 0x46, 0x5d,
0x95, 0xaf, 0x2b, 0x3e,
0x21, 0x6f, 0xd6, 0x5b, 0x38, 0x50, 0xdc, 0x0e, 0xc0, 0xce, 0xa9, 0xc4,
0xc1, 0x1e, 0x0b, 0x17,
0xbb, 0xcc, 0x55, 0x5b, 0x64, 0x14, 0x56, 0x2e, 0x46, 0x1f, 0x87, 0x2d,
0xb3, 0x76, 0x6b, 0x1f,
0x6e, 0xb1, 0xcc, 0xd9, 0x45, 0x4b, 0x0d, 0x23, 0xeb, 0xf0, 0xca, 0xb6,
0x16, 0xa8, 0x27, 0x93,
0x60, 0x21, 0x63, 0xbd, 0xd8, 0xb1, 0x59, 0xe7, 0xa9, 0x71, 0x71, 0xeb,
0xec, 0xcb, 0x88, 0x89,
0xa5, 0xe4, 0x9d, 0x40, 0x98, 0xc3, 0x35, 0x03, 0x49, 0x5f, 0x62, 0x17,
0xdc, 0x6a, 0x62, 0x3b,
0xfa, 0x6c, 0x61, 0x9d, 0x3d, 0x96, 0x36, 0x85, 0x83, 0x9c, 0x72, 0xeb,
0xf4, 0xea, 0xbb, 0xcc,
0xb6, 0x6d, 0x9c, 0x22, 0xba, 0xcb, 0x7f, 0xa2, 0xcb, 0x8e, 0x68, 0xf4,
0x80, 0xd9, 0xbe, 0x03,
0x4e, 0xa2, 0xb4, 0xef, 0x16, 0x22, 0x85, 0xa7, 0x75, 0x37, 0x96, 0xc9,
0x81, 0x46, 0x1e, 0xeb,
0x7a, 0x57, 0x3c, 0x2c, 0xe1, 0xec, 0x35, 0x0e, 0xfc, 0x61, 0xa7, 0xd9,
0xf6, 0x32, 0x96, 0x79,
0x1c, 0x7a, 0xdb, 0xcc, 0x75, 0x0e, 0xb1, 0xeb, 0xdc, 0x4a, 0x84, 0xce,
0x85, 0xeb, 0x39, 0xe4,
0x94, 0x34, 0xf6, 0xfa, 0x6d, 0xe6, 0xf8, 0x7d, 0x78, 0x47, 0x0e, 0x36,
0x19, 0x2a, 0x37, 0xca,
0x53, 0x16, 0x3e, 0xb6, 0xe3, 0x33, 0x37, 0x63, 0x97, 0x4e, 0xf2, 0x77,
0xbd, 0xa3, 0x27, 0x92,
0x93, 0xad, 0x32, 0xed, 0x97, 0xde, 0xfa, 0xe4, 0x9c, 0x8f, 0xd7, 0xcd,
0xb1, 0xc8, 0xa5, 0xd0,
0x42, 0x16, 0x2e, 0x64, 0xc7, 0x5a, 0xae, 0x6b, 0x38, 0xaf, 0xc4, 0xd6,
0x35, 0xd5, 0x3d, 0xce,
0x55, 0x96, 0xfe, 0x6d, 0x50, 0x4c, 0x93, 0x47, 0x39, 0x07, 0x6e, 0x41,
0x06, 0xeb, 0x3a, 0xc3,
0x89, 0xe7, 0x46, 0xad, 0x71, 0x5f, 0x34, 0x62, 0x1d, 0x6c, 0x64, 0xac,
0x91, 0xbc, 0xda, 0x4e,
0x89, 0x9d, 0x6a, 0xd3, 0x12, 0x56, 0xda, 0x17, 0x8b, 0xc2, 0x82, 0x20,
0x98, 0x8f, 0x06, 0x33,
0x58, 0x73, 0x9d, 0x89, 0x0d, 0xec, 0x7e, 0x0f, 0xc8, 0x7f, 0x53, 0x41,
0xa7, 0xa2, 0xd7, 0x75,
0x16, 0xec, 0x92, 0x7b, 0x89, 0x11, 0x55, 0x5d, 0x6c, 0x36, 0xdb, 0xb6,
0x22, 0x53, 0x7b, 0x64,
0x9e, 0x82, 0xff, 0x0f, 0x67, 0xc7, 0x6e, 0x32, 0x7b, 0xb6, 0x93, 0xc5,
0xab, 0xd0, 0x52, 0x2c,
0xa3, 0xd7, 0xbb, 0xdb, 0x36, 0x52, 0x67, 0x0c, 0xa3, 0x2d, 0x07, 0xcf,
0xf2, 0xb4, 0x6d, 0xc2,
0xfb, 0xee, 0x84, 0x8b, 0x22, 0x64, 0xda, 0x64, 0xe1, 0x62, 0x01, 0xb2,
0x6c, 0x74, 0xff, 0xb6,
0x1e, 0x4d, 0xdf, 0x4f, 0x66, 0x9e, 0x4a, 0x0e, 0x77, 0xf1, 0x3d, 0x83,
0x75, 0xbd, 0x34, 0xd4,
0x6a, 0x23, 0xb0, 0xfb, 0x1c, 0xec, 0x92, 0xc8, 0xce, 0xb6, 0xcd, 0x42,
0x67, 0x39, 0x5c, 0x67,
0x62, 0x97, 0x6a, 0xac, 0x3d, 0x4d, 0x47, 0xe7, 0x3a, 0x1f, 0xbc, 0x0c,
0xcf, 0x0a, 0x5b, 0x2c,
0xab, 0xbb, 0x78, 0x5d, 0x8a, 0x8f, 0xd4, 0x52, 0xd9, 0x2c, 0x82, 0xca,
0x3a, 0x3f, 0xac, 0x67,
0xf4, 0x2e, 0x6c, 0x96, 0x82, 0x57, 0x36, 0x59, 0xda, 0xf7, 0xb0, 0x5a,
0x07, 0x2c, 0xd6, 0x97,
0x9c, 0xbb, 0xce, 0x32, 0xaf, 0x09, 0x0e, 0x6c, 0x70, 0xb0, 0x30, 0x80,
0x0d, 0xb4, 0x85, 0x8c,
0x15, 0x32, 0x56, 0xd9, 0xac, 0x26, 0x2b, 0x71, 0xa9, 0xa1, 0x5a, 0x17,
0x92, 0x69, 0x16, 0x07,
0xc0, 0x12, 0x7a, 0x6a, 0xc8, 0x61, 0x6b, 0x90, 0xcc, 0x83, 0x2d, 0x9c,
0x8b, 0xee, 0x85, 0xd3,
0x5c, 0xf9, 0x07, 0xbe, 0xb7, 0xda, 0xd2, 0xb3, 0x59, 0xfe, 0x8a, 0xcd,
0x0a, 0xf0, 0x8c, 0x95,
0x66, 0xdb, 0x26, 0xec, 0xdb, 0x47, 0xdf, 0xcd, 0x53, 0x77, 0x79, 0x5f,
0x44, 0x16, 0x4f, 0xcf,
0x5a, 0x5a, 0x6d, 0xd8, 0x23, 0x85, 0x6b, 0xa5, 0x85, 0x46, 0x1f, 0x5d,
0xe7, 0x7b, 0x57, 0xdc,
0x28, 0x83, 0xd9, 0x17, 0xe6, 0x90, 0x9d, 0xaa, 0x7c, 0x56, 0x5b, 0x69,
0x99, 0xb5, 0x16, 0x9e,
0xd4, 0xbe, 0xf3, 0x12, 0x1c, 0xbb, 0xe0, 0xc4, 0xee, 0x8b, 0x64, 0x85,
0x39, 0x62, 0x03, 0xbe,
0x50, 0xa0, 0xa5, 0x9c, 0x42, 0x0e, 0x5c, 0x6b, 0xa1, 0xb2, 0x80, 0xaa,
0x65, 0xb6, 0xce, 0x35,
0x4b, 0xd8, 0x3d, 0x52, 0x2d, 0x7d, 0xff, 0x1e, 0x4d, 0x9c, 0x20, 0x5e,
0x60, 0xef, 0xb0, 0xc3,
0xdb, 0x4a, 0x9f, 0x9e, 0x55, 0xd8, 0x7d, 0x0d, 0x3e, 0x30, 0x15, 0x3f,
0x49, 0xc1, 0x4b, 0x56,
0x5b, 0x56, 0x5b, 0x2c, 0xff, 0xa7, 0x4f, 0x3f, 0x73, 0xe8, 0xb1, 0xea,
0x75, 0x15, 0x5e, 0x16,
0x41, 0x84, 0x2c, 0x69, 0x63, 0x89, 0x25, 0x2e, 0x3b, 0x1a, 0x4b, 0x25,
0x5b, 0xc7, 0x59, 0x46,
0xe2, 0x22, 0x43, 0x65, 0x92, 0xb9, 0x48, 0xb7, 0x2c, 0x00, 0x96, 0x33,
0x63, 0x22, 0xd9, 0xdc,
0x1b, 0x87, 0x8b, 0xe0, 0x32, 0x1c, 0xaf, 0x5f, 0x89, 0x7e, 0x6a, 0xd9,
0x39, 0x97, 0x5a, 0xfc,
0x61, 0x15, 0xf9, 0x45, 0xed, 0x66, 0x8d, 0x16, 0x6f, 0x59, 0x08, 0x1f,
0x0b, 0x88, 0x9e, 0xb9,
0x5c, 0xf3, 0xc1, 0x42, 0x0b, 0xa5, 0xa9, 0xd8, 0x70, 0x2e, 0x12, 0x64,
0x41, 0xcb, 0xd3, 0xba,
0x8c, 0x8c, 0x99, 0x48, 0xac, 0x2e, 0x31, 0x5b, 0x56, 0x10, 0x3f, 0xd5,
0x70, 0x50, 0xee, 0xc3,
0x87, 0x2f, 0x96, 0xe3, 0xb9, 0x39, 0x7a, 0xf6, 0x72, 0xf7, 0x35, 0x07,
0xaf, 0xb2, 0xf2, 0xb1,
0x9c, 0x1d, 0xb1, 0x98, 0x7f, 0x97, 0xc2, 0xa1, 0xcd, 0x42, 0x7d, 0x11,
0x3b, 0xc6, 0x93, 0x8c,
0x5e, 0xae, 0x67, 0x39, 0xa9, 0x19, 0x5e, 0x0a, 0x9a, 0x73, 0xac, 0x50,
0x67, 0xa3, 0x1b, 0x91,
0x60, 0x01, 0x59, 0x73, 0xa6, 0x4f, 0x74, 0x2c, 0xc1, 0x6f, 0x6f, 0x92,
0xff, 0xa0, 0x16, 0xba,
0x15, 0xff, 0x13, 0x7c, 0x7e, 0x91, 0xd9, 0xf7, 0x12, 0x5c, 0x0e, 0x40,
0x8a, 0x15, 0x7c, 0x9a,
0xc4, 0xe7, 0x97, 0x2c, 0x7c, 0x38, 0xf1, 0x81, 0xf9, 0x6e, 0x3e, 0xac,
0x58, 0xe1, 0xca, 0xf6,
0xc6, 0x42, 0xc9, 0xc0, 0x66, 0x9d, 0x6b, 0x13, 0xe3, 0xe7, 0x19, 0x6a,
0x9f, 0x6b, 0xc4, 0x17,
0x56, 0x06, 0xc0, 0x2a, 0x64, 0x9c, 0x80, 0xae, 0xe6, 0x30, 0xc2, 0x85,
0xb9, 0xe8, 0xee, 0x51,
0xf8, 0x5a, 0x0d, 0xad, 0x06, 0x32, 0xf3, 0x3c, 0xb3, 0xa7, 0x91, 0xd6,
0x07, 0xe0, 0xd7, 0xa1,
0xe9, 0x79, 0xe1, 0x9f, 0x9d, 0xbd, 0x58, 0x84, 0xb6, 0x16, 0xf0, 0x7f,
0x14, 0x9f, 0x3c, 0x6d,
0xf3, 0xd8, 0x21, 0xfa, 0xa1, 0xd7, 0xd9, 0xe6, 0x7a, 0x95, 0x44, 0xf5,
0x42, 0xf8, 0xa8, 0x44,
0xe7, 0x73, 0x7d, 0xe6, 0x5b, 0xb1, 0x10, 0x2a, 0xf5, 0x48, 0xe8, 0xe2,
0x5a, 0x3d, 0x37, 0xb1,
0xe1, 0xb9, 0xb3, 0x2d, 0x6b, 0x0d, 0x46, 0x8e, 0x55, 0x70, 0x3d, 0x83,
0x28, 0xf6, 0x72, 0x3d,
0x07, 0xff, 0x7b, 0x0a, 0x5d, 0xb9, 0x66, 0xcd, 0xc6, 0x7f, 0xe6, 0x05,
0x5d, 0xc3, 0x3b, 0x47,
0x9d, 0x87, 0xff, 0x8b, 0x3c, 0xba, 0x02, 0x99, 0x0b, 0xf9, 0x3c, 0xdb,
0x22, 0xed, 0x3c, 0xf9,
0x3d, 0xa7, 0xf8, 0x49, 0x7c, 0x9a, 0xcf, 0x55, 0xc2, 0x27, 0xaf, 0xf6,
0x16, 0xe0, 0xe5, 0xf1,
0x70, 0xa9, 0x22, 0x6f, 0x3a, 0x3b, 0xc5, 0x3c, 0xcb, 0xbc, 0x06, 0x2c,
0x3c, 0xd7, 0xcd, 0x87,
0x15, 0xab, 0xe9, 0xc3, 0x46, 0xc6, 0x3c, 0x49, 0xc3, 0x66, 0x5d, 0xa6,
0x8e, 0x8c, 0x9b, 0x6d,
0x9f, 0x81, 0x14, 0xf5, 0x96, 0xcc, 0xef, 0x9b, 0x95, 0x57, 0xe2, 0x27,
0x85, 0x8c, 0x98, 0xe6,
0xc6, 0x4c, 0x7e, 0x1b, 0x08, 0xdd, 0xf5, 0xe4, 0x90, 0xf9, 0xf8, 0xf2,
0x54, 0xd6, 0xf6, 0xf4,
0xcd, 0x26, 0x5b, 0x3a, 0xb1, 0x59, 0x9d, 0xd9, 0xe2, 0x9a, 0x51, 0x1f,
0x10, 0x33, 0xe1, 0xf0,
0x19, 0x7c, 0x6e, 0x99, 0xbe, 0xa7, 0xee, 0x59, 0x61, 0x3a, 0xd1, 0xfb,
0x0c, 0x94, 0x3c, 0xb3,
0x1b, 0x91, 0x3f, 0x12, 0x4e, 0x56, 0x52, 0x09, 0x5a, 0xf9, 0xf0, 0xc7,
0x4c, 0x2c, 0x92, 0x0d,
0xb5, 0x35, 0x5a, 0x92, 0xb5, 0x7c, 0x52, 0x1e, 0xee, 0xe5, 0xad, 0x01,
0x3a, 0x15, 0xf4, 0xad,
0xe1, 0x93, 0x4d, 0x57, 0xd0, 0x2e, 0xcc, 0x20, 0x8f, 0xf4, 0xc2, 0x06,
0xeb, 0xf4, 0x3c, 0x25,
0xd1, 0x4c, 0x3f, 0xca, 0x56, 0x9e, 0x9d, 0xcc, 0x9e, 0x47, 0x5b, 0x7f,
0x2c, 0x96, 0x86, 0xc5,
0xd6, 0xc3, 0xfd, 0x78, 0xbc, 0x7a, 0xba, 0x65, 0xf4, 0x58, 0xf2, 0xb4,
0xca, 0xe8, 0x1b, 0xb8,
0x96, 0xeb, 0xbb, 0x70, 0x5e, 0xae, 0xd5, 0x9b, 0x36, 0x39, 0x58, 0x61,
0x03, 0x7c, 0xcc, 0x62,
0xb7, 0xf0, 0xae, 0xa5, 0x28, 0x28, 0x0f, 0x6e, 0x6b, 0x83, 0x8d, 0xfa,
0x1c, 0x36, 0xc3, 0x68,
0x94, 0x94, 0xda, 0xce, 0xd4, 0xfa, 0x03, 0x62, 0x1a, 0xec, 0x75, 0x8e,
0x3a, 0xb4, 0xbc, 0x81,
0x9d, 0x67, 0x63, 0x1b, 0xa8, 0x5d, 0xb7, 0x8e, 0x8c, 0x5d, 0x83, 0xb7,
0xb8, 0x50, 0x83, 0x4d,
0x86, 0xb2, 0xea, 0x66, 0x66, 0xcc, 0xc7, 0x63, 0xbd, 0x3d, 0x93, 0x58,
0xf7, 0x31, 0x74, 0x5c,
0xc0, 0xbe, 0x33, 0xc9, 0x32, 0x3e, 0x5f, 0x3f, 0x1b, 0xf6, 0xc0, 0xfa,
0x04, 0xd6, 0x86, 0xb6,
0x96, 0xb1, 0x82, 0x93, 0xba, 0x7f, 0x8a, 0x39, 0x63, 0x0a, 0x55, 0x89,
0xf7, 0x37, 0x27, 0x27,
0xb3, 0x09, 0xec, 0xa1, 0x6b, 0x68, 0x33, 0x7c, 0x56, 0xf3, 0xc7, 0x14,
0x72, 0xea, 0x14, 0xbc,
0x69, 0xa3, 0x96, 0x64, 0xa9, 0xbe, 0x17, 0x32, 0xd9, 0xec, 0xad, 0x23,
0x27, 0x4d, 0xa0, 0x67,
0x03, 0x5e, 0x6f, 0xe5, 0x7a, 0x32, 0x79, 0xb8, 0x37, 0x5c, 0x6c, 0x42,
0x22, 0x75, 0x77, 0x2d,
0xcf, 0x6f, 0x8d, 0x5a, 0xf7, 0xb3, 0x6d, 0x17, 0xef, 0x31, 0x50, 0xf9,
0xb3, 0xfc, 0x0f, 0x7b,
0x40, 0xb1, 0xae, 0x8e, 0x36, 0xe1, 0x4b, 0xe5, 0x50, 0xf0, 0xae, 0xa3,
0xf2, 0x7d, 0x8c, 0xae,
0xd3, 0x14, 0xc5, 0x55, 0xb4, 0xe4, 0xfb, 0xf4, 0x46, 0x41, 0x65, 0xad,
0xae, 0xba, 0x94, 0xef,
0x58, 0xf9, 0xa8, 0xa4, 0xbe, 0x5e, 0xaa, 0x69, 0xfa, 0xda, 0xa0, 0x09,
0x3f, 0xc0, 0x42, 0x46,
0xbd, 0x8c, 0xc1, 0x66, 0x61, 0x33, 0x1e, 0x8d, 0x72, 0xda, 0x6b, 0x1c,
0x6a, 0xe6, 0x06, 0xf6,
0xcd, 0xa6, 0x36, 0xd8, 0x0a, 0x85, 0xd9, 0xac, 0x52, 0xa1, 0xef, 0xe0,
0x95, 0xeb, 0x3b, 0xb8,
0x25, 0xc4, 0xd9, 0x62, 0xc6, 0xaf, 0xc5, 0x4b, 0xf2, 0x2c, 0x3d, 0xe5,
0x50, 0x79, 0x82, 0x1c,
0xa4, 0xee, 0xe2, 0x7b, 0x5b, 0x6b, 0x38, 0x45, 0xdd, 0xc2, 0x19, 0xe0,
0x5e, 0xae, 0xbb, 0xf9,
0x7c, 0x3b, 0xf8, 0xb3, 0xc6, 0x9d, 0x72, 0x0f, 0x5c, 0x2b, 0x9e, 0x56,
0xe0, 0xb3, 0x25, 0x96,
0x39, 0x95, 0x96, 0x4f, 0xf9, 0xd4, 0x35, 0x2b, 0xa8, 0xf3, 0x36, 0xe0,
0x11, 0xbe, 0xab, 0x95,
0x63, 0x03, 0xdf, 0xdf, 0xab, 0xa8, 0x08, 0x17, 0xc0, 0xf1, 0x56, 0x4d,
0x53, 0xdd, 0x39, 0xf7,
0xf6, 0x4f, 0xa4, 0x52, 0x9b, 0x4c, 0xcf, 0x16, 0x46, 0xd8, 0x7c, 0xe4,
0x29, 0xe4, 0x1c, 0xbe,
0x50, 0xfb, 0xf3, 0x16, 0x74, 0x66, 0xf8, 0xd1, 0xac, 0x93, 0x76, 0x70,
0x7d, 0x0f, 0xb8, 0x9b,
0xeb, 0x21, 0xa8, 0x24, 0x63, 0xc7, 0x75, 0xee, 0x8a, 0xbe, 0x09, 0x2d,
0x4c, 0xf0, 0x91, 0x77,
0x02, 0x36, 0xcb, 0xd6, 0xf7, 0x13, 0x95, 0xf6, 0xd6, 0xeb, 0xb8, 0xab,
0xb4, 0x70, 0x98, 0x06,
0x8f, 0xab, 0xe9, 0x5b, 0x8f, 0x3c, 0x36, 0x1f, 0x99, 0x0d, 0x72, 0xf4,
0xba, 0x00, 0x56, 0xd8,
0xc1, 0xc8, 0xc9, 0x52, 0x63, 0x4c, 0x93, 0xc4, 0x9a, 0xce, 0x89, 0xe1,
0xce, 0x3b, 0x22, 0x6a,
0xed, 0xea, 0x3e, 0x64, 0x25, 0xfe, 0xb2, 0x93, 0xde, 0xb6, 0xd8, 0x86,
0x1c, 0xd9, 0x3e, 0xcf,
0x7a, 0xca, 0x38, 0x29, 0x96, 0x22, 0x79, 0x83, 0xbe, 0xef, 0x6e, 0xed,
0x29, 0x47, 0xfa, 0xe5,
0xda, 0x33, 0xbd, 0xad, 0xa5, 0x8c, 0xce, 0x42, 0x27, 0xcb, 0xb0, 0xf3,
0x6c, 0xd6, 0x2e, 0xd5,
0x99, 0xb0, 0x50, 0xdf, 0xab, 0x99, 0xaf, 0x6b, 0xf0, 0x1d, 0x68, 0xab,
0x82, 0x6a, 0xbb, 0x24,
0xc0, 0xb3, 0xa3, 0x72, 0x62, 0x20, 0x1e, 0xbe, 0x5f, 0x46, 0x0b, 0x33,
0x7d, 0xe8, 0x16, 0xc1,
0xf3, 0x5f, 0xc9, 0xa2, 0x15, 0x96, 0x96, 0x12, 0x38, 0x2d, 0xd0, 0xfa,
0xdc, 0x41, 0x5c, 0xaa,
0xb3, 0x6c, 0xb1, 0x85, 0xd2, 0x33, 0x78, 0xf9, 0xcb, 0xf4, 0x2d, 0xc1,
0xf6, 0xc5, 0x96, 0xa7,
0x59, 0x25, 0xf4, 0x94, 0x93, 0xa7, 0x57, 0x61, 0xed, 0x15, 0xcc, 0xf1,
0xe5, 0xa0, 0x42, 0x1e,
0x81, 0xfb, 0xd5, 0xf4, 0xae, 0x06, 0xeb, 0xe1, 0x63, 0x07, 0x54, 0x5e,
0x36, 0xf5, 0xb3, 0x11,
0x99, 0xc4, 0x47, 0xde, 0xe1, 0xd0, 0xdf, 0xa6, 0x47, 0xa8, 0x53, 0xc2,
0x62, 0x2a, 0x51, 0xab,
0x64, 0xa5, 0xe4, 0x55, 0xb5, 0x6b, 0x2d, 0xa2, 0xd5, 0xe1, 0x33, 0x2f,
0x92, 0xca, 0x76, 0xab,
0x85, 0xb2, 0x07, 0x7b, 0xe0, 0x7b, 0x82, 0x4c, 0x34, 0xa6, 0x48, 0x5c,
0x4d, 0xe7, 0x84, 0x6e,
0xb3, 0xc2, 0x22, 0xc6, 0x4b, 0xb5, 0xbd, 0x0a, 0x9e, 0x1b, 0x39, 0xd5,
0xed, 0x0e, 0x88, 0x8d,
0x58, 0x26, 0xcf, 0xe7, 0x69, 0x77, 0x01, 0xb9, 0xcc, 0x0e, 0xf2, 0xfc,
0x9e, 0x82, 0x8f, 0xc3,
0x53, 0xd6, 0x63, 0xe3, 0x31, 0x70, 0x63, 0xfd, 0x89, 0xc6, 0x53, 0x54,
0xad, 0x51, 0xa5, 0xdf,
0x05, 0x70, 0x68, 0xb8, 0x7e, 0xd6, 0x41, 0x7f, 0x0f, 0x7c, 0x2e, 0xc1,
0x32, 0x8e, 0x00, 0xcf,
0xd5, 0xc7, 0x51, 0x7b, 0xcd, 0x64, 0xcc, 0x5e, 0x6c, 0xdb, 0xa8, 0xef,
0xee, 0x7b, 0x7e, 0xf2,
0x99, 0xd1, 0x81, 0x88, 0x1f, 0xeb, 0x33, 0xaf, 0x80, 0xb5, 0x1a, 0xf4,
0xdf, 0x32, 0x6e, 0x44,
0x0b, 0x63, 0x2d, 0x3d, 0x85, 0xf2, 0x34, 0x5c, 0xa8, 0x3b, 0x14, 0x2b,
0xe0, 0xc2, 0xf7, 0x0d,
0x0a, 0xf5, 0x54, 0xc9, 0x86, 0x2f, 0x2a, 0xbb, 0x14, 0xfa, 0xf5, 0x8d,
0x93, 0x9e, 0xd8, 0x69,
0x9f, 0xec, 0x35, 0xb1, 0xc7, 0x47, 0x3b, 0x4d, 0xe4, 0xe3, 0x5c, 0x1f,
0x0e, 0x9e, 0x83, 0xfe,
0x2e, 0xf7, 0xa8, 0x9d, 0xf0, 0x91, 0xeb, 0xd3, 0xef, 0x20, 0xd2, 0x32,
0xf5, 0x53, 0x92, 0x5c,
0x9f, 0x75, 0xc6, 0xcb, 0x7d, 0x5c, 0x7b, 0xfc, 0xa8, 0x2b, 0xbc, 0x42,
0x14, 0x54, 0x48, 0x95,
0x31, 0x49, 0x62, 0x6a, 0xbb, 0x24, 0x76, 0x9b, 0xd5, 0x39, 0x22, 0xa9,
0xa0, 0x2a, 0xaf, 0x4c,
0x3f, 0xe5, 0x69, 0x81, 0xb3, 0xb6, 0xd8, 0x8f, 0xb6, 0x1a, 0xd0, 0x44,
0x9e, 0xcf, 0x4e, 0x94,
0x1b, 0xf0, 0x0d, 0x21, 0x3b, 0xfb, 0xd3, 0x16, 0x7d, 0x3a, 0x1c, 0x63,
0x19, 0x91, 0xab, 0xdf,
0x99, 0xb2, 0x41, 0xc1, 0xfa, 0xb6, 0x52, 0x1e, 0xbc, 0x3f, 0x48, 0xc6,
0x53, 0x2b, 0xec, 0xd5,
0x92, 0xb5, 0x7d, 0xdf, 0x2b, 0x0f, 0xdf, 0xf8, 0x3b, 0xde, 0xbf, 0x1f,
0xec, 0xc4, 0x3b, 0xd3,
0x7c, 0xfa, 0x62, 0xe5, 0x79, 0xfd, 0xac, 0xd8, 0xee, 0xf7, 0x7e, 0x56,
0x0a, 0x9a, 0xdf, 0xc5,
0x8e, 0x51, 0x4e, 0xdd, 0xee, 0xcb, 0x5b, 0xbd, 0x96, 0x68, 0x9d, 0x7e,
0x8f, 0x67, 0xac, 0x9f,
0x3c, 0x79, 0xc4, 0xc7, 0x34, 0x3c, 0xae, 0xc8, 0xef, 0x9d, 0x2a, 0x97,
0x4c, 0x07, 0x02, 0xea,
0x46, 0x61, 0x3b, 0x9e, 0x90, 0xe9, 0x33, 0x7e, 0x20, 0xf2, 0xef, 0x85,
0x63, 0x57, 0xff, 0xcb,
0xd4, 0x0f, 0xa3, 0x7d, 0xb4, 0x97, 0xa7, 0xdf, 0xfc, 0xf2, 0xdf, 0xd9,
0x53, 0x38, 0x5f, 0xae,
0x34, 0x67, 0x59, 0xd1, 0xcc, 0x9e, 0x33, 0x5e, 0xca, 0x8c, 0x2a, 0x89,
0xc2, 0x66, 0xed, 0xaa,
0xbb, 0xa6, 0xf6, 0x2e, 0xa9, 0xcc, 0x2a, 0xd1, 0x4f, 0xe3, 0x76, 0x06,
0xbc, 0x7b, 0x7a, 0x10,
0x3a, 0x4d, 0xfa, 0xee, 0x6a, 0x46, 0x80, 0xb7, 0x34, 0xd5, 0xfb, 0x8c,
0xde, 0xdf, 0xb2, 0xf0,
0xe5, 0xed, 0xac, 0xb2, 0x06, 0x4d, 0xa6, 0x59, 0xc6, 0x67, 0x04, 0x98,
0x6b, 0xc0, 0x63, 0x12,
0xba, 0x70, 0xad, 0xb2, 0x8b, 0xbc, 0x19, 0xd9, 0x66, 0x54, 0x0e, 0xb9,
0x36, 0x01, 0x3f, 0x3b,
0x08, 0xf6, 0x92, 0xa1, 0x92, 0x2d, 0x7d, 0x99, 0x9c, 0x40, 0x63, 0xc9,
0x41, 0xe3, 0x65, 0xa4,
0x7e, 0x27, 0xd1, 0xbb, 0x56, 0x2c, 0x1e, 0xb8, 0x0d, 0x3d, 0x57, 0xe1,
0x39, 0x5e, 0x8a, 0xd9,
0xe4, 0x80, 0x06, 0xbd, 0x56, 0x13, 0x76, 0x49, 0x69, 0xc3, 0x4f, 0x36,
0xb6, 0x99, 0x88, 0x7f,
0x8c, 0x27, 0x97, 0xa5, 0xb7, 0x91, 0xe9, 0x60, 0xd0, 0xfb, 0xbb, 0x3b,
0xf5, 0x5d, 0x01, 0x2b,
0x9d, 0x7e, 0xc4, 0xea, 0x2b, 0xee, 0x19, 0x07, 0xf5, 0x5b, 0x5c, 0xe9,
0x54, 0x25, 0x99, 0x41,
0xdf, 0x74, 0x4d, 0xd7, 0xef, 0x7d, 0xa9, 0x7b, 0x45, 0x07, 0x02, 0xae,
0x73, 0x84, 0xd3, 0x29,
0x79, 0xdf, 0x28, 0x97, 0xc8, 0xda, 0x2e, 0x09, 0xed, 0xaa, 0xc3, 0x53,
0xfe, 0x54, 0x51, 0x99,
0x5a, 0xa8, 0xdf, 0x91, 0x99, 0xab, 0xef, 0x9e, 0xb6, 0x45, 0x0b, 0x56,
0x9b, 0x43, 0xa5, 0x9c,
0xae, 0x9f, 0xfc, 0x59, 0x91, 0xca, 0x6a, 0x03, 0xb0, 0x8e, 0xf7, 0xf7,
0x7e, 0xfa, 0xce, 0xe8,
0x7e, 0x3c, 0xb6, 0xa7, 0x7e, 0x4a, 0x96, 0x1c, 0x10, 0xea, 0x5e, 0xed,
0xdf, 0xe5, 0x7e, 0xf6,
0xef, 0xc3, 0xee, 0x35, 0x5e, 0x25, 0xd2, 0xd4, 0x73, 0x6c, 0xdf, 0x71,
0x59, 0xd4, 0x2b, 0x33,
0xf4, 0x98, 0xc3, 0xfa, 0xdd, 0x87, 0x31, 0x96, 0x11, 0xea, 0x3d, 0xc4,
0x44, 0xfc, 0x63, 0x33,
0x36, 0x4b, 0xf4, 0xe3, 0x6c, 0x34, 0xf9, 0x6f, 0x33, 0xde, 0x19, 0x6f,
0x69, 0x4b, 0xc3, 0x66,
0xf3, 0xe0, 0xed, 0x10, 0xd9, 0xa7, 0x11, 0x7b, 0xfb, 0xf3, 0x96, 0x06,
0xc7, 0xb5, 0xe8, 0xb7,
0x42, 0x3f, 0xb9, 0x4c, 0xf6, 0x93, 0xe9, 0x70, 0x40, 0xcd, 0x28, 0xec,
0x45, 0x37, 0x49, 0x3e,
0x74, 0xfa, 0x60, 0xf7, 0x66, 0xcb, 0x8c, 0x03, 0x44, 0xf6, 0x20, 0xea,
0xc5, 0xb6, 0xfa, 0xf3,
0xcc, 0xc8, 0xa5, 0x4a, 0x7b, 0x9a, 0x88, 0x0c, 0xbc, 0xc2, 0x09, 0x5d,
0x89, 0x15, 0x1a, 0x25,
0x32, 0x4a, 0xc5, 0x99, 0x7a, 0xef, 0x6a, 0x52, 0x4a, 0x72, 0x81, 0xe1,
0xd0, 0xf7, 0x60, 0x8f,
0xb6, 0x79, 0xb2, 0xe4, 0xc2, 0x6b, 0xac, 0x5b, 0x23, 0xff, 0xa4, 0xe2,
0x49, 0x32, 0xff, 0xe6,
0x25, 0x41, 0x3f, 0x85, 0xf8, 0x03, 0x3b, 0x74, 0x9a, 0x65, 0xfd, 0xe7,
0x18, 0x79, 0x54, 0x8f,
0x9f, 0xce, 0x59, 0x6d, 0x28, 0x2d, 0x49, 0x8c, 0x8c, 0xb7, 0xcc, 0x4a,
0x42, 0x0b, 0x51, 0xd2,
0x89, 0x2a, 0x6c, 0x05, 0x94, 0x8f, 0x9a, 0x2b, 0xec, 0x23, 0x2e, 0x22,
0x7d, 0x64, 0x51, 0x6f,
0xaa, 0x3f, 0x84, 0x24, 0x47, 0xf5, 0xb8, 0x16, 0xf2, 0xa8, 0x7a, 0x56,
0xe5, 0xed, 0x7d, 0x1e,
0x8f, 0x79, 0x0d, 0xcf, 0x9c, 0x23, 0x43, 0x7c, 0xb4, 0x96, 0x0c, 0x9f,
0x45, 0x44, 0x5a, 0x3d,
0x19, 0xdd, 0xaa, 0xfb, 0xde, 0x9c, 0xc2, 0x8e, 0x6a, 0x4a, 0x3b, 0xe1,
0x64, 0x84, 0x7e, 0x47,
0xc2, 0xf3, 0x57, 0x20, 0x49, 0xd0, 0xeb, 0xcd, 0xce, 0xa9, 0xf6, 0xfb,
0x68, 0x3f, 0x9d, 0xba,
0x64, 0x3a, 0x12, 0x10, 0xea, 0xf9, 0xd4, 0x0a, 0x1f, 0x6f, 0x4b, 0xa5,
0xb2, 0xac, 0xb6, 0x48,
0xa6, 0x64, 0x6b, 0xa1, 0x32, 0x53, 0x7f, 0x77, 0x9e, 0xc8, 0xb8, 0x44,
0x1f, 0x6d, 0xa8, 0xb7,
0x34, 0x86, 0x72, 0x76, 0x18, 0x80, 0x8f, 0x05, 0x5b, 0xe3, 0x0c, 0x3b,
0xad, 0x5d, 0x1c, 0x46,
0xa1, 0xbc, 0xa8, 0xe2, 0x4c, 0xfd, 0x9d, 0xe0, 0xb4, 0xee, 0x31, 0x85,
0x76, 0x9b, 0x43, 0xbd,
0xc5, 0xb9, 0x5a, 0xce, 0x62, 0xd5, 0x40, 0x50, 0xbc, 0x55, 0xa3, 0xc1,
0x1e, 0x44, 0xb9, 0x4b,
0xc6, 0x68, 0xe2, 0xe4, 0x77, 0xc8, 0x93, 0xcd, 0x09, 0xf2, 0x2e, 0x5d,
0xc7, 0xdf, 0xcd, 0xff,
0xf1, 0x70, 0x78, 0x52, 0x8f, 0x57, 0xcf, 0x5f, 0x9e, 0xa5, 0x9e, 0xef,
0x81, 0xd7, 0x7b, 0xfe,
0xc2, 0x63, 0x0c, 0x9f, 0x9f, 0x92, 0xce, 0xf2, 0xbf, 0xe8, 0x7b, 0x8d,
0x0f, 0xfd, 0xe3, 0xf8,
0xe5, 0x26, 0x22, 0xe7, 0x2e, 0x93, 0x96, 0xaa, 0xac, 0xbb, 0xe0, 0x47,
0x47, 0x4c, 0x0e, 0xf6,
0xe1, 0x8f, 0xf7, 0x59, 0xfa, 0xef, 0xc2, 0x32, 0xa7, 0xe4, 0x18, 0x51,
0x5d, 0x8a, 0x7f, 0x78,
0xdb, 0x55, 0xcf, 0x20, 0xe2, 0x76, 0x35, 0xff, 0xde, 0x69, 0xb6, 0xdd,
0x29, 0x8f, 0xd2, 0xa6,
0x78, 0x3b, 0xc6, 0x5a, 0x6b, 0xb1, 0xf3, 0xed, 0xcc, 0xea, 0xa5, 0xff,
0x8e, 0x7f, 0x00, 0xa7,
0xd9, 0xee, 0xf2, 0x00, 0xb5, 0xdc, 0x21, 0xb4, 0xdb, 0xd3, 0x32, 0xcb,
0x2a, 0x53, 0x60, 0xbc,
0x86, 0x57, 0x45, 0x5b, 0xf8, 0xbe, 0x4b, 0xfe, 0xc2, 0x19, 0xd8, 0x77,
0xfc, 0x31, 0x46, 0x6d,
0xc1, 0x93, 0xd4, 0x59, 0x61, 0xa8, 0xe9, 0x27, 0x63, 0xf0, 0xc9, 0x27,
0xf4, 0x1b, 0x2b, 0xc9,
0xfa, 0x39, 0x52, 0x30, 0x9c, 0xd7, 0x6f, 0x69, 0xd8, 0x88, 0xab, 0x11,
0xb5, 0x5d, 0x13, 0x5c,
0xef, 0x11, 0x87, 0x8d, 0xca, 0x34, 0x72, 0x0d, 0xf5, 0xde, 0x73, 0x36,
0xfd, 0x67, 0x7c, 0x9e,
0xac, 0x7b, 0x71, 0x12, 0xad, 0x6d, 0x60, 0xbd, 0x7b, 0x24, 0x0c, 0xad,
0xb7, 0x97, 0x9b, 0xf1,
0x9c, 0x3a, 0x72, 0x80, 0xaa, 0x38, 0x5c, 0x3b, 0x96, 0x7a, 0xb3, 0x76,
0xb5, 0xf9, 0xdc, 0xfe,
0x14, 0x9f, 0x0e, 0xea, 0xea, 0xe5, 0x3e, 0xc6, 0x87, 0x11, 0x59, 0x1d,
0xe5, 0x46, 0xfe, 0x7d,
0x8c, 0x91, 0x4b, 0xb1, 0xd1, 0xeb, 0x7e, 0x2b, 0x9d, 0x82, 0xfe, 0x72,
0x76, 0xb0, 0x74, 0xf7,
0x3b, 0xd9, 0x8a, 0x5e, 0x11, 0x7e, 0xef, 0xed, 0x3f, 0x46, 0x85, 0x60,
0x33, 0xfb, 0xb3, 0xc8,
0xff, 0x4d, 0x50, 0x39, 0x0d, 0xad, 0x83, 0xec, 0x44, 0x19, 0x26, 0x32,
0xf5, 0xb3, 0x4b, 0xf5,
0xd4, 0xae, 0xde, 0xa7, 0x6d, 0x2a, 0xb6, 0xf2, 0xd0, 0x3a, 0xce, 0x8e,
0x53, 0x8f, 0xae, 0xfa,
0xcb, 0xe3, 0xd8, 0xf2, 0x51, 0xec, 0x34, 0x80, 0xda, 0x60, 0x1f, 0x3d,
0x2d, 0xfa, 0x59, 0x92,
0x97, 0x07, 0xab, 0x4c, 0x81, 0xa0, 0x9e, 0x9c, 0x2f, 0xd6, 0xbb, 0xba,
0x67, 0x46, 0x25, 0xf9,
0xf2, 0x4c, 0xc0, 0x71, 0x6b, 0xd0, 0xf0, 0x13, 0xd2, 0x15, 0x74, 0x46,
0x13, 0x37, 0x92, 0x11,
0x7b, 0xb0, 0xea, 0x26, 0xe8, 0xbf, 0x1e, 0x94, 0xfe, 0x69, 0x79, 0x1b,
0x3d, 0x64, 0xc9, 0x58,
0xc3, 0x26, 0xc3, 0xdc, 0x36, 0x53, 0x75, 0x48, 0x9f, 0xa2, 0xbc, 0x9c,
0x2c, 0xfd, 0xf6, 0xfd,
0x62, 0x79, 0x57, 0xce, 0x06, 0xc1, 0xeb, 0xfa, 0xfd, 0x8c, 0xdd, 0x68,
0x76, 0x0e, 0x1e, 0xd9,
0x84, 0xef, 0xb8, 0x5a, 0xcf, 0xb8, 0x39, 0x54, 0xfd, 0x67, 0xf5, 0xe5,
0x9d, 0x71, 0x06, 0x4d,
0xef, 0x45, 0xd7, 0xf3, 0xf5, 0x9d, 0xc3, 0xe5, 0xfa, 0x29, 0xb1, 0x7a,
0x97, 0xe3, 0x8d, 0x00,
0xf4, 0xcf, 0x58, 0x68, 0x9d, 0xd6, 0xbf, 0x9d, 0xf5, 0xa1, 0x77, 0xc6,
0x0d, 0x57, 0xef, 0x19,
0x68, 0x78, 0x56, 0xb4, 0xce, 0x73, 0xf5, 0xf9, 0x8e, 0xf6, 0x50, 0x7b,
0xdd, 0x4f, 0x1a, 0xa5,
0xc7, 0x66, 0xbd, 0xef, 0x1f, 0xc2, 0x63, 0x4e, 0xb9, 0xe9, 0x58, 0x69,
0xb5, 0x95, 0xa9, 0xad,
0x56, 0xac, 0x7c, 0xab, 0xcf, 0x6f, 0x04, 0x19, 0xaf, 0x68, 0x29, 0x3f,
0xde, 0xe2, 0x7e, 0x5a,
0xb9, 0x4c, 0x3f, 0xf3, 0x3b, 0x13, 0x50, 0x17, 0x56, 0xbc, 0x47, 0xb5,
0x41, 0x2d, 0x44, 0x54,
0x0d, 0x31, 0x6d, 0xd6, 0x2d, 0xa5, 0x6b, 0x55, 0x46, 0x6a, 0xba, 0x91,
0xa6, 0xdf, 0x1e, 0x3a,
0x8a, 0x5d, 0xcf, 0x07, 0xc4, 0x05, 0x0d, 0xf5, 0xde, 0xc9, 0x3b, 0xfa,
0x0d, 0x95, 0xb7, 0xdc,
0x2d, 0x6f, 0x5a, 0x70, 0x41, 0xbf, 0xe1, 0x63, 0x1d, 0xff, 0xa6, 0x7e,
0x8b, 0xc7, 0x35, 0x47,
0xfd, 0xff, 0x96, 0xdf, 0x28, 0x5f, 0xfa, 0x6f, 0x06, 0xa5, 0x76, 0x3e,
0xe0, 0x5a, 0x17, 0x7c,
0xd6, 0xf1, 0xef, 0xbb, 0x12, 0xde, 0xde, 0x72, 0x23, 0xd8, 0xac, 0x60,
0xdc, 0xb6, 0xa5, 0x74,
0xb9, 0xf1, 0xde, 0x15, 0x5d, 0xda, 0x78, 0x47, 0x6b, 0xe3, 0xc2, 0x65,
0xe8, 0x9f, 0x97, 0x0f,
0xc9, 0x64, 0x54, 0x2a, 0x46, 0xa6, 0x0c, 0xf6, 0xd8, 0xcc, 0xbd, 0xa7,
0x65, 0xda, 0x93, 0x1d,
0xc9, 0xd8, 0xcc, 0x2e, 0x9f, 0x6a, 0x5a, 0x21, 0xfc, 0x56, 0xf0, 0x29,
0xf5, 0x21, 0xb5, 0x17,
0x31, 0x35, 0xb0, 0xc6, 0x6b, 0xb3, 0x6e, 0xb3, 0xba, 0x46, 0x8c, 0x74,
0x8c, 0xb1, 0xab, 0x9d,
0x31, 0x82, 0xea, 0xe9, 0x22, 0xf1, 0xf8, 0xf3, 0xe1, 0x03, 0xf9, 0x38,
0xf4, 0x4d, 0x11, 0xd7,
0x80, 0xef, 0xd8, 0xc5, 0xe3, 0x24, 0xd1, 0x18, 0x23, 0x03, 0x2c, 0x71,
0xa6, 0xce, 0x69, 0xb7,
0x97, 0x8f, 0x49, 0x8b, 0x33, 0xe2, 0xe8, 0x7d, 0x41, 0x56, 0xc9, 0xd7,
0xf2, 0x2f, 0x74, 0xfd,
0x73, 0xe0, 0x13, 0x72, 0xc0, 0x0a, 0x7d, 0xaf, 0x2e, 0x84, 0x9f, 0x86,
0x4d, 0xfa, 0x6f, 0x3d,
0xe3, 0x8c, 0x44, 0xe9, 0x67, 0xb5, 0x19, 0xe8, 0x3a, 0xed, 0xb1, 0x98,
0x04, 0x7b, 0xb4, 0x43,
0xfd, 0x65, 0xe4, 0x10, 0x2a, 0x8c, 0x6f, 0x88, 0x8e, 0x8f, 0xae, 0x19,
0x17, 0xc9, 0xc6, 0x71,
0x32, 0x8c, 0xda, 0x3e, 0x84, 0x9f, 0x8e, 0xd1, 0x54, 0xdf, 0xd1, 0xc4,
0x53, 0x9f, 0xda, 0xb0,
0x78, 0x9f, 0xef, 0x9a, 0x20, 0x3f, 0xf6, 0x2d, 0x88, 0xc9, 0x55, 0xdf,
0xa4, 0x13, 0x81, 0x96,
0xd7, 0x49, 0xab, 0x7c, 0x46, 0x2e, 0xbd, 0x16, 0xa8, 0x68, 0x4d, 0x22,
0x6e, 0x23, 0x43, 0xb8,
0x76, 0x18, 0xd1, 0xf2, 0x4c, 0x6d, 0x58, 0x82, 0xff, 0xf7, 0xff, 0x75,
0x9d, 0x34, 0x78, 0x4c,
0xa4, 0xe1, 0xfa, 0xe6, 0xaa, 0x7e, 0x9c, 0xad, 0xd4, 0x77, 0xc4, 0x7d,
0xfe, 0x13, 0x71, 0x51,
0x7e, 0xe4, 0x3c, 0x38, 0x44, 0x46, 0xb8, 0xbf, 0x0b, 0x2b, 0xd2, 0x1e,
0xe9, 0x08, 0x5d, 0xd7,
0x70, 0xd9, 0xa2, 0x1c, 0x6d, 0x6c, 0xa6, 0x63, 0x2d, 0x7c, 0xd4, 0x73,
0x32, 0xca, 0xfe, 0x82,
0x28, 0x0c, 0xe4, 0x04, 0xf8, 0xa5, 0xfe, 0x0b, 0xba, 0x2f, 0xae, 0x1a,
0xdf, 0x32, 0x6f, 0x89,
0x0c, 0xc6, 0x62, 0x8a, 0xd2, 0x8b, 0xf6, 0x91, 0xd2, 0xab, 0xac, 0x57,
0x7a, 0xaf, 0xf2, 0x5f,
0xfb, 0x7a, 0x2a, 0xbd, 0x7b, 0x45, 0xf7, 0xb4, 0xee, 0xe5, 0xbd, 0xd2,
0x2e, 0x37, 0xb6, 0x67,
0x39, 0xe3, 0x18, 0xdb, 0xd3, 0x6c, 0x7b, 0x32, 0xfd, 0x91, 0xca, 0x47,
0x52, 0x1f, 0xa9, 0xe8,
0xc1, 0xdc, 0x9e, 0xf4, 0xf7, 0xcc, 0xe8, 0xf9, 0x4b, 0xca, 0x54, 0xd6,
0x3b, 0xfd, 0xe1, 0xba,
0xf0, 0x98, 0x40, 0xdf, 0xb5, 0x19, 0x36, 0xe9, 0xd9, 0xa4, 0x17, 0xec,
0xc3, 0x1d, 0xc3, 0x65,
0xb8, 0x0c, 0x92, 0x01, 0xd4, 0x23, 0xea, 0xef, 0x51, 0xbf, 0xba, 0x0a,
0xa8, 0xbf, 0x83, 0x3d,
0x2b, 0x29, 0xd2, 0x87, 0x0c, 0x0b, 0x15, 0x03, 0xbb, 0x95, 0xdd, 0x93,
0xde, 0xb5, 0x21, 0x2c,
0x22, 0x2c, 0x74, 0x5d, 0xf3, 0x15, 0xf0, 0xfb, 0x36, 0x89, 0xb5, 0x5e,
0x05, 0x2f, 0xd8, 0x86,
0x1a, 0x43, 0xf5, 0x77, 0x04, 0x3c, 0xad, 0x9f, 0x98, 0xb4, 0xea, 0xbf,
0x66, 0xfd, 0xe6, 0x32,
0xf8, 0xd6, 0xfd, 0x2d, 0xaa, 0xd5, 0xd8, 0x6b, 0xa0, 0x0c, 0xd5, 0x18,
0x0e, 0x9d, 0xbb, 0x66,
0x86, 0x8f, 0x0e, 0x7d, 0x33, 0xe6, 0xf5, 0xfd, 0x5e, 0xdb, 0xae, 0x75,
0xff, 0x88, 0x1b, 0x6a,
0x1b, 0x22, 0xcf, 0x81, 0xc1, 0xc4, 0x5a, 0x0f, 0xf6, 0xb7, 0x55, 0x3a,
0x4f, 0xba, 0x6c, 0xd7,
0xf6, 0x1b, 0xa4, 0x3d, 0xdf, 0x4f, 0x7c, 0x58, 0xf2, 0x19, 0xdd, 0x97,
0x59, 0x6a, 0xee, 0x73,
0xf6, 0x61, 0x8e, 0xbe, 0x13, 0xc3, 0x93, 0xc2, 0xab, 0x43, 0xdf, 0x6f,
0x7b, 0xdd, 0xbf, 0xdb,
0x96, 0x58, 0xbb, 0xb3, 0xe2, 0xd9, 0xd4, 0x21, 0xf6, 0x41, 0x0e, 0xd7,
0x37, 0x32, 0xf4, 0x97,
0xa7, 0xa8, 0x4a, 0xb2, 0x65, 0x99, 0xbc, 0x1d, 0xf0, 0x6f, 0xf9, 0x2f,
0xca, 0x3e, 0xa9, 0x60,
0xf7, 0x7a, 0x52, 0x47, 0x98, 0x9e, 0x63, 0x0c, 0x96, 0xa1, 0xc5, 0x0f,
0x67, 0x87, 0xcf, 0xea,
0x36, 0x2a, 0xa4, 0xd1, 0x5f, 0x26, 0xd6, 0xc2, 0x67, 0x85, 0x47, 0x3c,
0x58, 0x3c, 0x30, 0x7b,
0xa0, 0x7d, 0x80, 0x0c, 0x70, 0x7f, 0xf7, 0xf0, 0x33, 0xd8, 0xe4, 0x31,
0x79, 0x1c, 0xdb, 0x64,
0x4a, 0x91, 0x4c, 0x90, 0x49, 0x52, 0xc6, 0x19, 0x3d, 0x9a, 0xfc, 0xf9,
0x88, 0x74, 0x97, 0xde,
0xc4, 0x97, 0x7b, 0xac, 0xf1, 0xac, 0x0c, 0xca, 0x7f, 0xca, 0x76, 0x9b,
0x33, 0x3c, 0xa2, 0x5b,
0x28, 0xc6, 0x7e, 0x59, 0xbb, 0x39, 0x6f, 0x8d, 0x78, 0xb4, 0x70, 0x60,
0xee, 0xb3, 0xf6, 0xfe,
0xe2, 0x85, 0x7a, 0x7a, 0xd7, 0x5b, 0x7a, 0x49, 0x4f, 0x62, 0xaf, 0x27,
0x9f, 0x9e, 0xd1, 0xdf,
0x28, 0x6d, 0x02, 0x1b, 0x0f, 0x32, 0x7a, 0x19, 0xf7, 0xcc, 0x08, 0x8f,
0x0a, 0xd9, 0xeb, 0xd7,
0x8a, 0xb7, 0x6e, 0xa3, 0x1e, 0x1c, 0xff, 0x74, 0x66, 0x7f, 0x5b, 0xbf,
0xfc, 0xbe, 0x46, 0x5f,
0x09, 0x0a, 0xfa, 0xfa, 0xd9, 0xfa, 0x3b, 0xfa, 0x16, 0x3e, 0x9e, 0x7b,
0x47, 0x7d, 0xd8, 0xe8,
0x50, 0x4e, 0xfc, 0xd5, 0xf3, 0xe4, 0xa8, 0x3b, 0x26, 0x3f, 0x9c, 0xd0,
0xd3, 0x20, 0xca, 0xf2,
0xfa, 0xe6, 0xf7, 0xb5, 0xf7, 0x71, 0xf4, 0x31, 0xfa, 0x88, 0xbe, 0xec,
0x7d, 0x1d, 0x7d, 0x6d,
0xfd, 0x1c, 0xfd, 0xed, 0xcf, 0x38, 0x9e, 0xa8, 0xbc, 0x2f, 0x45, 0xed,
0x85, 0xa1, 0xf8, 0xfa,
0x6d, 0xd8, 0x4d, 0xd9, 0x22, 0xac, 0xa1, 0xdb, 0xa8, 0x3b, 0x6a, 0xef,
0x8f, 0x7f, 0xa8, 0xf4,
0xb1, 0x8c, 0x7f, 0x16, 0xf6, 0x18, 0xdb, 0xa3, 0xb0, 0x7b, 0xee, 0xe3,
0xe3, 0xff, 0x91, 0xf5,
0xc0, 0xa4, 0xbb, 0x93, 0x6e, 0x65, 0xff, 0x53, 0x7b, 0x60, 0xb7, 0x50,
0x7c, 0xfd, 0x26, 0x6d,
0x17, 0xde, 0xc0, 0xd5, 0x88, 0x8d, 0xd4, 0xa5, 0x3e, 0x63, 0xa7, 0x90,
0xad, 0x42, 0x08, 0x21,
0x30, 0xfe, 0x1f, 0x7e, 0x26, 0xe7, 0x5b
};

View File

@ -1,228 +1,89 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube DVD
*
* softdev July 2006
* svpe & crunchy2 June 2007
* Tantric September 2008
*
* dvd.cpp
*
* DVD I/O functions
***************************************************************************/
****************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <dvd.h>
#include "snes9xGx.h"
#ifdef WII_DVD
extern "C" {
#include <di/di.h>
}
#endif
#include "memmap.h"
#include "menudraw.h"
#include "snes9xGX.h"
#include "unzip.h"
u64 dvddir = 0; // offset of currently selected file or folder
int dvddirlength = 0; // length of currently selected file or folder
u64 dvdrootdir = 0; // offset of DVD root
bool isWii = false;
#ifdef HW_DOL
/** DVD I/O Address base **/
volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000;
#endif
/****************************************************************************
* dvd_read
*
* Main DVD function, everything else uses this!
* returns: 1 - ok ; 0 - error
***************************************************************************/
#define ALIGN_FORWARD(x,align) ((typeof(x))((((uint32_t)(x)) + (align) - 1) & (~(align-1))))
#define ALIGN_BACKWARD(x,align) ((typeof(x))(((uint32_t)(x)) & (~(align-1))))
/** Due to lack of memory, we'll use this little 2k keyhole for all DVD operations **/
unsigned char DVDreadbuffer[2048] ATTRIBUTE_ALIGN (32);
unsigned char dvdbuffer[2048];
/**
* dvd_driveid
*
* Gets and returns the dvd driveid
**/
static unsigned char *inquiry=(unsigned char *)0x80000004;
int dvd_driveid()
{
dvd[0] = 0x2e;
dvd[1] = 0;
dvd[2] = 0x12000000;
dvd[3] = 0;
dvd[4] = 0x20;
dvd[5] = 0x80000000;
dvd[6] = 0x20;
dvd[7] = 3;
while( dvd[7] & 1 )
;
DCFlushRange((void *)0x80000000, 32);
return (int)inquiry[2];
}
/**
* dvd_read
*
* The only DVD function we need - you gotta luv gc-linux self-boots!
*/
int
dvd_read (void *dst, unsigned int len, u64 offset)
{
if (len > 2048)
return 0; /*** We only allow 2k reads **/
// don't read past the end of the DVD (1.5 GB for GC DVD, 4.7 GB for DVD)
if((offset < 0x57057C00) || (isWii && (offset < 0x118244F00LL)))
{
u8 * buffer = (u8 *)memalign(32, 0x8000);
u32 off_size = 0;
unsigned char *buffer = (unsigned char *) (unsigned int) DVDreadbuffer;
DCInvalidateRange ((void *) buffer, len);
if (len > 2048)
return 1; /*** We only allow 2k reads **/
#ifdef HW_DOL
dvd[0] = 0x2E;
dvd[1] = 0;
dvd[2] = 0xA8000000;
dvd[3] = (u32)(offset >> 2);
dvd[4] = len;
dvd[5] = (u32) buffer;
dvd[6] = len;
dvd[7] = 3;
DCInvalidateRange ((void *) buffer, len);
// Enable reading with DMA
while (dvd[7] & 1);
// Ensure it has completed
if (dvd[0] & 0x4)
return 0;
#else
off_size = offset - ALIGN_BACKWARD(offset,0x800);
if (DI_ReadDVD(
buffer,
(ALIGN_FORWARD(offset + len,0x800) - ALIGN_BACKWARD(offset,0x800)) >> 11,
(u32)(ALIGN_BACKWARD(offset, 0x800) >> 11)
))
return 0;
#endif
memcpy (dst, buffer+off_size, len);
free(buffer);
return 1;
}
return 0;
}
/****************************************************************************
* dvd_buffered_read
*
* the GC's dvd drive only supports offsets and length which are a multiple
* of 32 bytes additionally the max length of a read is 2048 bytes
* this function removes these limitations
* additionally the 7zip SDK does often read data in 1 byte parts from the
* DVD even when it could read 32 bytes. the dvdsf_buffer has been added to
* avoid having to read the same sector over and over again
***************************************************************************/
#define DVD_LENGTH_MULTIPLY 32
#define DVD_OFFSET_MULTIPLY 32
#define DVD_MAX_READ_LENGTH 2048
#define DVD_SECTOR_SIZE 2048
unsigned char dvdsf_buffer[DVD_SECTOR_SIZE];
u64 dvdsf_last_offset = 0;
u64 dvdsf_last_length = 0;
int dvd_buffered_read(void *dst, u32 len, u64 offset)
{
int ret = 0;
// only read data if the data inside dvdsf_buffer cannot be used
if(offset != dvdsf_last_offset || len > dvdsf_last_length)
if(offset < 0x57057C00 || (isWii == true && offset < 0x118244F00LL)) // don't read past the end of the DVD
{
memset(&dvdsf_buffer, '\0', DVD_SECTOR_SIZE);
ret = dvd_read(&dvdsf_buffer, len, offset);
dvdsf_last_offset = offset;
dvdsf_last_length = len;
offset >>= 2;
dvd[0] = 0x2E;
dvd[1] = 0;
dvd[2] = 0xA8000000;
dvd[3] = (u32)offset;
dvd[4] = len;
dvd[5] = (unsigned long) buffer;
dvd[6] = len;
dvd[7] = 3; /*** Enable reading with DMA ***/
while (dvd[7] & 1);
memcpy (dst, buffer, len);
}
else // Let's not read past end of DVD
return 0;
memcpy(dst, &dvdsf_buffer, len);
return ret;
}
if (dvd[0] & 0x4) /* Ensure it has completed */
return 0;
int dvd_safe_read(void *dst_v, u32 len, u64 offset)
{
unsigned char buffer[DVD_SECTOR_SIZE]; // buffer for one dvd sector
return 1;
// if read size and length are a multiply of DVD_(OFFSET,LENGTH)_MULTIPLY and length < DVD_MAX_READ_LENGTH
// we don't need to fix anything
if(len % DVD_LENGTH_MULTIPLY == 0 && offset % DVD_OFFSET_MULTIPLY == 0 && len <= DVD_MAX_READ_LENGTH)
{
int ret = dvd_buffered_read(buffer, len, offset);
memcpy(dst_v, &buffer, len);
return ret;
}
else
{
// no errors yet -> ret = 0
// the return value of dvd_read will be OR'd with ret
// because dvd_read does return 1 on error and 0 on success and
// because 0 | 1 = 1 ret will also contain 1 if at least one error
// occured and 0 otherwise ;)
int ret = 0; // return value of dvd_read
// we might need to fix all 3 issues
unsigned char *dst = (unsigned char *)dst_v; // gcc will not allow to use var[num] on void* types
u64 bytesToRead; // the number of bytes we still need to read & copy to the output buffer
u64 currentOffset; // the current dvd offset
u64 bufferOffset; // the current buffer offset
u64 i, j, k; // temporary variables which might be used for different stuff
// unsigned char buffer[DVD_SECTOR_SIZE]; // buffer for one dvd sector
currentOffset = offset;
bytesToRead = len;
bufferOffset = 0;
// fix first issue (offset is not a multiply of 32)
if(offset % DVD_OFFSET_MULTIPLY)
{
// calculate offset of the prior 32 byte position
i = currentOffset - (currentOffset % DVD_OFFSET_MULTIPLY);
// calculate the offset from which the data of the dvd buffer will be copied
j = currentOffset % DVD_OFFSET_MULTIPLY;
// calculate the number of bytes needed to reach the next DVD_OFFSET_MULTIPLY byte mark
k = DVD_OFFSET_MULTIPLY - j;
// maybe we'll only need to copy a few bytes and we therefore don't even reach the next sector
if(k > len)
{
k = len;
}
// read 32 bytes from the last 32 byte position
ret |= dvd_buffered_read(buffer, DVD_OFFSET_MULTIPLY, i);
// copy the bytes to the output buffer and update currentOffset, bufferOffset and bytesToRead
memcpy(&dst[bufferOffset], &buffer[j], k);
currentOffset += k;
bufferOffset += k;
bytesToRead -= k;
}
// fix second issue (more than 2048 bytes are needed)
if(bytesToRead > DVD_MAX_READ_LENGTH)
{
// calculate the number of 2048 bytes sector needed to get all data
i = (bytesToRead - (bytesToRead % DVD_MAX_READ_LENGTH)) / DVD_MAX_READ_LENGTH;
// read data in 2048 byte sector
for(j = 0; j < i; j++)
{
ret |= dvd_buffered_read(buffer, DVD_MAX_READ_LENGTH, currentOffset); // read sector
memcpy(&dst[bufferOffset], buffer, DVD_MAX_READ_LENGTH); // copy to output buffer
// update currentOffset, bufferOffset and bytesToRead
currentOffset += DVD_MAX_READ_LENGTH;
bufferOffset += DVD_MAX_READ_LENGTH;
bytesToRead -= DVD_MAX_READ_LENGTH;
}
}
// fix third issue (length is not a multiply of 32)
if(bytesToRead)
{
ret |= dvd_buffered_read(buffer, DVD_MAX_READ_LENGTH, currentOffset); // read 32 byte from the dvd
memcpy(&dst[bufferOffset], buffer, bytesToRead); // copy bytes to output buffer
}
//free(tmp);
return ret;
}
}
/** Minimal ISO Directory Definition **/
@ -236,391 +97,235 @@ int dvd_safe_read(void *dst_v, u32 len, u64 offset)
/** Minimal Primary Volume Descriptor **/
#define PVDROOT 0x9c
static int IsJoliet = 0;
u64 rootdir = 0;
int rootdirlength = 0;
/****************************************************************************
/** Global file entry table **/
FILEENTRIES filelist[MAXFILES];
/**
* Primary Volume Descriptor
*
* The PVD should reside between sector 16 and 31.
* This is for single session DVD only.
***************************************************************************/
*/
int
getpvd ()
{
int sector = 16;
u32 rootdir32;
unsigned char dvdbuffer[2048];
int sector = 16;
u32 rootdir32;
dvddir = dvddirlength = 0;
IsJoliet = -1;
rootdir = rootdirlength = 0;
IsJoliet = -1;
/** Look for Joliet PVD first **/
while (sector < 32)
while (sector < 32)
{
if (dvd_read (dvdbuffer, 2048, (u64)(sector << 11)))
{
if (dvd_read (&dvdbuffer, 2048, (u64)(sector << 11)))
{
if (memcmp (&dvdbuffer, "\2CD001\1", 8) == 0)
{
memcpy(&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
dvddir = (u64)rootdir32;
dvddir <<= 11;
dvdrootdir = dvddir;
memcpy (&dvddirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
IsJoliet = 1;
break;
}
}
else
return 0; /*** Can't read sector! ***/
sector++;
if (memcmp (&dvdbuffer, "\2CD001\1", 8) == 0)
{
memcpy(&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
rootdir = (u64)rootdir32;
rootdir <<= 11;
memcpy (&rootdirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
IsJoliet = 1;
break;
}
}
else
return 0; /*** Can't read sector! ***/
if (IsJoliet > 0) /*** Joliet PVD Found ? ***/
return 1;
sector++;
}
sector = 16;
if (IsJoliet > 0) /*** Joliet PVD Found ? ***/
return 1;
sector = 16;
/*** Look for standard ISO9660 PVD ***/
while (sector < 32)
while (sector < 32)
{
if (dvd_read (&dvdbuffer, 2048, sector << 11))
{
if (dvd_read (&dvdbuffer, 2048, sector << 11))
{
if (memcmp (&dvdbuffer, "\1CD001\1", 8) == 0)
{
memcpy (&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
dvddir = (u64)rootdir32;
dvddir <<= 11;
dvdrootdir = dvddir;
memcpy (&dvddirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
IsJoliet = 0;
break;
}
}
else
return 0; /*** Can't read sector! ***/
sector++;
if (memcmp (&dvdbuffer, "\1CD001\1", 8) == 0)
{
memcpy (&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
rootdir = (u64)rootdir32;
rootdir <<= 11;
memcpy (&rootdirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
IsJoliet = 0;
break;
}
}
return (IsJoliet == 0);
else
return 0; /*** Can't read sector! ***/
sector++;
}
return (IsJoliet == 0);
}
/****************************************************************************
* TestDVD()
*
* Tests if a ISO9660 DVD is inserted and available
***************************************************************************/
bool TestDVD()
{
if (!getpvd())
{
#ifdef HW_DOL
DVD_Mount();
#elif WII_DVD
DI_Mount();
while(DI_GetStatus() & DVD_INIT);
#endif
if (!getpvd())
return false;
}
return true;
}
/****************************************************************************
/**
* getentry
*
* Support function to return the next file entry, if any
* Declared static to avoid accidental external entry.
***************************************************************************/
*/
static int diroffset = 0;
static int
getentry (int entrycount, unsigned char dvdbuffer[])
getentry (int entrycount)
{
char fname[512]; /* Huge, but experience has determined this */
char *ptr;
char *filename;
char *filenamelength;
char *rr;
int j;
u32 offset32;
char fname[512]; /* Huge, but experience has determined this */
char *ptr;
char *filename;
char *filenamelength;
char *rr;
int j;
u32 offset32;
/* Basic checks */
if (entrycount >= MAXFILES)
return 0;
/* Basic checks */
if (entrycount >= MAXFILES)
return 0;
if (diroffset >= 2048)
return 0;
if (diroffset >= 2048)
return 0;
/** Decode this entry **/
if (dvdbuffer[diroffset]) /* Record length available */
if (dvdbuffer[diroffset]) /* Record length available */
{
/* Update offsets into sector buffer */
ptr = (char *) &dvdbuffer[0];
ptr += diroffset;
filename = ptr + FILENAME;
filenamelength = ptr + FILENAME_LENGTH;
/* Check for wrap round - illegal in ISO spec,
* but certain crap writers do it! */
if ((diroffset + dvdbuffer[diroffset]) > 2048)
return 0;
if (*filenamelength)
{
/* Update offsets into sector buffer */
ptr = (char *) &dvdbuffer[0];
ptr += diroffset;
filename = ptr + FILENAME;
filenamelength = ptr + FILENAME_LENGTH;
memset (&fname, 0, 512);
/* Check for wrap round - illegal in ISO spec,
* but certain crap writers do it! */
if ((diroffset + dvdbuffer[diroffset]) > 2048)
return 0;
if (!IsJoliet) /*** Do ISO 9660 first ***/
strcpy (fname, filename);
else
{ /*** The more tortuous unicode joliet entries ***/
if (*filenamelength)
for (j = 0; j < (*filenamelength >> 1); j++)
{
memset (&fname, 0, 512);
fname[j] = filename[j * 2 + 1];
}
if (!IsJoliet) /*** Do ISO 9660 first ***/
strcpy (fname, filename);
else
{ /*** The more tortuous unicode joliet entries ***/
for (j = 0; j < (*filenamelength >> 1); j++)
{
fname[j] = filename[j * 2 + 1];
}
fname[j] = 0;
fname[j] = 0;
if (strlen (fname) >= MAXJOLIET)
fname[MAXJOLIET] = 0;
if (strlen (fname) >= MAXJOLIET)
fname[MAXJOLIET - 1] = 0;
if (strlen (fname) == 0)
fname[0] = filename[0];
}
if (strlen (fname) == 0)
fname[0] = filename[0];
}
if (strlen (fname) == 0)
strcpy (fname, "ROOT");
else
{
if (fname[0] == 1)
strcpy (fname, "..");
else
{ /*
* Move *filenamelength to t,
* Only to stop gcc warning for noobs :)
*/
int t = *filenamelength;
fname[t] = 0;
}
}
if (strlen (fname) == 0) // root entry
{
fname[0] = 0; // we'll skip it by setting the filename to 0 length
}
else
{
if (fname[0] == 1)
{
if(dvddir == dvdrootdir) // at root already, don't show ..
fname[0] = 0;
else
strcpy (fname, "..");
}
else
{
/*
* Move *filenamelength to t,
* Only to stop gcc warning for noobs :)
*/
int t = *filenamelength;
fname[t] = 0;
}
}
/** Rockridge Check **/
rr = strstr (fname, ";");
if (rr != NULL)
*rr = 0;
rr = strstr (fname, ";");
if (rr != NULL)
*rr = 0;
strcpy (filelist[entrycount].filename, fname);
fname[MAXDISPLAY - 1] = 0;
strcpy (filelist[entrycount].displayname, fname);
strcpy (filelist[entrycount].filename, fname);
fname[MAXDISPLAY] = 0;
strcpy (filelist[entrycount].displayname, fname);
memcpy (&offset32, &dvdbuffer[diroffset + EXTENT], 4);
memcpy (&offset32,
&dvdbuffer[diroffset + EXTENT], 4);
filelist[entrycount].offset = (u64)offset32;
memcpy (&filelist[entrycount].length,
&dvdbuffer[diroffset + FILE_LENGTH], 4);
memcpy (&filelist[entrycount].flags,
&dvdbuffer[diroffset + FILE_FLAGS], 1);
filelist[entrycount].offset = (u64)offset32;
memcpy (&filelist[entrycount].length, &dvdbuffer[diroffset + FILE_LENGTH], 4);
memcpy (&filelist[entrycount].flags, &dvdbuffer[diroffset + FILE_FLAGS], 1);
filelist[entrycount].offset <<= 11;
filelist[entrycount].flags = filelist[entrycount].flags & 2;
filelist[entrycount].offset <<= 11;
filelist[entrycount].flags = filelist[entrycount].flags & 2;
/*** Prepare for next entry ***/
diroffset += dvdbuffer[diroffset];
return 1;
diroffset += dvdbuffer[diroffset];
return 1;
}
}
return 0;
}
return 0;
}
/****************************************************************************
* parseDVDdirectory
/**
* parsedirectory
*
* This function will parse the directory tree.
* It relies on dvddir and dvddirlength being pre-populated by a call to
* It relies on rootdir and rootdirlength being pre-populated by a call to
* getpvd, a previous parse or a menu selection.
*
* The return value is number of files collected, or 0 on failure.
***************************************************************************/
*/
int
ParseDVDdirectory ()
parsedirectory ()
{
int pdlength;
u64 pdoffset;
u64 rdoffset;
int len = 0;
int filecount = 0;
unsigned char dvdbuffer[2048];
int pdlength;
u64 pdoffset;
u64 rdoffset;
int len = 0;
int filecount = 0;
// initialize selection
selection = offset = 0;
pdoffset = rdoffset = rootdir;
pdlength = rootdirlength;
filecount = 0;
pdoffset = rdoffset = dvddir;
pdlength = dvddirlength;
filecount = 0;
// Clear any existing values
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
/*** Clear any existing values ***/
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
/*** Get as many files as possible ***/
while (len < pdlength)
while (len < pdlength)
{
if (dvd_read (&dvdbuffer, 2048, pdoffset) == 0)
return 0;
diroffset = 0;
while (getentry (filecount))
{
if (dvd_read (&dvdbuffer, 2048, pdoffset) == 0)
return 0;
diroffset = 0;
while (getentry (filecount, dvdbuffer))
{
if(strlen(filelist[filecount].filename) > 0 && filecount < MAXFILES)
filecount++;
}
len += 2048;
pdoffset = rdoffset + len;
if (filecount < MAXFILES)
filecount++;
}
// Sort the file list
qsort(filelist, filecount, sizeof(FILEENTRIES), FileSortCallback);
len += 2048;
pdoffset = rdoffset + len;
}
return filecount;
return filecount;
}
/****************************************************************************
* DirectorySearch
*
* Searches for the directory name specified within the current directory
* Returns the index of the directory, or -1 if not found
***************************************************************************/
int DirectorySearch(char dir[512])
{
for (int i = 0; i < maxfiles; i++ )
if (strcmp(filelist[i].filename, dir) == 0)
return i;
return -1;
}
/****************************************************************************
* SwitchDVDFolder
*
* Recursively searches for any directory path 'dir' specified
* Also loads the directory contents via ParseDVDdirectory()
* It relies on dvddir, dvddirlength, and filelist being pre-populated
***************************************************************************/
bool SwitchDVDFolder(char * dir, int maxDepth)
{
if(maxDepth > 8) // only search to a max depth of 8 levels
return false;
bool lastdir = false;
char * nextdir = NULL;
unsigned int t = strcspn(dir, "/");
if(t != strlen(dir))
nextdir = dir + t + 1; // next directory path to find
else
lastdir = true;
dir[t] = 0;
int dirindex = DirectorySearch(dir);
if(dirindex >= 0)
{
dvddir = filelist[dirindex].offset;
dvddirlength = filelist[dirindex].length;
maxfiles = ParseDVDdirectory();
if(lastdir)
return true;
else
return SwitchDVDFolder(nextdir, maxDepth++);
}
return false;
}
bool SwitchDVDFolder(char origdir[])
{
// make a copy of origdir so we don't mess with original
char dir[200];
strcpy(dir, origdir);
char * dirptr = dir;
// strip off leading/trailing slashes on the directory path
// we don't want to screw up our recursion!
if(dir[0] == '/')
dirptr = dirptr + 1;
if(dir[strlen(dir)-1] == '/')
dir[strlen(dir)-1] = 0;
return SwitchDVDFolder(dirptr, 0);
}
/****************************************************************************
* LoadDVDFile
* This function will load a file from DVD
* The values for offset and length are inherited from dvddir and
* dvddirlength.
*
* The buffer parameter should re-use the initial ROM buffer
***************************************************************************/
int
LoadDVDFile (unsigned char *buffer, int length)
{
int offset;
int blocks;
int i;
u64 discoffset;
char readbuffer[2048];
dvddir = filelist[selection].offset;
dvddirlength = filelist[selection].length;
// How many 2k blocks to read
blocks = dvddirlength / 2048;
offset = 0;
discoffset = dvddir;
ShowAction ((char*) "Loading...");
if(length > 0 && length <= 2048)
{
dvd_read (buffer, length, discoffset);
}
else // load whole file
{
dvd_read (readbuffer, 2048, discoffset);
if (!IsZipFile (readbuffer))
{
for (i = 0; i < blocks; i++)
{
dvd_read (readbuffer, 2048, discoffset);
memcpy (buffer + offset, readbuffer, 2048);
offset += 2048;
discoffset += 2048;
}
/*** And final cleanup ***/
if (dvddirlength % 2048)
{
i = dvddirlength % 2048;
dvd_read (readbuffer, 2048, discoffset);
memcpy (buffer + offset, readbuffer, i);
}
}
else
{
return UnZipBuffer (buffer, METHOD_DVD); // unzip from dvd
}
}
return dvddirlength;
}
/****************************************************************************
* uselessinquiry
*
@ -629,27 +334,23 @@ LoadDVDFile (unsigned char *buffer, int length)
* memcard interface.
*
* libOGC tends to foul up if you don't, and sometimes does if you do!
***************************************************************************/
#ifdef HW_DOL
****************************************************************************/
void uselessinquiry ()
{
dvd[0] = 0;
dvd[1] = 0;
dvd[2] = 0x12000000;
dvd[3] = 0;
dvd[4] = 0x20;
dvd[5] = 0x80000000;
dvd[6] = 0x20;
dvd[7] = 1;
while (dvd[7] & 1);
dvd[0] = 0;
dvd[1] = 0;
dvd[2] = 0x12000000;
dvd[3] = 0;
dvd[4] = 0x20;
dvd[5] = 0x80000000;
dvd[6] = 0x20;
dvd[7] = 1;
while (dvd[7] & 1);
}
/****************************************************************************
* dvd_motor_off( )
* Turns off DVD drive motor so it doesn't make noise (Gamecube only)
***************************************************************************/
void dvd_motor_off ()
void dvd_motor_off( )
{
dvd[0] = 0x2e;
dvd[1] = 0;
@ -666,48 +367,3 @@ void dvd_motor_off ()
dvd[1] = 0;
}
/****************************************************************************
* dvd_driveid
*
* Gets and returns the dvd driveid
***************************************************************************/
int dvd_driveid()
{
static unsigned char *inquiry=(unsigned char *)0x80000004;
dvd[0] = 0x2e;
dvd[1] = 0;
dvd[2] = 0x12000000;
dvd[3] = 0;
dvd[4] = 0x20;
dvd[5] = 0x80000000;
dvd[6] = 0x20;
dvd[7] = 3;
while( dvd[7] & 1 )
;
DCFlushRange((void *)0x80000000, 32);
return (int)inquiry[2];
}
#endif
/****************************************************************************
* SetDVDDriveType()
*
* Sets the DVD drive ID for use to determine disc size (1.5 GB or 4.7 GB)
***************************************************************************/
void SetDVDDriveType()
{
#ifdef HW_RVL
isWii = true;
#else
int drvid = dvd_driveid ();
if ( drvid == 4 || drvid == 6 || drvid == 8 )
isWii = false;
else
isWii = true;
#endif
}

View File

@ -1,31 +1,37 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube DVD
*
* softdev July 2006
* svpe & crunchy2 June 2007
* Tantric September 2008
*
* dvd.h
*
* DVD I/O functions
***************************************************************************/
****************************************************************************/
#ifndef _NGCDVD_H_
#define _NGCDVD_H_
#ifndef _NGCDVD_
#define _NGCDVD_
#define MAXJOLIET 255
#define MAXDISPLAY 54
typedef struct
{
u64 offset;
unsigned int length;
char flags;
char filename[MAXJOLIET + 1];
char displayname[MAXDISPLAY + 1];
} FILEENTRIES;
extern u64 rootdir;
extern int rootdirlength;
#define MAXFILES 2000 /** Restrict to 2000 files per dir **/
extern int getpvd ();
extern int parsedirectory ();
extern FILEENTRIES filelist[MAXFILES];
int dvd_driveid();
int getpvd ();
int ParseDVDdirectory ();
int LoadDVDFile (unsigned char *buffer, int length);
bool TestDVD();
int dvd_read (void *dst, unsigned int len, u64 offset);
int dvd_safe_read (void *dst, unsigned int len, u64 offset);
bool SwitchDVDFolder(char dir[]);
void SetDVDDriveType();
#ifdef HW_DOL
void dvd_motor_off ();
#endif
extern u64 dvddir;
extern int dvddirlength;
extern void dvd_motor_off ();
#endif

View File

@ -1,305 +0,0 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* softdev July 2006
* crunchy2 May 2007
* Michniewski 2008
* Tantric August 2008
*
* fileop.cpp
*
* FAT File operations
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <string.h>
#include <ogcsys.h>
#include <zlib.h>
#include "memmap.h"
#include "fileop.h"
#include "unzip.h"
#include "video.h"
#include "menudraw.h"
#include "filesel.h"
#include "sram.h"
#include "preferences.h"
#include "snes9xGX.h"
// FAT file pointer - the only one we should ever use!
FILE * fatfile;
/****************************************************************************
* fat_is_mounted
* to check whether FAT media are detected.
***************************************************************************/
bool FatIsMounted(PARTITION_INTERFACE partition) {
char prefix[] = "fatX:/";
prefix[3] = partition + '0';
DIR_ITER *dir = diropen(prefix);
if (dir) {
dirclose(dir);
return true;
}
return false;
}
/****************************************************************************
* changeFATInterface
* Checks if the device (method) specified is available, and
* sets libfat to use the device
***************************************************************************/
bool ChangeFATInterface(int method, bool silent)
{
bool devFound = false;
if(method == METHOD_SD)
{
// check which SD device is loaded
#ifdef HW_RVL
if (FatIsMounted(PI_INTERNAL_SD))
{
devFound = true;
fatSetDefaultInterface(PI_INTERNAL_SD);
fatEnableReadAhead (PI_INTERNAL_SD, 6, 64);
}
#endif
if (!devFound && FatIsMounted(PI_SDGECKO_A))
{
devFound = true;
fatSetDefaultInterface(PI_SDGECKO_A);
}
if(!devFound && FatIsMounted(PI_SDGECKO_B))
{
devFound = true;
fatSetDefaultInterface(PI_SDGECKO_B);
}
if(!devFound)
{
if(!silent)
WaitPrompt ((char *)"SD card not found!");
}
}
else if(method == METHOD_USB)
{
#ifdef HW_RVL
if(FatIsMounted(PI_USBSTORAGE))
{
devFound = true;
fatSetDefaultInterface(PI_USBSTORAGE);
fatEnableReadAhead (PI_USBSTORAGE, 6, 64);
}
else
{
if(!silent)
WaitPrompt ((char *)"USB flash drive not found!");
}
#endif
}
return devFound;
}
/***************************************************************************
* Browse FAT subdirectories
**************************************************************************/
int
ParseFATdirectory(int method)
{
int nbfiles = 0;
DIR_ITER *fatdir;
char filename[MAXPATHLEN];
struct stat filestat;
char msg[128];
// initialize selection
selection = offset = 0;
// Clear any existing values
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
// open the directory
fatdir = diropen(currentdir);
if (fatdir == NULL)
{
sprintf(msg, "Couldn't open %s", currentdir);
WaitPrompt(msg);
// if we can't open the dir, open root dir
sprintf(currentdir,"%s",ROOTFATDIR);
fatdir = diropen(currentdir);
if (fatdir == NULL)
{
sprintf(msg, "Error opening %s", currentdir);
WaitPrompt(msg);
return 0;
}
}
// index files/folders
while(dirnext(fatdir,filename,&filestat) == 0)
{
if(strcmp(filename,".") != 0)
{
memset(&filelist[nbfiles], 0, sizeof(FILEENTRIES));
strncpy(filelist[nbfiles].filename, filename, MAXPATHLEN);
strncpy(filelist[nbfiles].displayname, filename, MAXDISPLAY+1); // crop name for display
filelist[nbfiles].length = filestat.st_size;
filelist[nbfiles].flags = (filestat.st_mode & _IFDIR) == 0 ? 0 : 1; // flag this as a dir
nbfiles++;
}
}
// close directory
dirclose(fatdir);
// Sort the file list
qsort(filelist, nbfiles, sizeof(FILEENTRIES), FileSortCallback);
return nbfiles;
}
/****************************************************************************
* LoadFATFile
***************************************************************************/
int
LoadFATFile (char * rbuffer, int length)
{
char zipbuffer[2048];
char filepath[MAXPATHLEN];
u32 size;
/* Check filename length */
if (!MakeROMPath(filepath, METHOD_SD))
{
WaitPrompt((char*) "Maximum filepath length reached!");
return -1;
}
fatfile = fopen (filepath, "rb");
if (fatfile > 0)
{
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header)
{
fread (rbuffer, 1, length, fatfile);
size = length;
}
else // load whole file
{
fread (zipbuffer, 1, 2048, fatfile);
if (IsZipFile (zipbuffer))
{
size = UnZipBuffer ((unsigned char *)rbuffer, METHOD_SD); // unzip from FAT
}
else
{
// Just load the file up
fseek(fatfile, 0, SEEK_END);
size = ftell(fatfile); // get filesize
fseek(fatfile, 2048, SEEK_SET); // seek back to point where we left off
memcpy (rbuffer, zipbuffer, 2048); // copy what we already read
ShowProgress ((char *)"Loading...", 2048, size);
u32 offset = 2048;
while(offset < size)
{
offset += fread (rbuffer + offset, 1, (1024*512), fatfile); // read in 512K chunks
ShowProgress ((char *)"Loading...", offset, size);
}
}
}
fclose (fatfile);
return size;
}
else
{
WaitPrompt((char*) "Error opening file");
return 0;
}
}
/****************************************************************************
* LoadFATSzFile
* Loads the selected file # from the specified 7z into rbuffer
* Returns file size
***************************************************************************/
int
LoadFATSzFile(char * filepath, unsigned char * rbuffer)
{
u32 size;
fatfile = fopen (filepath, "rb");
if (fatfile > 0)
{
size = SzExtractFile(filelist[selection].offset, rbuffer);
fclose (fatfile);
return size;
}
else
{
WaitPrompt((char*) "Error opening file");
return 0;
}
}
/****************************************************************************
* Load savebuffer from FAT file
***************************************************************************/
int
LoadBufferFromFAT (char *filepath, bool silent)
{
int size = 0;
fatfile = fopen (filepath, "rb");
if (fatfile <= 0)
{
if ( !silent )
{
char msg[100];
sprintf(msg, "Couldn't open %s", filepath);
WaitPrompt (msg);
}
return 0;
}
// Just load the file up
fseek(fatfile, 0, SEEK_END); // go to end of file
size = ftell(fatfile); // get filesize
fseek(fatfile, 0, SEEK_SET); // go to start of file
fread (savebuffer, 1, size, fatfile);
fclose (fatfile);
return size;
}
/****************************************************************************
* Write savebuffer to FAT card file
***************************************************************************/
int
SaveBufferToFAT (char *filepath, int datasize, bool silent)
{
if (datasize)
{
fatfile = fopen (filepath, "wb");
if (fatfile <= 0)
{
char msg[100];
sprintf(msg, "Couldn't save %s", filepath);
WaitPrompt (msg);
return 0;
}
fwrite (savebuffer, 1, datasize, fatfile);
fclose (fatfile);
}
return datasize;
}

View File

@ -1,37 +0,0 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* softdev July 2006
* crunchy2 May 2007
* Michniewski 2008
* Tantric August 2008
*
* fileop.h
*
* FAT File operations
****************************************************************************/
#ifndef _FATFILESC_
#define _FATFILESC_
#include <gccore.h>
#include <stdio.h>
#include <string.h>
#include <ogcsys.h>
#include <fat.h>
#include <sys/dir.h>
#include <sys/stat.h>
#include <unistd.h>
#define ROOTFATDIR "fat:/"
bool ChangeFATInterface(int method, bool silent);
int ParseFATdirectory(int method);
int LoadFATFile (char * fbuffer, int length);
int LoadFATSzFile(char * filepath, unsigned char * rbuffer);
int SaveBufferToFAT (char *filepath, int datasize, bool silent);
int LoadBufferFromFAT (char *filepath, bool silent);
extern char currFATdir[MAXPATHLEN];
extern FILE * fatfile;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,50 +1,26 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Filesel - borrowed from GPP
*
* softdev July 2006
* crunchy2 May 2007
* Michniewski 2008
* Tantric August 2008
*
* filesel.h
*
* Generic file routines - reading, writing, browsing
****************************************************************************/
#ifndef _NGCFILESEL_
#define _NGCFILESEL_
#include <unistd.h>
int OpenDVD ();
int OpenSMB ();
int OpenSD ();
int OpenUSB ();
#define SAVEBUFFERSIZE (512 * 1024)
#define MAXJOLIET 255
#define MAXDISPLAY 54
typedef struct
{
u64 offset;
unsigned int length;
char flags;
char filename[MAXJOLIET + 1];
char displayname[MAXDISPLAY + 1];
} FILEENTRIES;
#define MAXFILES 2000 // Restrict to 2000 files per dir
extern FILEENTRIES filelist[MAXFILES];
extern unsigned char *savebuffer;
extern int offset;
extern int selection;
extern char currentdir[MAXPATHLEN];
extern int maxfiles;
extern unsigned long SNESROMSize;
void AllocSaveBuffer();
void FreeSaveBuffer();
bool MakeROMPath(char filepath[], int method);
int OpenROM (int method);
int autoLoadMethod();
int autoSaveMethod();
int FileSortCallback(const void *f1, const void *f2);
void StripExt(char* returnstring, char * inputstring);
#define LOAD_DVD 1
#define LOAD_SMB 2
#define LOAD_SDC 4
#define LOAD_USB 8
#define ROOTSDDIR "fat3:/"
#define SNESROMDIR "snes9x/roms"
#define SNESSAVEDIR "snes9x/saves"
#endif

View File

@ -1,348 +0,0 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* softdev July 2006
* crunchy2 May 2007-July 2007
* Michniewski 2008
* Tantric August 2008
*
* freeze.cpp
*
* Snapshots Memory File System
*
* This is a single global memory file controller.
* Don't even think of opening two at the same time!
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fat.h>
#include <zlib.h>
#include <smb.h>
#include "snes9x.h"
#include "memmap.h"
#include "soundux.h"
#include "snapshot.h"
#include "srtc.h"
#include "snes9xGX.h"
#include "images/saveicon.h"
#include "freeze.h"
#include "filesel.h"
#include "menudraw.h"
#include "smbop.h"
#include "fileop.h"
#include "memcardop.h"
extern void S9xSRTCPreSaveState ();
extern void NGCFreezeStruct ();
extern bool8 S9xUnfreezeGame (const char *filename);
static int bufoffset;
char freezecomment[2][32];
/****************************************************************************
* GetMem
*
* Return x bytes from memory buffer
***************************************************************************/
int
GetMem (char *buffer, int len)
{
memcpy (buffer, savebuffer + bufoffset, len);
bufoffset += len;
return len;
}
/****************************************************************************
* PutMem
*
* Put some values in memory buffer
***************************************************************************/
static void
PutMem (char *buffer, int len)
{
memcpy (savebuffer + bufoffset, buffer, len);
bufoffset += len;
}
void
NGCFreezeBlock (char *name, uint8 * block, int size)
{
char buffer[512];
sprintf (buffer, "%s:%06d:", name, size);
PutMem (buffer, strlen (buffer));
PutMem ((char *) block, size);
}
/****************************************************************************
* NGCFreezeMembuffer
*
* Copies a snapshot of Snes9x state into memory
***************************************************************************/
static int
NGCFreezeMemBuffer ()
{
int i;
char buffer[1024];
bufoffset = 0;
S9xUpdateRTC ();
S9xSRTCPreSaveState ();
for (i = 0; i < 8; i++)
{
SoundData.channels[i].previous16[0] =
(int16) SoundData.channels[i].previous[0];
SoundData.channels[i].previous16[1] =
(int16) SoundData.channels[i].previous[1];
}
sprintf (buffer, "%s:%04d\n", SNAPSHOT_MAGIC, SNAPSHOT_VERSION);
PutMem (buffer, strlen (buffer));
sprintf (buffer, "NAM:%06d:%s%c", (int) strlen (Memory.ROMFilename) + 1,
Memory.ROMFilename, 0);
PutMem (buffer, strlen (buffer) + 1);
NGCFreezeStruct ();
return 0;
}
/****************************************************************************
* NGCFreezeGame
*
* Do freeze game for Nintendo Gamecube
***************************************************************************/
int
NGCFreezeGame (int method, bool8 silent)
{
ShowAction ((char*) "Saving...");
if(method == METHOD_AUTO)
method = autoSaveMethod();
char filename[1024];
int offset = 0;
char msg[100];
S9xSetSoundMute (TRUE);
S9xPrepareSoundForSnapshotSave (FALSE);
AllocSaveBuffer ();
NGCFreezeMemBuffer (); // copy freeze mem into savebuffer
S9xPrepareSoundForSnapshotSave (TRUE);
S9xSetSoundMute (FALSE);
if (method == METHOD_SD || method == METHOD_USB) // FAT devices
{
if(ChangeFATInterface(method, NOTSILENT))
{
sprintf (filename, "%s/%s/%s.frz", ROOTFATDIR, GCSettings.SaveFolder, Memory.ROMFilename);
offset = SaveBufferToFAT (filename, bufoffset, silent);
}
}
else if (method == METHOD_SMB) // SMB
{
sprintf (filename, "%s/%s.frz", GCSettings.SaveFolder, Memory.ROMFilename);
offset = SaveBufferToSMB (filename, bufoffset, silent);
}
else if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB) // MC Slot A or B
{
sprintf (filename, "%s.snz", Memory.ROMName);
// Copy in save icon
int woffset = sizeof (saveicon);
memcpy (savebuffer, saveicon, woffset);
// And the freezecomment
sprintf (freezecomment[0], "%s Freeze", VERSIONSTR);
sprintf (freezecomment[1], Memory.ROMName);
memcpy (savebuffer + woffset, freezecomment, 64);
woffset += 64;
// Zip and copy in the freeze
uLongf DestBuffSize = (uLongf) SAVEBUFFERSIZE;
int err= compress2((Bytef*)(savebuffer+woffset+8), (uLongf*)&DestBuffSize, (const Bytef*)savebuffer, (uLongf)bufoffset, Z_BEST_COMPRESSION);
if(err!=Z_OK)
{
sprintf (msg, "zip error %s ",zError(err));
WaitPrompt (msg);
return 0;
}
int zippedsize = (int)DestBuffSize;
memcpy (savebuffer + woffset, &zippedsize, 4);
woffset += 4;
int decompressedsize = (int)bufoffset;
memcpy (savebuffer + woffset, &decompressedsize, 4);
woffset += 4;
woffset += zippedsize;
if(method == METHOD_MC_SLOTA)
offset = SaveBufferToMC ( savebuffer, CARD_SLOTA, filename, woffset, SILENT );
else
offset = SaveBufferToMC ( savebuffer, CARD_SLOTB, filename, woffset, SILENT );
}
FreeSaveBuffer ();
if(offset > 0) // save successful!
{
if(!silent)
WaitPrompt((char*) "Save successful");
return 1;
}
return 0;
}
/****************************************************************************
* NGCUnFreezeBlock
***************************************************************************/
int
NGCUnFreezeBlock (char *name, uint8 * block, int size)
{
char buffer[20], *e;
int len = 0;
int rem = 0;
GetMem (buffer, 11);
if (strncmp (buffer, name, 3) != 0 || buffer[3] != ':' ||
buffer[10] != ':' || (len = strtol (&buffer[4], &e, 10)) == 0 ||
e != buffer + 10)
{
return WRONG_FORMAT;
}
if (len > size)
{
rem = len - size;
len = size;
}
ZeroMemory (block, size);
GetMem ((char *) block, len);
if (rem)
{
bufoffset += rem;
}
return SUCCESS;
}
/****************************************************************************
* NGCUnfreezeGame
***************************************************************************/
int
NGCUnfreezeGame (int method, bool8 silent)
{
ShowAction ((char*) "Loading...");
char filename[1024];
int offset = 0;
char msg[80];
bufoffset = 0;
if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because snapshot needs R/W
AllocSaveBuffer ();
if (method == METHOD_SD || method == METHOD_USB) // SD & USB
{
if(ChangeFATInterface(method, NOTSILENT))
{
sprintf (filename, "%s/%s/%s.frz", ROOTFATDIR, GCSettings.SaveFolder, Memory.ROMFilename);
offset = LoadBufferFromFAT (filename, silent);
}
}
else if (method == METHOD_SMB) // Network (SMB)
{
sprintf (filename, "%s/%s.frz", GCSettings.SaveFolder, Memory.ROMFilename);
offset = LoadBufferFromSMB (filename, silent);
}
else if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB) // MC in slot A or slot B
{
sprintf (filename, "%s.snz", Memory.ROMName);
int ret = 0;
if(method == METHOD_MC_SLOTA)
ret = LoadBufferFromMC ( savebuffer, CARD_SLOTA, filename, silent );
else
ret = LoadBufferFromMC ( savebuffer, CARD_SLOTB, filename, silent );
if (ret)
{
char * zipbuffer = (char *)malloc(SAVEBUFFERSIZE);
memset (zipbuffer, 0, SAVEBUFFERSIZE);
// skip the saveicon and comment
offset = (sizeof(saveicon) + 64);
uLongf zipsize = 0;
uLongf decompressedsize = 0;
memcpy (&zipsize, savebuffer+offset, 4);
offset += 4;
memcpy (&decompressedsize, savebuffer+offset, 4);
offset += 4;
uLongf DestBuffSize = SAVEBUFFERSIZE;
int err= uncompress((Bytef*)zipbuffer, (uLongf*)&DestBuffSize, (const Bytef*)(savebuffer + offset), zipsize);
if ( err!=Z_OK )
{
sprintf (msg, "Unzip error %s ",zError(err));
WaitPrompt (msg);
}
else if ( DestBuffSize != decompressedsize )
{
WaitPrompt((char*) "Unzipped size doesn't match expected size!");
}
else
{
offset = SAVEBUFFERSIZE;
memcpy (savebuffer, zipbuffer, SAVEBUFFERSIZE);
}
free(zipbuffer);
zipbuffer = NULL;
if(offset == 0)
return 0;
}
}
int result = 0;
if(offset > 0)
{
if (S9xUnfreezeGame ("AGAME") == SUCCESS)
result = 1;
else
WaitPrompt((char*) "Error thawing");
}
else
{
if(!silent)
WaitPrompt((char*) "Freeze file not found");
}
FreeSaveBuffer ();
return result;
}

View File

@ -1,34 +0,0 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* softdev July 2006
* crunchy2 May 2007-July 2007
* Michniewski 2008
* Tantric August 2008
*
* freeze.h
*
* Snapshots Memory File System
*
* This is a single global memory file controller.
* Don't even think of opening two at the same time!
***************************************************************************/
#ifndef _NGCMEMFILE_
#define _NGCMEMFILE_
typedef struct
{
char filename[512]; /*** Way over size - but who cares -;) ***/
int filehandle;
int currpos;
int length;
int mode;
char *buffer; /*** Memspace for read / write ***/
}
MEMFILE;
int NGCFreezeGame (int method, bool8 silent);
int NGCUnfreezeGame (int method, bool8 silent);
#endif

877
source/ngc/ftfont.cpp Normal file
View File

@ -0,0 +1,877 @@
/****************************************************************************
* Snes9x 1.50
*
* Nintendo Gamecube Screen Font Driver
*
* Uses libfreetype 2.2.1 compiled for GC with TTF support only.
* TTF only reduces the library by some 900k bytes!
*
* Visit - http://www.freetype.org !
*
* **WARNING***
*
* ONLY USE GUARANTEED PATENT FREE FONTS.
* THOSE IN YOUR WINDOWS\FONTS DIRECTORY ARE COPYRIGHT
* AND MAY NOT BE DISTRIBUTED!
*
* softdev July 2006
* crunchy2 June 2007
****************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <wiiuse/wpad.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include "video.h"
#include "ftfont.h"
#include "dkpro.h"
#include "snes9xGX.h"
#include "aram.h"
#include <zlib.h>
#include "gfx_bg.h"
/*** Globals ***/
FT_Library ftlibrary;
FT_Face face;
FT_GlyphSlot slot;
FT_UInt glyph_index;
static unsigned int fonthi, fontlo;
extern char fontface[]; /*** From fontface.s ***/
extern int fontsize; /*** From fontface.s ***/
extern int screenheight;
extern unsigned int *xfb[2];
extern int whichfb;
/**
* Unpack the devkit pro logo
*/
static u32 *dkproraw;
/*** Permanent backdrop ***/
#ifdef HW_RVL
u32 *backdrop;
#else
static u32 *backdrop;
#endif
static void unpackbackdrop ();
unsigned int getcolour (u8 r1, u8 g1, u8 b1);
void DrawLineFast( int startx, int endx, int y, u8 r, u8 g, u8 b );
u32 getrgb( u32 ycbr, u32 low );
/**
* Initialisation of libfreetype
*/
int
FT_Init ()
{
int err;
err = FT_Init_FreeType (&ftlibrary);
if (err)
return 1;
err =
FT_New_Memory_Face (ftlibrary, (FT_Byte *) fontface, fontsize, 0, &face);
if (err)
return 1;
setfontsize (16);
setfontcolour (0xff, 0xff, 0xff);
slot = face->glyph;
return 0;
}
/**
* setfontsize
*
* Set the screen font size in pixels
*/
void
setfontsize (int pixelsize)
{
int err;
err = FT_Set_Pixel_Sizes (face, 0, pixelsize);
if (err)
printf ("Error setting pixel sizes!");
}
static void
DrawCharacter (FT_Bitmap * bmp, FT_Int x, FT_Int y)
{
FT_Int i, j, p, q;
FT_Int x_max = x + bmp->width;
FT_Int y_max = y + bmp->rows;
int spos;
unsigned int pixel;
int c;
for (i = x, p = 0; i < x_max; i++, p++)
{
for (j = y, q = 0; j < y_max; j++, q++)
{
if (i < 0 || j < 0 || i >= 640 || j >= screenheight)
continue;
/*** Convert pixel position to GC int sizes ***/
spos = (j * 320) + (i >> 1);
pixel = xfb[whichfb][spos];
c = bmp->buffer[q * bmp->width + p];
/*** Cool Anti-Aliasing doesn't work too well at hires on GC ***/
if (c > 128)
{
if (i & 1)
pixel = (pixel & 0xffff0000) | fontlo;
else
pixel = ((pixel & 0xffff) | fonthi);
xfb[whichfb][spos] = pixel;
}
}
}
}
/**
* DrawText
*
* Place the font bitmap on the screen
*/
void
DrawText (int x, int y, char *text)
{
int px, n;
int i;
int err;
int value, count;
n = strlen (text);
if (n == 0)
return;
/*** x == -1, auto centre ***/
if (x == -1)
{
value = 0;
px = 0;
}
else
{
value = 1;
px = x;
}
for (count = value; count < 2; count++)
{
/*** Draw the string ***/
for (i = 0; i < n; i++)
{
err = FT_Load_Char (face, text[i], FT_LOAD_RENDER);
if (err)
{
printf ("Error %c %d\n", text[i], err);
continue; /*** Skip unprintable characters ***/
}
if (count)
DrawCharacter (&slot->bitmap, px + slot->bitmap_left,
y - slot->bitmap_top);
px += slot->advance.x >> 6;
}
px = (640 - px) >> 1;
}
}
/**
* setfontcolour
*
* Uses RGB triple values.
*/
void
setfontcolour (u8 r, u8 g, u8 b)
{
u32 fontcolour;
fontcolour = getcolour (r, g, b);
fonthi = fontcolour & 0xffff0000;
fontlo = fontcolour & 0xffff;
}
/**
* Licence Information
*
* THIS MUST NOT BE REMOVED IN ANY DERIVATIVE WORK.
*/
void
licence ()
{
int ypos = ((screenheight - (282 + dkpro_HEIGHT)) >> 1);
if (screenheight == 480)
ypos += 42;
else
ypos += 24;
setfontsize (16);
setfontcolour (0x00, 0x00, 0x00);
DrawText (-1, ypos += 40, (char*)"Snes9x - Copyright (c) Snes9x Team 1996 - 2006");
DrawText (-1, ypos += 40, (char*)"This is free software, and you are welcome to");
DrawText (-1, ypos += 20, (char*)"redistribute it under the conditions of the");
DrawText (-1, ypos += 20, (char*)"GNU GENERAL PUBLIC LICENSE Version 2");
DrawText (-1, ypos +=
20, (char*)"Additionally, the developers of this port disclaim");
DrawText (-1, ypos +=
20, (char*)"all copyright interests in the Nintendo GameCube");
DrawText (-1, ypos +=
20, (char*)"porting code. You are free to use it as you wish");
DrawText (-1, ypos += 40, (char*)"Developed with DevkitPPC and libOGC");
DrawText (-1, ypos += 20, (char*)"http://www.devkitpro.org");
}
/**
* dkunpack
*
* Support function to expand the DevkitPro logo
*/
int
dkunpack ()
{
unsigned long res, inbytes, outbytes;
inbytes = dkpro_COMPRESSED;
outbytes = dkpro_RAW;
dkproraw = (u32 *) malloc (dkpro_RAW + 16);
res = uncompress ((Bytef *) dkproraw, &outbytes, (Bytef *) dkpro, inbytes);
if (res == Z_OK)
return 1;
return 0;
}
/**
* showdklogo
*
* Display the DevkitPro logo
*/
void
showdklogo ()
{
int w, h, p, dispoffset;
p = 0;
dispoffset =
((screenheight != 480 ? 365 : 355) * 320) + ((640 - dkpro_WIDTH) >> 2);
dkunpack ();
for (h = 0; h < dkpro_HEIGHT; h++)
{
for (w = 0; w < dkpro_WIDTH >> 1; w++)
{
if (dkproraw[p] != 0x00800080)
xfb[whichfb][dispoffset + w] = dkproraw[p++];
else
p++;
}
dispoffset += 320;
}
free (dkproraw);
}
/**
* getcolour
*
* Simply converts RGB to Y1CbY2Cr format
*
* I got this from a pastebin, so thanks to whoever originally wrote it!
*/
unsigned int
getcolour (u8 r1, u8 g1, u8 b1)
{
int y1, cb1, cr1, y2, cb2, cr2, cb, cr;
u8 r2, g2, b2;
r2 = r1;
g2 = g1;
b2 = b1;
y1 = (299 * r1 + 587 * g1 + 114 * b1) / 1000;
cb1 = (-16874 * r1 - 33126 * g1 + 50000 * b1 + 12800000) / 100000;
cr1 = (50000 * r1 - 41869 * g1 - 8131 * b1 + 12800000) / 100000;
y2 = (299 * r2 + 587 * g2 + 114 * b2) / 1000;
cb2 = (-16874 * r2 - 33126 * g2 + 50000 * b2 + 12800000) / 100000;
cr2 = (50000 * r2 - 41869 * g2 - 8131 * b2 + 12800000) / 100000;
cb = (cb1 + cb2) >> 1;
cr = (cr1 + cr2) >> 1;
return ((y1 << 24) | (cb << 16) | (y2 << 8) | cr);
}
/**
* Unpackbackdrop
*/
void
unpackbackdrop ()
{
unsigned long res, inbytes, outbytes;
unsigned int colour;
int offset;
int i;
// backdrop = (unsigned int *) malloc (screenheight * 1280);
backdrop = (u32 *) malloc (screenheight * 1280);
colour = getcolour (0x00, 0x00, 0x00);
/*** Fill with black for now ***/
for (i = 0; i < (320 * screenheight); i++)
backdrop[i] = colour;
/*** If it's PAL50, need to move down a few lines ***/
offset = ((screenheight - 480) >> 1) * 320;
inbytes = BG_COMPRESSED;
outbytes = BG_RAW;
res =
uncompress ((Bytef *) backdrop + offset, &outbytes, (Bytef *) bg,
inbytes);
#ifndef HW_RVL
/*** Now store the backdrop in ARAM ***/
ARAMPut ((char *) backdrop, (char *) AR_BACKDROP, 640 * screenheight * 2);
free (backdrop);
#endif
// otherwise (on wii) backdrop is stored in memory
}
/**
* Display legal copyright and licence
*/
void
legal ()
{
unpackbackdrop ();
clearscreen ();
licence ();
showdklogo ();
showscreen ();
}
/**
* Wait for user to press A
*/
void
WaitButtonA ()
{
#ifdef HW_RVL
while ( (PAD_ButtonsDown (0) & PAD_BUTTON_A) || (WPAD_ButtonsDown(0) & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) ) VIDEO_WaitVSync();
while (!(PAD_ButtonsDown (0) & PAD_BUTTON_A) && !(WPAD_ButtonsDown(0) & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) ) VIDEO_WaitVSync();
#else
while ( PAD_ButtonsDown (0) & PAD_BUTTON_A ) VIDEO_WaitVSync();
while (!(PAD_ButtonsDown (0) & PAD_BUTTON_A) ) VIDEO_WaitVSync();
#endif
}
/**
* Wait for user to press A or B. Returns 0 = B; 1 = A
*/
int
WaitButtonAB ()
{
#ifdef HW_RVL
u32 gc_btns, wm_btns;
while ( (PAD_ButtonsDown (0) & (PAD_BUTTON_A | PAD_BUTTON_B))
|| (WPAD_ButtonsDown(0) & (WPAD_BUTTON_A | WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_A | WPAD_CLASSIC_BUTTON_B))
) VIDEO_WaitVSync();
while ( TRUE )
{
gc_btns = PAD_ButtonsDown (0);
wm_btns = WPAD_ButtonsDown (0);
if ( (gc_btns & PAD_BUTTON_A) || (wm_btns & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) )
return 1;
else if ( (gc_btns & PAD_BUTTON_B) || (wm_btns & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)) )
return 0;
}
#else
u32 gc_btns;
while ( (PAD_ButtonsDown (0) & (PAD_BUTTON_A | PAD_BUTTON_B)) ) VIDEO_WaitVSync();
while ( TRUE )
{
gc_btns = PAD_ButtonsDown (0);
if ( gc_btns & PAD_BUTTON_A )
return 1;
else if ( gc_btns & PAD_BUTTON_B )
return 0;
}
#endif
}
/**
* Show a prompt
*/
void
WaitPrompt (char *msg)
{
int ypos = (screenheight - 64) >> 1;
if (screenheight == 480)
ypos += 52;
else
ypos += 32;
clearscreen ();
DrawText (-1, ypos, msg);
ypos += 30;
DrawText (-1, ypos, (char*)"Press A to continue");
showscreen ();
WaitButtonA ();
}
/**
* Show a prompt with choice of two options. Returns 1 if A button was pressed
and 0 if B button was pressed.
*/
int
WaitPromptChoice (char *msg, char *bmsg, char *amsg)
{
int ypos = (screenheight - 64) >> 1;
if (screenheight == 480)
ypos += 37;
else
ypos += 17;
clearscreen ();
DrawText (-1, ypos, msg);
ypos += 60;
char txt[80];
sprintf (txt, "B = %s : A = %s", bmsg, amsg);
DrawText (-1, ypos, txt);
showscreen ();
return WaitButtonAB ();
}
/**
* Show an action in progress
*/
void
ShowAction (char *msg)
{
int ypos = (screenheight - 30) >> 1;
if (screenheight == 480)
ypos += 52;
else
ypos += 32;
clearscreen ();
DrawText (-1, ypos, msg);
showscreen ();
}
/****************************************************************************
* Generic Menu Routines
****************************************************************************/
void
DrawMenu (char items[][20], char *title, int maxitems, int selected, int fontsize)
{
int i, w;
int ypos;
#if 0
int bounding[] = { 80, 40, 600, 40, 560, 94, 40, 94 };
int base[] = { 80, screenheight - 90, 600, screenheight - 90,
560, screenheight - 40, 40, screenheight - 40
};
#endif
//ypos = (screenheight - (maxitems * 32)) >> 1; previous
ypos = (screenheight - (maxitems * (fontsize + 8))) >> 1;
if (screenheight == 480)
ypos += 52;
else
ypos += 32;
clearscreen ();
//#if 0
// DrawPolygon (4, bounding, 0x00, 0x00, 0xc0);
// DrawPolygon (4, base, 0x00, 0x00, 0xc0);
setfontsize (30);
if (title != NULL)
DrawText (-1, 60, title);
setfontsize (12);
DrawText (510, screenheight - 20, "Snes9x GX 004");
//#endif
setfontsize (fontsize); // set font size
setfontcolour (0, 0, 0);
for (i = 0; i < maxitems; i++)
{
if (i == selected)
{
//for( w = 0; w < 32; w++ )
for( w = 0; w < (fontsize + 8); w++ )
//DrawLineFast( 30, 610, (i << 5) + (ypos-26) + w, 0x80, 0x80, 0x80 ); previous
DrawLineFast( 30, 610, i * (fontsize + 8) + (ypos-(fontsize + 2)) + w, 0x80, 0x80, 0x80 );
setfontcolour (0xff, 0xff, 0xff);
//DrawText (-1, (i << 5) + ypos, items[i]); previous
DrawText (-1, i * (fontsize + 8) + ypos, items[i]);
setfontcolour (0x00, 0x00, 0x00);
}
else
DrawText (-1, i * (fontsize + 8) + ypos, items[i]);
//DrawText (-1, i * 32 + ypos, items[i]); previous
}
showscreen ();
}
/****************************************************************************
* RunMenu
*
* Call this with the menu array defined in menu.cpp
* It's here to keep all the font / interface stuff together.
****************************************************************************/
int menu = 0;
int
RunMenu (char items[][20], int maxitems, char *title, int fontsize)
{
int redraw = 1;
int quit = 0;
u32 p, wp;
int ret = 0;
signed char a;
float mag = 0;
float mag2 = 0;
u16 ang = 0;
u16 ang2 = 0;
//while (!(PAD_ButtonsDown (0) & PAD_BUTTON_B) && (quit == 0))
while (quit == 0)
{
if (redraw)
{
DrawMenu (&items[0], title, maxitems, menu, fontsize);
redraw = 0;
}
p = PAD_ButtonsDown (0);
#ifdef HW_RVL
wp = WPAD_ButtonsDown (0);
wpad_get_analogues(0, &mag, &ang, &mag2, &ang2); // get joystick info from wii expansions
#else
wp = 0;
#endif
a = PAD_StickY (0);
VIDEO_WaitVSync(); // slow things down a bit so we don't overread the pads
/*** Look for up ***/
if ( (p & PAD_BUTTON_UP) || (wp & (WPAD_BUTTON_UP | WPAD_CLASSIC_BUTTON_UP)) || (a > 70) || (mag>JOY_THRESHOLD && (ang>300 || ang<50)) )
{
redraw = 1;
menu--;
}
/*** Look for down ***/
if ( (p & PAD_BUTTON_DOWN) || (wp & (WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN)) || (a < -70) || (mag>JOY_THRESHOLD && (ang>130 && ang<230)) )
{
redraw = 1;
menu++;
}
if ((p & PAD_BUTTON_A) || (wp & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)))
{
quit = 1;
ret = menu;
}
if ((p & PAD_BUTTON_B) || (wp & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)))
{
quit = -1;
ret = -1;
}
if (menu == maxitems)
menu = 0;
if (menu < 0)
menu = maxitems - 1;
}
/*** Wait for B button to be released before proceeding ***/
while ( (PAD_ButtonsDown(0) & PAD_BUTTON_B)
#ifdef HW_RVL
|| (WPAD_ButtonsDown(0) & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B))
#endif
)
{
ret = -1;
VIDEO_WaitVSync();
}
return ret;
}
/****************************************************************************
* DrawLine
*
* Quick'n'Dirty Bresenham line drawing routine.
****************************************************************************/
#define SIGN(x) ((x<0)?-1:((x>0)?1:0))
void
DrawLine (int x1, int y1, int x2, int y2, u8 r, u8 g, u8 b)
{
u32 colour, pixel;
u32 colourhi, colourlo;
int i, dx, dy, sdx, sdy, dxabs, dyabs, x, y, px, py;
int sp;
colour = getcolour (r, g, b);
colourhi = colour & 0xffff0000;
colourlo = colour & 0xffff;
dx = x2 - x1; /*** Horizontal distance ***/
dy = y2 - y1; /*** Vertical distance ***/
dxabs = abs (dx);
dyabs = abs (dy);
sdx = SIGN (dx);
sdy = SIGN (dy);
x = dyabs >> 1;
y = dxabs >> 1;
px = x1;
py = y1;
sp = (py * 320) + (px >> 1);
pixel = xfb[whichfb][sp];
/*** Plot this pixel ***/
if (px & 1)
xfb[whichfb][sp] = (pixel & 0xffff0000) | colourlo;
else
xfb[whichfb][sp] = (pixel & 0xffff) | colourhi;
if (dxabs >= dyabs) /*** Mostly horizontal ***/
{
for (i = 0; i < dxabs; i++)
{
y += dyabs;
if (y >= dxabs)
{
y -= dxabs;
py += sdy;
}
px += sdx;
sp = (py * 320) + (px >> 1);
pixel = xfb[whichfb][sp];
if (px & 1)
xfb[whichfb][sp] = (pixel & 0xffff0000) | colourlo;
else
xfb[whichfb][sp] = (pixel & 0xffff) | colourhi;
}
}
else
{
for (i = 0; i < dyabs; i++)
{
x += dxabs;
if (x >= dyabs)
{
x -= dyabs;
px += sdx;
}
py += sdy;
sp = (py * 320) + (px >> 1);
pixel = xfb[whichfb][sp];
if (px & 1)
xfb[whichfb][sp] = (pixel & 0xffff0000) | colourlo;
else
xfb[whichfb][sp] = (pixel & 0xffff) | colourhi;
}
}
}
/****************************************************************************
* Progress Bar
*
* Show the user what's happening
****************************************************************************/
void
ShowProgress (char *msg, int done, int total)
{
int ypos = (screenheight - 30) >> 1;
if (screenheight == 480)
ypos += 52;
else
ypos += 32;
int xpos;
int i;
clearscreen ();
DrawText (-1, ypos, msg);
/*** Draw a white outline box ***/
for (i = 380; i < 401; i++)
DrawLine (100, i, 540, i, 0xff, 0xff, 0xff);
/*** Show progess ***/
xpos = (int) (((float) done / (float) total) * 438);
for (i = 381; i < 400; i++)
DrawLine (101, i, 101 + xpos, i, 0x00, 0x00, 0x80);
showscreen ();
}
/****************************************************************************
* DrawPolygon
****************************************************************************/
void
DrawPolygon (int vertices, int varray[], u8 r, u8 g, u8 b)
{
int i;
for (i = 0; i < vertices - 1; i++)
{
DrawLine (varray[(i << 1)], varray[(i << 1) + 1], varray[(i << 1) + 2],
varray[(i << 1) + 3], r, g, b);
}
DrawLine (varray[0], varray[1], varray[(vertices << 1) - 2],
varray[(vertices << 1) - 1], r, g, b);
}
/*****************************************************************************
* Draw Line Fast
*
* This routine requires that start and endx are 32bit aligned.
* It tries to perform a semi-transparency over the existing image.
*****************************************************************************/
#define SRCWEIGHT 0.7f
#define DSTWEIGHT (1.0f - SRCWEIGHT)
static inline u8 c_adjust( u8 c , float weight )
{
return (u8)((float)c * weight);
}
void DrawLineFast( int startx, int endx, int y, u8 r, u8 g, u8 b )
{
int width;
u32 offset;
int i;
u32 colour, clo, chi;
u32 lo,hi;
u8 *s, *d;
//colour = getcolour(r, g, b);
colour = ( r << 16 | g << 8 | b );
d = (u8 *)&colour;
d[1] = c_adjust(d[1], DSTWEIGHT);
d[2] = c_adjust(d[2], DSTWEIGHT);
d[3] = c_adjust(d[3], DSTWEIGHT);
width = ( endx - startx ) >> 1;
offset = ( y << 8 ) + ( y << 6 ) + ( startx >> 1 );
for ( i = 0; i < width; i++ )
{
lo = getrgb(xfb[whichfb][offset], 0);
hi = getrgb(xfb[whichfb][offset], 1);
s = (u8 *)&hi;
s[1] = ( ( c_adjust(s[1],SRCWEIGHT) ) + d[1] );
s[2] = ( ( c_adjust(s[2],SRCWEIGHT) ) + d[2] );
s[3] = ( ( c_adjust(s[3],SRCWEIGHT) ) + d[3] );
s = (u8 *)&lo;
s[1] = ( ( c_adjust(s[1],SRCWEIGHT) ) + d[1] );
s[2] = ( ( c_adjust(s[2],SRCWEIGHT) ) + d[2] );
s[3] = ( ( c_adjust(s[3],SRCWEIGHT) ) + d[3] );
clo = getcolour( s[1], s[2], s[3] );
s = (u8 *)&hi;
chi = getcolour( s[1], s[2], s[3] );
xfb[whichfb][offset++] = (chi & 0xffff0000 ) | ( clo & 0xffff) ;
}
}
/**
* Ok, I'm useless with Y1CBY2CR colour.
* So convert back to RGB so I can work with it -;)
*/
u32 getrgb( u32 ycbr, u32 low )
{
u8 r,g,b;
u32 y;
s8 cb,cr;
if ( low )
y = ( ycbr & 0xff00 ) >> 8;
else
y = ( ycbr & 0xff000000 ) >> 24;
cr = ycbr & 0xff;
cb = ( ycbr & 0xff0000 ) >> 16;
cr -= 128;
cb -= 128;
r = (u8)((float)y + 1.371 * (float)cr);
g = (u8)((float)y - 0.698 * (float)cr - 0.336 * (float)cb);
b = (u8)((float)y + 1.732 * (float)cb);
return (u32)( r << 16 | g << 8 | b );
}

View File

@ -1,42 +1,34 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* softdev July 2006
* crunchy2 June 2007
* Michniewski 2008
* Tantric August 2008
*
* menudraw.h
*
* Menu drawing routines
* Nintendo Gamecube Screen Font Driver
*
* Uses libfreetype 2.2.1 compiled for GC with TTF support only.
* TTF only reduces the library by some 900k bytes!
* TTF only reduces the library by some 900kbytes!
*
* Visit - http://www.freetype.org !
*
* **WARNING***
*
* ONLY USE GUARANTEED PATENT FREE FONTS.
***************************************************************************/
#ifndef _NGCMENUDRAW_
#define _NGCMENUDRAW_
#include "filesel.h"
#define PAGESIZE 17 // max item listing on a screen
* THOSE IN YOUR WINDOWS\FONTS DIRECTORY ARE COPYRIGHT
* AND MAY NOT BE DISTRIBUTED!
*
* softdev July 2006
* crunchy2 June 2007
****************************************************************************/
#ifndef _TTFFONTS_
#define _TTFFONTS_
int FT_Init ();
void setfontsize (int pixelsize);
void setfontcolour (u8 r, u8 g, u8 b);
void DrawText (int x, int y, char *text);
void unpackbackdrop ();
void Credits ();
void RomInfo ();
void legal ();
void highlight (int on);
void WaitButtonA ();
int RunMenu (char items[][50], int maxitems, char *title, int fontsize = 20, int x = -1);
void DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsize = 20, int x = -1);
void ShowCheats (char items[][50], char itemvalues[][50], int maxitems, int offset, int selection);
void ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection);
void setfontcolour (u8 r, u8 g, u8 b);
int RunMenu (char items[][20], int maxitems, char *title, int fontsize = 24);
void DrawMenu (char items[][20], char *title, int maxitems, int selected, int fontsize = 24);
void WaitPrompt (char *msg);
int WaitPromptChoice (char *msg, char* bmsg, char* amsg);
void ShowAction (char *msg);

View File

@ -1,139 +1,281 @@
/*
* File : saveicon.bmp
*/
#ifndef _IMGSAVEICON_
#define _IMGSAVEICON_
const unsigned short saveicon[1024] = {
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xE73F,
0xFFFF, 0xFFFF, 0xB5BF, 0x801F, 0xFFFF, 0xD29F, 0x801F, 0x801F,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xA11E, 0x843C, 0x8439, 0x9CF7,
0x801F, 0x801F, 0x801C, 0x8018, 0x801F, 0x801F, 0x801C, 0x8018,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEB5C, 0xFFFF, 0xFFFF, 0xFFFF,
0x800F, 0xB9D3, 0xFFFF, 0xFFFF, 0x8013, 0x8008, 0xDAD7, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0x801F, 0x801F, 0x885F, 0xFFFF, 0x98D6, 0x801F, 0x801F,
0xFFFF, 0xFFFF, 0xFFFF, 0x843C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFBDF, 0x801E, 0x801B, 0x8017, 0x801E, 0x801B, 0x8018, 0x8015,
0x801A, 0x8018, 0x8015, 0x8011, 0x8016, 0x8014, 0x8011, 0x800D,
0x8012, 0x800B, 0x8848, 0xFFFF, 0x8010, 0x8009, 0x8003, 0xFFFF,
0x800C, 0x8007, 0x8006, 0xFFFF, 0x8008, 0x8005, 0xA52E, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFBBD, 0xF1EF, 0xFFFF, 0xF508, 0xF000, 0xEC00,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xE56B, 0xE16B, 0xE673, 0xFFFF, 0xE800, 0xDC00, 0xCC00, 0xB400,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xDE94, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEBBA,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xEFBA, 0xE378, 0xB2EB, 0x9AA4, 0x9AA5, 0x9AA5,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xE778, 0xF3BC, 0xFFFF, 0xFFFF, 0x9A84, 0x9623, 0x91E3, 0xB66C,
0xD6BB, 0x800E, 0x800C, 0x8008, 0xFFFF, 0x8C6A, 0x8004, 0x8004,
0xFFFF, 0xFFFF, 0xB191, 0xDAD8, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x8006, 0x8004, 0xFFFF, 0xFFFF, 0x8006, 0xF39D, 0xFFFF, 0xFA94,
0xFFFF, 0xFFFF, 0xFFFF, 0xEC21, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xF484, 0xF800, 0xF800, 0xF000, 0xF800, 0xF800, 0xFD6B, 0xF8C6,
0xF400, 0xF400, 0xFDEF, 0xF4A5, 0xFF18, 0xEC63, 0xE400, 0xE000,
0xE800, 0xE000, 0xD400, 0xC400, 0xE400, 0xE000, 0xD000, 0xC400,
0xE000, 0xD800, 0xCC00, 0xC000, 0xD800, 0xD000, 0xC400, 0xB800,
0xA400, 0xD673, 0xFFFF, 0xFFFF, 0xB400, 0x9000, 0xFFFF, 0xFFFF,
0xB000, 0x9000, 0xFFFF, 0xFFFF, 0xA800, 0x9000, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xDB75, 0x9AE4, 0xFFFF, 0xFFFF, 0x9A84, 0xA6E7,
0xFFFF, 0xFFFF, 0xA1E7, 0x9604, 0xFFFF, 0xFFFF, 0xFFFF, 0x8D03,
0xA707, 0xA708, 0xAF2A, 0xAF2A, 0xA6E7, 0xA2C7, 0xBF4E, 0xCB71,
0x9E46, 0x9E26, 0x9A25, 0x9604, 0x80E0, 0x8922, 0x8D22, 0x8D22,
0xA2C7, 0xA2A7, 0x9E66, 0x95E4, 0xA2A6, 0x9E46, 0x9E25, 0x95C4,
0x99E5, 0x95C4, 0x9163, 0x8D02, 0x88E2, 0x84A1, 0x8060, 0x8020,
0x8500, 0xF7BD, 0xFFFF, 0xFFFF, 0x8901, 0xA148, 0xFFFF, 0xFFFF,
0x8040, 0xB9ED, 0xFFFF, 0xFFFF, 0x9926, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xE529, 0xD400, 0xFFFF, 0xFFFF, 0xFFFF, 0xD4C6,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xD000, 0xC400, 0xBC00, 0xB000, 0xC000, 0xB800, 0xAC00, 0xA000,
0xA800, 0xA800, 0x9C00, 0x9400, 0xC18C, 0x8C00, 0x8C00, 0x8C00,
0x9C00, 0x8C00, 0xFFFF, 0xFFFF, 0x9400, 0x8C00, 0xFFFF, 0xFFFF,
0x8800, 0xDEB5, 0xFFFF, 0xFFFF, 0xE2D6, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xD6D5, 0xAD8A, 0x8CC3, 0x8060, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x8060, 0x90E4, 0xB1CC, 0xE759, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xF7AF,
0xFFFF, 0xFFFF, 0xFBDC, 0xF7B1, 0xFFFB, 0xFFE2, 0xFFE0, 0xFFE0,
0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE5,
0xF38C, 0xEF6A, 0xEB4B, 0xEB4F, 0xFFE0, 0xFBC0, 0xF7A0, 0xEB40,
0xFFE0, 0xFFE0, 0xFBC0, 0xF7A0, 0xFFF5, 0xFFE4, 0xF380, 0xEF60,
0xEF76, 0xFFFF, 0xFFFF, 0xFFFF, 0xE300, 0xCE60, 0xD6AB, 0xFFFF,
0xEB40, 0xE300, 0xCE60, 0xB180, 0xE720, 0xDEE0, 0xCE60, 0xB180,
0xF7BD, 0xB96B, 0xDAB4, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xB9CA, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xF399, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xD280, 0xEB40, 0xEB40, 0xEB40, 0xDAD1, 0xAD60, 0xC200, 0xCA40,
0xFFFF, 0xF7BE, 0xBDEB, 0x98C0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xEB40, 0xE720, 0xE300, 0xDAC0, 0xCA40, 0xC620, 0xC200, 0xBDE0,
0x9080, 0x94A0, 0x94A0, 0x9080, 0xFBDD, 0xE738, 0xE337, 0xE738,
0xD280, 0xCA40, 0xB5A0, 0x98C0, 0xB180, 0xA100, 0x94A0, 0x9080,
0x8C60, 0x9080, 0xC20C, 0xFFFF, 0xF7BD, 0xFFFF, 0xFFFF, 0xFFFF,
0xB9C9, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
};
#endif
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
C4 x86 assembler and some C emulation code
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
Nach,
zsKnight (zsknight@zsnes.com)
C4 C++ code
(c) Copyright 2003 - 2006 Brad Jorsch,
Nach
DSP-1 emulator code
(c) Copyright 1998 - 2006 _Demo_,
Andreas Naive (andreasnaive@gmail.com)
Gary Henderson,
Ivar (ivar@snes9x.com),
John Weidman,
Kris Bleakley,
Matthew Kendora,
Nach,
neviksti (neviksti@hotmail.com)
DSP-2 emulator code
(c) Copyright 2003 John Weidman,
Kris Bleakley,
Lord Nightmare (lord_nightmare@users.sourceforge.net),
Matthew Kendora,
neviksti
DSP-3 emulator code
(c) Copyright 2003 - 2006 John Weidman,
Kris Bleakley,
Lancer,
z80 gaiden
DSP-4 emulator code
(c) Copyright 2004 - 2006 Dreamer Nom,
John Weidman,
Kris Bleakley,
Nach,
z80 gaiden
OBC1 emulator code
(c) Copyright 2001 - 2004 zsKnight,
pagefault (pagefault@zsnes.com),
Kris Bleakley,
Ported from x86 assembler to C by sanmaiwashi
SPC7110 and RTC C++ emulator code
(c) Copyright 2002 Matthew Kendora with research by
zsKnight,
John Weidman,
Dark Force
S-DD1 C emulator code
(c) Copyright 2003 Brad Jorsch with research by
Andreas Naive,
John Weidman
S-RTC C emulator code
(c) Copyright 2001-2006 byuu,
John Weidman
ST010 C++ emulator code
(c) Copyright 2003 Feather,
John Weidman,
Kris Bleakley,
Matthew Kendora
Super FX x86 assembler emulator code
(c) Copyright 1998 - 2003 _Demo_,
pagefault,
zsKnight,
Super FX C emulator code
(c) Copyright 1997 - 1999 Ivar,
Gary Henderson,
John Weidman
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
(c) Copyright 1998 - 2003 Brad Martin
(c) Copyright 1998 - 2006 Charles Bilyue'
SH assembler code partly based on x86 assembler code
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
warranty. In no event shall the authors be held liable for any damages
arising from the use of this software or it's derivatives.
Snes9x is freeware for PERSONAL USE only. Commercial users should
seek permission of the copyright holders first. Commercial use includes,
but is not limited to, charging money for Snes9x or software derived from
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
using Snes9x as a promotion for your commercial product.
The copyright holders request that bug fixes and improvements to the code
should be forwarded to them so everyone can benefit from the modifications
in future versions.
Super NES and Super Nintendo Entertainment System are trademarks of
Nintendo Co., Limited and its subsidiary companies.
**********************************************************************************/
#include "snes9xGx.h"
START_EXTERN_C
struct SGCSettings GCSettings;
bool8 isWii;
unsigned short saveicon[1024] = {
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xE73F,
0xFFFF, 0xFFFF, 0xB5BF, 0x801F, 0xFFFF, 0xD29F, 0x801F, 0x801F,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xA11E, 0x843C, 0x8439, 0x9CF7,
0x801F, 0x801F, 0x801C, 0x8018, 0x801F, 0x801F, 0x801C, 0x8018,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEB5C, 0xFFFF, 0xFFFF, 0xFFFF,
0x800F, 0xB9D3, 0xFFFF, 0xFFFF, 0x8013, 0x8008, 0xDAD7, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0x801F, 0x801F, 0x885F, 0xFFFF, 0x98D6, 0x801F, 0x801F,
0xFFFF, 0xFFFF, 0xFFFF, 0x843C, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFBDF, 0x801E, 0x801B, 0x8017, 0x801E, 0x801B, 0x8018, 0x8015,
0x801A, 0x8018, 0x8015, 0x8011, 0x8016, 0x8014, 0x8011, 0x800D,
0x8012, 0x800B, 0x8848, 0xFFFF, 0x8010, 0x8009, 0x8003, 0xFFFF,
0x800C, 0x8007, 0x8006, 0xFFFF, 0x8008, 0x8005, 0xA52E, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFBBD, 0xF1EF, 0xFFFF, 0xF508, 0xF000, 0xEC00,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xE56B, 0xE16B, 0xE673, 0xFFFF, 0xE800, 0xDC00, 0xCC00, 0xB400,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xDE94, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xEBBA,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xEFBA, 0xE378, 0xB2EB, 0x9AA4, 0x9AA5, 0x9AA5,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xE778, 0xF3BC, 0xFFFF, 0xFFFF, 0x9A84, 0x9623, 0x91E3, 0xB66C,
0xD6BB, 0x800E, 0x800C, 0x8008, 0xFFFF, 0x8C6A, 0x8004, 0x8004,
0xFFFF, 0xFFFF, 0xB191, 0xDAD8, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x8006, 0x8004, 0xFFFF, 0xFFFF, 0x8006, 0xF39D, 0xFFFF, 0xFA94,
0xFFFF, 0xFFFF, 0xFFFF, 0xEC21, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xF484, 0xF800, 0xF800, 0xF000, 0xF800, 0xF800, 0xFD6B, 0xF8C6,
0xF400, 0xF400, 0xFDEF, 0xF4A5, 0xFF18, 0xEC63, 0xE400, 0xE000,
0xE800, 0xE000, 0xD400, 0xC400, 0xE400, 0xE000, 0xD000, 0xC400,
0xE000, 0xD800, 0xCC00, 0xC000, 0xD800, 0xD000, 0xC400, 0xB800,
0xA400, 0xD673, 0xFFFF, 0xFFFF, 0xB400, 0x9000, 0xFFFF, 0xFFFF,
0xB000, 0x9000, 0xFFFF, 0xFFFF, 0xA800, 0x9000, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xDB75, 0x9AE4, 0xFFFF, 0xFFFF, 0x9A84, 0xA6E7,
0xFFFF, 0xFFFF, 0xA1E7, 0x9604, 0xFFFF, 0xFFFF, 0xFFFF, 0x8D03,
0xA707, 0xA708, 0xAF2A, 0xAF2A, 0xA6E7, 0xA2C7, 0xBF4E, 0xCB71,
0x9E46, 0x9E26, 0x9A25, 0x9604, 0x80E0, 0x8922, 0x8D22, 0x8D22,
0xA2C7, 0xA2A7, 0x9E66, 0x95E4, 0xA2A6, 0x9E46, 0x9E25, 0x95C4,
0x99E5, 0x95C4, 0x9163, 0x8D02, 0x88E2, 0x84A1, 0x8060, 0x8020,
0x8500, 0xF7BD, 0xFFFF, 0xFFFF, 0x8901, 0xA148, 0xFFFF, 0xFFFF,
0x8040, 0xB9ED, 0xFFFF, 0xFFFF, 0x9926, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xE529, 0xD400, 0xFFFF, 0xFFFF, 0xFFFF, 0xD4C6,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xD000, 0xC400, 0xBC00, 0xB000, 0xC000, 0xB800, 0xAC00, 0xA000,
0xA800, 0xA800, 0x9C00, 0x9400, 0xC18C, 0x8C00, 0x8C00, 0x8C00,
0x9C00, 0x8C00, 0xFFFF, 0xFFFF, 0x9400, 0x8C00, 0xFFFF, 0xFFFF,
0x8800, 0xDEB5, 0xFFFF, 0xFFFF, 0xE2D6, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xD6D5, 0xAD8A, 0x8CC3, 0x8060, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0x8060, 0x90E4, 0xB1CC, 0xE759, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xF7AF,
0xFFFF, 0xFFFF, 0xFBDC, 0xF7B1, 0xFFFB, 0xFFE2, 0xFFE0, 0xFFE0,
0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE5,
0xF38C, 0xEF6A, 0xEB4B, 0xEB4F, 0xFFE0, 0xFBC0, 0xF7A0, 0xEB40,
0xFFE0, 0xFFE0, 0xFBC0, 0xF7A0, 0xFFF5, 0xFFE4, 0xF380, 0xEF60,
0xEF76, 0xFFFF, 0xFFFF, 0xFFFF, 0xE300, 0xCE60, 0xD6AB, 0xFFFF,
0xEB40, 0xE300, 0xCE60, 0xB180, 0xE720, 0xDEE0, 0xCE60, 0xB180,
0xF7BD, 0xB96B, 0xDAB4, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xB9CA, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xF399, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xD280, 0xEB40, 0xEB40, 0xEB40, 0xDAD1, 0xAD60, 0xC200, 0xCA40,
0xFFFF, 0xF7BE, 0xBDEB, 0x98C0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xEB40, 0xE720, 0xE300, 0xDAC0, 0xCA40, 0xC620, 0xC200, 0xBDE0,
0x9080, 0x94A0, 0x94A0, 0x9080, 0xFBDD, 0xE738, 0xE337, 0xE738,
0xD280, 0xCA40, 0xB5A0, 0x98C0, 0xB180, 0xA100, 0x94A0, 0x9080,
0x8C60, 0x9080, 0xC20C, 0xFFFF, 0xF7BD, 0xFFFF, 0xFFFF, 0xFFFF,
0xB9C9, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
};
END_EXTERN_C

View File

@ -1,11 +1,10 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* Tantric August 2008
*
* cheatmgr.h
*
* Cheat handling
***************************************************************************/
* gctime.h
****************************************************************************/
void SetupCheats();
extern "C" {
long long gettime();
u32 diff_usec(long long start,long long end);
}

View File

@ -3,16 +3,12 @@
* Width : 640
* Height: 480
*/
#ifndef _IMGBG_
#define _IMGBG_
#define BG_WIDTH (640)
#define BG_HEIGHT (480)
#define BG_RAW (614400)
#define BG_COMPRESSED (8789)
const unsigned char bg[]=
static unsigned char bg[]=
{
0x78,0x9c,0xed,0xdd,0x77,0xb0,0x94,0xf5,0xbd,0xf8,0x71,0x9d,0x4c,
0x26,0xe3,0x24,0x93,0xdc,0xeb,0xe4,0xc6,0x4b,0x20,0x89,0xf1,0xc6,
@ -693,4 +689,3 @@ const unsigned char bg[]=
0x14,0x14
};
#endif

View File

@ -1,568 +0,0 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* Michniewski 2008
*
* gui.cpp
***************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <wiiuse/wpad.h>
#include <malloc.h>
#include <pngu/pngu.h>
#include <ft2build.h>
#include <zlib.h>
#include FT_FREETYPE_H
#include "video.h"
#include "snes9xGX.h"
#include "gui.h"
struct sGui Gui;
GXTexObj texobj_BG, texobj_MENU;
void * texdata_bg; // stores the blended menu backdrop
void * texdata_menu; // stores the menu overlay
bool mem_alloced = 0;
extern GXTexObj texobj;
extern int vwidth, vheight;
extern s16 square[];
extern Mtx view;
extern int whichfb;
extern unsigned int copynow;
extern int screenheight;
extern unsigned int *xfb[2];
extern GXRModeObj *vmode;
extern FT_Library ftlibrary;
extern FT_Face face;
extern FT_GlyphSlot slot;
extern FT_UInt glyph_index;
extern int WaitButtonAB ();
// MAIN
static void
draw_vert (u8 pos, u8 c, f32 s, f32 t)
{
GX_Position1x8 (pos);
GX_Color1x8 (c);
GX_TexCoord2f32 (s, t);
}
static void
draw_square (Mtx v)
{
Mtx m; // model matrix.
Mtx mv; // modelview matrix.
guMtxIdentity (m);
guMtxTransApply (m, m, 0, 0, -100);
guMtxConcat (v, m, mv);
GX_LoadPosMtxImm (mv, GX_PNMTX0);
GX_Begin (GX_QUADS, GX_VTXFMT0, 4);
draw_vert (0, 0, 0.0, 0.0);
draw_vert (1, 0, 1.0, 0.0);
draw_vert (2, 0, 1.0, 1.0);
draw_vert (3, 0, 0.0, 1.0);
GX_End ();
}
void
gui_alphasetup ()
{
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
GX_SetAlphaUpdate(GX_ENABLE);
}
void
gui_alloc ()
{
if (!mem_alloced)
{
texdata_bg = memalign (32, 640 * 480 * 4);
texdata_menu = memalign (32, 640 * 480 * 4);
Gui.texmem = memalign (32, 640 * 480 * 4);
mem_alloced = 1;
}
}
void
gui_free ()
{
if (mem_alloced)
{
free (texdata_bg);
free (texdata_menu);
free (Gui.texmem);
mem_alloced = 0;
}
}
/****************************************************************************
* make BG
*
* Blend the last rendered emulator screen and the menu backdrop.
* Save this as a texture to be loaded later
****************************************************************************/
void
gui_makebg ()
{
IMGCTX ctx;
PNGUPROP imgProp;
/** Load menu backdrop (either from file or buffer) **/
ctx = PNGU_SelectImageFromDevice ("bg.png");
PNGU_GetImageProperties (ctx, &imgProp);
// can check image dimensions here
//texdata_bg = memalign (32, imgProp.imgWidth * imgProp.imgHeight * 4);
GX_InitTexObj (&texobj_BG, &texdata_bg, 640, 480, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
//PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, &texdata_bg, 255);
PNGU_DecodeToRGBA8 (ctx, 640, 480, Gui.texmem, 0, 7);
Make_Texture_RGBA8 (&texdata_bg, Gui.texmem, 640, 480);
PNGU_ReleaseImageContext (ctx);
DCFlushRange (&texdata_bg, imgProp.imgWidth * imgProp.imgHeight * 4);
/*
texdata_bg = memalign (32, 640 * 480 * 4);
#ifdef HW_RVL
// on wii copy from memory
memcpy (texdata_bg, (char *) backdrop, 640 * 480 * 2);
#else
// on gc copy from aram
ARAMFetch (texdata_bg, (char *) AR_BACKDROP, 640 * 480 * 2);
#endif
*/
/** blend last rendered snes frame and menu backdrop **/
// draw 640x480 quads
int xscale, yscale, xshift, yshift;
xshift = yshift = 0;
xscale = 320;
yscale = 240;
square[6] = square[3] = xscale + xshift;
square[0] = square[9] = -xscale + xshift;
square[4] = square[1] = yscale + yshift;
square[7] = square[10] = -yscale + yshift;
// draw 2 quads
GX_InvalidateTexAll ();
// behind (last snes frame)
square[2] = square[5] = square[8] = square[11] = 0; // z value
GX_InvVtxCache ();
GX_LoadTexObj (&texobj, GX_TEXMAP0); // load last rendered snes frame
draw_square (view);
// in front (menu backdrop)
square[2] = square[5] = square[8] = square[11] = 1; // z value
GX_InvVtxCache ();
GX_LoadTexObj (&texobj_BG, GX_TEXMAP0);
draw_square (view);
GX_DrawDone ();
/* DEBUG -----------
// show the output
VIDEO_SetNextFramebuffer (xfb[whichfb]);
VIDEO_Flush ();
copynow = GX_TRUE;
#ifdef VIDEO_THREADING
// Return to caller, don't waste time waiting for vb
LWP_ResumeThread (vbthread);
#endif
WaitButtonAB();
*/
// load blended image from efb to a texture
GX_InitTexObj (&texobj_BG, &texdata_bg, 640, 480, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_SetTexCopySrc ( 0,0,640,480 );
GX_SetTexCopyDst ( 640, 480, GX_TF_RGBA8, 0 );
GX_CopyTex (&texdata_bg, 0); // assuming that the efb is 640x480, which it should be
GX_PixModeSync (); // wait until copy has completed
DCFlushRange (&texdata_bg, 640 * 480 * 4);
square[2] = square[5] = square[8] = square[11] = 0; // reset z value
GX_InvVtxCache ();
}
void
gui_clearscreen ()
{
whichfb ^= 1;
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], COLOR_BLACK);
memset ( Gui.texmem, 0, sizeof(Gui.texmem) );
Gui.fontcolour = 0;
}
void
gui_draw ()
{
gui_drawbox (0, 0, 640, 80, 255, 255, 255, 128); // topbar
gui_drawbox (0, 370, 640, 480, 255, 255, 255, 128); // bottombar
gui_setfontcolour (0,255,0,255);
// top bar text
setfontsize (32); // 32/24 depending on whether selected or not
gui_DrawText (-1, 35, (char *)"Menu");
// main text
setfontsize (24);
gui_DrawText (75, 113, (char *)"Hello World");
// bottom bar text
setfontsize (24);
gui_DrawText (75, 400, (char *)"Description");
}
void
gui_savescreen ()
{
FILE* handle;
handle = fopen ("out.txt", "wb");
fwrite (Gui.texmem, 1, sizeof(Gui.texmem), handle);
fclose (handle);
printf("\nsaved screen.");
}
void
gui_showscreen ()
{
/** Screen to Texture **/
GX_InitTexObj (&texobj_MENU, texdata_menu, 640, 480, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
Make_Texture_RGBA8 (texdata_menu, Gui.texmem, 640, 480);
DCFlushRange (&texdata_menu, 640 * 480 * 4);
GX_InvalidateTexAll ();
/** thats nice, but will it blend? **/
// draw 640x480 quads
int xscale, yscale, xshift, yshift;
xshift = yshift = 0;
xscale = 320;
yscale = 240;
square[6] = square[3] = xscale + xshift;
square[0] = square[9] = -xscale + xshift;
square[4] = square[1] = yscale + yshift;
square[7] = square[10] = -yscale + yshift;
// draw 2 quads
// backdrop
square[2] = square[5] = square[8] = square[11] = 0; // z value
GX_InvVtxCache ();
GX_LoadTexObj (&texobj_BG, GX_TEXMAP0);
draw_square (view);
// menu overlay
square[2] = square[5] = square[8] = square[11] = 1; // z value
GX_InvVtxCache ();
GX_LoadTexObj (&texobj_MENU, GX_TEXMAP0);
draw_square (view);
GX_DrawDone ();
/** Display **/
// show the output
VIDEO_SetNextFramebuffer (xfb[whichfb]);
VIDEO_Flush ();
copynow = GX_TRUE;
#ifdef VIDEO_THREADING
/* Return to caller, don't waste time waiting for vb */
LWP_ResumeThread (vbthread);
#endif
WaitButtonAB();
square[2] = square[5] = square[8] = square[11] = 0; // z value
GX_InvVtxCache ();
}
/****************************************************************************
* Make Texture RGBA8
*
* input: pointer to RGBA data
* output: formatted texture data (GX_TF_RGBA8)
* code modified from quake wii (thanks :)
* todo: fix last few lines (?)
****************************************************************************/
void
Make_Texture_RGBA8 (void * dst_tex, void * src_data, int width, int height)
{
if ( (width % 4) || (height % 4) ) {
printf ("Error: make_texture_rgba8 width/height not multiple of 4");
return;
}
int i, x, y;
u8 *pos;
pos = (u8 *)dst_tex;
for (y = 0; y < height; y += 4) // process 4 lines at a time to make rows of tiles
{
u8* row1 = (u8 *) src_data;
u8* row2 = (u8 *) src_data;
u8* row3 = (u8 *) src_data;
u8* row4 = (u8 *) src_data;
row1 += width * 4 * (y + 0); // move 640 pixels x 4 bytes * line #
row2 += width * 4 * (y + 1);
row3 += width * 4 * (y + 2);
row4 += width * 4 * (y + 3);
for (x = 0; x < width; x += 4) // move across 4 pixels per tile
{
u8 AR[32];
u8 GB[32];
for (i = 0; i < 4; i++) // save those 4 pixels of data in texture format
{
u8* ptr1 = &(row1[(x + i) * 4]); // start at beginning of a row
u8* ptr2 = &(row2[(x + i) * 4]); // move across (4 pixels per tile + pixel offset within tile) * 4 bytes per pixel
u8* ptr3 = &(row3[(x + i) * 4]);
u8* ptr4 = &(row4[(x + i) * 4]);
AR[(i * 2) + 0] = ptr1[3]; // fill columns of tile with rgba data
AR[(i * 2) + 1] = ptr1[0];
AR[(i * 2) + 8] = ptr2[3];
AR[(i * 2) + 9] = ptr2[0];
AR[(i * 2) + 16] = ptr3[3];
AR[(i * 2) + 17] = ptr3[0];
AR[(i * 2) + 24] = ptr4[3];
AR[(i * 2) + 25] = ptr4[0];
GB[(i * 2) + 0] = ptr1[1];
GB[(i * 2) + 1] = ptr1[2];
GB[(i * 2) + 8] = ptr2[1];
GB[(i * 2) + 9] = ptr2[2];
GB[(i * 2) + 16] = ptr3[1];
GB[(i * 2) + 17] = ptr3[2];
GB[(i * 2) + 24] = ptr4[1];
GB[(i * 2) + 25] = ptr4[2];
}
memcpy(pos, AR, sizeof(AR)); // copy over to resulting texture
pos += sizeof(AR);
memcpy(pos, GB, sizeof(GB));
pos += sizeof(GB);
}
}
}
void
gui_drawbox (int x1, int y1, int width, int height, int r, int g, int b, int a)
{
u32 colour = ((u8)r << 24) | ((u8)g << 16) | ((u8)b << 8) | (u8)a;
int i, j;
u32* memory = (u32*) Gui.texmem;
for (j = y1; j<height; j++) {
for (i = x1; i<width; i++) {
memory[(j*640) + i] = colour;
}
}
}
/****************************************************************************
* DrawCharacter
* Draws a single character on the screen
****************************************************************************/
static void
gui_DrawCharacter (FT_Bitmap * bmp, FT_Int x, FT_Int y)
{
FT_Int i, j, p, q;
FT_Int x_max = x + bmp->width;
FT_Int y_max = y + bmp->rows;
int c;
u32* memory = (u32*)Gui.texmem;
for (i = x, p = 0; i < x_max; i++, p++)
{
for (j = y, q = 0; j < y_max; j++, q++)
{
if (i < 0 || j < 0 || i >= 640 || j >= 480)
continue;
c = bmp->buffer[q * bmp->width + p];
/*** Cool Anti-Aliasing doesn't work too well at hires on GC ***/
if (c > 128)
memory[(j * 640) + i] = Gui.fontcolour;
}
}
}
/****************************************************************************
* DrawText
*
* Place the font bitmap on the screen
****************************************************************************/
void
gui_DrawText (int x, int y, char *text)
{
int px, n;
int i;
int err;
int value, count;
n = strlen (text);
if (n == 0)
return;
/*** x == -1, auto centre ***/
if (x == -1)
{
value = 0;
px = 0;
}
else
{
value = 1;
px = x;
}
for (count = value; count < 2; count++)
{
/*** Draw the string ***/
for (i = 0; i < n; i++)
{
err = FT_Load_Char (face, text[i], FT_LOAD_RENDER);
if (err)
{
printf ("Error %c %d\n", text[i], err);
continue; /*** Skip unprintable characters ***/
}
if (count)
gui_DrawCharacter (&slot->bitmap, px + slot->bitmap_left, y - slot->bitmap_top);
px += slot->advance.x >> 6;
}
px = (640 - px) >> 1;
}
}
/****************************************************************************
* setfontcolour
*
* Uses RGB triple values.
****************************************************************************/
void
gui_setfontcolour (int r, int g, int b, int a)
{
Gui.fontcolour = ((u8)r << 24) | ((u8)g << 16) | ((u8)b << 8) | (u8)a;
}
/****************************************************************************
* DrawLine
*
* Quick'n'Dirty Bresenham line drawing routine.
****************************************************************************/
#define SIGN(x) ((x<0)?-1:((x>0)?1:0))
void
gui_DrawLine (int x1, int y1, int x2, int y2, int r, int g, int b, int a)
{
u32 colour;
int i, dx, dy, sdx, sdy, dxabs, dyabs, x, y, px, py;
int sp;
u32* memory = (u32*)Gui.texmem;
colour = ((u8)r << 24) | ((u8)g << 16) | ((u8)b << 8) | (u8)a;
dx = x2 - x1; /*** Horizontal distance ***/
dy = y2 - y1; /*** Vertical distance ***/
dxabs = abs (dx);
dyabs = abs (dy);
sdx = SIGN (dx);
sdy = SIGN (dy);
x = dyabs >> 1;
y = dxabs >> 1;
px = x1;
py = y1;
sp = (py * 640) + px;
/*** Plot this pixel ***/
memory[sp] = colour;
if (dxabs >= dyabs) /*** Mostly horizontal ***/
{
for (i = 0; i < dxabs; i++)
{
y += dyabs;
if (y >= dxabs)
{
y -= dxabs;
py += sdy;
}
px += sdx;
sp = (py * 640) + px;
memory[sp] = colour;
}
}
else
{
for (i = 0; i < dyabs; i++)
{
x += dxabs;
if (x >= dyabs)
{
x -= dyabs;
px += sdx;
}
py += sdy;
sp = (py * 640) + px;
memory[sp] = colour;
}
}
}
/* */
/** draw menu, etc **/
// - draw topbar, bottombar
// - draw icons
// - draw bar text
// draw main text
/** make textures **/
// - load background texture
// - draw onto quad
// - make foreground texture
// - draw onto quad
/** render image **/
/** update framebuffer **/
/* */
// EOF

View File

@ -1,43 +0,0 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* Michniewski 2008
*
* gui.h
***************************************************************************/
#ifndef __GUI_H__
#define __GUI_H__
#include <gccore.h>
struct sGui {
void * texmem; // rgba8 - working draw area
int currmenu;
int prevmenu;
u32 fontcolour;
int screenheight;
};
extern struct sGui Gui;
// Prototypes
void gui_alphasetup ();
void gui_makebg ();
void Make_Texture_RGBA8 (void * dst_tex, void * src_data, int width, int height);
void gui_drawbox (int x1, int y1, int width, int height, int r, int g, int b, int a);
void gui_DrawText (int x, int y, char *text);
void gui_setfontcolour (int r, int g, int b, int a);
void gui_DrawLine (int x1, int y1, int x2, int y2, int r, int g, int b, int a);
void gui_clearscreen ();
void gui_draw ();
void gui_showscreen ();
void gui_savescreen ();
// external functions
extern void setfontsize (int pixelsize);
#endif

View File

@ -1,622 +0,0 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* softdev July 2006
* crunchy2 May-June 2007
* Michniewski 2008
* Tantric September 2008
*
* input.cpp
*
* Wii/Gamecube controller management
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ogcsys.h>
#include <unistd.h>
#include <wiiuse/wpad.h>
#include "snes9x.h"
#include "memmap.h"
#include "controls.h"
#include "snes9xGX.h"
#include "button_mapping.h"
#include "s9xconfig.h"
#include "menu.h"
#include "video.h"
#include "input.h"
extern int ConfigRequested;
/****************************************************************************
* Controller Functions
*
* The following map the NGC Pads to the *NEW* controller system.
***************************************************************************/
#define ASSIGN_BUTTON_TRUE( keycode, snescmd ) \
S9xMapButton( keycode, cmd = S9xGetCommandT(snescmd), true)
#define ASSIGN_BUTTON_FALSE( keycode, snescmd ) \
S9xMapButton( keycode, cmd = S9xGetCommandT(snescmd), false)
/*** Gamecube controller Padmap ***/
unsigned int gcpadmap[] = {
PAD_BUTTON_A, PAD_BUTTON_B,
PAD_BUTTON_X, PAD_BUTTON_Y,
PAD_TRIGGER_L, PAD_TRIGGER_R,
PAD_TRIGGER_Z, PAD_BUTTON_START,
PAD_BUTTON_UP, PAD_BUTTON_DOWN,
PAD_BUTTON_LEFT, PAD_BUTTON_RIGHT
};
/*** Wiimote Padmap ***/
unsigned int wmpadmap[] = {
WPAD_BUTTON_B, WPAD_BUTTON_2,
WPAD_BUTTON_1, WPAD_BUTTON_A,
0x0000, 0x0000,
WPAD_BUTTON_MINUS, WPAD_BUTTON_PLUS,
WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT,
WPAD_BUTTON_UP, WPAD_BUTTON_DOWN
};
/*** Classic Controller Padmap ***/
unsigned int ccpadmap[] = {
WPAD_CLASSIC_BUTTON_A, WPAD_CLASSIC_BUTTON_B,
WPAD_CLASSIC_BUTTON_X, WPAD_CLASSIC_BUTTON_Y,
WPAD_CLASSIC_BUTTON_FULL_L, WPAD_CLASSIC_BUTTON_FULL_R,
WPAD_CLASSIC_BUTTON_MINUS, WPAD_CLASSIC_BUTTON_PLUS,
WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN,
WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT
};
/*** Nunchuk + wiimote Padmap ***/
unsigned int ncpadmap[] = {
WPAD_BUTTON_A, WPAD_BUTTON_B,
WPAD_NUNCHUK_BUTTON_C, WPAD_NUNCHUK_BUTTON_Z,
WPAD_BUTTON_2, WPAD_BUTTON_1,
WPAD_BUTTON_MINUS, WPAD_BUTTON_PLUS,
WPAD_BUTTON_UP, WPAD_BUTTON_DOWN,
WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT
};
/*** Superscope : GC controller button mapping ***/
unsigned int gcscopemap[] = { PAD_TRIGGER_Z, PAD_BUTTON_B,
PAD_BUTTON_A, PAD_BUTTON_Y, PAD_BUTTON_START
};
/*** Superscope : wiimote button mapping ***/
unsigned int wmscopemap[] = { WPAD_BUTTON_MINUS, WPAD_BUTTON_B,
WPAD_BUTTON_A, WPAD_BUTTON_DOWN, WPAD_BUTTON_PLUS
};
/*** Mouse : GC controller button mapping ***/
unsigned int gcmousemap[] = { PAD_BUTTON_A, PAD_BUTTON_B };
/*** Mouse : wiimote button mapping ***/
unsigned int wmmousemap[] = { WPAD_BUTTON_A, WPAD_BUTTON_B };
/*** Justifier : GC controller button mapping ***/
unsigned int gcjustmap[] = { PAD_BUTTON_A, PAD_BUTTON_B, PAD_BUTTON_START };
/*** Justifier : wiimote button mapping ***/
unsigned int wmjustmap[] = { WPAD_BUTTON_A, WPAD_BUTTON_B, WPAD_BUTTON_PLUS };
/****************************************************************************
* WPAD_Stick
*
* Get X/Y value from Wii Joystick (classic, nunchuk) input
***************************************************************************/
s8 WPAD_Stick(u8 chan, u8 right, int axis)
{
float mag = 0.0;
float ang = 0.0;
WPADData *data = WPAD_Data(chan);
switch (data->exp.type)
{
case WPAD_EXP_NUNCHUK:
case WPAD_EXP_GUITARHERO3:
if (right == 0)
{
mag = data->exp.nunchuk.js.mag;
ang = data->exp.nunchuk.js.ang;
}
break;
case WPAD_EXP_CLASSIC:
if (right == 0)
{
mag = data->exp.classic.ljs.mag;
ang = data->exp.classic.ljs.ang;
}
else
{
mag = data->exp.classic.rjs.mag;
ang = data->exp.classic.rjs.ang;
}
break;
default:
break;
}
/* calculate x/y value (angle need to be converted into radian) */
if (mag > 1.0) mag = 1.0;
else if (mag < -1.0) mag = -1.0;
double val;
if(axis == 0) // x-axis
val = mag * sin((PI * ang)/180.0f);
else // y-axis
val = mag * cos((PI * ang)/180.0f);
return (s8)(val * 128.0f);
}
// hold superscope/mouse/justifier cursor positions
static int cursor_x[5] = {0,0,0,0,0};
static int cursor_y[5] = {0,0,0,0,0};
/****************************************************************************
* UpdateCursorPosition
*
* Updates X/Y coordinates for Superscope/mouse/justifier position
***************************************************************************/
void UpdateCursorPosition (int pad, int &pos_x, int &pos_y)
{
#define SCOPEPADCAL 20
// gc left joystick
signed char pad_x = PAD_StickX (pad);
signed char pad_y = PAD_StickY (pad);
if (pad_x > SCOPEPADCAL){
pos_x += (pad_x*1.0)/SCOPEPADCAL;
if (pos_x > 256) pos_x = 256;
}
if (pad_x < -SCOPEPADCAL){
pos_x -= (pad_x*-1.0)/SCOPEPADCAL;
if (pos_x < 0) pos_x = 0;
}
if (pad_y < -SCOPEPADCAL){
pos_y += (pad_y*-1.0)/SCOPEPADCAL;
if (pos_y > 224) pos_y = 224;
}
if (pad_y > SCOPEPADCAL){
pos_y -= (pad_y*1.0)/SCOPEPADCAL;
if (pos_y < 0) pos_y = 0;
}
#ifdef HW_RVL
struct ir_t ir; // wiimote ir
WPAD_IR(pad, &ir);
if (ir.valid)
{
pos_x = (ir.x * 256) / 640;
pos_y = (ir.y * 224) / 480;
}
else
{
signed char wm_ax = WPAD_Stick (pad, 0, 0);
signed char wm_ay = WPAD_Stick (pad, 0, 1);
if (wm_ax > SCOPEPADCAL){
pos_x += (wm_ax*1.0)/SCOPEPADCAL;
if (pos_x > 256) pos_x = 256;
}
if (wm_ax < -SCOPEPADCAL){
pos_x -= (wm_ax*-1.0)/SCOPEPADCAL;
if (pos_x < 0) pos_x = 0;
}
if (wm_ay < -SCOPEPADCAL){
pos_y += (wm_ay*-1.0)/SCOPEPADCAL;
if (pos_y > 224) pos_y = 224;
}
if (wm_ay > SCOPEPADCAL){
pos_y -= (wm_ay*1.0)/SCOPEPADCAL;
if (pos_y < 0) pos_y = 0;
}
}
#endif
}
/****************************************************************************
* decodepad
*
* Reads the changes (buttons pressed, etc) from a controller and reports
* these changes to Snes9x
***************************************************************************/
void decodepad (int pad)
{
int i, offset;
float t;
signed char pad_x = PAD_StickX (pad);
signed char pad_y = PAD_StickY (pad);
u32 jp = PAD_ButtonsHeld (pad);
#ifdef HW_RVL
signed char wm_ax = 0;
signed char wm_ay = 0;
u32 wp = 0;
wm_ax = WPAD_Stick ((u8)pad, 0, 0);
wm_ay = WPAD_Stick ((u8)pad, 0, 1);
wp = WPAD_ButtonsHeld (pad);
u32 exp_type;
if ( WPAD_Probe(pad, &exp_type) != 0 )
exp_type = WPAD_EXP_NONE;
#endif
/***
Gamecube Joystick input
***/
// Is XY inside the "zone"?
if (pad_x * pad_x + pad_y * pad_y > PADCAL * PADCAL)
{
/*** we don't want division by zero ***/
if (pad_x > 0 && pad_y == 0)
jp |= PAD_BUTTON_RIGHT;
if (pad_x < 0 && pad_y == 0)
jp |= PAD_BUTTON_LEFT;
if (pad_x == 0 && pad_y > 0)
jp |= PAD_BUTTON_UP;
if (pad_x == 0 && pad_y < 0)
jp |= PAD_BUTTON_DOWN;
if (pad_x != 0 && pad_y != 0)
{
/*** Recalc left / right ***/
t = (float) pad_y / pad_x;
if (t >= -2.41421356237 && t < 2.41421356237)
{
if (pad_x >= 0)
jp |= PAD_BUTTON_RIGHT;
else
jp |= PAD_BUTTON_LEFT;
}
/*** Recalc up / down ***/
t = (float) pad_x / pad_y;
if (t >= -2.41421356237 && t < 2.41421356237)
{
if (pad_y >= 0)
jp |= PAD_BUTTON_UP;
else
jp |= PAD_BUTTON_DOWN;
}
}
}
#ifdef HW_RVL
/***
Wii Joystick (classic, nunchuk) input
***/
// Is XY inside the "zone"?
if (wm_ax * wm_ax + wm_ay * wm_ay > PADCAL * PADCAL)
{
/*** we don't want division by zero ***/
if (wm_ax > 0 && wm_ay == 0)
wp |= WPAD_BUTTON_RIGHT;
if (wm_ax < 0 && wm_ay == 0)
wp |= WPAD_BUTTON_LEFT;
if (wm_ax == 0 && wm_ay > 0)
wp |= WPAD_BUTTON_UP;
if (wm_ax == 0 && wm_ay < 0)
wp |= WPAD_BUTTON_DOWN;
if (wm_ax != 0 && wm_ay != 0)
{
/*** Recalc left / right ***/
t = (float) wm_ay / wm_ax;
if (t >= -2.41421356237 && t < 2.41421356237)
{
if (wm_ax >= 0)
wp |= WPAD_BUTTON_RIGHT;
else
wp |= WPAD_BUTTON_LEFT;
}
/*** Recalc up / down ***/
t = (float) wm_ax / wm_ay;
if (t >= -2.41421356237 && t < 2.41421356237)
{
if (wm_ay >= 0)
wp |= WPAD_BUTTON_UP;
else
wp |= WPAD_BUTTON_DOWN;
}
}
}
#endif
/*** Fix offset to pad ***/
offset = ((pad + 1) << 4);
/*** Report pressed buttons (gamepads) ***/
for (i = 0; i < MAXJP; i++)
{
if ( (jp & gcpadmap[i]) // gamecube controller
#ifdef HW_RVL
|| ( (exp_type == WPAD_EXP_NONE) && (wp & wmpadmap[i]) ) // wiimote
|| ( (exp_type == WPAD_EXP_CLASSIC) && (wp & ccpadmap[i]) ) // classic controller
|| ( (exp_type == WPAD_EXP_NUNCHUK) && (wp & ncpadmap[i]) ) // nunchuk + wiimote
#endif
)
S9xReportButton (offset + i, true);
else
S9xReportButton (offset + i, false);
}
/*** Superscope ***/
if (Settings.SuperScopeMaster && pad == GCSettings.Superscope - 1) // report only once
{
// buttons
offset = 0x50;
for (i = 0; i < 6; i++)
{
if (jp & gcscopemap[i]
#ifdef HW_RVL
|| wp & wmscopemap[i]
#endif
)
S9xReportButton(offset + i, true);
else
S9xReportButton(offset + i, false);
}
// pointer
offset = 0x80;
UpdateCursorPosition(pad, cursor_x[0], cursor_y[0]);
S9xReportPointer(offset, (u16) cursor_x[0], (u16) cursor_y[0]);
}
/*** Mouse ***/
else if (Settings.MouseMaster && pad < GCSettings.Mouse)
{
// buttons
offset = 0x60 + (2 * pad);
for (i = 0; i < 2; i++)
{
if (jp & gcmousemap[i]
#ifdef HW_RVL
|| wp & wmmousemap[i]
#endif
)
S9xReportButton(offset + i, true);
else
S9xReportButton(offset + i, false);
}
// pointer
offset = 0x81;
UpdateCursorPosition(pad, cursor_x[1 + pad], cursor_y[1 + pad]);
S9xReportPointer(offset + pad, (u16) cursor_x[1 + pad],
(u16) cursor_y[1 + pad]);
}
/*** Justifier ***/
else if (Settings.JustifierMaster && pad < GCSettings.Justifier)
{
// buttons
offset = 0x70 + (3 * pad);
for (i = 0; i < 3; i++)
{
if (jp & gcjustmap[i]
#ifdef HW_RVL
|| wp & wmjustmap[i]
#endif
)
S9xReportButton(offset + i, true);
else
S9xReportButton(offset + i, false);
}
// pointer
offset = 0x83;
UpdateCursorPosition(pad, cursor_x[3 + pad], cursor_y[3 + pad]);
S9xReportPointer(offset + pad, (u16) cursor_x[3 + pad],
(u16) cursor_y[3 + pad]);
}
}
/****************************************************************************
* NGCReportButtons
*
* Called on each rendered frame
* Our way of putting controller input into Snes9x
***************************************************************************/
void NGCReportButtons ()
{
s8 gc_px = PAD_SubStickX (0);
s8 gc_py = PAD_SubStickY (0);
u16 gc_pb = PAD_ButtonsHeld (0);
#ifdef HW_RVL
s8 wm_sx = WPAD_Stick (0,1,0);
s8 wm_sy = WPAD_Stick (0,1,1);
u32 wm_pb = WPAD_ButtonsHeld (0); // wiimote / expansion button info
#endif
/*** Check for video zoom ***/
if (GCSettings.NGCZoom)
{
if (gc_py < -36 || gc_py > 36)
zoom ((float) gc_py / -36);
#ifdef HW_RVL
if (wm_sy < -36 || wm_sy > 36)
zoom ((float) wm_sy / -36);
#endif
}
Settings.TurboMode = ( (gc_px > 70)
#ifdef HW_RVL
|| (wm_sx > 70)
#endif
); // RIGHT on c-stick and on classic ctrlr right joystick
/*** Check for menu:
CStick left
OR "L+R+X+Y" (eg. Hombrew/Adapted SNES controllers)
OR "Home" on the wiimote or classic controller
OR LEFT on classic right analog stick***/
if ((gc_px < -70) ||
((gc_pb & PAD_TRIGGER_L) &&
(gc_pb & PAD_TRIGGER_R ) &&
(gc_pb & PAD_BUTTON_X) &&
(gc_pb & PAD_BUTTON_Y ))
#ifdef HW_RVL
|| (wm_pb & WPAD_BUTTON_HOME)
|| (wm_pb & WPAD_CLASSIC_BUTTON_HOME)
|| (wm_sx < -70)
#endif
)
{
ConfigRequested = 1; // go to the menu
}
else
{
int j = (Settings.MultiPlayer5Master == true ? 4 : 2);
for (int i = 0; i < j; i++)
decodepad (i);
}
}
void SetControllers ()
{
if (Settings.MultiPlayer5Master == true)
{
S9xSetController (0, CTL_JOYPAD, 0, 0, 0, 0);
S9xSetController (1, CTL_MP5, 1, 2, 3, -1);
}
else if (Settings.SuperScopeMaster == true)
{
S9xSetController (0, CTL_JOYPAD, 0, 0, 0, 0);
S9xSetController (1, CTL_SUPERSCOPE, 1, 0, 0, 0);
}
else if (Settings.MouseMaster == true)
{
S9xSetController (0, CTL_MOUSE, 0, 0, 0, 0);
if (GCSettings.Mouse == 2)
S9xSetController (1, CTL_MOUSE, 1, 0, 0, 0);
else
S9xSetController (1, CTL_JOYPAD, 1, 0, 0, 0);
}
else if (Settings.JustifierMaster == true)
{
S9xSetController(0, CTL_JUSTIFIER, 0, 0, 0, 0);
if(GCSettings.Justifier == 2)
S9xSetController(1, CTL_JUSTIFIER, 1, 0, 0, 0);
else
S9xSetController (1, CTL_JOYPAD, 1, 0, 0, 0);
}
else
{
// Plugin 2 Joypads by default
S9xSetController (0, CTL_JOYPAD, 0, 0, 0, 0);
S9xSetController (1, CTL_JOYPAD, 1, 0, 0, 0);
}
}
/****************************************************************************
* Set the default mapping for NGC
***************************************************************************/
void SetDefaultButtonMap ()
{
int maxcode = 0x10;
s9xcommand_t cmd;
/*** Joypad 1 ***/
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 A");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 B");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 X");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Y");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 L");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 R");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Select");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Start");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Up");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Down");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Left");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Right");
maxcode = 0x20;
/*** Joypad 2 ***/
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 A");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 B");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 X");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Y");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 L");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 R");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Select");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Start");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Up");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Down");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Left");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Right");
maxcode = 0x30;
/*** Joypad 3 ***/
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 A");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 B");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 X");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Y");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 L");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 R");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Select");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Start");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Up");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Down");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Left");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Right");
maxcode = 0x40;
/*** Joypad 4 ***/
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 A");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 B");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 X");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Y");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 L");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 R");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Select");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Start");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Up");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Down");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Left");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Right");
maxcode = 0x50;
/*** Superscope ***/
ASSIGN_BUTTON_FALSE (maxcode++, "Superscope AimOffscreen");
ASSIGN_BUTTON_FALSE (maxcode++, "Superscope Fire");
ASSIGN_BUTTON_FALSE (maxcode++, "Superscope Cursor");
ASSIGN_BUTTON_FALSE (maxcode++, "Superscope ToggleTurbo");
ASSIGN_BUTTON_FALSE (maxcode++, "Superscope Pause");
maxcode = 0x60;
/*** Mouse ***/
ASSIGN_BUTTON_FALSE (maxcode++, "Mouse1 L");
ASSIGN_BUTTON_FALSE (maxcode++, "Mouse1 R");
ASSIGN_BUTTON_FALSE (maxcode++, "Mouse2 L");
ASSIGN_BUTTON_FALSE (maxcode++, "Mouse2 R");
maxcode = 0x70;
/*** Justifier ***/
ASSIGN_BUTTON_FALSE (maxcode++, "Justifier1 AimOffscreen");
ASSIGN_BUTTON_FALSE (maxcode++, "Justifier1 Trigger");
ASSIGN_BUTTON_FALSE (maxcode++, "Justifier1 Start");
ASSIGN_BUTTON_FALSE (maxcode++, "Justifier2 AimOffscreen");
ASSIGN_BUTTON_FALSE (maxcode++, "Justifier2 Trigger");
ASSIGN_BUTTON_FALSE (maxcode++, "Justifier2 Start");
maxcode = 0x80;
S9xMapPointer( maxcode++, S9xGetCommandT("Pointer Superscope"), false);
S9xMapPointer( maxcode++, S9xGetCommandT("Pointer Mouse1"), false);
S9xMapPointer( maxcode++, S9xGetCommandT("Pointer Mouse2"), false);
S9xMapPointer( maxcode++, S9xGetCommandT("Pointer Justifier1"), false);
S9xMapPointer( maxcode++, S9xGetCommandT("Pointer Justifier2"), false);
SetControllers ();
}

View File

@ -1,42 +0,0 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* softdev July 2006
* crunchy2 May-June 2007
* Michniewski 2008
* Tantric September 2008
*
* input.h
*
* Wii/Gamecube controller management
***************************************************************************/
#ifndef _INPUT_H_
#define _INPUT_H_
#include <gccore.h>
#define PI 3.14159265f
#define PADCAL 50
#define MAXJP 12 // # of mappable controller buttons
extern unsigned int gcpadmap[];
extern unsigned int wmpadmap[];
extern unsigned int ccpadmap[];
extern unsigned int ncpadmap[];
extern unsigned int gcscopemap[];
extern unsigned int wmscopemap[];
extern unsigned int gcmousemap[];
extern unsigned int wmmousemap[];
extern unsigned int gcjustmap[];
extern unsigned int wmjustmap[];
s8 WPAD_Stick(u8 chan,u8 right, int axis);
void UpdateCursorPosition (int pad, int &pos_x, int &pos_y);
void decodepad (int pad);
void NGCReportButtons ();
void SetControllers ();
void SetDefaultButtonMap ();
#endif

View File

@ -1,15 +1,14 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Port
* softdev July 2006
* crunchy2 May-June 2007
* Tantric September 2008
*
* memcardop.cpp
* mcsave.cpp
*
* Memory Card routines
***************************************************************************/
* Memory Card Save Routines.
****************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <stdio.h>
@ -17,118 +16,136 @@
#include <string.h>
#include <unistd.h>
#include "snes9x.h"
#include "memmap.h"
#include "debug.h"
#include "cpuexec.h"
#include "ppu.h"
#include "apu.h"
#include "display.h"
#include "gfx.h"
#include "soundux.h"
#include "spc700.h"
#include "spc7110.h"
#include "snes9xGX.h"
#include "video.h"
#include "menudraw.h"
#include "ftfont.h"
#include "s9xconfig.h"
#include "audio.h"
#include "menu.h"
#include "sram.h"
#include "preferences.h"
#include "memcardop.h"
#include "fileop.h"
#include "filesel.h"
#include "mcsave.h"
#define VERIFBUFFERSIZE 65536
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32);
unsigned char savebuffer[SAVEBUFFERSIZE] ATTRIBUTE_ALIGN (32);
unsigned char verifbuffer[VERIFBUFFERSIZE] ATTRIBUTE_ALIGN (32);
card_dir CardDir;
card_file CardFile;
card_stat CardStatus;
extern void uselessinquiry();
/****************************************************************************
* Clear the savebuffer
****************************************************************************/
void
ClearSaveBuffer ()
{
memset (savebuffer, 0, SAVEBUFFERSIZE);
}
/****************************************************************************
* CardFileExists
*
* Wrapper to search through the files on the card.
* Returns TRUE if found.
***************************************************************************/
****************************************************************************/
int
CardFileExists (char *filename, int slot)
{
int CardError;
int CardError;
CardError = CARD_FindFirst (slot, &CardDir, TRUE);
while (CardError != CARD_ERROR_NOFILE)
{
CardError = CARD_FindNext (&CardDir);
CardError = CARD_FindFirst (slot, &CardDir, TRUE);
while (CardError != CARD_ERROR_NOFILE)
{
CardError = CARD_FindNext (&CardDir);
if (strcmp ((char *) CardDir.filename, filename) == 0)
return 1;
}
if (strcmp ((char *) CardDir.filename, filename) == 0)
return 1;
}
return 0;
}
/****************************************************************************
* TestCard
*
* Checks to see if a card is in the card slot specified
***************************************************************************/
bool TestCard(int slot, bool silent)
{
// Memory Cards do not work in Wii mode - disable
#ifdef HW_RVL
return false;
#endif
/*** Initialize Card System ***/
memset (SysArea, 0, CARD_WORKAREA);
CARD_Init ("SNES", "00");
/*** Try to mount the card ***/
if (MountCard(slot, silent) == 0)
{
// Mount successful!
if(!silent)
{
if (slot == CARD_SLOTA)
WaitPrompt((char*) "Mounted Slot A Memory Card!");
else
WaitPrompt((char*) "Mounted Slot B Memory Card!");
}
CARD_Unmount (slot);
return true;
}
else
{
if(!silent)
{
if (slot == CARD_SLOTA)
WaitPrompt((char*) "Unable to Mount Slot A Memory Card!");
else
WaitPrompt((char*) "Unable to Mount Slot B Memory Card!");
}
return false;
}
return 0;
}
/****************************************************************************
* MountCard
*
* Mounts the memory card in the given slot.
* Mounts the memory card in the given slot. Error checking is done and
* workarounds implemented for when the mount fails.
* Returns the result of the last attempted CARD_Mount command.
***************************************************************************/
int MountCard(int cslot, bool silent)
{
int ret = -1;
int tries = 0;
****************************************************************************/
int MountCard(int cslot)
{
int ret;
int tries;
EXI_ProbeReset();
//Mount the card
ret = CARD_Mount (cslot, SysArea, NULL);
// Mount the card
while ( tries < 10 && ret != 0)
tries = 0;
while ( tries < 3 && ret == CARD_ERROR_IOERROR )
{
EXI_ProbeReset ();
if (cslot == CARD_SLOTA)
WaitPrompt((char*) "Replug card in slot A!");
else
WaitPrompt((char*) "Replug card in slot B!");
ShowAction ((char*) "");
ret = CARD_Mount (cslot, SysArea, NULL);
VIDEO_WaitVSync ();
tries++;
}
tries = 0;
while ( tries < 5 && ret == CARD_ERROR_NOCARD )
{
EXI_ProbeReset ();
ShowAction ((char*) "Mounting card...");
CARD_Unmount (cslot);
usleep(500000); // wait half second
ShowAction ((char*) "");
usleep(500000); // wait half second
ret = CARD_Mount (cslot, SysArea, NULL);
tries++;
}
tries = 0;
while ( tries < 5 && ret == CARD_ERROR_UNLOCKED )
{
EXI_ProbeReset ();
ShowAction ((char*) "Waiting for unlock...");
usleep(500000); // wait half second
ShowAction ((char*) "");
usleep(500000); // wait half second
ret = CARD_Probe(cslot);
tries++;
}
return ret;
}
/****************************************************************************
* Verify Memory Card file against buffer
***************************************************************************/
****************************************************************************/
int
VerifyMCFile (unsigned char *buf, int slot, char *filename, int datasize)
{
@ -142,36 +159,36 @@ VerifyMCFile (unsigned char *buf, int slot, char *filename, int datasize)
/*** Initialize Card System ***/
memset (SysArea, 0, CARD_WORKAREA);
CARD_Init ("SNES", "00");
/*** Try to mount the card ***/
CardError = MountCard(slot, NOTSILENT);
CardError = MountCard(slot);
if (CardError == 0)
{
/*** Get Sector Size ***/
CARD_GetSectorSize (slot, &SectorSize);
if (!CardFileExists (filename, slot))
{
CARD_Unmount (slot);
WaitPrompt((char*) "Unable to open file for verify!");
return 0;
}
memset (&CardFile, 0, sizeof (CardFile));
CardError = CARD_Open (slot, filename, &CardFile);
blocks = CardFile.len;
if (blocks < SectorSize)
blocks = SectorSize;
if (blocks % SectorSize)
blocks += SectorSize;
if (blocks > (unsigned int)datasize)
blocks = datasize;
memset (verifbuffer, 0, VERIFBUFFERSIZE);
bytesleft = blocks;
bytesread = 0;
@ -185,16 +202,16 @@ VerifyMCFile (unsigned char *buf, int slot, char *filename, int datasize)
WaitPrompt((char*) "File did not verify!");
return 0;
}
bytesleft -= SectorSize;
bytesread += SectorSize;
sprintf (msg, "Verified %d of %d bytes", bytesread, blocks);
ShowProgress (msg, bytesread, blocks);
}
CARD_Close (&CardFile);
CARD_Unmount (slot);
return 1;
}
else
@ -202,54 +219,56 @@ VerifyMCFile (unsigned char *buf, int slot, char *filename, int datasize)
WaitPrompt((char*) "Unable to Mount Slot A Memory Card!");
else
WaitPrompt((char*) "Unable to Mount Slot B Memory Card!");
return 0;
}
/****************************************************************************
* Load savebuffer from Memory Card file
***************************************************************************/
****************************************************************************/
int
LoadBufferFromMC (unsigned char *buf, int slot, char *filename, bool8 silent)
{
int CardError;
unsigned int blocks;
unsigned int SectorSize;
char msg[80];
int bytesleft = 0;
int bytesread = 0;
/*** Initialize Card System ***/
memset (SysArea, 0, CARD_WORKAREA);
CARD_Init ("SNES", "00");
/*** Try to mount the card ***/
CardError = MountCard(slot, NOTSILENT);
CardError = MountCard(slot);
if (CardError == 0)
{
/*** Get Sector Size ***/
CARD_GetSectorSize (slot, &SectorSize);
if (!CardFileExists (filename, slot))
{
if (!silent)
if ( !silent )
WaitPrompt((char*) "Unable to open file");
return 0;
}
memset (&CardFile, 0, sizeof (CardFile));
CardError = CARD_Open (slot, filename, &CardFile);
blocks = CardFile.len;
if (blocks < SectorSize)
blocks = SectorSize;
if (blocks % SectorSize)
blocks += SectorSize;
memset (buf, 0, 0x22000);
bytesleft = blocks;
bytesread = 0;
while (bytesleft > 0)
@ -257,6 +276,9 @@ LoadBufferFromMC (unsigned char *buf, int slot, char *filename, bool8 silent)
CARD_Read (&CardFile, buf + bytesread, SectorSize, bytesread);
bytesleft -= SectorSize;
bytesread += SectorSize;
sprintf (msg, "Read %d of %d bytes", bytesread, blocks);
ShowProgress (msg, bytesread, blocks);
}
CARD_Close (&CardFile);
CARD_Unmount (slot);
@ -266,14 +288,14 @@ LoadBufferFromMC (unsigned char *buf, int slot, char *filename, bool8 silent)
WaitPrompt((char*) "Unable to Mount Slot A Memory Card!");
else
WaitPrompt((char*) "Unable to Mount Slot B Memory Card!");
return bytesread;
}
/****************************************************************************
* Write savebuffer to Memory Card file
***************************************************************************/
****************************************************************************/
int
SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool8 silent)
{
@ -281,26 +303,26 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
unsigned int blocks;
unsigned int SectorSize;
char msg[80];
/*** Initialize Card System ***/
memset (SysArea, 0, CARD_WORKAREA);
CARD_Init ("SNES", "00");
/*** Try to mount the card ***/
CardError = MountCard(slot, NOTSILENT);
CardError = MountCard(slot);
if (CardError == 0)
{
/*** Get Sector Size ***/
CARD_GetSectorSize (slot, &SectorSize);
if (datasize)
{
{
/*** Calculate number of blocks required ***/
blocks = (datasize / SectorSize) * SectorSize;
if (datasize % SectorSize)
blocks += SectorSize;
/*** Does this file exist ? ***/
if (CardFileExists (filename, slot))
{
@ -312,11 +334,36 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
WaitPrompt((char*) "Unable to open card file!");
return 0;
}
// if ( (s32)blocks < CardFile.len ) /*** new data is shorter ***/
// {
// CARD_Close (&CardFile);
//
// /*** Delete the existing longer file ***/
// CardError = CARD_Delete(slot, filename);
// if (CardError)
// {
// CARD_Unmount (slot);
// WaitPrompt((char*) "Unable to delete existing file!");
// return 0;
// }
//
// /*** Create new, shorter file ***/
// CardError = CARD_Create (slot, filename, blocks, &CardFile);
// if (CardError)
// {
// CARD_Unmount (slot);
// WaitPrompt((char*) "Unable to create updated card file!");
// return 0;
// }
//
// }
// else
if ( (s32)blocks > CardFile.len ) /*** new data is longer ***/
{
CARD_Close (&CardFile);
/*** Try to create temp file to check available space ***/
CardError = CARD_Create (slot, "TEMPFILESNES9XGX201", blocks, &CardFile);
if (CardError)
@ -325,7 +372,7 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
WaitPrompt((char*) "Not enough space to update file!");
return 0;
}
/*** Delete the temporary file ***/
CARD_Close (&CardFile);
CardError = CARD_Delete(slot, "TEMPFILESNES9XGX201");
@ -335,7 +382,7 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
WaitPrompt((char*) "Unable to delete temporary file!");
return 0;
}
/*** Delete the existing shorter file ***/
CardError = CARD_Delete(slot, filename);
if (CardError)
@ -344,7 +391,7 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
WaitPrompt((char*) "Unable to delete existing file!");
return 0;
}
/*** Create new, longer file ***/
CardError = CARD_Create (slot, filename, blocks, &CardFile);
if (CardError)
@ -362,14 +409,14 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
if (CardError)
{
CARD_Unmount (slot);
if ( CardError == CARD_ERROR_INSSPACE )
if ( CardError = CARD_ERROR_INSSPACE )
WaitPrompt((char*) "Not enough space to create file!");
else
WaitPrompt((char*) "Unable to create card file!");
return 0;
}
}
/*** Now, have an open file handle, ready to send out the data ***/
CARD_GetStatus (slot, CardFile.filenum, &CardStatus);
CardStatus.icon_addr = 0x0;
@ -377,7 +424,7 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
CardStatus.icon_speed = 1;
CardStatus.comment_addr = 2048;
CARD_SetStatus (slot, CardFile.filenum, &CardStatus);
int byteswritten = 0;
int bytesleft = blocks;
while (bytesleft > 0)
@ -387,14 +434,14 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
SectorSize, byteswritten);
bytesleft -= SectorSize;
byteswritten += SectorSize;
sprintf (msg, "Wrote %d of %d bytes", byteswritten, blocks);
ShowProgress (msg, byteswritten, blocks);
}
CARD_Close (&CardFile);
CARD_Unmount (slot);
if ( GCSettings.VerifySaves )
{
/*** Verify the written file, but only up to the length we wrote
@ -416,7 +463,129 @@ SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool
WaitPrompt((char*) "Unable to Mount Slot A Memory Card!");
else
WaitPrompt((char*) "Unable to Mount Slot B Memory Card!");
return 0;
}
/****************************************************************************
* Memory Card SRAM Load
****************************************************************************/
void
LoadSRAMFromMC (int slot, int silent)
{
char filename[MAXPATHLEN];
int offset = 0;
ShowAction ((char*) "Loading SRAM from MC...");
// check for 'old' version of sram
sprintf (filename, "%s.srm", Memory.ROMName); // Build old SRAM filename
offset = LoadBufferFromMC (savebuffer, slot, filename, silent); // load file
if (offset > 0) // old sram found
{
if (WaitPromptChoice ((char*)"Old SRAM found. Convert and delete?", (char*)"Cancel", (char*)"Do it"))
{
decodesavedata (offset);
CARD_Delete (slot, filename); // delete old sram
SaveSRAMToMC (slot, silent);
}
}
//
/*** Build SRAM filename ***/
sprintf (filename, "%s.srm", Memory.ROMFilename);
offset = LoadBufferFromMC (savebuffer, slot, filename, silent);
if ( offset > 0 )
{
decodesavedata (offset);
if ( !silent )
{
sprintf (filename, "Loaded %d bytes", offset);
WaitPrompt (filename);
}
S9xSoftReset();
}
}
/****************************************************************************
* Memory Card SRAM Save
****************************************************************************/
void
SaveSRAMToMC (int slot, int silent)
{
char filename[128];
int datasize;
int offset;
if (!silent)
ShowAction ((char*) "Saving SRAM to MC...");
/*** Build SRAM filename ***/
sprintf (filename, "%s.srm", Memory.ROMFilename);
datasize = prepareMCsavedata ();
offset = SaveBufferToMC (savebuffer, slot, filename, datasize, silent);
if ( (offset > 0) && (!silent))
{
sprintf (filename, "Wrote %d bytes", offset);
WaitPrompt (filename);
}
}
/****************************************************************************
* Memory Card Preferences Load
****************************************************************************/
void
LoadPrefsFromMC (int slot, int silent)
{
int offset;
char msg[80];
ShowAction ((char*) "Loading Prefs from MC...");
offset = LoadBufferFromMC (savebuffer, slot, PREFS_FILE_NAME, silent);
if ( offset > 0 )
{
decodePrefsData ();
if ( !silent )
{
sprintf (msg, "Loaded %d bytes", offset);
WaitPrompt (msg);
}
}
}
/****************************************************************************
* Memory Card Preferences Save
****************************************************************************/
void
SavePrefsToMC (int slot, int silent)
{
int datasize;
int offset;
char msg[80];
if (!silent)
ShowAction ((char*) "Saving Prefs to MC...");
datasize = preparePrefsData ();
offset = SaveBufferToMC (savebuffer, slot, PREFS_FILE_NAME, datasize, silent);
if ( offset > 0 && !silent)
{
sprintf (msg, "Wrote %d bytes", offset);
WaitPrompt (msg);
}
}

View File

@ -1,23 +1,31 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Port
* softdev July 2006
* crunchy2 May-June 2007
* Tantric September 2008
* crunchy2 May 2007
*
* memcardop.cpp
* mcsave.cpp
*
* Memory Card routines
***************************************************************************/
* Memory Card Save Routines.
****************************************************************************/
#ifndef _NGCMCSAVE_
#define _NGCMCSAVE_
#define SAVEBUFFERSIZE ((512 * 1024) + 2048 + 64 + 4 + 4)
void ClearSaveBuffer ();
int VerifyMCFile (unsigned char *buf, int slot, char *filename, int datasize);
int LoadBufferFromMC (unsigned char *buf, int slot, char *filename, bool8 silent);
int SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool8 silent);
int MountCard(int cslot, bool silent);
bool TestCard(int slot, bool silent);
void LoadSRAMFromMC (int slot, int silent);
void SaveSRAMToMC (int slot, int silent);
void LoadPrefsFromMC (int slot, int silent);
void SavePrefsToMC (int slot, int silent);
#endif

489
source/ngc/memfile.cpp Normal file
View File

@ -0,0 +1,489 @@
/****************************************************************************
* Snes9x 1.50 - GX 2.0
*
* NGC Snapshots Memory File System
*
* This is a single global memory file controller. Don't even think of opening two
* at the same time !
*
* There's just enough here to do SnapShots - you should add anything else you
* need.
*
* softdev July 2006
* crunchy2 May 2007-July 2007
****************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fat.h>
#include <zlib.h>
#include "memfile.h"
#include "snes9x.h"
#include "memmap.h"
#include "soundux.h"
#include "snapshot.h"
#include "srtc.h"
#include "Snes9xGx.h"
#include "filesel.h"
#include "ftfont.h"
#include "smbload.h"
#include "mcsave.h"
extern "C"
{
#include "smb.h"
}
#define MEMBUFFER (512 * 1024)
extern void S9xSRTCPreSaveState ();
extern void NGCFreezeStruct ();
extern bool8 S9xUnfreezeGame (const char *filename);
extern unsigned char savebuffer[];
static int bufoffset;
static char membuffer[MEMBUFFER];
char freezecomment[2][32] = { {"Snes9x GX 004 Freeze"}, {"Freeze"} };
/**
* GetMem
*
* Return x bytes from memory buffer
*/
int
GetMem (char *buffer, int len)
{
memcpy (buffer, membuffer + bufoffset, len);
bufoffset += len;
return len;
}
/**
* PutMem
*
* Put some values in memory buffer
*/
static void
PutMem (char *buffer, int len)
{
memcpy (membuffer + bufoffset, buffer, len);
bufoffset += len;
}
void
NGCFreezeBlock (char *name, uint8 * block, int size)
{
char buffer[512];
// char msg[90];
// sprintf (msg, "name=%s", name);
// WaitPrompt(msg);
sprintf (buffer, "%s:%06d:", name, size);
PutMem (buffer, strlen (buffer));
PutMem ((char *) block, size);
}
/**
* NGCFreezeMembuffer
*/
static int
NGCFreezeMemBuffer ()
{
int i;
char buffer[1024];
bufoffset = 0;
S9xUpdateRTC ();
S9xSRTCPreSaveState ();
for (i = 0; i < 8; i++)
{
SoundData.channels[i].previous16[0] =
(int16) SoundData.channels[i].previous[0];
SoundData.channels[i].previous16[1] =
(int16) SoundData.channels[i].previous[1];
}
sprintf (buffer, "%s:%04d\n", SNAPSHOT_MAGIC, SNAPSHOT_VERSION);
PutMem (buffer, strlen (buffer));
sprintf (buffer, "NAM:%06d:%s%c", (int) strlen (Memory.ROMFilename) + 1,
Memory.ROMFilename, 0);
PutMem (buffer, strlen (buffer) + 1);
NGCFreezeStruct ();
return 0;
}
/**
* NGCFreezeGame
*
* Do freeze game for Nintendo Gamecube
*/
int
NGCFreezeGame (int where, bool8 silent)
{
char filename[1024];
SMBFILE smbfile;
FILE *handle;
int len = 0;
int wrote = 0;
int offset = 0;
char msg[100];
if (where == 4)
{
/*** Freeze to SMB ***/
sprintf (filename, "/%s/%s.frz", SNESSAVEDIR, Memory.ROMFilename);
}
else if (where == 2 || where == 3)
{
/*** Freeze to SDCard in slot A or slot B ***/
#ifdef SDUSE_LFN
sprintf (filename, "%s/%s/%s.frz", ROOTSDDIR, SNESSAVEDIR, Memory.ROMFilename);
#else
/*** Until we have LFN on SD ... ***/
sprintf (filename, "%s/%s/%08x.frz", ROOTSDDIR, SNESSAVEDIR, Memory.ROMCRC32);
#endif
}
else
{
/*** Freeze to MC in slot A or slot B ***/
sprintf (filename, "%s.snz", Memory.ROMFilename);
}
S9xSetSoundMute (TRUE);
S9xPrepareSoundForSnapshotSave (FALSE);
NGCFreezeMemBuffer ();
S9xPrepareSoundForSnapshotSave (TRUE);
S9xSetSoundMute (FALSE);
if (where == 4) /*** SMB ***/
{
ConnectSMB ();
smbfile = SMB_Open (filename, SMB_OPEN_WRITING | SMB_DENY_NONE,
SMB_OF_CREATE | SMB_OF_TRUNCATE);
if (smbfile)
{
if (!silent)
ShowAction ((char*) "Saving freeze game...");
len = bufoffset;
offset = 0;
while (len > 0)
{
if (len > 1024)
wrote =
SMB_Write ((char *) membuffer + offset, 1024, offset,
smbfile);
else
wrote =
SMB_Write ((char *) membuffer + offset, len, offset,
smbfile);
offset += wrote;
len -= wrote;
}
SMB_Close (smbfile);
if ( !silent )
{
sprintf (filename, "Written %d bytes", bufoffset);
WaitPrompt (filename);
}
}
else
{
char msg[100];
sprintf(msg, "Couldn't save to SMB:\\%s\\", SNESSAVEDIR);
WaitPrompt (msg);
}
}
else if (where == 2 || where == 3) /*** SDCard slot A or slot B ***/
{
handle = fopen (filename, "wb");
if (handle > 0)
{
if (!silent)
ShowAction ((char*) "Saving freeze game...");
len = fwrite (membuffer, 1, bufoffset, handle);
fclose (handle);
if (len != bufoffset)
WaitPrompt((char*) "Error writing freeze file");
else if ( !silent )
{
sprintf (filename, "Written %d bytes", bufoffset);
WaitPrompt (filename);
}
}
else
{
sprintf(msg, "Couldn't save to %s/%s/", ROOTSDDIR, SNESSAVEDIR);
WaitPrompt (msg);
}
}
else /*** MC in slot A or slot B ***/
{
if (!silent)
ShowAction ((char*) "Saving freeze game...");
ClearSaveBuffer ();
/*** Copy in save icon ***/
int offset = sizeof (saveicon);
memcpy (savebuffer, saveicon, offset);
/*** And the freezecomment ***/
sprintf (freezecomment[1], "%s", Memory.ROMName);
memcpy (savebuffer + offset, freezecomment, 64);
offset += 64;
/*** Zip and copy in the freeze ***/
uLongf DestBuffSize = (uLongf) SAVEBUFFERSIZE;
int err= compress2((Bytef*)(savebuffer+offset+8), (uLongf*)&DestBuffSize, (const Bytef*)membuffer, (uLongf)bufoffset, Z_BEST_COMPRESSION);
if(err!=Z_OK)
{
sprintf (msg, "zip error %s ",zError(err));
WaitPrompt (msg);
return 0;
}
int zippedsize = (int)DestBuffSize;
memcpy (savebuffer + offset, &zippedsize, 4);
offset += 4;
int decompressedsize = (int)bufoffset;
memcpy (savebuffer + offset, &decompressedsize, 4);
offset += 4;
offset += zippedsize;
int ret = SaveBufferToMC ( savebuffer, where, filename, offset, SILENT );
if ( ret && !silent )
{
sprintf (filename, "Written %d bytes", ret);
WaitPrompt (filename);
}
}
return 0;
}
/**
* NGCUnFreezeBlock
*/
int
NGCUnFreezeBlock (char *name, uint8 * block, int size)
{
char buffer[20], *e;
int len = 0;
int rem = 0;
GetMem (buffer, 11);
if (strncmp (buffer, name, 3) != 0 || buffer[3] != ':' ||
buffer[10] != ':' || (len = strtol (&buffer[4], &e, 10)) == 0 ||
e != buffer + 10)
{
return WRONG_FORMAT;
}
if (len > size)
{
rem = len - size;
len = size;
}
ZeroMemory (block, size);
GetMem ((char *) block, len);
if (rem)
{
bufoffset += rem;
}
return SUCCESS;
}
/**
* NGCUnfreezeGame
*/
int
NGCUnfreezeGame (int from, bool8 silent)
{
char filename[1024];
SMBFILE smbfile;
FILE *handle;
int read = 0;
int offset = 0;
char msg[80];
bufoffset = 0;
if (from == 4)
{
/*** From SMB ***/
sprintf (filename, "\\%s\\%s.frz", SNESSAVEDIR, Memory.ROMFilename);
ConnectSMB ();
/*** Read the file into memory ***/
smbfile =
SMB_Open (filename, SMB_OPEN_READING | SMB_DENY_NONE, SMB_OF_OPEN);
if (smbfile)
{
ShowAction ((char*) "Loading freeze file...");
while ((read =
SMB_Read ((char *) membuffer + offset, 1024, offset,
smbfile)) > 0)
offset += read;
SMB_Close (smbfile);
ShowAction ((char*) "Unpacking freeze file");
if (S9xUnfreezeGame ("AGAME") != SUCCESS)
{
WaitPrompt((char*) "Error thawing");
return 0;
}
}
else if ( !silent )
{
WaitPrompt((char*) "No freeze file found");
return 0;
}
}
else if (from == 2 || from == 3) /*** From SD slot A or slot B ***/
{
#ifdef SDUSE_LFN
sprintf (filename, "%s/%s/%s.frz", ROOTSDDIR, SNESSAVEDIR, Memory.ROMFilename);
#else
/*** From SDCard ***/
sprintf (filename, "%s/%s/%08x.frz", ROOTSDDIR, SNESSAVEDIR, Memory.ROMCRC32);
#endif
handle = fopen (filename, "rb");
if (handle > 0)
{
ShowAction ((char*) "Loading freeze file...");
offset = 0;
/*** Usual chunks into memory ***/
while ((read = fread (membuffer + offset, 1, 2048, handle)) >
0)
offset += read;
fclose (handle);
ShowAction ((char*) "Unpacking freeze file");
if (S9xUnfreezeGame ("AGAME") != SUCCESS)
{
WaitPrompt((char*) "Error thawing");
return 0;
}
}
else if ( !silent )
{
WaitPrompt((char*) "No freeze file found");
return 0;
}
}
else /*** From MC in slot A or slot B ***/
{
ShowAction ((char*) "Loading freeze file...");
sprintf (filename, "%s.snz", Memory.ROMFilename);
int ret = LoadBufferFromMC ( savebuffer, from, filename, silent );
if ( ret )
{
ShowAction ((char*) "Unpacking freeze file");
// skip the saveicon and comment
offset = (sizeof(saveicon) + 64);
uLongf zipsize = 0;
uLongf decompressedsize = 0;
memcpy (&zipsize, savebuffer+offset, 4);
offset += 4;
memcpy (&decompressedsize, savebuffer+offset, 4);
offset += 4;
memset(membuffer, 0, MEMBUFFER);
uLongf DestBuffSize = MEMBUFFER;
int err= uncompress((Bytef*)membuffer, (uLongf*)&DestBuffSize, (const Bytef*)(savebuffer + offset), zipsize);
if ( err!=Z_OK )
{
sprintf (msg, "unzip error %s ",zError(err));
WaitPrompt (msg);
return 0;
}
if ( DestBuffSize != decompressedsize )
{
WaitPrompt((char*) "Unzipped size doesn't match expected size!");
return 0;
}
if (S9xUnfreezeGame ("AGAME") != SUCCESS)
{
WaitPrompt((char*) "Error thawing");
return 0;
}
}
else if ( !silent )
{
sprintf(msg, "Couldn't load from MC slot %s", (from ? "B" : "A"));
WaitPrompt (msg);
return 0;
}
}
return 1;
}
void quickLoadFreeze (bool8 silent)
{
if ( QUICK_SAVE_SLOT >= 0 )
NGCUnfreezeGame ( QUICK_SAVE_SLOT, silent );
}
void quickSaveFreeze (bool8 silent)
{
if ( QUICK_SAVE_SLOT >= 0 )
NGCFreezeGame ( QUICK_SAVE_SLOT, silent );
}

34
source/ngc/memfile.h Normal file
View File

@ -0,0 +1,34 @@
/****************************************************************************
* Snes9x 1.50 - GX 2.0
*
* NGC Snapshots Memory File System
*
* This is a single global memory file controller. Don't even think of opening two
* at the same time !
*
* There's just enough here to do SnapShots - you should add anything else you
* need.
****************************************************************************/
#include "snes9x.h"
#ifndef _NGCMEMFILE_
#define _NGCMEMFILE_
typedef struct
{
char filename[512]; /*** Way over size - but who cares -;) ***/
int filehandle;
int currpos;
int length;
int mode;
char *buffer; /*** Memspace for read / write ***/
}
MEMFILE;
int NGCFreezeGame (int where, bool8 silent);
int NGCUnfreezeGame (int from, bool8 silent);
void quickLoadFreeze (bool8 silent);
void quickSaveFreeze (bool8 silent);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,15 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Menu
*
* softdev July 2006
* crunchy2 May-June 2007
* Michniewski 2008
* Tantric August 2008
*
* menu.h
*
* Menu flow routines - handles all menu logic
***************************************************************************/
****************************************************************************/
#ifndef _NGCMENU_
#define _NGCMENU_
void MainMenu (int selectedMenu);
void mainmenu ();
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,20 @@
/**********************************************************************************
/****************************************************************************
* Snes9x 1.50
*
* Nintendo Gamecube Port
* softdev July 2006
*
* ngc_missing.cpp
*
* This file contains the missing low-level file I/O function definitions.
* Note that these are DUMMY functions, and only allow Snes9x to
* compile. Where possible, they will return an error signal.
****************************************************************************/
/****************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +25,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +123,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -156,23 +152,30 @@
Super NES and Super Nintendo Entertainment System are trademarks of
Nintendo Co., Limited and its subsidiary companies.
**********************************************************************************/
*****************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*** splitpath function ***/
void
_splitpath (char const *buffer, char *drive, char *dir, char *fname,
char *ext)
{
return; /*** Do nothing - NGC code should NEVER call a function which relies on it ***/
}
#ifndef LOGGER_H
#define LOGGER_H
void
_makepath (char *filename, const char *drive, const char *dir,
const char *fname, const char *ext)
{
return; /*** Do nothing - NGC code should NEVER call a function which relies on it ***/
}
extern int dumpstreams;
extern char autodemo[128];
extern int maxframes;
extern int logger_pivot;
int Logger_FrameCounter();
void Logger_NextFrame();
void ResetLogger();
void VideoLogger(void *pixels, int width, int height, int depth, int bytes_per_row);
void AudioLogger(void *samples, int length);
#endif
char *
S9xBasename (char *name)
{
return name;
}

View File

@ -1,424 +1,153 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Tantric September 2008
* Nintendo Gamecube Port
* crunchy2 April 2007-July 2007
*
* preferences.cpp
*
* Preferences save/load to XML file
***************************************************************************/
* Preferences save/load preferences utilities
****************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <string.h>
#include <ogcsys.h>
#include <mxml.h>
#include "snes9xGX.h"
#include "images/saveicon.h"
#include "menudraw.h"
#include "memcardop.h"
#include "fileop.h"
#include "smbop.h"
#include "filesel.h"
#include "input.h"
#include "snes9x.h"
#include "snes9xGx.h"
#include "memmap.h"
#include "srtc.h"
#include "ftfont.h"
#include "mcsave.h"
#include "sdload.h"
#include "smbload.h"
extern unsigned char savebuffer[];
extern int currconfig[4];
#define PREFS_FILE_NAME "SNES9xGX.xml"
// button map configurations
extern unsigned int gcpadmap[];
extern unsigned int wmpadmap[];
extern unsigned int ccpadmap[];
extern unsigned int ncpadmap[];
char prefscomment[2][32];
#define PREFSVERSTRING "Snes9x GX 004 Prefs"
char prefscomment[2][32] = { {PREFSVERSTRING}, {"Preferences"} };
/****************************************************************************
* Prepare Preferences Data
*
* This sets up the save buffer for saving.
***************************************************************************/
mxml_node_t *xml;
mxml_node_t *data;
mxml_node_t *section;
mxml_node_t *item;
mxml_node_t *elem;
char temp[20];
const char * toStr(int i)
{
sprintf(temp, "%d", i);
return temp;
}
void createXMLSection(const char * name, const char * description)
{
section = mxmlNewElement(data, "section");
mxmlElementSetAttr(section, "name", name);
mxmlElementSetAttr(section, "description", description);
}
void createXMLSetting(const char * name, const char * description, const char * value)
{
item = mxmlNewElement(section, "setting");
mxmlElementSetAttr(item, "name", name);
mxmlElementSetAttr(item, "value", value);
mxmlElementSetAttr(item, "description", description);
}
void createXMLController(unsigned int controller[], const char * name, const char * description)
{
item = mxmlNewElement(section, "controller");
mxmlElementSetAttr(item, "name", name);
mxmlElementSetAttr(item, "description", description);
// create buttons
for(int i=0; i < MAXJP; i++)
{
elem = mxmlNewElement(item, "button");
mxmlElementSetAttr(elem, "number", toStr(i));
mxmlElementSetAttr(elem, "assignment", toStr(controller[i]));
}
}
const char * XMLSaveCallback(mxml_node_t *node, int where)
{
const char *name;
name = node->value.element.name;
if(where == MXML_WS_BEFORE_CLOSE)
{
if(!strcmp(name, "file") || !strcmp(name, "section"))
return ("\n");
else if(!strcmp(name, "controller"))
return ("\n\t");
}
if (where == MXML_WS_BEFORE_OPEN)
{
if(!strcmp(name, "file"))
return ("\n");
else if(!strcmp(name, "section"))
return ("\n\n");
else if(!strcmp(name, "setting") || !strcmp(name, "controller"))
return ("\n\t");
else if(!strcmp(name, "button"))
return ("\n\t\t");
}
return (NULL);
}
* This sets up the save buffer for saving to a memory card.
****************************************************************************/
int
preparePrefsData (int method)
preparePrefsData ()
{
int offset = 0;
int offset = sizeof (saveicon);
int size;
// add save icon and comments for Memory Card saves
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
offset = sizeof (saveicon);
memset (savebuffer, 0, SAVEBUFFERSIZE);
// Copy in save icon
memcpy (savebuffer, saveicon, offset);
/*** Copy in save icon ***/
memcpy (savebuffer, saveicon, offset);
// And the comments
sprintf (prefscomment[0], "%s Prefs", VERSIONSTR);
sprintf (prefscomment[1], "Preferences");
memcpy (savebuffer + offset, prefscomment, 64);
offset += 64;
}
/*** And the prefscomments ***/
memcpy (savebuffer + offset, prefscomment, 64);
offset += 64;
xml = mxmlNewXML("1.0");
mxmlSetWrapMargin(0); // disable line wrapping
/*** Save all settings ***/
size = sizeof (Settings);
memcpy (savebuffer + offset, &Settings, size);
offset += size;
data = mxmlNewElement(xml, "file");
mxmlElementSetAttr(data, "version",VERSIONSTR);
createXMLSection("File", "File Settings");
createXMLSetting("AutoLoad", "Auto Load", toStr(GCSettings.AutoLoad));
createXMLSetting("AutoSave", "Auto Save", toStr(GCSettings.AutoSave));
createXMLSetting("LoadMethod", "Load Method", toStr(GCSettings.LoadMethod));
createXMLSetting("SaveMethod", "Save Method", toStr(GCSettings.SaveMethod));
createXMLSetting("LoadFolder", "Load Folder", GCSettings.LoadFolder);
createXMLSetting("SaveFolder", "Save Folder", GCSettings.SaveFolder);
createXMLSetting("CheatFolder", "Cheats Folder", GCSettings.CheatFolder);
createXMLSetting("VerifySaves", "Verify Memory Card Saves", toStr(GCSettings.VerifySaves));
createXMLSection("Network", "Network Settings");
createXMLSetting("smbip", "Share Computer IP", GCSettings.smbip);
createXMLSetting("smbshare", "Share Name", GCSettings.smbshare);
createXMLSetting("smbuser", "Share Username", GCSettings.smbuser);
createXMLSetting("smbpwd", "Share Password", GCSettings.smbpwd);
createXMLSection("Emulation", "Emulation Settings");
createXMLSetting("ReverseStereo", "Reverse Stereo", toStr(Settings.ReverseStereo));
createXMLSetting("InterpolatedSound", "Interpolated Sound", toStr(Settings.InterpolatedSound));
createXMLSetting("Transparency", "Transparency", toStr(Settings.Transparency));
createXMLSetting("DisplayFrameRate", "Display Frame Rate", toStr(Settings.DisplayFrameRate));
createXMLSetting("NGCZoom", "C-Stick Zoom", toStr(GCSettings.NGCZoom));
createXMLSetting("render", "Video Filtering", toStr(GCSettings.render));
createXMLSetting("widescreen", "Aspect Ratio Correction", toStr(GCSettings.widescreen));
createXMLSetting("xshift", "Horizontal Video Shift", toStr(GCSettings.xshift));
createXMLSetting("yshift", "Vertical Video Shift", toStr(GCSettings.yshift));
createXMLSection("Controller", "Controller Settings");
createXMLSetting("MultiTap", "MultiTap", toStr(Settings.MultiPlayer5Master));
createXMLSetting("Superscope", "Superscope", toStr(GCSettings.Superscope));
createXMLSetting("Mice", "Mice", toStr(GCSettings.Mouse));
createXMLSetting("Justifiers", "Justifiers", toStr(GCSettings.Justifier));
createXMLController(gcpadmap, "gcpadmap", "GameCube Pad");
createXMLController(wmpadmap, "wmpadmap", "Wiimote");
createXMLController(ccpadmap, "ccpadmap", "Classic Controller");
createXMLController(ncpadmap, "ncpadmap", "Nunchuk");
int datasize = mxmlSaveString(xml, (char *)savebuffer+offset, (SAVEBUFFERSIZE-offset), XMLSaveCallback);
mxmlDelete(xml);
return datasize;
/*** Save GC specific settings ***/
size = sizeof (GCSettings);
memcpy (savebuffer + offset, &GCSettings, size);
offset += size;
/*** Save buttonmaps ***/
size = sizeof (unsigned int) *12; // this size applies to all padmaps
memcpy (savebuffer + offset, &gcpadmap, size);
offset += size;
memcpy (savebuffer + offset, &wmpadmap, size);
offset += size;
memcpy (savebuffer + offset, &ccpadmap, size);
offset += size;
memcpy (savebuffer + offset, &ncpadmap, size);
offset += size;
return offset;
}
/****************************************************************************
* loadXMLSetting
*
* Load XML elements into variables for an individual variable
***************************************************************************/
void loadXMLSetting(char * var, const char * name)
* Decode Preferences Data
****************************************************************************/
void
decodePrefsData ()
{
item = mxmlFindElement(xml, xml, "setting", "name", name, MXML_DESCEND);
if(item)
sprintf(var, "%s", mxmlElementGetAttr(item, "value"));
}
void loadXMLSetting(int * var, const char * name)
{
item = mxmlFindElement(xml, xml, "setting", "name", name, MXML_DESCEND);
if(item)
*var = atoi(mxmlElementGetAttr(item, "value"));
}
void loadXMLSetting(bool8 * var, const char * name)
{
item = mxmlFindElement(xml, xml, "setting", "name", name, MXML_DESCEND);
if(item)
*var = atoi(mxmlElementGetAttr(item, "value"));
}
/****************************************************************************
* loadXMLController
*
* Load XML elements into variables for a controller mapping
***************************************************************************/
void loadXMLController(unsigned int controller[], const char * name)
{
item = mxmlFindElement(xml, xml, "controller", "name", name, MXML_DESCEND);
if(item)
int offset;
char prefscomment[32];
int size;
offset = sizeof (saveicon);
memcpy (prefscomment, savebuffer + offset, 32);
if ( strcmp (prefscomment, PREFSVERSTRING) == 0 )
{
// populate buttons
for(int i=0; i < MAXJP; i++)
{
elem = mxmlFindElement(item, xml, "button", "number", toStr(i), MXML_DESCEND);
if(elem)
controller[i] = atoi(mxmlElementGetAttr(elem, "assignment"));
}
offset += 64;
memcpy (&Settings, savebuffer + offset, sizeof (Settings));
offset += sizeof (Settings);
memcpy (&GCSettings, savebuffer + offset, sizeof (GCSettings));
offset += sizeof (GCSettings);
// load padmaps (order important)
size = sizeof (unsigned int) *12;
memcpy (&gcpadmap, savebuffer + offset, size);
offset += size;
memcpy (&wmpadmap, savebuffer + offset, size);
offset += size;
memcpy (&ccpadmap, savebuffer + offset, size);
offset += size;
memcpy (&ncpadmap, savebuffer + offset, size);
}
else
WaitPrompt((char*) "Preferences reset - check settings!");
}
void quickLoadPrefs (bool8 silent)
{
switch ( QUICK_SAVE_SLOT )
{
case CARD_SLOTA:
case CARD_SLOTB:
LoadPrefsFromMC(QUICK_SAVE_SLOT, silent);
break;
case CARD_SLOTA+2:
case CARD_SLOTB+2:
LoadPrefsFromSD(silent);
break;
case CARD_SLOTA+4:
LoadPrefsFromSMB(silent);
break;
}
}
/****************************************************************************
* decodePrefsData
*
* Decodes preferences - parses XML and loads preferences into the variables
***************************************************************************/
bool
decodePrefsData (int method)
void quickSavePrefs (bool8 silent)
{
int offset = 0;
// skip save icon and comments for Memory Card saves
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
switch ( QUICK_SAVE_SLOT )
{
offset = sizeof (saveicon);
offset += 64; // sizeof prefscomment
case CARD_SLOTA:
case CARD_SLOTB:
SavePrefsToMC(QUICK_SAVE_SLOT, silent);
break;
case CARD_SLOTA+2:
case CARD_SLOTB+2:
SavePrefsToSD(silent);
break;
case CARD_SLOTA+4:
SavePrefsToSMB(silent);
break;
}
xml = mxmlLoadString(NULL, (char *)savebuffer+offset, MXML_TEXT_CALLBACK);
// check settings version
// we don't do anything with the version #, but we'll store it anyway
char * version;
item = mxmlFindElement(xml, xml, "file", "version", NULL, MXML_DESCEND);
if(item) // a version entry exists
version = (char *)mxmlElementGetAttr(item, "version");
else // version # not found, must be invalid
return false;
// File Settings
loadXMLSetting(&GCSettings.AutoLoad, "AutoLoad");
loadXMLSetting(&GCSettings.AutoSave, "AutoSave");
loadXMLSetting(&GCSettings.LoadMethod, "LoadMethod");
loadXMLSetting(&GCSettings.SaveMethod, "SaveMethod");
loadXMLSetting(GCSettings.LoadFolder, "LoadFolder");
loadXMLSetting(GCSettings.SaveFolder, "SaveFolder");
loadXMLSetting(GCSettings.CheatFolder, "CheatFolder");
loadXMLSetting(&GCSettings.VerifySaves, "VerifySaves");
// Network Settings
loadXMLSetting(GCSettings.smbip, "smbip");
loadXMLSetting(GCSettings.smbshare, "smbshare");
loadXMLSetting(GCSettings.smbuser, "smbuser");
loadXMLSetting(GCSettings.smbpwd, "smbpwd");
// Emulation Settings
loadXMLSetting(&Settings.ReverseStereo, "ReverseStereo");
loadXMLSetting(&Settings.InterpolatedSound, "InterpolatedSound");
loadXMLSetting(&Settings.Transparency, "Transparency");
loadXMLSetting(&Settings.DisplayFrameRate, "DisplayFrameRate");
loadXMLSetting(&GCSettings.NGCZoom, "NGCZoom");
loadXMLSetting(&GCSettings.render, "render");
loadXMLSetting(&GCSettings.widescreen, "widescreen");
loadXMLSetting(&GCSettings.xshift, "xshift");
loadXMLSetting(&GCSettings.yshift, "yshift");
// Controller Settings
loadXMLSetting(&Settings.MultiPlayer5Master, "MultiTap");
loadXMLSetting(&GCSettings.Superscope, "Superscope");
loadXMLSetting(&GCSettings.Mouse, "Mice");
loadXMLSetting(&GCSettings.Justifier, "Justifiers");
loadXMLController(gcpadmap, "gcpadmap");
loadXMLController(wmpadmap, "wmpadmap");
loadXMLController(ccpadmap, "ccpadmap");
loadXMLController(ncpadmap, "ncpadmap");
mxmlDelete(xml);
return true;
}
/****************************************************************************
* Save Preferences
***************************************************************************/
bool
SavePrefs (int method, bool silent)
{
// there's no point in saving SMB settings TO SMB, because then we'll have no way to load them the next time!
// so instead we'll save using whatever other method is available (eg: SD)
if(method == METHOD_AUTO || method == METHOD_SMB)
method = autoSaveMethod();
char filepath[1024];
int datasize;
int offset = 0;
AllocSaveBuffer ();
datasize = preparePrefsData (method);
if (!silent)
ShowAction ((char*) "Saving preferences...");
if(method == METHOD_SD || method == METHOD_USB)
{
if(ChangeFATInterface(method, NOTSILENT))
{
sprintf (filepath, "%s/%s/%s", ROOTFATDIR, GCSettings.SaveFolder, PREFS_FILE_NAME);
offset = SaveBufferToFAT (filepath, datasize, silent);
}
}
else if(method == METHOD_SMB)
{
sprintf (filepath, "%s/%s", GCSettings.SaveFolder, PREFS_FILE_NAME);
offset = SaveBufferToSMB (filepath, datasize, silent);
}
else if(method == METHOD_MC_SLOTA)
{
offset = SaveBufferToMC (savebuffer, CARD_SLOTA, (char *)PREFS_FILE_NAME, datasize, silent);
}
else if(method == METHOD_MC_SLOTB)
{
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, datasize, silent);
}
FreeSaveBuffer ();
if (offset > 0)
{
if (!silent)
WaitPrompt ((char *)"Preferences saved");
return true;
}
return false;
}
/****************************************************************************
* Load Preferences from specified method
***************************************************************************/
bool
LoadPrefsFromMethod (int method)
{
bool retval = false;
char filepath[1024];
int offset = 0;
AllocSaveBuffer ();
if(method == METHOD_SD || method == METHOD_USB)
{
if(ChangeFATInterface(method, NOTSILENT))
{
sprintf (filepath, "%s/%s/%s", ROOTFATDIR, GCSettings.SaveFolder, PREFS_FILE_NAME);
offset = LoadBufferFromFAT (filepath, SILENT);
}
}
else if(method == METHOD_SMB)
{
sprintf (filepath, "%s/%s", GCSettings.SaveFolder, PREFS_FILE_NAME);
offset = LoadBufferFromSMB (filepath, SILENT);
}
else if(method == METHOD_MC_SLOTA)
{
offset = LoadBufferFromMC (savebuffer, CARD_SLOTA, (char *)PREFS_FILE_NAME, SILENT);
}
else if(method == METHOD_MC_SLOTB)
{
offset = LoadBufferFromMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, SILENT);
}
if (offset > 0)
retval = decodePrefsData (method);
FreeSaveBuffer ();
return retval;
}
/****************************************************************************
* Load Preferences
* Checks sources consecutively until we find a preference file
***************************************************************************/
bool LoadPrefs()
{
ShowAction ((char*) "Loading preferences...");
bool prefFound = false;
if(ChangeFATInterface(METHOD_SD, SILENT))
prefFound = LoadPrefsFromMethod(METHOD_SD);
if(!prefFound && ChangeFATInterface(METHOD_USB, SILENT))
prefFound = LoadPrefsFromMethod(METHOD_USB);
if(!prefFound && TestCard(CARD_SLOTA, SILENT))
prefFound = LoadPrefsFromMethod(METHOD_MC_SLOTA);
if(!prefFound && TestCard(CARD_SLOTB, SILENT))
prefFound = LoadPrefsFromMethod(METHOD_MC_SLOTB);
if(!prefFound && ConnectShare (SILENT))
prefFound = LoadPrefsFromMethod(METHOD_SMB);
return prefFound;
}

View File

@ -1,12 +1,18 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Tantric September 2008
* Nintendo Gamecube Port
* crunchy2 April 2007
*
* preferences.h
* preferences.cpp
*
* Preferences save/load to XML file
***************************************************************************/
* Preferences save/load preferences utilities
****************************************************************************/
bool SavePrefs (int method, bool silent);
bool LoadPrefs ();
#define PREFS_FILE_NAME "snes9xGx.prf"
int preparePrefsData ();
void decodePrefsData ();
void quickLoadPrefs (bool8 silent);
void quickSavePrefs (bool8 silent);

View File

@ -1,128 +1,240 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Port
* softdev July 2006
* crunchy2 May 2007
* Michniewski 2008
* Tantric September 2008
*
* s9xconfig.cpp
*
* Configuration parameters are here for easy maintenance.
* Configuration parameters have been moved here for easier maintenance.
* Refer to Snes9x.h for all combinations.
* The defaults used here are taken directly from porting.html
***************************************************************************/
****************************************************************************/
/****************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
C4 x86 assembler and some C emulation code
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
Nach,
zsKnight (zsknight@zsnes.com)
C4 C++ code
(c) Copyright 2003 - 2006 Brad Jorsch,
Nach
DSP-1 emulator code
(c) Copyright 1998 - 2006 _Demo_,
Andreas Naive (andreasnaive@gmail.com)
Gary Henderson,
Ivar (ivar@snes9x.com),
John Weidman,
Kris Bleakley,
Matthew Kendora,
Nach,
neviksti (neviksti@hotmail.com)
DSP-2 emulator code
(c) Copyright 2003 John Weidman,
Kris Bleakley,
Lord Nightmare (lord_nightmare@users.sourceforge.net),
Matthew Kendora,
neviksti
DSP-3 emulator code
(c) Copyright 2003 - 2006 John Weidman,
Kris Bleakley,
Lancer,
z80 gaiden
DSP-4 emulator code
(c) Copyright 2004 - 2006 Dreamer Nom,
John Weidman,
Kris Bleakley,
Nach,
z80 gaiden
OBC1 emulator code
(c) Copyright 2001 - 2004 zsKnight,
pagefault (pagefault@zsnes.com),
Kris Bleakley,
Ported from x86 assembler to C by sanmaiwashi
SPC7110 and RTC C++ emulator code
(c) Copyright 2002 Matthew Kendora with research by
zsKnight,
John Weidman,
Dark Force
S-DD1 C emulator code
(c) Copyright 2003 Brad Jorsch with research by
Andreas Naive,
John Weidman
S-RTC C emulator code
(c) Copyright 2001-2006 byuu,
John Weidman
ST010 C++ emulator code
(c) Copyright 2003 Feather,
John Weidman,
Kris Bleakley,
Matthew Kendora
Super FX x86 assembler emulator code
(c) Copyright 1998 - 2003 _Demo_,
pagefault,
zsKnight,
Super FX C emulator code
(c) Copyright 1997 - 1999 Ivar,
Gary Henderson,
John Weidman
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
(c) Copyright 1998 - 2003 Brad Martin
(c) Copyright 1998 - 2006 Charles Bilyue'
SH assembler code partly based on x86 assembler code
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
warranty. In no event shall the authors be held liable for any damages
arising from the use of this software or it's derivatives.
Snes9x is freeware for PERSONAL USE only. Commercial users should
seek permission of the copyright holders first. Commercial use includes,
but is not limited to, charging money for Snes9x or software derived from
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
using Snes9x as a promotion for your commercial product.
The copyright holders request that bug fixes and improvements to the code
should be forwarded to them so everyone can benefit from the modifications
in future versions.
Super NES and Super Nintendo Entertainment System are trademarks of
Nintendo Co., Limited and its subsidiary companies.
*****************************************************************************/
#include <gccore.h>
#include "snes9x.h"
#include "snes9xGX.h"
#include "smbop.h"
struct SGCSettings GCSettings;
#include "smbload.h"
void
DefaultSettings ()
{
/************** GameCube/Wii Settings *********************/
GCSettings.LoadMethod = METHOD_AUTO; // Auto, SD, DVD, USB, Network (SMB)
GCSettings.SaveMethod = METHOD_AUTO; // Auto, SD, Memory Card Slot A, Memory Card Slot B, USB, Network (SMB)
sprintf (GCSettings.LoadFolder,"snes9x/roms"); // Path to game files
sprintf (GCSettings.SaveFolder,"snes9x/saves"); // Path to save files
sprintf (GCSettings.CheatFolder,"snes9x/cheats"); // Path to cheat files
GCSettings.AutoLoad = 1;
GCSettings.AutoSave = 1;
/*** Default ALL to false ***/
memset (&Settings, 0, sizeof (Settings));
GCSettings.VerifySaves = 0;
/*** General ***/
Settings.MouseMaster = true;
Settings.SuperScopeMaster = true;
Settings.MultiPlayer5Master = false;
Settings.JustifierMaster = true;
Settings.ShutdownMaster = false;
Settings.CyclesPercentage = 100; // snes9x 1.50 and earlier
/* Eke-Eke: specific to snes9x 1.51 */
// Settings.BlockInvalidVRAMAccess = true;
// Settings.HDMATimingHack = 100;
// custom SMB settings
strncpy (GCSettings.smbip, "", 15); // IP Address of share server
strncpy (GCSettings.smbuser, "", 19); // Your share user
strncpy (GCSettings.smbpwd, "", 19); // Your share user password
strncpy (GCSettings.smbshare, "", 19); // Share name on server
/*** Sound defaults. On GC this is 32Khz/16bit/Stereo/InterpolatedSound ***/
Settings.APUEnabled = true;
Settings.NextAPUEnabled = true;
Settings.SoundPlaybackRate = 32000;
Settings.Stereo = true;
Settings.SixteenBitSound = true;
Settings.SoundEnvelopeHeightReading = true;
Settings.DisableSampleCaching = true;
Settings.InterpolatedSound = true;
Settings.ReverseStereo = false;
GCSettings.smbip[15] = 0;
GCSettings.smbuser[19] = 0;
GCSettings.smbpwd[19] = 0;
GCSettings.smbshare[19] = 0;
/*** Graphics ***/
Settings.Transparency = true;
Settings.SupportHiRes = true;
Settings.SkipFrames = 10;
Settings.TurboSkipFrames = 19;
Settings.DisplayFrameRate = false;
// Settings.AutoDisplayMessages = 1; /*** eke-eke snes9x 1.51 ***/
/* Eke-Eke: frame timings in 50hz and 60hz cpu mode */
Settings.FrameTimePAL = 20000;
Settings.FrameTimeNTSC = 16667;
GCSettings.gcip[0] = 0;
GCSettings.gwip[0] = 0;
GCSettings.mask[0] = 0;
GCSettings.smbsvid[0] = 0;
GCSettings.smbgcid[0] = 0;
GCSettings.Superscope = 0;
GCSettings.Mouse = 0;
GCSettings.Justifier = 0;
GCSettings.NGCZoom = 0; // zooming default off
GCSettings.render = 2; // Unfiltered
GCSettings.widescreen = 0; // no aspect ratio correction
GCSettings.xshift = 0; // video shift
GCSettings.yshift = 0;
/****************** SNES9x Settings ***********************/
// Default ALL to false
memset (&Settings, 0, sizeof (Settings));
// General
Settings.MouseMaster = false;
Settings.SuperScopeMaster = false;
Settings.MultiPlayer5Master = false;
Settings.JustifierMaster = false;
Settings.ShutdownMaster = false;
Settings.ApplyCheats = true;
Settings.BlockInvalidVRAMAccess = true;
Settings.HDMATimingHack = 100;
// Sound defaults. On GC this is 32Khz/16bit/Stereo/InterpolatedSound
Settings.APUEnabled = true;
Settings.NextAPUEnabled = true;
Settings.SoundPlaybackRate = 32000;
Settings.Stereo = true;
Settings.SixteenBitSound = true;
Settings.SoundEnvelopeHeightReading = true;
Settings.SoundSync = true;
Settings.FixFrequency = false;
Settings.DisableSampleCaching = true;
Settings.InterpolatedSound = true;
Settings.ReverseStereo = false;
// Graphics
Settings.Transparency = true;
Settings.SupportHiRes = true;
Settings.SkipFrames = AUTO_FRAMERATE;
Settings.TurboSkipFrames = 19;
Settings.DisplayFrameRate = false;
Settings.AutoDisplayMessages = 0;
Settings.InitialInfoStringTimeout = 200; // # frames to display messages for
// Frame timings in 50hz and 60hz cpu mode
Settings.FrameTimePAL = 20000;
Settings.FrameTimeNTSC = 16667;
// SDD1 - Star Ocean Returns
Settings.SDD1Pack = true;
Settings.ForceNTSC = 0;
Settings.ForcePAL = 0;
Settings.ForceHiROM = 0;
Settings.ForceLoROM = 0;
Settings.ForceHeader = 0;
Settings.ForceNoHeader = 0;
Settings.ForceTransparency = 0;
Settings.ForceInterleaved = 0;
Settings.ForceInterleaved2 = 0;
Settings.ForceInterleaveGD24 = 0;
Settings.ForceNotInterleaved = 0;
Settings.ForceNoSuperFX = 0;
Settings.ForceSuperFX = 0;
Settings.ForceDSP1 = 0;
Settings.ForceNoDSP1 = 0;
/*** SDD1 - Star Ocean Returns -;) ***/
Settings.SDD1Pack = true;
GCSettings.AutoLoad = 1;
GCSettings.AutoSave = 1;
strncpy (GCSettings.gcip, GC_IP, 15);
strncpy (GCSettings.gwip, GW_IP, 15);
strncpy (GCSettings.mask, MASK, 15);
strncpy (GCSettings.smbip, SMB_IP, 15);
strncpy (GCSettings.smbuser, SMB_USER, 19);
strncpy (GCSettings.smbpwd, SMB_PWD, 19);
strncpy (GCSettings.smbgcid, SMB_GCID, 19);
strncpy (GCSettings.smbsvid, SMB_SVID, 19);
strncpy (GCSettings.smbshare, SMB_SHARE, 19);
GCSettings.NGCZoom = 0;
GCSettings.VerifySaves = 0;
GCSettings.render = 0;
Settings.ForceNTSC = 0;
Settings.ForcePAL = 0;
Settings.ForceHiROM = 0;
Settings.ForceLoROM = 0;
Settings.ForceHeader = 0;
Settings.ForceNoHeader = 0;
Settings.ForceTransparency = 0;
Settings.ForceInterleaved = 0;
Settings.ForceInterleaved2 = 0;
Settings.ForceInterleaveGD24 = 0;
Settings.ForceNotInterleaved = 0;
Settings.ForceNoSuperFX = 0;
Settings.ForceSuperFX = 0;
Settings.ForceDSP1 = 0;
Settings.ForceNoDSP1 = 0;
}

View File

@ -1,18 +1,158 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Port
* softdev July 2006
* crunchy2 May 2007
* Michniewski 2008
* Tantric September 2008
*
* s9xconfig.h
*
* Configuration parameters are here for easy maintenance.
* Configuration parameters have been moved here for easier maintenance.
* Refer to Snes9x.h for all combinations.
* The defaults used here are taken directly from porting.html
***************************************************************************/
****************************************************************************/
/****************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
C4 x86 assembler and some C emulation code
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
Nach,
zsKnight (zsknight@zsnes.com)
C4 C++ code
(c) Copyright 2003 - 2006 Brad Jorsch,
Nach
DSP-1 emulator code
(c) Copyright 1998 - 2006 _Demo_,
Andreas Naive (andreasnaive@gmail.com)
Gary Henderson,
Ivar (ivar@snes9x.com),
John Weidman,
Kris Bleakley,
Matthew Kendora,
Nach,
neviksti (neviksti@hotmail.com)
DSP-2 emulator code
(c) Copyright 2003 John Weidman,
Kris Bleakley,
Lord Nightmare (lord_nightmare@users.sourceforge.net),
Matthew Kendora,
neviksti
DSP-3 emulator code
(c) Copyright 2003 - 2006 John Weidman,
Kris Bleakley,
Lancer,
z80 gaiden
DSP-4 emulator code
(c) Copyright 2004 - 2006 Dreamer Nom,
John Weidman,
Kris Bleakley,
Nach,
z80 gaiden
OBC1 emulator code
(c) Copyright 2001 - 2004 zsKnight,
pagefault (pagefault@zsnes.com),
Kris Bleakley,
Ported from x86 assembler to C by sanmaiwashi
SPC7110 and RTC C++ emulator code
(c) Copyright 2002 Matthew Kendora with research by
zsKnight,
John Weidman,
Dark Force
S-DD1 C emulator code
(c) Copyright 2003 Brad Jorsch with research by
Andreas Naive,
John Weidman
S-RTC C emulator code
(c) Copyright 2001-2006 byuu,
John Weidman
ST010 C++ emulator code
(c) Copyright 2003 Feather,
John Weidman,
Kris Bleakley,
Matthew Kendora
Super FX x86 assembler emulator code
(c) Copyright 1998 - 2003 _Demo_,
pagefault,
zsKnight,
Super FX C emulator code
(c) Copyright 1997 - 1999 Ivar,
Gary Henderson,
John Weidman
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
(c) Copyright 1998 - 2003 Brad Martin
(c) Copyright 1998 - 2006 Charles Bilyue'
SH assembler code partly based on x86 assembler code
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
warranty. In no event shall the authors be held liable for any damages
arising from the use of this software or it's derivatives.
Snes9x is freeware for PERSONAL USE only. Commercial users should
seek permission of the copyright holders first. Commercial use includes,
but is not limited to, charging money for Snes9x or software derived from
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
using Snes9x as a promotion for your commercial product.
The copyright holders request that bug fixes and improvements to the code
should be forwarded to them so everyone can benefit from the modifications
in future versions.
Super NES and Super Nintendo Entertainment System are trademarks of
Nintendo Co., Limited and its subsidiary companies.
*****************************************************************************/
#ifndef _S9XCONFIG_
#define _S9XCONFIG_

View File

@ -1,17 +1,158 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Port
* softdev July 2006
* crunchy2 May 2007
* Michniewski 2008
* Tantric September 2008
*
* s9xsupport.cpp
*
* This file contains the supporting functions defined in porting.html, with
* others taken from unix/x11.cpp and unix/unix.cpp
***************************************************************************/
****************************************************************************/
/****************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
C4 x86 assembler and some C emulation code
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
Nach,
zsKnight (zsknight@zsnes.com)
C4 C++ code
(c) Copyright 2003 - 2006 Brad Jorsch,
Nach
DSP-1 emulator code
(c) Copyright 1998 - 2006 _Demo_,
Andreas Naive (andreasnaive@gmail.com)
Gary Henderson,
Ivar (ivar@snes9x.com),
John Weidman,
Kris Bleakley,
Matthew Kendora,
Nach,
neviksti (neviksti@hotmail.com)
DSP-2 emulator code
(c) Copyright 2003 John Weidman,
Kris Bleakley,
Lord Nightmare (lord_nightmare@users.sourceforge.net),
Matthew Kendora,
neviksti
DSP-3 emulator code
(c) Copyright 2003 - 2006 John Weidman,
Kris Bleakley,
Lancer,
z80 gaiden
DSP-4 emulator code
(c) Copyright 2004 - 2006 Dreamer Nom,
John Weidman,
Kris Bleakley,
Nach,
z80 gaiden
OBC1 emulator code
(c) Copyright 2001 - 2004 zsKnight,
pagefault (pagefault@zsnes.com),
Kris Bleakley,
Ported from x86 assembler to C by sanmaiwashi
SPC7110 and RTC C++ emulator code
(c) Copyright 2002 Matthew Kendora with research by
zsKnight,
John Weidman,
Dark Force
S-DD1 C emulator code
(c) Copyright 2003 Brad Jorsch with research by
Andreas Naive,
John Weidman
S-RTC C emulator code
(c) Copyright 2001-2006 byuu,
John Weidman
ST010 C++ emulator code
(c) Copyright 2003 Feather,
John Weidman,
Kris Bleakley,
Matthew Kendora
Super FX x86 assembler emulator code
(c) Copyright 1998 - 2003 _Demo_,
pagefault,
zsKnight,
Super FX C emulator code
(c) Copyright 1997 - 1999 Ivar,
Gary Henderson,
John Weidman
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
(c) Copyright 1998 - 2003 Brad Martin
(c) Copyright 1998 - 2006 Charles Bilyue'
SH assembler code partly based on x86 assembler code
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
warranty. In no event shall the authors be held liable for any damages
arising from the use of this software or it's derivatives.
Snes9x is freeware for PERSONAL USE only. Commercial users should
seek permission of the copyright holders first. Commercial use includes,
but is not limited to, charging money for Snes9x or software derived from
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
using Snes9x as a promotion for your commercial product.
The copyright holders request that bug fixes and improvements to the code
should be forwarded to them so everyone can benefit from the modifications
in future versions.
Super NES and Super Nintendo Entertainment System are trademarks of
Nintendo Co., Limited and its subsidiary companies.
*****************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <stdio.h>
@ -31,8 +172,10 @@
#include "spc700.h"
#include "spc7110.h"
#include "controls.h"
#include "gctime.h"
#include "snes9xGx.h"
#include "snes9xGX.h"
#include "video.h"
#include "audio.h"
@ -41,12 +184,6 @@ extern u32 FrameTimer;
long long prev;
long long now;
extern "C" {
long long gettime();
u32 diff_usec(long long start,long long end);
}
/*** Miscellaneous Functions ***/
void
@ -65,7 +202,7 @@ S9xExit ()
{
/*** Nintendo Gamecube will NEVER get here ... unless
something major went wrong !!
In which case, I'll settle for a reboot first -;)
***/
}
@ -105,7 +242,7 @@ S9xGetFilenameInc (const char *e, enum s9x_getdirtype dirtype)
void
S9xAutoSaveSRAM ()
{
//Memory.SaveSRAM (S9xGetFilename (".srm", SRAM_DIR));
}
/*** Sound based functions ***/
@ -123,7 +260,7 @@ S9xToggleSoundChannel (int c)
* OpenSoundDevice
*
* Main initialisation for NGC sound system
***************************************************************************/
****************************************************************************/
bool8
S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size)
{
@ -147,7 +284,7 @@ S9xGenerateSound ()
/* eke-eke */
void S9xInitSync()
{
{
FrameTimer = 0;
prev = gettime();
}
@ -158,7 +295,7 @@ extern int timerstyle;
void S9xSyncSpeed ()
{
uint32 skipFrms = Settings.SkipFrames;
if ( Settings.TurboMode )
skipFrms = Settings.TurboSkipFrames;
@ -168,10 +305,10 @@ void S9xSyncSpeed ()
{
usleep (50);
}
if (FrameTimer > skipFrms)
FrameTimer = skipFrms;
if ((FrameTimer > 1) && (IPPU.SkippedFrames < skipFrms))
{
IPPU.SkippedFrames++;
@ -183,11 +320,11 @@ void S9xSyncSpeed ()
IPPU.RenderThisFrame = TRUE;
}
}
else /* use internal timer for PAL roms */
else /* use internal timer for PAL roms */
{
unsigned int timediffallowed = Settings.TurboMode ? 0 : Settings.FrameTime;
now = gettime();
if (diff_usec(prev, now) > timediffallowed)
{
/*while ( diff_usec((prev, now) < timediffallowed * 2) {
@ -216,7 +353,7 @@ void S9xSyncSpeed ()
prev = now;
}
if ( !Settings.TurboMode )
FrameTimer--;
return;
@ -295,29 +432,3 @@ S9xLoadSDD1Data ()
return;
}
/****************************************************************************
* Note that these are DUMMY functions, and only allow Snes9x to
* compile. Where possible, they will return an error signal.
***************************************************************************/
/*** splitpath function ***/
void
_splitpath (char const *buffer, char *drive, char *dir, char *fname,
char *ext)
{
return; /*** Do nothing - NGC code should NEVER call a function which relies on it ***/
}
void
_makepath (char *filename, const char *drive, const char *dir,
const char *fname, const char *ext)
{
return; /*** Do nothing - NGC code should NEVER call a function which relies on it ***/
}
char *
S9xBasename (char *name)
{
return name;
}

445
source/ngc/sdload.cpp Normal file
View File

@ -0,0 +1,445 @@
/****************************************************************************
* Snes9x 1.50
*
* Nintendo Gamecube Port
* softdev July 2006
* crunchy2 May 2007
*
* sdload.cpp
*
* Load ROMS from SD Card
****************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <string.h>
#include <ogcsys.h>
#include "sdload.h"
#include "unzip.h"
#include "memmap.h"
#include "video.h"
#include "ftfont.h"
#include "dvd.h"
#include "filesel.h"
#include "sram.h"
#include "preferences.h"
#include <zlib.h>
extern unsigned char savebuffer[];
extern char output[16384];
FILE * filehandle;
char currSDdir[MAXPATHLEN];
extern int offset;
extern int selection;
extern int loadtype;
extern FILEENTRIES filelist[MAXFILES];
/***************************************************************************
* FileSortCallback
*
* Quick sort callback to sort file entries with the following order:
* .
* ..
* <dirs>
* <files>
***************************************************************************/
static int FileSortCallback(const void *f1, const void *f2)
{
/* Special case for implicit directories */
if(((FILEENTRIES *)f1)->filename[0] == '.' || ((FILEENTRIES *)f2)->filename[0] == '.')
{
if(strcmp(((FILEENTRIES *)f1)->filename, ".") == 0) { return -1; }
if(strcmp(((FILEENTRIES *)f2)->filename, ".") == 0) { return 1; }
if(strcmp(((FILEENTRIES *)f1)->filename, "..") == 0) { return -1; }
if(strcmp(((FILEENTRIES *)f2)->filename, "..") == 0) { return 1; }
}
/* If one is a file and one is a directory the directory is first. */
if(((FILEENTRIES *)f1)->flags == 1 && ((FILEENTRIES *)f2)->flags == 0) return -1;
if(((FILEENTRIES *)f1)->flags == 0 && ((FILEENTRIES *)f2)->flags == 1) return 1;
return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename);
}
/***************************************************************************
* Update FAT (sdcard, usb) curent directory name
***************************************************************************/
int updateFATdirname()
{
int size=0;
char *test;
char temp[1024];
/* current directory doesn't change */
if (strcmp(filelist[selection].filename,".") == 0) return 0;
/* go up to parent directory */
else if (strcmp(filelist[selection].filename,"..") == 0)
{
/* determine last subdirectory namelength */
sprintf(temp,"%s",currSDdir);
test = strtok(temp,"/");
while (test != NULL) {
size = strlen(test);
test = strtok(NULL,"/");
}
/* remove last subdirectory name */
size = strlen(currSDdir) - size - 1;
currSDdir[size] = 0;
/* handles root name */
if (strcmp(currSDdir, "/") == 0)
return 1;
}
else /* Open a directory */
{
/* test new directory namelength */
if ((strlen(currSDdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
{
/* handles root name */
sprintf(temp, "/%s/..", SNESROMDIR);
if (strcmp(currSDdir, temp) == 0)
sprintf(currSDdir,"%s",ROOTSDDIR);
/* update current directory name */
sprintf(currSDdir, "%s/%s",currSDdir, filelist[selection].filename);
return 1;
} else {
WaitPrompt((char*)"Dirname is too long !");
return -1;
}
}
}
/***************************************************************************
* Browse FAT (sdcard, usb) subdirectories
***************************************************************************/
int parseFATdirectory() {
int nbfiles = 0;
DIR_ITER *sddir;
char filename[MAXPATHLEN];
struct stat filestat;
char msg[128];
/* initialize selection */
selection = offset = 0;
/* open the directory */
sddir = diropen(currSDdir);
if (sddir == NULL) {
/*** if we can't open the previous dir, open root dir ***/
if (loadtype == LOAD_USB)
sprintf(currSDdir,"fat4:/");
else // LOAD_SDC
//sprintf(currSDdir,"%s",ROOTSDDIR);
sprintf(currSDdir,"fat3:/");
sddir = diropen(currSDdir);
WaitPrompt(msg);
if (sddir == NULL) {
sprintf(msg, "Error opening %s", currSDdir);
WaitPrompt(msg);
return 0;
}
}
/* Move to DVD structure - this is required for the file selector */
while(dirnext(sddir,filename,&filestat) == 0) {
if(strcmp(filename,".") != 0) {
memset(&filelist[nbfiles], 0, sizeof(FILEENTRIES));
strncpy(filelist[nbfiles].filename, filename, MAXPATHLEN);
strncpy(filelist[nbfiles].displayname, filename, MAXDISPLAY+1); // crop name for display
filelist[nbfiles].length = filestat.st_size;
filelist[nbfiles].flags = (filestat.st_mode & _IFDIR) == 0 ? 0 : 1;
nbfiles++;
}
}
/*** close directory ***/
dirclose(sddir);
/* Sort the file list */
qsort(filelist, nbfiles, sizeof(FILEENTRIES), FileSortCallback);
return nbfiles;
}
/****************************************************************************
* LoadSDFile
****************************************************************************/
extern bool haveSDdir;
extern bool haveUSBdir;
int
LoadSDFile (char *filename, int length)
{
char zipbuffer[2048];
char filepath[MAXPATHLEN];
FILE *handle;
unsigned char *rbuffer;
u32 size;
rbuffer = (unsigned char *) Memory.ROM;
/* Check filename length */
if ((strlen(currSDdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
sprintf(filepath, "%s/%s",currSDdir,filelist[selection].filename);
else
{
WaitPrompt((char*) "Maximum Filename Length reached !");
haveSDdir = 0; // reset everything before next access
haveUSBdir = 0;
return -1;
}
handle = fopen (filepath, "rb");
if (handle > 0)
{
fread (zipbuffer, 1, 2048, handle);
if (IsZipFile (zipbuffer))
{
/*** Unzip the ROM ***/
size = UnZipBuffer (rbuffer, 0, 0, handle); // unzip from SD
fclose (handle);
return size;
}
else
{
/*** Just load the file up ***/
fseek(handle, 0, SEEK_END);
length = ftell(handle); // get filesize
fseek(handle, 2048, SEEK_SET); // seek back to point where we left off
sprintf (filepath, "Loading %d bytes", length);
ShowAction (filepath);
memcpy (rbuffer, zipbuffer, 2048); // copy what we already read
fread (rbuffer + 2048, 1, length - 2048, handle);
fclose (handle);
return length;
}
}
else
{
WaitPrompt((char*) "Error opening file");
return 0;
}
return 0;
}
/****************************************************************************
* Load savebuffer from SD card file
****************************************************************************/
int
LoadBufferFromSD (char *filepath, bool silent)
{
FILE *handle;
int offset = 0;
int read = 0;
handle = fopen (filepath, "rb");
if (handle <= 0)
{
if ( !silent )
{
char msg[100];
sprintf(msg, "Couldn't open %s", filepath);
WaitPrompt (msg);
}
return 0;
}
memset (savebuffer, 0, 0x22000);
/*** This is really nice, just load the file and decode it ***/
while ((read = fread (savebuffer + offset, 1, 1024, handle)) > 0)
{
offset += read;
}
fclose (handle);
return offset;
}
/****************************************************************************
* Write savebuffer to SD card file
****************************************************************************/
int
SaveBufferToSD (char *filepath, int datasize, bool silent)
{
FILE *handle;
if (datasize)
{
handle = fopen (filepath, "wb");
if (handle <= 0)
{
char msg[100];
sprintf(msg, "Couldn't save %s", filepath);
WaitPrompt (msg);
return 0;
}
fwrite (savebuffer, 1, datasize, handle);
fclose (handle);
}
return datasize;
}
/****************************************************************************
* Save SRAM to SD Card
****************************************************************************/
void SaveSRAMToSD (bool silent)
{
char filepath[1024];
int datasize;
int offset;
if (!silent)
ShowAction ((char*) "Saving SRAM to SD...");
#ifdef SDUSE_LFN
sprintf (filepath, "%s/%s/%s.srm", ROOTSDDIR, SNESSAVEDIR, Memory.ROMFilename);
#else
sprintf (filepath, "%s/%s/%08x.srm", ROOTSDDIR, SNESSAVEDIR, Memory.ROMCRC32);
#endif
datasize = prepareEXPORTsavedata ();
if ( datasize )
{
offset = SaveBufferToSD (filepath, datasize, silent);
if ( (offset > 0) && (!silent) )
{
sprintf (filepath, "Wrote %d bytes", offset);
WaitPrompt (filepath);
}
}
}
/****************************************************************************
* Load SRAM From SD Card
****************************************************************************/
void
LoadSRAMFromSD (bool silent)
{
char filepath[MAXPATHLEN];
int offset = 0;
ShowAction ((char*) "Loading SRAM from SD...");
// check for 'old' version of sram
sprintf (filepath, "%s/%s/%s.srm", ROOTSDDIR, SNESSAVEDIR, Memory.ROMName); // Build old SRAM filename
offset = LoadBufferFromSD (filepath, silent); // load file
if (offset > 0) // old sram found
{
if (WaitPromptChoice ((char*)"Old SRAM found. Convert and delete?", (char*)"Cancel", (char*)"Do it"))
{
decodesavedata (offset);
remove (filepath); // delete old sram
SaveSRAMToSD (silent);
}
}
//
#ifdef SDUSE_LFN
sprintf (filepath, "%s/%s/%s.srm", ROOTSDDIR, SNESSAVEDIR, Memory.ROMFilename);
#else
sprintf (filepath, "%s/%s/%08x.srm", ROOTSDDIR, SNESSAVEDIR, Memory.ROMCRC32);
#endif
offset = LoadBufferFromSD (filepath, silent);
if (offset > 0)
{
decodesavedata (offset);
if ( !silent )
{
sprintf (filepath, "Loaded %d bytes", offset);
WaitPrompt(filepath);
}
S9xSoftReset();
}
}
/****************************************************************************
* Save Preferences to SD Card
****************************************************************************/
void
SavePrefsToSD (bool silent)
{
char filepath[1024];
int datasize;
int offset;
if (!silent)
ShowAction ((char*) "Saving prefs to SD...");
#ifdef SDUSE_LFN
sprintf (filepath, "%s/%s/%s", ROOTSDDIR, SNESSAVEDIR, PREFS_FILE_NAME);
#else
sprintf (filepath, "%s/%s/%s", ROOTSDDIR, SNESSAVEDIR, PREFS_FILE_NAME);
#endif
datasize = preparePrefsData ();
offset = SaveBufferToSD (filepath, datasize, silent);
if ( (offset > 0) && (!silent) )
{
sprintf (filepath, "Wrote %d bytes", offset);
WaitPrompt (filepath);
}
}
/****************************************************************************
* Load Preferences from SD Card
****************************************************************************/
void
LoadPrefsFromSD (bool silent)
{
char filepath[1024];
int offset = 0;
ShowAction ((char*) "Loading prefs from SD...");
#ifdef SDUSE_LFN
sprintf (filepath, "%s/%s/%s", ROOTSDDIR, SNESSAVEDIR, PREFS_FILE_NAME);
#else
sprintf (filepath, "%s/%s/%s", ROOTSDDIR, SNESSAVEDIR, PREFS_FILE_NAME);
#endif
offset = LoadBufferFromSD (filepath, silent);
if (offset > 0)
{
decodePrefsData ();
if ( !silent )
{
sprintf (filepath, "Loaded %d bytes", offset);
WaitPrompt(filepath);
}
}
}

35
source/ngc/sdload.h Normal file
View File

@ -0,0 +1,35 @@
/****************************************************************************
* Snes9x 1.50
*
* Nintendo Gamecube Port
* softdev July 2006
* crunchy2 May 2007
*
* sdload.cpp
*
* Load ROMS from SD Card
****************************************************************************/
#ifndef _LOADFROMSDC_
#define _LOADFROMSDC_
#include <gccore.h>
#include <stdio.h>
#include <string.h>
#include <ogcsys.h>
#include <fat.h>
#include <sys/dir.h>
#include <sys/stat.h>
#include <unistd.h>
static int FileSortCallback(const void *f1, const void *f2);
int updateFATdirname();
int parseFATdirectory();
int LoadSDFile (char *filename, int length);
void SaveSRAMToSD (bool silent);
void LoadSRAMFromSD (bool silent);
void SavePrefsToSD (bool silent);
void LoadPrefsFromSD (bool silent);
extern char currSDdir[MAXPATHLEN];
#endif

484
source/ngc/smbload.cpp Normal file
View File

@ -0,0 +1,484 @@
/****************************************************************************
* Snes9x 1.50
*
* Nintendo Gamecube Port
* softdev July 2006
* crunchy2 May 2007
*
* smbload.cpp
*
* Load ROMS from a Network share.
****************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <string.h>
#include <ogcsys.h>
#include <network.h>
extern "C"
{
#include "smb.h"
}
#include "unzip.h"
#include "memmap.h"
#include "video.h"
#include "ftfont.h"
#include "dvd.h"
#include "filesel.h"
#include "sram.h"
#include "preferences.h"
#include "smbload.h"
#include "Snes9xGx.h"
#include <zlib.h>
static int connected = 0;
static int netinited = 0;
char output[16384];
unsigned int SMBTimer = 0;
extern unsigned char savebuffer[];
#define ZIPCHUNK 16384
#define SMBTIMEOUT ( 3600 ) /*** Some implementations timeout in 10 minutes ***/
SMBINFO smbinfo =
{ GC_IP, GW_IP, MASK, SMB_IP,
SMB_USER, SMB_PWD, SMB_GCID, SMB_SVID, SMB_SHARE
};
extern FILEENTRIES filelist[MAXFILES];
/****************************************************************************
* Mount SMB Share
****************************************************************************/
void
ConnectSMB ()
{
int ret;
if (SMBTimer > SMBTIMEOUT)
{
connected = 0;
SMBTimer = 0;
}
if (connected == 0)
{
if (netinited == 0)
{
ShowAction ((char*) "Setting up network interface ...");
ret = if_config (smbinfo.gcip, smbinfo.gwip, smbinfo.mask, 0);
netinited = 1;
}
ShowAction ((char*) "Connecting to share ...");
SMB_Destroy ();
if (SMB_Init (smbinfo.smbuser, smbinfo.smbpwd,
smbinfo.smbgcid, smbinfo.smbsvid, smbinfo.smbshare,
smbinfo.smbip) != SMB_SUCCESS)
{
WaitPrompt((char*) "Failed to connect to SMB share");
connected = 0;
return;
}
}
connected = 1;
}
/****************************************************************************
* parseSMBDirectory
*
* Load the share directory and put in the filelist array
*****************************************************************************/
int
parseSMBDirectory ()
{
char searchpath[1024];
int filecount = 0;
SMBDIRENTRY smbdir;
ConnectSMB ();
strcpy (searchpath, SNESROMDIR);
strcat (searchpath, "\\*.*");
if (SMB_FindFirst
(searchpath, SMB_SRCH_READONLY | SMB_SRCH_SYSTEM | SMB_SRCH_HIDDEN,
&smbdir) != SMB_SUCCESS)
{
return 0;
}
do
{
memset (&filelist[filecount], 0, sizeof (FILEENTRIES));
filelist[filecount].length = smbdir.size_low;
smbdir.name[MAXJOLIET] = 0;
/*** Update display name ***/
memcpy (&filelist[filecount].displayname, smbdir.name, MAXDISPLAY);
filelist[filecount].displayname[MAXDISPLAY] = 0;
strcpy (filelist[filecount].filename, smbdir.name);
filecount++;
}
while (SMB_FindNext (&smbdir) == SMB_SUCCESS);
SMB_FindClose ();
return filecount;
}
/****************************************************************************
* Load SMB file
****************************************************************************/
int
LoadSMBFile (char *filename, int length)
{
char buffer[128];
int offset = 0;
int bytesread = 0;
int total = 0;
char filepath[1024];
SMBFILE smbfile;
char *rbuffer;
char zipbuffer[16384];
int pass = 0;
int zip = 0;
PKZIPHEADER pkzip;
z_stream zs;
int res, outbytes;
strcpy (filepath, SNESROMDIR);
strcat (filepath, "\\");
strcat (filepath, filename);
rbuffer = (char *) Memory.ROM;
outbytes = 0;
int have = 0;
ConnectSMB ();
if ( connected )
{
/*** Open the file for reading ***/
smbfile =
SMB_Open (filepath, SMB_OPEN_READING | SMB_DENY_NONE, SMB_OF_OPEN);
if (smbfile)
{
while (total < length)
{
bytesread = SMB_Read (zipbuffer, 16384, offset, smbfile);
if (pass == 0)
{
/*** Is this a Zip file ? ***/
zip = IsZipFile (zipbuffer);
if (zip)
{
memcpy (&pkzip, zipbuffer, sizeof (PKZIPHEADER));
pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);
memset (&zs, 0, sizeof (zs));
zs.zalloc = Z_NULL;
zs.zfree = Z_NULL;
zs.opaque = Z_NULL;
zs.avail_in = 0;
zs.next_in = Z_NULL;
res = inflateInit2 (&zs, -MAX_WBITS);
if (res != Z_OK)
{
SMB_Close (smbfile);
return 0;
}
zs.avail_in =
16384 - (sizeof (PKZIPHEADER) +
FLIP16 (pkzip.filenameLength) +
FLIP16 (pkzip.extraDataLength));
zs.next_in =
(Bytef *) zipbuffer + (sizeof (PKZIPHEADER) +
FLIP16 (pkzip.filenameLength) +
FLIP16 (pkzip.extraDataLength));
}
}
if (zip)
{
if (pass)
{
zs.avail_in = bytesread;
zs.next_in = (Bytef *) zipbuffer;
}
do
{
zs.avail_out = ZIPCHUNK;
zs.next_out = (Bytef *) output;
res = inflate (&zs, Z_NO_FLUSH);
have = ZIPCHUNK - zs.avail_out;
if (have)
{
memcpy (rbuffer + outbytes, output, have);
outbytes += have;
}
}
while (zs.avail_out == 0);
}
else
memcpy (rbuffer + offset, zipbuffer, bytesread);
total += bytesread;
offset += bytesread;
if (!zip)
{
sprintf (buffer, "Read %d of %d bytes", total, length);
ShowProgress (buffer, total, length);
}
else
{
sprintf (buffer, "Unzipped %d of %d", outbytes,
pkzip.uncompressedSize);
ShowProgress (buffer, outbytes, pkzip.uncompressedSize);
}
//ShowAction (buffer);
pass++;
}
if (zip)
{
inflateEnd (&zs);
total = outbytes;
}
SMB_Close (smbfile);
return total;
}
else
{
WaitPrompt((char*) "SMB Reading Failed!");
//while (1);
return 0;
}
}
return 0;
}
/****************************************************************************
* Write savebuffer to SMB file
****************************************************************************/
int
SaveBufferToSMB (char *filepath, int datasize, bool8 silent)
{
SMBFILE smbfile;
int dsize = datasize;
int wrote = 0;
int offset = 0;
ConnectSMB ();
if ( connected )
{
smbfile =
SMB_Open (filepath, SMB_OPEN_WRITING | SMB_DENY_NONE,
SMB_OF_CREATE | SMB_OF_TRUNCATE);
if (smbfile)
{
while (dsize > 0)
{
if (dsize > 1024)
wrote =
SMB_Write ((char *) savebuffer + offset, 1024, offset, smbfile);
else
wrote =
SMB_Write ((char *) savebuffer + offset, dsize, offset, smbfile);
offset += wrote;
dsize -= wrote;
}
SMB_Close (smbfile);
SMBTimer = 0;
return offset;
}
else
{
char msg[100];
sprintf(msg, "Couldn't save SMB:%s", filepath);
WaitPrompt (msg);
}
}
return 0;
}
/****************************************************************************
* Load savebuffer from SMB file
****************************************************************************/
int
LoadBufferFromSMB (char *filepath, bool8 silent)
{
SMBFILE smbfile;
int ret;
int offset = 0;
ConnectSMB ();
if ( connected )
{
smbfile =
SMB_Open (filepath, SMB_OPEN_READING | SMB_DENY_NONE, SMB_OF_OPEN);
if (!smbfile)
{
if (!silent)
{
char msg[100];
sprintf(msg, "Couldn't open SMB:%s", filepath);
WaitPrompt (msg);
}
return 0;
}
memset (savebuffer, 0, 0x22000);
while ((ret =
SMB_Read ((char *) savebuffer + offset, 1024, offset,
smbfile)) > 0)
offset += ret;
SMB_Close (smbfile);
return offset;
}
return 0;
}
/****************************************************************************
* Save SRAM to SMB
****************************************************************************/
void
SaveSRAMToSMB (bool8 silent)
{
char filepath[1024];
int datasize;
int offset;
sprintf (filepath, "%s\\%s.srm", SNESSAVEDIR, Memory.ROMFilename);
if (!silent)
ShowAction ((char*) "Saving SRAM to SMB...");
datasize = prepareEXPORTsavedata ();
if ( datasize )
{
offset = SaveBufferToSMB (filepath, datasize, silent);
if ( (offset > 0) && (!silent) )
{
sprintf (filepath, "Wrote %d bytes", offset);
WaitPrompt (filepath);
}
}
}
/****************************************************************************
* Load SRAM from SMB
****************************************************************************/
void
LoadSRAMFromSMB (bool8 silent)
{
char filepath[1024];
int offset;
sprintf (filepath, "%s\\%s.srm", SNESSAVEDIR, Memory.ROMFilename);
ShowAction ((char*) "Loading SRAM from SMB...");
offset = LoadBufferFromSMB (filepath, silent);
if (offset > 0)
{
decodesavedata (offset);
if ( !silent )
{
sprintf (filepath, "Loaded %d bytes", offset);
WaitPrompt(filepath);
}
S9xSoftReset();
}
}
/****************************************************************************
* Save Preferences to SMB
****************************************************************************/
void
SavePrefsToSMB (bool8 silent)
{
char filepath[1024];
int datasize;
int offset;
sprintf (filepath, "%s\\%s", SNESSAVEDIR, PREFS_FILE_NAME);
if (!silent)
ShowAction ((char*) "Saving preferences to SMB...");
datasize = preparePrefsData ();
if ( datasize )
{
offset = SaveBufferToSMB (filepath, datasize, silent);
if ( (offset > 0) && (!silent) )
{
sprintf (filepath, "Wrote %d bytes", offset);
WaitPrompt (filepath);
}
}
}
/****************************************************************************
* Load Preferences from SMB
****************************************************************************/
void
LoadPrefsFromSMB (bool8 silent)
{
char filepath[1024];
int offset;
ShowAction ((char*) "Loading preferences from SMB...");
sprintf (filepath, "%s\\%s", SNESSAVEDIR, PREFS_FILE_NAME);
offset = LoadBufferFromSMB (filepath, silent);
if (offset > 0)
{
decodePrefsData ();
if ( !silent )
{
sprintf (filepath, "Loaded %d bytes", offset);
WaitPrompt(filepath);
}
}
}

38
source/ngc/smbload.h Normal file
View File

@ -0,0 +1,38 @@
/****************************************************************************
* Snes9x 1.50
*
* Nintendo Gamecube Port
* softdev July 2006
* crunchy2 May 2007
*
* smbload.cpp
*
* Load ROMS from a Network share.
****************************************************************************/
#ifndef _NGCSMB_
#define _NGCSMB_
void ConnectSMB ();
int parseSMBDirectory ();
int LoadSMBFile (char *filename, int length);
void SaveSRAMToSMB (bool8 silent);
void LoadSRAMFromSMB (bool8 silent);
void SavePrefsToSMB (bool8 silent);
void LoadPrefsFromSMB (bool8 silent);
typedef struct
{
char gcip[16];
char gwip[16];
char mask[16];
char smbip[16];
char smbuser[20];
char smbpwd[20];
char smbgcid[20];
char smbsvid[20];
char smbshare[20];
}
SMBINFO;
#endif

View File

@ -1,380 +0,0 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* softdev July 2006
* crunchy2 May 2007
* Tantric August 2008
*
* smbload.cpp
*
* SMB support routines
****************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <string.h>
#include <ogcsys.h>
#include <network.h>
#include <smb.h>
#include <zlib.h>
#include <errno.h>
#include "memmap.h"
#include "smbop.h"
#include "unzip.h"
#include "video.h"
#include "menudraw.h"
#include "filesel.h"
#include "snes9xGX.h"
bool networkInit = false;
bool networkShareInit = false;
unsigned int SMBTimer = 0;
#define SMBTIMEOUT ( 3600 ) // Some implementations timeout in 10 minutes
// SMB connection/file handles - the only ones we should ever use!
SMBCONN smbconn;
SMBFILE smbfile;
#define ZIPCHUNK 16384
/****************************************************************************
* InitializeNetwork
* Initializes the Wii/GameCube network interface
****************************************************************************/
bool InitializeNetwork(bool silent)
{
ShowAction ((char*) "Initializing network...");
s32 result;
while ((result = net_init()) == -EAGAIN);
if (result >= 0)
{
char myIP[16];
if (if_config(myIP, NULL, NULL, true) < 0)
{
if(!silent)
WaitPrompt((char*) "Error reading IP address.");
return false;
}
else
{
return true;
}
}
if(!silent)
WaitPrompt((char*) "Unable to initialize network.");
return false;
}
/****************************************************************************
* Mount SMB Share
****************************************************************************/
bool
ConnectShare (bool silent)
{
// Crashes or stalls system in GameCube mode - so disable
#ifndef HW_RVL
return false;
#endif
// check that all parameter have been set
if(strlen(GCSettings.smbuser) == 0 ||
strlen(GCSettings.smbpwd) == 0 ||
strlen(GCSettings.smbshare) == 0 ||
strlen(GCSettings.smbip) == 0)
{
if(!silent)
WaitPrompt((char*) "Invalid network settings. Check SNES9xGX.xml.");
return false;
}
if(!networkInit)
networkInit = InitializeNetwork(silent);
if(networkInit)
{
// connection may have expired
if (networkShareInit && SMBTimer > SMBTIMEOUT)
{
networkShareInit = false;
SMBTimer = 0;
SMB_Close(smbconn);
}
if(!networkShareInit)
{
if(!silent)
ShowAction ((char*) "Connecting to network share...");
if(SMB_Connect(&smbconn, GCSettings.smbuser, GCSettings.smbpwd,
GCSettings.smbgcid, GCSettings.smbsvid, GCSettings.smbshare, GCSettings.smbip) == SMB_SUCCESS)
networkShareInit = true;
}
if(!networkShareInit && !silent)
WaitPrompt ((char*) "Failed to connect to network share.");
}
return networkShareInit;
}
/****************************************************************************
* SMBPath
*
* Returns a SMB-style path
*****************************************************************************/
char * SMBPath(char * path)
{
// fix path - replace all '/' with '\'
for(uint i=0; i < strlen(path); i++)
if(path[i] == '/')
path[i] = '\\';
return path;
}
/****************************************************************************
* parseSMBDirectory
*
* Load the directory and put in the filelist array
*****************************************************************************/
int
ParseSMBdirectory ()
{
if(!ConnectShare (NOTSILENT))
return 0;
int filecount = 0;
char searchpath[1024];
SMBDIRENTRY smbdir;
// initialize selection
selection = offset = 0;
// Clear any existing values
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
if(strlen(currentdir) <= 1) // root
sprintf(searchpath, "*");
else
sprintf(searchpath, "%s/*", currentdir);
if (SMB_FindFirst
(SMBPath(searchpath), SMB_SRCH_READONLY | SMB_SRCH_DIRECTORY, &smbdir, smbconn) != SMB_SUCCESS)
{
char msg[200];
sprintf(msg, "Could not open %s", currentdir);
WaitPrompt (msg);
// if we can't open the dir, open root dir
sprintf(searchpath, "/");
sprintf(searchpath,"*");
if (SMB_FindFirst
(SMBPath(searchpath), SMB_SRCH_READONLY | SMB_SRCH_DIRECTORY, &smbdir, smbconn) != SMB_SUCCESS)
return 0;
}
// index files/folders
do
{
if(strcmp(smbdir.name,".") != 0 &&
!(strlen(currentdir) <= 1 && strcmp(smbdir.name,"..") == 0))
{
memset (&filelist[filecount], 0, sizeof (FILEENTRIES));
filelist[filecount].length = smbdir.size_low;
smbdir.name[MAXJOLIET] = 0;
if(smbdir.attributes == SMB_SRCH_DIRECTORY)
filelist[filecount].flags = 1; // flag this as a dir
else
filelist[filecount].flags = 0;
// Update display name
memcpy (&filelist[filecount].displayname, smbdir.name, MAXDISPLAY);
filelist[filecount].displayname[MAXDISPLAY] = 0;
strcpy (filelist[filecount].filename, smbdir.name);
filecount++;
}
} while (SMB_FindNext (&smbdir, smbconn) == SMB_SUCCESS);
// close directory
SMB_FindClose (smbconn);
// Sort the file list
qsort(filelist, filecount, sizeof(FILEENTRIES), FileSortCallback);
return filecount;
}
/****************************************************************************
* Open SMB file
***************************************************************************/
SMBFILE OpenSMBFile(char * filepath)
{
return SMB_OpenFile (SMBPath(filepath), SMB_OPEN_READING, SMB_OF_OPEN, smbconn);
}
/****************************************************************************
* Load SMB file
* rom - pointer to memory where ROM will be stored
* length - # bytes to read (0 for all)
****************************************************************************/
int
LoadSMBFile (char * rom, int length)
{
char filepath[MAXPATHLEN];
/* Check filename length */
if (!MakeROMPath(filepath, METHOD_SMB))
{
WaitPrompt((char*) "Maximum filepath length reached!");
return -1;
}
return LoadBufferFromSMB(rom, filepath, length, NOTSILENT);
}
/****************************************************************************
* LoadSMBSzFile
* Loads the selected file # from the specified 7z into rbuffer
* Returns file size
***************************************************************************/
int
LoadSMBSzFile(char * filepath, unsigned char * rbuffer)
{
if(!ConnectShare (NOTSILENT))
return 0;
smbfile = OpenSMBFile(filepath);
if (smbfile)
{
u32 size = SzExtractFile(filelist[selection].offset, rbuffer);
SMB_CloseFile (smbfile);
return size;
}
else
{
WaitPrompt((char*) "Error opening file");
return 0;
}
}
/****************************************************************************
* Write savebuffer to SMB file
****************************************************************************/
// no buffer specified, use savebuffer
int
SaveBufferToSMB (char *filepath, int datasize, bool silent)
{
return SaveBufferToSMB((char *)savebuffer, filepath, datasize, silent);
}
int
SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent)
{
if(!ConnectShare (NOTSILENT))
return 0;
int dsize = datasize;
int wrote = 0;
int boffset = 0;
smbfile =
SMB_OpenFile (SMBPath(filepath), SMB_OPEN_WRITING | SMB_DENY_NONE,
SMB_OF_CREATE | SMB_OF_TRUNCATE, smbconn);
if (smbfile)
{
while (dsize > 0)
{
if (dsize > 1024)
wrote =
SMB_WriteFile ((char *) sbuffer + boffset, 1024, boffset, smbfile);
else
wrote =
SMB_WriteFile ((char *) sbuffer + boffset, dsize, boffset, smbfile);
boffset += wrote;
dsize -= wrote;
}
SMB_CloseFile (smbfile);
}
else
{
char msg[100];
sprintf(msg, "Couldn't save SMB: %s", SMBPath(filepath));
WaitPrompt (msg);
}
return boffset;
}
/****************************************************************************
* Load up a buffer from SMB file
****************************************************************************/
// no buffer is specified - so use savebuffer
int
LoadBufferFromSMB (char *filepath, bool silent)
{
return LoadBufferFromSMB((char *)savebuffer, filepath, 0, silent);
}
int
LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent)
{
if(!ConnectShare (NOTSILENT))
return 0;
int ret;
int boffset = 0;
smbfile = OpenSMBFile(filepath);
if (!smbfile)
{
if(!silent)
{
char msg[100];
sprintf(msg, "Couldn't open SMB: %s", SMBPath(filepath));
WaitPrompt (msg);
}
return 0;
}
if(length > 0 && length <= 2048) // do a partial read (eg: to check file header)
{
boffset = SMB_ReadFile (sbuffer, length, 0, smbfile);
}
else // load whole file
{
ret = SMB_ReadFile (sbuffer, 1024, boffset, smbfile);
if (IsZipFile (sbuffer))
{
boffset = UnZipBuffer ((unsigned char *)sbuffer, METHOD_SMB); // unzip from SMB
}
else
{
// Just load the file up
while ((ret = SMB_ReadFile (sbuffer + boffset, 2048, boffset, smbfile)) > 0)
{
boffset += ret;
ShowProgress ((char *)"Loading...", boffset, length);
}
}
}
SMB_CloseFile (smbfile);
return boffset;
}

View File

@ -1,34 +0,0 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* softdev July 2006
* crunchy2 May 2007
* Tantric August 2008
*
* smbload.h
*
* SMB support routines
****************************************************************************/
#ifndef _NGCSMB_
#define _NGCSMB_
#include <smb.h>
bool InitializeNetwork(bool silent);
bool ConnectShare (bool silent);
char * SMBPath(char * path);
int UpdateSMBdirname();
int ParseSMBdirectory ();
SMBFILE OpenSMBFile(char * filepath);
int LoadSMBFile (char * fbuffer, int length);
int LoadSMBSzFile(char * filepath, unsigned char * rbuffer);
int LoadBufferFromSMB (char *filepath, bool silent);
int LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent);
int SaveBufferToSMB (char *filepath, int datasize, bool silent);
int SaveBufferToSMB (char * sbuffer, char *filepath, int datasize, bool silent);
extern SMBFILE smbfile;
#endif

View File

@ -1,16 +1,157 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Port
* softdev July 2006
* crunchy2 May 2007-July 2007
* Michniewski 2008
* Tantric September 2008
*
* snes9xGX.cpp
*
* This file controls overall program flow. Most things start and end here!
***************************************************************************/
****************************************************************************/
/****************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
C4 x86 assembler and some C emulation code
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
Nach,
zsKnight (zsknight@zsnes.com)
C4 C++ code
(c) Copyright 2003 - 2006 Brad Jorsch,
Nach
DSP-1 emulator code
(c) Copyright 1998 - 2006 _Demo_,
Andreas Naive (andreasnaive@gmail.com)
Gary Henderson,
Ivar (ivar@snes9x.com),
John Weidman,
Kris Bleakley,
Matthew Kendora,
Nach,
neviksti (neviksti@hotmail.com)
DSP-2 emulator code
(c) Copyright 2003 John Weidman,
Kris Bleakley,
Lord Nightmare (lord_nightmare@users.sourceforge.net),
Matthew Kendora,
neviksti
DSP-3 emulator code
(c) Copyright 2003 - 2006 John Weidman,
Kris Bleakley,
Lancer,
z80 gaiden
DSP-4 emulator code
(c) Copyright 2004 - 2006 Dreamer Nom,
John Weidman,
Kris Bleakley,
Nach,
z80 gaiden
OBC1 emulator code
(c) Copyright 2001 - 2004 zsKnight,
pagefault (pagefault@zsnes.com),
Kris Bleakley,
Ported from x86 assembler to C by sanmaiwashi
SPC7110 and RTC C++ emulator code
(c) Copyright 2002 Matthew Kendora with research by
zsKnight,
John Weidman,
Dark Force
S-DD1 C emulator code
(c) Copyright 2003 Brad Jorsch with research by
Andreas Naive,
John Weidman
S-RTC C emulator code
(c) Copyright 2001-2006 byuu,
John Weidman
ST010 C++ emulator code
(c) Copyright 2003 Feather,
John Weidman,
Kris Bleakley,
Matthew Kendora
Super FX x86 assembler emulator code
(c) Copyright 1998 - 2003 _Demo_,
pagefault,
zsKnight,
Super FX C emulator code
(c) Copyright 1997 - 1999 Ivar,
Gary Henderson,
John Weidman
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
(c) Copyright 1998 - 2003 Brad Martin
(c) Copyright 1998 - 2006 Charles Bilyue'
SH assembler code partly based on x86 assembler code
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
warranty. In no event shall the authors be held liable for any damages
arising from the use of this software or it's derivatives.
Snes9x is freeware for PERSONAL USE only. Commercial users should
seek permission of the copyright holders first. Commercial use includes,
but is not limited to, charging money for Snes9x or software derived from
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
using Snes9x as a promotion for your commercial product.
The copyright holders request that bug fixes and improvements to the code
should be forwarded to them so everyone can benefit from the modifications
in future versions.
Super NES and Super Nintendo Entertainment System are trademarks of
Nintendo Co., Limited and its subsidiary companies.
*****************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
@ -18,17 +159,11 @@
#include <ogcsys.h>
#include <unistd.h>
#include <fat.h>
#include <wiiuse/wpad.h>
#include <sdcard/card_cmn.h>
#include <sdcard/wiisd_io.h>
#include <sdcard/card_io.h>
#include <fat.h>
#ifdef WII_DVD
extern "C" {
#include <di/di.h>
}
#endif
#include "snes9x.h"
#include "memmap.h"
@ -44,26 +179,20 @@ extern "C" {
#include "controls.h"
#include "snes9xGX.h"
#include "aram.h"
#include "dvd.h"
#include "smbop.h"
#include "video.h"
#include "menudraw.h"
#include "ftfont.h"
#include "s9xconfig.h"
#include "audio.h"
#include "menu.h"
#include "sram.h"
#include "freeze.h"
#include "memfile.h"
#include "preferences.h"
#include "gctime.h"
#include "button_mapping.h"
#include "fileop.h"
#include "input.h"
#include "gui.h"
unsigned long ARAM_ROMSIZE = 0;
int ConfigRequested = 0;
FILE* debughandle;
extern int FrameTimer;
extern long long prev;
@ -71,19 +200,221 @@ extern unsigned int timediffallowed;
extern void fat_enable_readahead_all();
/****************************************************************************
* Controller Functions
*
* The following map the NGC Pads to the *NEW* controller system.
****************************************************************************/
#define ASSIGN_BUTTON_TRUE( keycode, snescmd ) \
S9xMapButton( keycode, cmd = S9xGetCommandT(snescmd), true)
#define ASSIGN_BUTTON_FALSE( keycode, snescmd ) \
S9xMapButton( keycode, cmd = S9xGetCommandT(snescmd), false)
#define MAXJP 12
int padcal = 50;
/*** Gamecube controller Padmap ***/
unsigned int gcpadmap[] = { PAD_BUTTON_A, PAD_BUTTON_B,
PAD_BUTTON_X, PAD_BUTTON_Y,
PAD_TRIGGER_L, PAD_TRIGGER_R,
PAD_TRIGGER_Z, PAD_BUTTON_START,
PAD_BUTTON_UP, PAD_BUTTON_DOWN,
PAD_BUTTON_LEFT, PAD_BUTTON_RIGHT
};
/*** Wiimote Padmap ***/
unsigned int wmpadmap[] = { WPAD_BUTTON_B, WPAD_BUTTON_2,
WPAD_BUTTON_1, WPAD_BUTTON_A,
0x0000, 0x0000,
WPAD_BUTTON_MINUS, WPAD_BUTTON_PLUS,
WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT,
WPAD_BUTTON_UP, WPAD_BUTTON_DOWN
};
/*** Classic Controller Padmap ***/
unsigned int ccpadmap[] = { WPAD_CLASSIC_BUTTON_A, WPAD_CLASSIC_BUTTON_B,
WPAD_CLASSIC_BUTTON_X, WPAD_CLASSIC_BUTTON_Y,
WPAD_CLASSIC_BUTTON_FULL_L, WPAD_CLASSIC_BUTTON_FULL_R,
WPAD_CLASSIC_BUTTON_MINUS, WPAD_CLASSIC_BUTTON_PLUS,
WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN,
WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT
};
/*** Nunchuk + wiimote Padmap ***/
unsigned int ncpadmap[] = { WPAD_BUTTON_A, WPAD_BUTTON_B,
WPAD_NUNCHUK_BUTTON_C, WPAD_NUNCHUK_BUTTON_Z,
WPAD_BUTTON_MINUS, WPAD_BUTTON_PLUS,
WPAD_BUTTON_2, WPAD_BUTTON_1,
WPAD_BUTTON_UP, WPAD_BUTTON_DOWN,
WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT
};
#if 0
/****************************************************************************
* decodepad
* Called per pad with offset
****************************************************************************/
void
decodepadold (int pad)
{
int i, offset;
signed char x, y;
unsigned short jp;
/*** Do analogue updates ***/
x = PAD_StickX (pad);
y = PAD_StickY (pad);
jp = PAD_ButtonsHeld (pad);
/*** Recalc left / right ***/
if (x < -padcal)
jp |= PAD_BUTTON_LEFT;
if (x > padcal)
jp |= PAD_BUTTON_RIGHT;
/*** Recalc up / down ***/
if (y > padcal)
jp |= PAD_BUTTON_UP;
if (y < -padcal)
jp |= PAD_BUTTON_DOWN;
/*** Fix offset to pad ***/
offset = ((pad + 1) << 4);
for (i = 0; i < MAXJP; i++)
{
if (jp & gcpadmap[i])
S9xReportButton (offset + i, true);
else
S9xReportButton (offset + i, false);
}
}
#endif
/****************************************************************************
* This is the joypad algorithm submitted by Krullo.
****************************************************************************/
void
decodepad (int pad)
{
int i, offset;
signed char x, y;
//unsigned short jp, wp; //
u32 jp, wp;
float t;
float mag = 0;
float mag2 = 0;
u16 ang = 0;
u16 ang2 = 0;
u32 exp_type;
/*** Do analogue updates ***/
x = PAD_StickX (pad);
y = PAD_StickY (pad);
jp = PAD_ButtonsHeld (pad);
#ifdef HW_RVL
exp_type = wpad_get_analogues(pad, &mag, &ang, &mag2, &ang2); // get joystick info from wii expansions
wp = WPAD_ButtonsHeld (pad); // wiimote
#else
wp = 0;
#endif
/***
Gamecube Joystick input
***/
// Is XY inside the "zone"?
if (x * x + y * y > padcal * padcal)
{
/*** we don't want division by ZERO ***/
if (x > 0 && y == 0)
jp |= PAD_BUTTON_RIGHT;
if (x < 0 && y == 0)
jp |= PAD_BUTTON_LEFT;
if (x == 0 && y > 0)
jp |= PAD_BUTTON_UP;
if (x == 0 && y < 0)
jp |= PAD_BUTTON_DOWN;
if (x != 0 && y != 0)
{
/*** Recalc left / right ***/
t = (float) y / x;
if (t >= -2.41421356237 && t < 2.41421356237)
{
if (x >= 0)
jp |= PAD_BUTTON_RIGHT;
else
jp |= PAD_BUTTON_LEFT;
}
/*** Recalc up / down ***/
t = (float) x / y;
if (t >= -2.41421356237 && t < 2.41421356237)
{
if (y >= 0)
jp |= PAD_BUTTON_UP;
else
jp |= PAD_BUTTON_DOWN;
}
}
}
#ifdef HW_RVL
/***
Wii Joystick (classic, nunchuk) input
***/
if (exp_type == WPAD_EXP_NUNCHUK)
{
if ( mag>JOY_THRESHOLD && (ang>300 || ang<50) )
wp |= WPAD_BUTTON_UP;
if ( mag>JOY_THRESHOLD && (ang>130 && ang<230) )
wp |= WPAD_BUTTON_DOWN;
if ( mag>JOY_THRESHOLD && (ang>220 && ang<320) )
wp |= WPAD_BUTTON_LEFT;
if ( mag>JOY_THRESHOLD && (ang>40 && ang<140) )
wp |= WPAD_BUTTON_RIGHT;
} else if (exp_type == WPAD_EXP_CLASSIC)
{
if ( mag>JOY_THRESHOLD && (ang>300 || ang<50) )
wp |= WPAD_CLASSIC_BUTTON_UP;
if ( mag>JOY_THRESHOLD && (ang>130 && ang<230) )
wp |= WPAD_CLASSIC_BUTTON_DOWN;
if ( mag>JOY_THRESHOLD && (ang>220 && ang<320) )
wp |= WPAD_CLASSIC_BUTTON_LEFT;
if ( mag>JOY_THRESHOLD && (ang>40 && ang<140) )
wp |= WPAD_CLASSIC_BUTTON_RIGHT;
}
#endif
/*** Fix offset to pad ***/
offset = ((pad + 1) << 4);
for (i = 0; i < MAXJP; i++)
{
/*** Report pressed buttons ***/
if ( (jp & gcpadmap[i]) // gamecube controller
#ifdef HW_RVL
|| ( (exp_type == WPAD_EXP_NONE) && (wp & wmpadmap[i]) ) // wiimote
|| ( (exp_type == WPAD_EXP_CLASSIC) && (wp & ccpadmap[i]) ) // classic controller
|| ( (exp_type == WPAD_EXP_NUNCHUK) && (wp & ncpadmap[i]) ) // nunchuk + wiimote
#endif
)
S9xReportButton (offset + i, true);
else
S9xReportButton (offset + i, false);
}
}
/****************************************************************************
* setFrameTimerMethod()
* change frametimer method depending on whether ROM is NTSC or PAL
***************************************************************************/
* change frametimer method depending on whether ROM is NTSC or PAL
****************************************************************************/
extern u8 vmode_60hz;
int timerstyle;
void setFrameTimerMethod()
{
/*
Set frametimer method
(timerstyle: 0=NTSC vblank, 1=PAL int timer)
Set frametimer method
(timerstyle: 0=NTSC vblank, 1=PAL int timer)
*/
if ( Settings.PAL ) {
if(vmode_60hz == 1)
@ -100,87 +431,241 @@ void setFrameTimerMethod()
}
return;
}
/****************************************************************************
* NGCReportButtons
* Called on each rendered frame
****************************************************************************/
void
NGCReportButtons ()
{
s8 gc_px = PAD_SubStickX (0);
s8 gc_py = PAD_SubStickY (0);
u16 gc_pb = PAD_ButtonsHeld (0);
#ifdef HW_RVL
float mag1 = 0;
float mag2 = 0;
u16 ang1 = 0;
u16 ang2 = 0;
u32 wm_pb = WPAD_ButtonsHeld (0); // wiimote / expansion button info
wpad_get_analogues(0, &mag1, &ang1, &mag2, &ang2); // get joystick info from wii expansions
#endif
/*** Check for video zoom ***/
if (GCSettings.NGCZoom)
{
if (gc_py < -18 || gc_py > 18)
zoom ((float) gc_py / -18);
#ifdef HW_RVL
if ( mag2>0.2 && (ang2>340 || ang2<20) ) // classic rjs up
zoom ((float) mag2 / -0.2);
if ( mag2>0.2 && (ang2>160 && ang2<200) ) // classic rjs down
zoom ((float) mag2 / 0.2);
#endif
}
Settings.TurboMode = ( (gc_px > 70)
#ifdef HW_RVL
|| (mag2>JOY_THRESHOLD && ang2>75 && ang2<115)
#endif
); // RIGHT on c-stick and on classic ctrlr right joystick
/*** Check for menu:
CStick left
OR "L+R+X+Y" (eg. Hombrew/Adapted SNES controllers)
OR "Home" on the wiimote or classic controller ***/
if ((gc_px < -70) ||
((gc_pb & PAD_TRIGGER_L) &&
(gc_pb & PAD_TRIGGER_R ) &&
(gc_pb & PAD_BUTTON_X) &&
(gc_pb & PAD_BUTTON_Y ))
#ifdef HW_RVL
|| (wm_pb & WPAD_BUTTON_HOME)
|| (wm_pb & WPAD_CLASSIC_BUTTON_HOME)
#endif
)
{
ConfigRequested = 1;
VIDEO_WaitVSync ();
if ( GCSettings.AutoSave == 1 )
{
//if ( WaitPromptChoice ((char*)"Save SRAM?", (char*)"Don't Save", (char*)"Save") )
quickSaveSRAM ( SILENT );
}
else if ( GCSettings.AutoSave == 2 )
{
if ( WaitPromptChoice ((char*)"Save Freeze State?", (char*)"Don't Save", (char*)"Save") )
quickSaveFreeze ( SILENT );
}
else if ( GCSettings.AutoSave == 3 )
{
if ( WaitPromptChoice ((char*)"Save SRAM and Freeze State?", (char*)"Don't Save", (char*)"Save") )
{
quickSaveSRAM ( SILENT );
quickSaveFreeze ( SILENT );
}
}
mainmenu ();
FrameTimer = 0;
ConfigRequested = 0;
setFrameTimerMethod(); // set frametimer method every time a ROM is loaded
// auto load freeze/sram?
}
else
{
int j = (Settings.MultiPlayer5Master == true ? 4 : 2);
for (int i = 0; i < j; i++)
decodepad (i);
}
}
/****************************************************************************
* wpad_get_analogues()
*
* gets the analogue stick magnitude and angle values (
* from classic or nunchuk expansions)
****************************************************************************/
u32 wpad_get_analogues(int pad, float* mag1, u16* ang1, float* mag2, u16* ang2)
{
*mag1 = *ang1 = *mag2 = *ang2 = 0;
u32 exp_type = 0;
#ifdef HW_RVL
struct expansion_t exp;
memset( &exp, 0, sizeof(exp) );
if ( WPAD_Probe( pad, &exp_type) == 0) // check wiimote and expansion status (first if wiimote is connected & no errors)
{
WPAD_Expansion(pad, &exp); // expansion connected. get info
if (exp_type == WPAD_EXP_CLASSIC)
{
*ang1 = exp.classic.ljs.ang; // left cc joystick
*mag1 = exp.classic.ljs.mag;
*ang2 = exp.classic.rjs.ang; // right cc joystick
*mag2 = exp.classic.rjs.mag;
}
else if (exp_type == WPAD_EXP_NUNCHUK)
{
*ang1 = exp.nunchuk.js.ang; // nunchuk joystick
*mag1 = exp.nunchuk.js.mag;
}
}
#endif
return exp_type; // return expansion type
}
/****************************************************************************
* Set the default mapping for NGC
****************************************************************************/
void
SetDefaultButtonMap ()
{
int maxcode = 0x10;
s9xcommand_t cmd;
/*** Joypad 1 ***/
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 A");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 B");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 X");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Y");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 L");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 R");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Select");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Start");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Up");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Down");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Left");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad1 Right");
maxcode = 0x20;
/*** Joypad 2 ***/
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 A");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 B");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 X");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Y");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 L");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 R");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Select");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Start");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Up");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Down");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Left");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad2 Right");
maxcode = 0x30;
/*** Joypad 3 ***/
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 A");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 B");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 X");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Y");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 L");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 R");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Select");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Start");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Up");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Down");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Left");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad3 Right");
maxcode = 0x40;
/*** Joypad 4 ***/
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 A");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 B");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 X");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Y");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 L");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 R");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Select");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Start");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Up");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Down");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Left");
ASSIGN_BUTTON_FALSE (maxcode++, "Joypad4 Right");
if (Settings.MultiPlayer5Master == false)
{
/*** Plugin 2 Joypads by default ***/
S9xSetController (0, CTL_JOYPAD, 0, 0, 0, 0);
S9xSetController (1, CTL_JOYPAD, 1, 0, 0, 0);
}
else
{
S9xSetController (0, CTL_JOYPAD, 0, 0, 0, 0);
S9xSetController (1, CTL_MP5, 1, 2, 3, -1);
}
}
/****************************************************************************
* Emulation loop
***************************************************************************/
*
* The 'clock' timer is long gone.
* System now only uses vbl as hardware clock, so force PAL50 if you need 50hz
****************************************************************************/
/* Eke-Eke: initialize frame Sync */
extern void S9xInitSync();
bool CheckVideo = 0; // for forcing video reset in video.cpp
extern uint32 prevRenderedFrameCount;
void
emulate ()
{
S9xSetSoundMute (TRUE);
AudioStart ();
S9xInitSync(); // Eke-Eke: initialize frame Sync
S9xInitSync();
setFrameTimerMethod(); // set frametimer method every time a ROM is loaded
setFrameTimerMethod(); // also called in NGCReportButtons()
while (1)
{
S9xMainLoop ();
NGCReportButtons ();
if (ConfigRequested)
{
// change to menu video mode
ResetVideo_Menu ();
if ( GCSettings.AutoSave == 1 )
{
SaveSRAM ( GCSettings.SaveMethod, SILENT );
}
else if ( GCSettings.AutoSave == 2 )
{
if ( WaitPromptChoice ((char*)"Save Freeze State?", (char*)"Don't Save", (char*)"Save") )
NGCFreezeGame ( GCSettings.SaveMethod, SILENT );
}
else if ( GCSettings.AutoSave == 3 )
{
if ( WaitPromptChoice ((char*)"Save SRAM and Freeze State?", (char*)"Don't Save", (char*)"Save") )
{
SaveSRAM(GCSettings.SaveMethod, SILENT );
NGCFreezeGame ( GCSettings.SaveMethod, SILENT );
}
}
// GUI Stuff
/*
gui_alloc();
gui_makebg ();
gui_clearscreen();
gui_draw ();
gui_showscreen ();
//gui_savescreen ();
*/
MainMenu (2); // go to game menu
FrameTimer = 0;
setFrameTimerMethod (); // set frametimer method every time a ROM is loaded
Settings.SuperScopeMaster = (GCSettings.Superscope > 0 ? true : false);
Settings.MouseMaster = (GCSettings.Mouse > 0 ? true : false);
Settings.JustifierMaster = (GCSettings.Justifier > 0 ? true : false);
SetControllers ();
//S9xReportControllers ();
ConfigRequested = 0;
#ifdef _DEBUG_VIDEO
// log stuff
fprintf(debughandle, "\n\nPlaying ROM: %s", Memory.ROMFilename);
fprintf(debughandle, "\nrender: %u", GCSettings.render);
#endif
CheckVideo = 1; // force video update
prevRenderedFrameCount = IPPU.RenderedFramesCount;
}//if ConfigRequested
}//while
S9xMainLoop ();
NGCReportButtons ();
}
}
/****************************************************************************
@ -196,138 +681,118 @@ emulate ()
* 7. Initialise Snes9x/GC Sound System
* 8. Initialise Snes9x Graphics subsystem
* 9. Let's Party!
***************************************************************************/
*
* NB: The SNES ROM is now delivered from ARAM. (AR_SNESROM)
* Any method of loading a ROM, RAM, DVD, SMB, SDCard,
* MUST place the unpacked ROM at this location.
* This provides a single consistent interface in memmap.cpp.
* Refer to that file if you need to change it.
****************************************************************************/
int
main ()
{
#ifdef WII_DVD
DI_Init(); // first
unsigned int save_flags;
/*** Initialise GC ***/
InitGCVideo (); /*** Get the ball rolling ***/
/*** Initialize libFAT and SD cards ***/
fatInitDefault();
//fatInit(8192, false);
//fat_enable_readahead_all();
/*** Initialize DVD subsystem ***/
DVD_Init ();
#ifdef FORCE_WII
isWii = TRUE;
#else
int drvid = dvd_driveid ();
if ( drvid == 4 || drvid == 6 || drvid == 8 )
isWii = FALSE;
else
isWii = TRUE;
#endif
int selectedMenu = -1;
// Initialise video
InitGCVideo ();
// Controllers
#ifdef HW_RVL
WPAD_Init();
// read wiimote accelerometer and IR data
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
WPAD_SetVRes(WPAD_CHAN_ALL,640,480);
#endif
PAD_Init ();
// Audio
AUDIO_Init (NULL);
// GC Audio RAM (for ROM and backdrop storage)
AR_Init (NULL, 0);
// GameCube only - Injected ROM
// Before going any further, let's copy any injected ROM image
// We'll put it in ARAM for safe storage
#ifdef HW_DOL
int *romptr = (int *) 0x81000000; // location of injected rom
if (memcmp ((char *) romptr, "SNESROM0", 8) == 0)
{
SNESROMSize = romptr[2];
if(SNESROMSize > (1024*128) && SNESROMSize < (1024*1024*8))
{
romptr = (int *) 0x81000020;
ARAMPut ((char *) romptr, (char *) AR_SNESROM, SNESROMSize);
}
else // not a valid ROM size
{
SNESROMSize = 0;
}
}
#endif
// Initialise freetype font system
/*** Initialise freetype ***/
if (FT_Init ())
{
printf ("Cannot initialise font subsystem!\n");
while (1);
}
unpackbackdrop ();
// Set defaults
setfontsize (16);/***sets the font size.***/
/*** Set defaults ***/
DefaultSettings ();
S9xUnmapAllControls ();
SetDefaultButtonMap ();
// Allocate SNES Memory
printf ("Initialise Memory\n");
/*** Allocate SNES Memory ***/
if (!Memory.Init ())
while (1);
// Allocate APU
printf ("Initialise APU\n");
/*** Allocate APU ***/
if (!S9xInitAPU ())
while (1);
// Set Pixel Renderer to match 565
/*** Set Pixel Renderer to match 565 ***/
S9xSetRenderPixelFormat (RGB565);
// Initialise Snes Sound System
/*** Initialise Snes Sound System ***/
S9xInitSound (5, TRUE, 1024);
// Initialise Graphics
printf ("Initialise GFX\n");
/*** Initialise Graphics ***/
setGFX ();
if (!S9xGraphicsInit ())
while (1);
// Initialize libFAT for SD and USB
fatInit (8, false);
#ifdef _DEBUG_VIDEO
// log stuff
debughandle = fopen ("log.txt", "wb");
#endif
// Initialize DVD subsystem (GameCube only)
#ifndef HW_RVL
DVD_Init ();
#endif
// Check if DVD drive belongs to a Wii
SetDVDDriveType();
legal ();
WaitButtonA ();
// Load preferences
if(!LoadPrefs())
quickLoadPrefs(SILENT);
// Correct any relevant saved settings that are invalid
Settings.FrameTimeNTSC = 16667;
Settings.FrameTimePAL = 20000;
if ( Settings.TurboSkipFrames <= Settings.SkipFrames )
Settings.TurboSkipFrames = 20;
/*** No appended ROM, so get the user to load one ***/
if (ARAM_ROMSIZE == 0)
{
WaitPrompt((char*) "Preferences reset - check settings!");
selectedMenu = 1; // change to preferences menu
while (ARAM_ROMSIZE == 0)
{
mainmenu ();
}
}
// GameCube only - Injected ROM
// Everything's been initialized, we can copy our ROM back
// from ARAM into main memory
#ifdef HW_DOL
if(SNESROMSize > 0)
else
{
ARAMFetchSlow( (char *)Memory.ROM, (char *)AR_SNESROM, SNESROMSize);
Memory.LoadROM ("BLANK.SMC");
Memory.LoadSRAM ("BLANK");
/*** Load ROM ***/
save_flags = CPU.Flags;
if (!Memory.LoadROM ("VIRTUAL.ROM"))
while (1);
CPU.Flags = save_flags;
/*** Load SRAM ***/
Memory.LoadSRAM ("DVD");
}
#endif
// Get the user to load a ROM
while (SNESROMSize <= 0)
{
MainMenu (selectedMenu);
}
// Emulate
/*** Emulate ***/
emulate ();
// NO! - We're never leaving here!
/*** NO! - We're never leaving here ! ***/
while (1);
return 0;
return 0;
}

View File

@ -1,15 +1,157 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Port
* softdev July 2006
* crunchy2 May 2007-July 2007
* Michniewski 2008
* Tantric September 2008
*
* snes9xGX.h
* snes9xGX.cpp
*
* This file controls overall program flow. Most things start and end here!
***************************************************************************/
****************************************************************************/
/****************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
C4 x86 assembler and some C emulation code
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
Nach,
zsKnight (zsknight@zsnes.com)
C4 C++ code
(c) Copyright 2003 - 2006 Brad Jorsch,
Nach
DSP-1 emulator code
(c) Copyright 1998 - 2006 _Demo_,
Andreas Naive (andreasnaive@gmail.com)
Gary Henderson,
Ivar (ivar@snes9x.com),
John Weidman,
Kris Bleakley,
Matthew Kendora,
Nach,
neviksti (neviksti@hotmail.com)
DSP-2 emulator code
(c) Copyright 2003 John Weidman,
Kris Bleakley,
Lord Nightmare (lord_nightmare@users.sourceforge.net),
Matthew Kendora,
neviksti
DSP-3 emulator code
(c) Copyright 2003 - 2006 John Weidman,
Kris Bleakley,
Lancer,
z80 gaiden
DSP-4 emulator code
(c) Copyright 2004 - 2006 Dreamer Nom,
John Weidman,
Kris Bleakley,
Nach,
z80 gaiden
OBC1 emulator code
(c) Copyright 2001 - 2004 zsKnight,
pagefault (pagefault@zsnes.com),
Kris Bleakley,
Ported from x86 assembler to C by sanmaiwashi
SPC7110 and RTC C++ emulator code
(c) Copyright 2002 Matthew Kendora with research by
zsKnight,
John Weidman,
Dark Force
S-DD1 C emulator code
(c) Copyright 2003 Brad Jorsch with research by
Andreas Naive,
John Weidman
S-RTC C emulator code
(c) Copyright 2001-2006 byuu,
John Weidman
ST010 C++ emulator code
(c) Copyright 2003 Feather,
John Weidman,
Kris Bleakley,
Matthew Kendora
Super FX x86 assembler emulator code
(c) Copyright 1998 - 2003 _Demo_,
pagefault,
zsKnight,
Super FX C emulator code
(c) Copyright 1997 - 1999 Ivar,
Gary Henderson,
John Weidman
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
(c) Copyright 1998 - 2003 Brad Martin
(c) Copyright 1998 - 2006 Charles Bilyue'
SH assembler code partly based on x86 assembler code
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
warranty. In no event shall the authors be held liable for any damages
arising from the use of this software or it's derivatives.
Snes9x is freeware for PERSONAL USE only. Commercial users should
seek permission of the copyright holders first. Commercial use includes,
but is not limited to, charging money for Snes9x or software derived from
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
using Snes9x as a promotion for your commercial product.
The copyright holders request that bug fixes and improvements to the code
should be forwarded to them so everyone can benefit from the modifications
in future versions.
Super NES and Super Nintendo Entertainment System are trademarks of
Nintendo Co., Limited and its subsidiary companies.
*****************************************************************************/
#ifndef _SNES9XGX_H_
#define _SNES9XGX_H_
@ -17,50 +159,81 @@
#include <gccore.h>
#include "snes9x.h"
#define VERSIONNUM "006"
#define VERSIONSTR "Snes9x GX 006"
// FIX: these are unused, but could be... must also change "freezecomment", PREFSVERSTRING, and "sramcomment"
//#define GCVERSION "002"
//#define GCVERSIONSTRING "Snes9x 1.5 v002"
#define NOTSILENT 0
#define SILENT 1
enum {
METHOD_AUTO,
METHOD_SD,
METHOD_USB,
METHOD_DVD,
METHOD_SMB,
METHOD_MC_SLOTA,
METHOD_MC_SLOTB
};
struct SGCSettings{
int AutoLoad;
int AutoSave;
int LoadMethod; // For ROMS: Auto, SD, DVD, USB, Network (SMB)
int SaveMethod; // For SRAM, Freeze, Prefs: Auto, SD, Memory Card Slot A, Memory Card Slot B, USB, SMB
char LoadFolder[200]; // Path to game files
char SaveFolder[200]; // Path to save files
char CheatFolder[200]; // Path to cheat files
char gcip[16];
char gwip[16];
char mask[16];
char smbip[16];
char smbuser[20];
char smbpwd[20];
char smbgcid[20];
char smbsvid[20];
char smbshare[20];
int NGCZoom; // 0 - off, 1 - on
int VerifySaves;
int render; // 0 - original, 1 - filtered, 2 - unfiltered
int Superscope;
int Mouse;
int Justifier;
int widescreen; // 0 - 4:3 aspect, 1 - 16:9 aspect
int xshift; // video output shift
int yshift;
uint8 AutoLoad;
uint8 AutoSave;
char gcip[16];
char gwip[16];
char mask[16];
char smbip[16];
char smbuser[20];
char smbpwd[20];
char smbgcid[20];
char smbsvid[20];
char smbshare[20];
bool8 NGCZoom;
uint8 VerifySaves;
u16 render; // 0 - original, 1 - no AA
u32 QuickSaveSlot; // -1 Disabled - no prefs are loaded, 0 Memory card in slot A, 1 Memory card in slot B, 2 SD card in slot A, 3 SD card in slot B, 4 SMB share, 5 USB
};
START_EXTERN_C
extern struct SGCSettings GCSettings;
extern unsigned short saveicon[1024];
extern bool8 isWii;
extern u32 wpad_get_analogues(int pad, float* mag1, u16* ang1, float* mag2, u16* ang2);
END_EXTERN_C
#define JOY_THRESHOLD 0.70 // for wii (expansion) analogues
#endif
/*** QUICK_SAVE_SLOT defines where preferences are loaded and saved, and also
where SRAM and Freezes are auto loaded or saved if enabled:
-1 Disabled - no prefs are loaded
0 Memory card in slot A
1 Memory card in slot B
2 SD card in slot A
3 SD card in slot B
4 SMB share ***/
#ifndef QUICK_SAVE_SLOT
#define QUICK_SAVE_SLOT 2 // save to SD
#endif
/*** default SMB settings ***/
#ifndef GC_IP
#define GC_IP "192.168.1.32" /*** IP to assign the GameCube ***/
#endif
#ifndef GW_IP
#define GW_IP "192.168.1.100" /*** Your gateway IP ***/
#endif
#ifndef MASK
#define MASK "255.255.255.0" /*** Your subnet mask ***/
#endif
#ifndef SMB_USER
#define SMB_USER "Guest" /*** Your share user ***/
#endif
#ifndef SMB_PWD
#define SMB_PWD "password" /*** Your share user password ***/
#endif
#ifndef SMB_GCID
#define SMB_GCID "gamecube" /*** Machine Name of GameCube ***/
#endif
#ifndef SMB_SVID
#define SMB_SVID "mypc" /*** Machine Name of Server(Share) ***/
#endif
#ifndef SMB_SHARE
#define SMB_SHARE "gcshare" /*** Share name on server ***/
#endif
#ifndef SMB_IP
#define SMB_IP "192.168.1.100" /*** IP Address of share server ***/
#endif

View File

@ -1,262 +1,271 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Port
* crunchy2 April 2007-July 2007
* Michniewski 2008
* Tantric September 2008
*
* sram.cpp
*
* SRAM save/load/import/export handling
***************************************************************************/
****************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <string.h>
#include <ogcsys.h>
#include "snes9x.h"
#include "snes9xGx.h"
#include "memmap.h"
#include "srtc.h"
#include "ftfont.h"
#include "mcsave.h"
#include "sdload.h"
#include "smbload.h"
#include "snes9xGX.h"
#include "images/saveicon.h"
#include "menudraw.h"
#include "memcardop.h"
#include "fileop.h"
#include "smbop.h"
#include "filesel.h"
extern unsigned char savebuffer[];
//extern int currconfig[4];
extern int padcal;
extern unsigned short gcpadmap[];
//extern unsigned short padmap[4];
char sramcomment[2][32];
char sramcomment[2][32] = { {"Snes9x GX 004 SRAM"}, {"Savegame"} };
/****************************************************************************
* Prepare SRAM Save Data
* Prepare Memory Card SRAM Save Data
*
* This sets up the savebuffer for saving in a format compatible with
* snes9x on other platforms.
***************************************************************************/
* This sets up the save buffer for saving to a memory card.
****************************************************************************/
int
preparesavedata (int method)
prepareMCsavedata ()
{
int offset = 0;
int size;
int offset = sizeof (saveicon);
int size;
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
// Copy in save icon
memcpy (savebuffer, saveicon, sizeof(saveicon));
offset += sizeof (saveicon);
}
ClearSaveBuffer ();
// Copy in the sramcomments
sprintf (sramcomment[0], "%s SRAM", VERSIONSTR);
sprintf (sramcomment[1], Memory.ROMName);
memcpy (savebuffer + offset, sramcomment, 64);
offset += 64;
/*** Copy in save icon ***/
memcpy (savebuffer, saveicon, offset);
if(method != METHOD_MC_SLOTA && method != METHOD_MC_SLOTB)
{
// make it a 512 byte header so it is compatible with other platforms
if (offset <= 512)
offset = 512;
// header was longer than 512 bytes - hopefully this never happens!
else
return 0;
}
/*** And the sramcomments ***/
sprintf (sramcomment[1], "%s", Memory.ROMName);
memcpy (savebuffer + offset, sramcomment, 64);
offset += 64;
// Copy in the SRAM
/*** Copy SRAM size ***/
size = Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0;
if (size > 0x20000)
size = 0x20000;
memcpy (savebuffer + offset, &size, 4);
offset += 4;
/*** Copy SRAM ***/
if (size != 0)
{
memcpy (savebuffer + offset, Memory.SRAM, size);
offset += size;
}
// /*** Save Joypad Configuration ***/
// memcpy (savebuffer + offset, &currconfig, 16);
offset += 16;
// memcpy (savebuffer + offset, &padcal, 4);
offset += 4;
return offset;
}
/****************************************************************************
* Prepare Exportable SRAM Save Data
*
* This sets up the save buffer for saving in a format compatible with
* snes9x on other platforms. This is used when saving to SD or SMB.
****************************************************************************/
int
prepareEXPORTsavedata ()
{
int offset = 0;
int size;
ClearSaveBuffer ();
/*** Copy in the sramcomments ***/
sprintf (sramcomment[1], "%s", Memory.ROMName);
memcpy (savebuffer + offset, sramcomment, 64);
offset += 64;
// /*** Save Joypad Configuration ***/
// memcpy (savebuffer + offset, &currconfig, 16);
offset += 16;
// memcpy (savebuffer + offset, &padcal, 4);
offset += 4;
if ( offset <= 512 )
{
// make it a 512 byte header so it is compatible with other platforms
offset = 512;
/*** Copy in the SRAM ***/
size = Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0;
if (size > 0x20000)
size = 0x20000;
size = 0x20000;
if (size != 0)
{
memcpy (savebuffer + offset, Memory.SRAM, size);
offset += size;
memcpy (savebuffer + offset, Memory.SRAM, size);
offset += size;
}
else
{
offset = 0;
}
return offset;
}
else
{
// header was longer than 512 bytes - hopefully this never happens!
return 0;
}
}
/****************************************************************************
* Decode Save Data
***************************************************************************/
****************************************************************************/
void
decodesavedata (int method, int readsize)
decodesavedata (int readsize)
{
int offset = 0;
char sramsavecomment[32];
int offset;
int size;
char sramcomment[32];
// Check for exportable format sram - it has the sram comment at the start
memcpy (sramcomment, savebuffer, 32);
int size = Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0;
if ( (strncmp (sramcomment, "Snes9x GX 2.0", 13) == 0) || (strncmp (sramcomment, "Snes9x GX 00", 12) == 0) ) // version 2.0.XX or 00x
{
offset = 64;
// Get the control pad configuration
// memcpy (&currconfig, savebuffer + offset, 16);
offset += 16;
// memcpy (&padcal, savebuffer + offset, 4);
offset += 4;
// for (size = 0; size < 4; size++)
// gcpadmap[size] = padmap[currconfig[size]];
// move to start of SRAM which is after the 512 byte header
offset = 512;
// import the SRAM
size = Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0;
if (size > 0x20000)
size = 0x20000;
// memory card save
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
offset = sizeof (saveicon); // skip save icon
// Check for sram comment
memcpy (sramsavecomment, savebuffer+offset, 32);
// version 0xx found!
if ( (strncmp (sramsavecomment, "Snes9x GX 0", 11) == 0) )
size = 0x20000;
memcpy (Memory.SRAM, savebuffer + offset, size);
offset += size;
}
else
{
// else, check for a v2.0 memory card format save
offset = sizeof (saveicon);
memcpy (sramcomment, savebuffer + offset, 32);
if ( strncmp (sramcomment, "Snes9x GX 2.0", 13) == 0 )
{
// adjust offset
if(method != METHOD_MC_SLOTA && method != METHOD_MC_SLOTB)
offset = 512; // skip entire 512 byte header
else
offset += 64; // skip savecomments
// import the SRAM
memcpy (Memory.SRAM, savebuffer + offset, size);
//WaitPrompt((char*) "Memory Card format save");
offset += 64;
memcpy (&size, savebuffer + offset, 4);
offset += 4;
memcpy (Memory.SRAM, savebuffer + offset, size);
offset += size;
// If it is an old 2.0 format save, skip over the Settings as we
// don't save them in SRAM now
if ( strcmp (sramcomment, "Snes9x GX 2.0") == 0 )
offset += sizeof (Settings);
// Get the control pad configuration
// memcpy (&currconfig, savebuffer + offset, 16);
offset += 16;
// memcpy (&padcal, savebuffer + offset, 4);
offset += 4;
// for (size = 0; size < 4; size++)
// gcpadmap[size] = padmap[currconfig[size]];
}
// check for SRAM from other version/platform of snes9x
else if ( readsize == size || readsize == size + SRTC_SRAM_PAD)
else if ( strncmp (sramcomment, "Snes9x 1.43 SRAM (GX", 20) == 0)
{
// it's an older SnesGx memory card format save
size = Memory.SRAMSize ? ( 1 << (Memory.SRAMSize + 3)) * 128 : 0;
// import the SRAM
if ( size )
memcpy(&Memory.SRAM[0], &savebuffer[sizeof(saveicon)+68], size);
// Ignore the settings saved in the file
// NOTE: need to add import of joypad config?? Nah.
}
else
{
// else, check for SRAM from other version/platform of snes9x
size = Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0;
if ( readsize == size || readsize == size + SRTC_SRAM_PAD)
{
//WaitPrompt("readsize=size or + SRTC_SRAM_PAD");
// SRAM data should be at the start of the file, just import it and
// ignore anything after the SRAM
memcpy (Memory.SRAM, savebuffer, size);
}
else if ( readsize == size + 512 )
{
}
else if ( readsize == size + 512 )
{
//WaitPrompt("readsize=size+512");
// SRAM has a 512 byte header - remove it, then import the SRAM,
// ignoring anything after the SRAM
memcpy(Memory.SRAM, savebuffer+512, size);
}
else
{
WaitPrompt((char*)"Incompatible SRAM save!");
memmove (savebuffer, savebuffer + 512, size);
memcpy (Memory.SRAM, savebuffer, size);
}
else
WaitPrompt((char*)"Incompatible SRAM save!");
}
}
}
/****************************************************************************
* Load SRAM
***************************************************************************/
int
LoadSRAM (int method, bool silent)
void quickLoadSRAM (bool8 silent)
{
ShowAction ((char*) "Loading...");
if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because SRAM needs R/W
char filepath[1024];
int offset = 0;
AllocSaveBuffer();
if(method == METHOD_SD || method == METHOD_USB)
{
if(ChangeFATInterface(method, NOTSILENT))
{
sprintf (filepath, "%s/%s/%s.srm", ROOTFATDIR, GCSettings.SaveFolder, Memory.ROMFilename);
offset = LoadBufferFromFAT (filepath, silent);
}
}
else if(method == METHOD_SMB)
{
sprintf (filepath, "%s/%s.srm", GCSettings.SaveFolder, Memory.ROMFilename);
offset = LoadBufferFromSMB (filepath, silent);
}
else if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
sprintf (filepath, "%s.srm", Memory.ROMName);
if(method == METHOD_MC_SLOTA)
offset = LoadBufferFromMC (savebuffer, CARD_SLOTA, filepath, silent);
else
offset = LoadBufferFromMC (savebuffer, CARD_SLOTB, filepath, silent);
}
if (offset > 0)
{
decodesavedata (method, offset);
S9xSoftReset();
}
FreeSaveBuffer ();
if(offset > 0)
{
return 1;
}
else
{
// if we reached here, nothing was done!
if(!silent)
WaitPrompt ((char*) "SRAM file not found");
return 0;
}
switch ( QUICK_SAVE_SLOT )
{
case CARD_SLOTA:
case CARD_SLOTB:
LoadSRAMFromMC(QUICK_SAVE_SLOT, silent);
break;
case CARD_SLOTA+2:
case CARD_SLOTB+2:
LoadSRAMFromSD(silent);
break;
case CARD_SLOTA+4:
LoadSRAMFromSMB(SILENT);
break;
}
}
/****************************************************************************
* Save SRAM
***************************************************************************/
bool
SaveSRAM (int method, bool silent)
void quickSaveSRAM (bool8 silent)
{
ShowAction ((char*) "Saving...");
if(method == METHOD_AUTO)
method = autoSaveMethod();
bool retval = false;
char filepath[1024];
int datasize;
int offset = 0;
AllocSaveBuffer ();
datasize = preparesavedata (method);
if ( datasize )
{
if(method == METHOD_SD || method == METHOD_USB)
{
if(ChangeFATInterface(method, NOTSILENT))
{
sprintf (filepath, "%s/%s/%s.srm", ROOTFATDIR, GCSettings.SaveFolder, Memory.ROMFilename);
offset = SaveBufferToFAT (filepath, datasize, silent);
}
}
else if(method == METHOD_SMB)
{
sprintf (filepath, "%s/%s.srm", GCSettings.SaveFolder, Memory.ROMFilename);
offset = SaveBufferToSMB (filepath, datasize, silent);
}
else if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
sprintf (filepath, "%s.srm", Memory.ROMName);
if(method == METHOD_MC_SLOTA)
offset = SaveBufferToMC (savebuffer, CARD_SLOTA, filepath, datasize, silent);
else
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, filepath, datasize, silent);
}
if (offset > 0)
{
if ( !silent )
WaitPrompt((char *)"Save successful");
retval = true;
}
}
else
{
if(!silent)
WaitPrompt((char *)"No SRAM data to save!");
}
FreeSaveBuffer ();
return retval;
switch ( QUICK_SAVE_SLOT )
{
case CARD_SLOTA:
case CARD_SLOTB:
SaveSRAMToMC(QUICK_SAVE_SLOT, silent);
break;
case CARD_SLOTA+2:
case CARD_SLOTB+2:
SaveSRAMToSD(silent);
break;
case CARD_SLOTA+4:
SaveSRAMToSMB(SILENT);
break;
}
}

View File

@ -1,14 +1,17 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* crunchy2 April 2007-July 2007
* Michniewski 2008
* Tantric September 2008
* Nintendo Gamecube Port
* crunchy2 April 2007
*
* sram.cpp
*
* SRAM save/load/import/export handling
***************************************************************************/
****************************************************************************/
bool SaveSRAM (int method, bool silent);
int LoadSRAM (int method, bool silent);
int prepareMCsavedata ();
int prepareEXPORTsavedata ();
void decodesavedata (int readsize);
void quickLoadSRAM (bool8 silent);
void quickSaveSRAM (bool8 silent);

556
source/ngc/tempgfx.h Normal file
View File

@ -0,0 +1,556 @@
/*******************************************************************
* Image File : ..\snesGX2.bmp
* Width : 640
* Height : 480
*
* This header contains a compressed Zip image.
* Use zlib1.2.3 uncompress function to restore.
*******************************************************************/
#define tempgfx_RAW 614400
#define tempgfx_COMPRESSED 8647
#define tempgfx_WIDTH 640
#define tempgfx_HEIGHT 480
unsigned char tempgfx[8647] = {
0x78,0xda,0xed,0x9d,0xd9,0x77,0x14,0x47,0x9e,0xef,0xf9,0xdb,0xee,0xcb,0x9d,0x99,
0x3b,0x67,0x66,0x7a,0xe6,0x9c,0xdb,0xe3,0xf6,0x9d,0xde,0x6c,0xb7,0xdb,0xdd,0xee,
0xf6,0xc2,0x8e,0xa9,0x88,0x5f,0xa6,0x58,0x8d,0x31,0x60,0xcc,0x2a,0x30,0x8b,0x58,
0x2c,0x10,0x48,0x2c,0x02,0x81,0x16,0xb4,0x21,0xb4,0x21,0xc4,0x22,0x21,0xc0,0x02,
0x03,0x9e,0x87,0xee,0x73,0x6e,0x9f,0xe3,0x7e,0xe8,0x97,0x7e,0xb8,0xf7,0x17,0x51,
0x59,0xa5,0xcc,0x92,0x4a,0xca,0x12,0x2a,0x55,0x09,0x3e,0xfd,0x3d,0x9f,0x36,0x52,
0xe5,0x12,0x99,0x59,0xf9,0x51,0x44,0x46,0x64,0xe6,0x32,0x59,0x46,0x08,0x21,0x84,
0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,
0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0xbc,0xa6,
0xe9,0x91,0x2b,0x72,0x46,0x8e,0xcb,0x7e,0xd9,0x47,0x08,0x21,0x65,0xc9,0x7e,0x75,
0xcc,0x19,0x75,0x4d,0x4f,0xd5,0x98,0xaf,0x5d,0xce,0xcb,0x37,0x52,0x4b,0x08,0x21,
0x8b,0x96,0x6f,0xd4,0x3b,0xed,0x15,0xb7,0x5f,0xb3,0xfa,0x98,0x10,0x42,0x2a,0x91,
0xe6,0x0a,0xba,0xef,0x96,0x5c,0x94,0x7a,0x42,0x08,0xa9,0x58,0x2e,0xaa,0x87,0x2a,
0x61,0xbf,0x6e,0xb9,0xa4,0xeb,0x26,0x84,0x90,0x4a,0xe6,0x92,0xba,0x68,0xf1,0xfb,
0x3b,0xae,0x11,0x42,0x48,0x55,0xa4,0x67,0x91,0x5b,0xbe,0xad,0x84,0x10,0x52,0x35,
0x59,0xbc,0x56,0xf0,0x90,0x74,0x48,0xdb,0xb4,0x74,0x49,0xbf,0x19,0x92,0x3b,0xe6,
0x4e,0x00,0x00,0x50,0x1e,0x86,0xd4,0x33,0x5d,0xd2,0x66,0x0b,0xfd,0xd3,0xa1,0x5e,
0x5a,0xac,0xb6,0x6f,0x47,0x41,0x3a,0x65,0x88,0x63,0x03,0x00,0x8b,0x83,0xfa,0xa6,
0x53,0x3a,0x6c,0xd2,0x42,0x8b,0xd3,0x06,0xee,0x97,0x1b,0x05,0xe9,0xb3,0x23,0xd4,
0xfb,0x00,0x60,0x11,0x19,0x91,0x3e,0x53,0x68,0xa2,0xfe,0x45,0xf0,0x5f,0xaf,0xd6,
0xf6,0xe2,0xe9,0xc7,0x7d,0x00,0x50,0x01,0xfa,0xa5,0xd3,0xc6,0x5d,0xd4,0xbb,0x28,
0xad,0xdf,0xee,0x58,0xfa,0x2c,0xc7,0x01,0x00,0x2a,0xd3,0x0e,0xee,0x33,0x71,0x1b,
0x95,0xbf,0x05,0x3c,0xa8,0xeb,0x88,0x67,0x04,0xff,0x01,0x40,0x85,0xfc,0x77,0xdb,
0x24,0x7d,0x34,0x58,0x66,0xff,0x0d,0xc8,0xcd,0x58,0x68,0xfb,0x02,0x40,0x65,0xdb,
0xc0,0x37,0x6d,0xdc,0x48,0xe5,0xee,0xfd,0xe8,0x8b,0x85,0xf1,0x2e,0x00,0x50,0xd9,
0xf1,0x30,0x7d,0x76,0xca,0x48,0xb7,0xca,0x5e,0xff,0xeb,0x8f,0x65,0x84,0xfd,0x0f,
0x00,0x15,0xed,0x07,0xee,0xb7,0x71,0x27,0x95,0xdb,0x7f,0xf1,0xb0,0xff,0x01,0xa0,
0xb2,0xd7,0x00,0x07,0x6c,0xdc,0x49,0xe5,0xee,0xff,0x88,0x87,0xfd,0x0f,0x00,0x95,
0xf5,0xdf,0xa0,0x8d,0x3b,0xa9,0xbc,0xfe,0x1b,0x49,0x84,0xfd,0x0f,0x00,0x95,0xf5,
0xdf,0xb0,0x1d,0x96,0xa9,0x94,0xd7,0x7f,0xb7,0x13,0x61,0xff,0x03,0x40,0x85,0xc7,
0xc0,0xd8,0xb8,0x93,0xa8,0xff,0x01,0xc0,0x9b,0xe3,0xbf,0x11,0x1b,0x77,0x52,0x79,
0xfd,0x77,0x27,0x19,0xf6,0x3f,0x00,0x54,0xd4,0x7f,0x77,0x6c,0xdc,0x49,0xe5,0xf5,
0xdf,0xdd,0x44,0xd8,0xff,0x73,0x1d,0x9b,0xcb,0x66,0x9b,0xac,0xb6,0xab,0x65,0xee,
0x6c,0x93,0xba,0x45,0xbb,0x97,0xe6,0xb2,0x6c,0x33,0x69,0xca,0xa4,0xa5,0xb2,0x75,
0x6e,0x8c,0xa7,0x34,0xa6,0xda,0x8e,0x6d,0xd2,0xc8,0xfd,0x40,0xb0,0xc8,0xe7,0xd8,
0x5d,0x1b,0x77,0x52,0x79,0xfd,0x77,0x2f,0x11,0xf6,0xff,0xac,0xd7,0x65,0xcd,0x9e,
0x94,0xee,0xcb,0xe5,0xa8,0x7c,0x6e,0xd3,0x7a,0xa9,0x31,0x37,0xf6,0x3c,0xa5,0x9b,
0x72,0x8e,0x1d,0x96,0x3d,0xa6,0x94,0x32,0x69,0xa9,0xec,0xee,0x12,0xb6,0xe3,0xac,
0x0c,0x99,0x63,0x5a,0xbe,0xe4,0x7a,0xaf,0xc7,0xf6,0xcb,0xf5,0x82,0xf2,0x46,0x8e,
0x9d,0x63,0x7f,0xf6,0xc9,0x61,0xb3,0x25,0xf5,0x76,0x76,0x9a,0xba,0x05,0x2a,0xc3,
0xb0,0xec,0x33,0x61,0xaa,0xf5,0xae,0xb7,0xbb,0xe2,0xeb,0x28,0xa0,0xb1,0xa0,0x3c,
0x73,0x1e,0x57,0x48,0x79,0x9e,0xdd,0xb3,0x71,0x27,0x95,0xd7,0x7f,0xf7,0x13,0x61,
0xff,0xcf,0x76,0x5c,0x9c,0x67,0x32,0xf6,0xe4,0x86,0x3b,0x99,0x3b,0x9b,0xee,0xac,
0x9f,0x8b,0xab,0xe1,0xea,0x12,0xbd,0xb4,0xdb,0xf6,0x07,0x03,0xe6,0xeb,0x12,0x1d,
0xeb,0x5c,0x96,0x09,0x4e,0x9a,0x34,0x65,0xba,0xb3,0xf1,0xea,0xfa,0xd5,0xf2,0xb9,
0xb8,0xed,0x38,0x9b,0x62,0x3b,0xce,0x06,0xae,0x2c,0x33,0x9f,0xe7,0x57,0xd5,0x8b,
0xc3,0xc1,0x6d,0x73,0x7d,0xc6,0xf2,0x6e,0xb7,0x43,0xc1,0xb0,0xb9,0x1d,0x8c,0x98,
0x19,0xc7,0xd4,0xab,0xcf,0x4c,0x49,0xfb,0xa6,0x46,0x16,0xaa,0x0c,0xfb,0x4a,0xdc,
0xbf,0x67,0xa3,0x75,0x8c,0xe8,0x72,0xa6,0x1c,0x5a,0xca,0xdf,0x1c,0x77,0x5c,0x67,
0xd9,0x17,0x15,0x19,0x63,0x7c,0xd3,0xdc,0xf4,0x74,0xeb,0xbe,0xbb,0xee,0xb9,0x22,
0x4d,0xb6,0xc9,0x73,0xce,0x9e,0x92,0x53,0x33,0x72,0x42,0x0e,0xd9,0x43,0x52,0x98,
0x13,0x05,0xd3,0x9d,0xf5,0xcb,0xb9,0xe2,0x97,0xdb,0xed,0xd7,0x73,0xbb,0xa4,0xf3,
0xec,0xbe,0x8d,0x3b,0xa9,0xbc,0xfe,0x7b,0x90,0x08,0x9e,0xbb,0x33,0xcb,0xdf,0x7b,
0xf5,0x4c,0x38,0x90,0x19,0xdf,0x38,0xbe,0x3e,0x0d,0x6d,0x81,0xfa,0x2f,0x68,0x33,
0xa9,0xa6,0xaf,0x69,0x5a,0x9f,0xd1,0xe5,0xef,0x94,0x5d,0xd6,0xb9,0xa9,0xa9,0xa6,
0x84,0x75,0xe8,0xf4,0x03,0x1b,0xd2,0x4d,0x3f,0xbe,0xa1,0x6d,0xbd,0x3b,0x23,0x53,
0x6f,0x87,0x96,0xcb,0xdb,0xa7,0x60,0x3b,0xea,0xbc,0x17,0x9b,0x6c,0xaf,0x34,0x7b,
0x0f,0xd4,0xd5,0x8c,0x67,0xe2,0xeb,0x50,0x5b,0xd9,0x16,0xe9,0x33,0x03,0xd1,0x79,
0x5f,0xb8,0x2f,0x3b,0x65,0x8d,0xce,0xbf,0xd7,0xf6,0xa4,0x2c,0xf7,0x4e,0x5d,0xde,
0x42,0x95,0xc1,0xd5,0xfd,0x52,0xed,0xaf,0x0d,0xa3,0xd1,0x3a,0x4e,0xe9,0x3a,0xfa,
0xcd,0x90,0x77,0x60,0x76,0x19,0x7b,0xfc,0xdf,0x9c,0x26,0x93,0xfe,0xb8,0xf6,0x9a,
0x5b,0xc1,0xe0,0x8c,0xfb,0xa2,0x0c,0xf7,0xcf,0xaa,0x73,0xba,0x22,0xaf,0x65,0x9d,
0xf6,0x6d,0xe4,0xa6,0xc3,0x72,0xa8,0x82,0x39,0xa5,0xe5,0x68,0xb2,0x97,0xb4,0x5c,
0x9d,0xb3,0x39,0x51,0x1e,0xd8,0xb8,0x93,0xca,0xeb,0xbf,0xb1,0x44,0xf0,0x5c,0x71,
0x76,0xe9,0xf7,0xf8,0x72,0x38,0x99,0x99,0xac,0x49,0x47,0xb7,0xf7,0x5f,0xb7,0x49,
0x3b,0xfd,0x9d,0xc0,0xf8,0xf3,0xd8,0xe8,0xba,0x4a,0x5b,0xc7,0x65,0x9b,0x76,0xfa,
0xc9,0xb0,0x3b,0xe3,0xd6,0x51,0xca,0x76,0xe4,0xda,0x95,0x89,0x79,0xc2,0x53,0x7e,
0x39,0xf5,0x92,0xf5,0x43,0x7c,0xfa,0xcb,0xde,0x19,0x9b,0xed,0x35,0xad,0xe3,0xf5,
0xca,0xc0,0x8c,0xe7,0xbc,0xdb,0x97,0x47,0x4a,0x28,0xc3,0xae,0x05,0x2c,0x83,0xf3,
0xdf,0x9d,0xd4,0xfb,0xeb,0xb2,0xae,0x43,0xe4,0x4a,0x70,0x63,0x6a,0x39,0x7a,0xfe,
0xea,0x51,0x92,0x3b,0x25,0x1d,0xd7,0x6f,0x6d,0x7b,0xd0,0xab,0x6e,0x1a,0x7e,0xf5,
0x3a,0xa0,0x3a,0xfd,0xa6,0xf4,0x78,0xbf,0x35,0x27,0xea,0x6b,0x87,0xed,0x21,0x59,
0x5a,0x39,0xa5,0xfb,0xa5,0x49,0xae,0xa9,0x0f,0x6f,0xc5,0xb6,0x6f,0xcc,0xc6,0x9d,
0x54,0x5e,0xff,0x8d,0x27,0x82,0xe7,0x8a,0xb3,0x5e,0xcf,0x9b,0xc9,0xf0,0x87,0xcc,
0x0f,0x35,0xe9,0xb8,0xe5,0xce,0xc1,0xe0,0x96,0x4d,0x3b,0xfd,0x0f,0x61,0x7d,0xf6,
0x7c,0x2e,0x79,0x1d,0x93,0x26,0xfd,0x3a,0x6e,0xf9,0x75,0x94,0xb2,0x1d,0x17,0x74,
0xbb,0xb3,0xd7,0xcb,0x2e,0x24,0xb6,0xa5,0x3e,0x72,0x52,0xa2,0xbc,0x61,0x8b,0x5f,
0xfe,0xe7,0x72,0xd2,0x9c,0x97,0x16,0xff,0xbd,0x1e,0x9e,0xe6,0xbf,0x01,0xe7,0x8f,
0x92,0xf6,0xa5,0x6b,0xe3,0x7f,0xbe,0x40,0x65,0x70,0xdb,0x32,0x56,0x53,0xda,0xba,
0xf7,0xcb,0x05,0xd3,0xaa,0x75,0xb8,0x41,0xad,0x03,0xde,0x91,0x3a,0x2d,0x7f,0x7d,
0x89,0xc7,0xf5,0x4b,0x7b,0x5e,0xcf,0xf3,0xee,0x60,0x20,0x75,0x1d,0xd0,0xb5,0x1b,
0x3b,0x7d,0x1d,0xee,0xa2,0x69,0x92,0x46,0xef,0xb8,0x63,0x33,0xb6,0x3f,0x5f,0x97,
0x9c,0xb4,0x0d,0x72,0xc9,0xb6,0xca,0xb8,0x8d,0x3b,0xa9,0xbc,0xfe,0x7b,0x98,0x08,
0x9e,0x2b,0x8e,0x3b,0xa7,0xfe,0x1c,0xfe,0xd9,0xe4,0x48,0xd7,0x17,0x32,0x64,0xe3,
0xf3,0xcc,0x4a,0x30,0xe4,0xd7,0x31,0x14,0xa4,0x9c,0x5e,0x19,0x72,0x65,0x08,0xfe,
0x3c,0xb5,0x8e,0x20,0xdd,0x75,0xa9,0xb9,0xb6,0xa3,0x2d,0x56,0x86,0x36,0xfd,0x7c,
0x8d,0x6c,0xf0,0xd3,0x34,0xc4,0xcb,0x16,0x34,0xe8,0xba,0x1a,0x12,0xdb,0xd7,0xe0,
0x97,0x65,0xec,0x16,0xf9,0xda,0x1c,0x57,0x67,0xb4,0x07,0x37,0xb5,0xdd,0x58,0x70,
0xbe,0xcb,0x55,0x9d,0x6f,0x4f,0xfa,0xfd,0x12,0x95,0x71,0x63,0xd4,0x97,0xf4,0xaa,
0x65,0x70,0xfe,0x7b,0x52,0xc2,0xba,0x2f,0xbb,0xb6,0xb7,0x1c,0x35,0x8d,0xd2,0x6e,
0xfa,0xb4,0x2d,0x3d,0x22,0x5f,0x9a,0xd2,0x8f,0x6b,0x46,0xcf,0xef,0x06,0x75,0x59,
0xef,0xb4,0xfd,0x71,0x4b,0x3d,0x77,0x43,0x3d,0x77,0x55,0xeb,0x72,0x8d,0xbe,0x1e,
0x77,0xe4,0x35,0x76,0x5c,0x9a,0x24,0x9d,0x54,0x5e,0xff,0x4d,0x24,0x82,0xe7,0x66,
0xf7,0xdf,0x8f,0xc1,0x8f,0x26,0xc7,0x5c,0xd7,0xd1,0x57,0xc8,0x4a,0xfd,0x7c,0xd4,
0xe6,0xe7,0x29,0x32,0xfd,0xd4,0xe7,0xcf,0xfd,0x3a,0x46,0x63,0xeb,0x48,0x77,0x7d,
0xfd,0xc7,0xd8,0x3a,0xf6,0xcd,0x31,0xcf,0x0a,0x9b,0x66,0x3b,0x3a,0x65,0xea,0xf3,
0x4e,0xfd,0xfc,0x13,0x59,0x1f,0xd5,0xbf,0x1a,0x6d,0x7c,0xde,0x78,0x59,0x7f,0x94,
0x46,0xbf,0xee,0x4f,0x64,0xb9,0x35,0xb2,0xc3,0x6c,0x8b,0x9c,0x39,0x53,0x9f,0xe8,
0x6a,0xd9,0x17,0x2b,0x73,0x67,0xaa,0xed,0x14,0xad,0x43,0x7d,0x55,0x62,0x19,0x8e,
0x4a,0x93,0xfa,0xaf,0x2f,0x51,0xff,0x4b,0xd3,0xff,0x11,0x5f,0x66,0xa7,0xf7,0xff,
0x97,0xf6,0xb8,0x5c,0x36,0x5d,0x5a,0x7f,0xcb,0xfa,0x6f,0xa6,0xe3,0xfa,0x3c,0x71,
0x1c,0xa6,0xca,0x38,0xea,0xcb,0xb4,0x55,0xf6,0x9a,0xd3,0x5a,0xbe,0xcb,0xd2,0xac,
0xf5,0xb9,0xf3,0x55,0x70,0x3d,0xae,0x5a,0x93,0x74,0x12,0xfe,0xab,0x9e,0xf6,0xef,
0x5f,0x82,0xbf,0xd9,0xbf,0x45,0x1c,0x98,0xe3,0x3c,0x5a,0xe5,0x3f,0x7f,0x90,0x9f,
0xfe,0x6f,0x45,0xa6,0xcf,0x7f,0x1e,0xfc,0xb7,0xff,0xfc,0x81,0x4c,0xad,0x63,0x6e,
0x2b,0xe8,0x5a,0xe4,0x2f,0xb1,0x75,0x1c,0xb0,0x73,0x4f,0xaf,0x73,0xc4,0xb6,0x63,
0x2e,0x7a,0xb4,0xdc,0x1f,0xca,0xc7,0xbe,0x3e,0xe5,0xe6,0x3d,0x23,0x33,0x4f,0x77,
0xc6,0x6f,0xdf,0x6f,0xec,0xbb,0xf2,0x91,0xb5,0xb2,0x61,0x0e,0xa7,0x1d,0x88,0x95,
0xb9,0x67,0xce,0xed,0x5c,0xa9,0x7f,0x4b,0xc4,0xfb,0xec,0x68,0x09,0x65,0xd8,0x65,
0x4e,0xc8,0x25,0xf5,0x57,0x7f,0xa2,0xcd,0x39,0xac,0xcb,0x59,0x2d,0x5b,0xa4,0x47,
0xd2,0x6d,0x7f,0xab,0xf7,0x7f,0xc6,0xee,0xd5,0xfa,0x5b,0x9b,0x5b,0x96,0xf7,0xdf,
0xf4,0xe3,0x7a,0x51,0x92,0xfb,0x6c,0xea,0xf3,0x07,0xfa,0xf9,0x87,0xf2,0xb6,0xfc,
0x41,0x8c,0x6c,0x93,0x3d,0x72,0x10,0xc7,0x55,0x8d,0xff,0x1e,0x25,0x82,0xe7,0x66,
0xef,0xff,0x68,0x96,0xbf,0xdb,0xbf,0xcf,0xc9,0x73,0x9d,0xce,0x9d,0x11,0x9f,0xe9,
0xf7,0x7e,0x22,0xf6,0x7b,0x77,0x9e,0xfc,0x93,0xfd,0x77,0xf9,0xb9,0xfd,0x40,0x7d,
0xb2,0xd2,0xf7,0x81,0xae,0x96,0xa9,0xcf,0xff,0xe4,0x7f,0x9e,0x48,0xb5,0x0e,0x47,
0x9f,0xcd,0xd6,0xe7,0x9a,0x25,0xcd,0xf4,0xcf,0x25,0x5b,0x2a,0xf5,0xb8,0xf4,0xa5,
0x5e,0xc7,0xdf,0x6d,0x9f,0x96,0xfb,0x03,0x79,0xdf,0x86,0x52,0x6b,0x0e,0xfb,0x32,
0x1f,0x9c,0x61,0x7d,0x07,0x7d,0xd9,0x7f,0x25,0x6f,0xdb,0xf7,0xb4,0x4c,0x9b,0x45,
0x4c,0x72,0xdb,0xe3,0x34,0x17,0x2c,0xa3,0xcf,0x3b,0xeb,0x5f,0xe4,0x3f,0xed,0x3b,
0xf2,0xa1,0xfd,0x54,0x56,0x39,0xc7,0x15,0x3a,0x51,0xdb,0xbf,0xbb,0x6d,0x9d,0xd6,
0xe7,0x4e,0xa7,0x2e,0x43,0xad,0x69,0x08,0x5a,0x4d,0xaf,0x24,0xfb,0x5d,0xeb,0x74,
0x59,0x5b,0xe5,0xaf,0xa9,0xb7,0xff,0xa0,0x2e,0xf3,0x5d,0xad,0x4f,0x7e,0x29,0xa7,
0xcc,0x35,0xad,0x4b,0x66,0xfd,0x57,0x78,0x5c,0xb7,0xc6,0xca,0xf3,0x57,0x75,0x75,
0xfc,0xb8,0x4e,0xe8,0xe7,0x1f,0xc8,0xbf,0xcb,0x7b,0xb2,0x56,0xbd,0xbb,0xbb,0x6a,
0xfc,0x77,0x58,0x72,0x63,0x56,0xea,0xf3,0x63,0x5f,0x2e,0xdb,0xdc,0x78,0x98,0xf6,
0xfc,0x18,0x99,0x42,0xfa,0x8a,0x5e,0xaf,0x8c,0xd3,0x96,0xed,0x7f,0xce,0xd7,0x75,
0x8f,0xa7,0xbe,0x76,0x99,0x74,0x52,0x79,0xfd,0xf7,0x38,0x11,0x3c,0x57,0x9c,0xec,
0x18,0xb3,0x27,0xf2,0xff,0x52,0xe5,0xff,0x8a,0xf8,0xf3,0x36,0x3e,0xbd,0xfb,0xf9,
0x7f,0xd9,0xb7,0xe4,0xf7,0x76,0x9d,0x6c,0x32,0xdb,0xb5,0x7e,0xe2,0x7e,0x13,0x9f,
0xa7,0x70,0x8e,0xd9,0x33,0xe0,0xea,0x73,0xb6,0x94,0x79,0x72,0xa5,0x12,0xfd,0x57,
0x29,0x6b,0xf9,0xad,0xbc,0xa7,0xe7,0xf4,0x41,0x73,0x4a,0x44,0xd7,0x57,0x3b,0xc3,
0x54,0xb5,0x3a,0xd5,0xa7,0x5a,0xc7,0xf9,0xb9,0xd6,0x15,0xc5,0xee,0x91,0x1a,0x53,
0xbc,0x54,0x57,0x24,0xb9,0x0c,0xb7,0x86,0xf7,0xec,0x4f,0xe4,0x97,0x5a,0xcf,0xb2,
0x66,0xab,0xd6,0xcf,0x02,0x37,0x46,0xa5,0x60,0xe9,0x5b,0xd4,0x67,0xf5,0x72,0xc5,
0x34,0x4b,0x90,0xb2,0x0c,0xa7,0xcd,0x55,0xe9,0x9a,0xd6,0xe7,0xea,0xfa,0xb3,0x4b,
0xdb,0xc7,0x1f,0xcb,0x7f,0x6a,0x7d,0x72,0x93,0x1c,0xd6,0xf5,0x5f,0x30,0x97,0x64,
0x93,0x9d,0x7e,0x5c,0xe3,0x3f,0x9f,0x93,0xe4,0x71,0x7d,0xe2,0xf7,0xe0,0x3f,0xcb,
0x2f,0xb5,0x1e,0xbb,0x49,0xbe,0x5a,0x14,0xff,0xd5,0x79,0xe7,0x9c,0xf1,0x4e,0xbb,
0x10,0x39,0xad,0x27,0x72,0x53,0x25,0xcf,0xa3,0x01,0x5d,0x7f,0x9b,0x1f,0x97,0xd3,
0xa0,0xe5,0x3b,0x3a,0x63,0xd9,0x93,0x4e,0x2a,0xaf,0xff,0x9e,0x24,0x82,0xe7,0x66,
0x1b,0x77,0x50,0xe7,0x7d,0xd5,0x20,0xcf,0x53,0xd5,0xb7,0xda,0xbd,0x2f,0x0b,0xeb,
0x09,0x3f,0xd1,0x3a,0xce,0x3a,0x75,0xdf,0x21,0x73,0x52,0xea,0xcd,0xab,0xd7,0xff,
0xd6,0x6a,0x3b,0xcf,0x2d,0xd7,0x97,0x2a,0xc5,0x3c,0xed,0x3a,0xad,0xf3,0x87,0xa4,
0xae,0x03,0xba,0xfa,0xdf,0xfb,0xf2,0x8e,0x35,0xd1,0x7d,0x13,0x07,0x67,0xa9,0x27,
0x7d,0xaa,0xf5,0xc4,0xb5,0xea,0xaf,0x93,0xb2,0xb9,0xe4,0xfa,0xdf,0x4f,0xb5,0xee,
0x17,0xca,0x6e,0x6d,0xe3,0x9e,0x36,0xee,0x5a,0x63,0x5f,0xc1,0xb2,0xbf,0x90,0x23,
0xe6,0x5c,0x70,0xd1,0x6c,0x4a,0x5d,0x86,0x2b,0xa6,0xbb,0xa0,0xed,0x9b,0xbb,0x8e,
0x9b,0x6e,0xff,0xfe,0x35,0xaa,0xc7,0xff,0x87,0xfc,0x83,0xfc,0x54,0x7e,0x2f,0x19,
0xdf,0x7a,0xad,0x95,0x40,0x0a,0x8f,0x6b,0x43,0x6c,0xbe,0x89,0xa8,0xee,0x9a,0xac,
0xff,0xfd,0x56,0xfe,0x51,0xfe,0x4b,0x96,0xcb,0x46,0xd9,0x25,0x07,0x16,0x68,0xec,
0x48,0xae,0xde,0x76,0xd5,0xfb,0xad,0x23,0xaa,0x77,0x2d,0xb5,0xf3,0xaa,0x4f,0x7a,
0x7d,0x1f,0xf7,0x19,0x75,0x76,0x76,0xcb,0x92,0x4e,0xc2,0x7f,0xd5,0x41,0x67,0x8a,
0x7b,0x6c,0xe3,0xd7,0x94,0x1e,0xcc,0x78,0xfd,0xef,0x7f,0xdb,0xdf,0x69,0xfd,0xc1,
0xf5,0x05,0x5e,0xd5,0xbf,0x83,0xaf,0x7e,0xfd,0xef,0x33,0xfb,0xd9,0x9c,0xd7,0xf3,
0x7b,0x0a,0xae,0x45,0x7d,0x66,0x4b,0xd9,0x8e,0x9e,0xc8,0x7f,0x19,0x71,0xe3,0xd8,
0x76,0xda,0xa2,0xd7,0x0e,0xfd,0xb5,0xc7,0x15,0x6a,0x87,0x03,0xe6,0xbc,0xd6,0x15,
0x5f,0xf5,0xfa,0x5f,0xbc,0x0c,0x07,0x7c,0x9b,0xb5,0xd6,0x9c,0xf0,0x7d,0x2a,0x69,
0xcb,0xd0,0x6e,0x6e,0x05,0xd3,0xc7,0xdb,0x25,0xf7,0xf9,0xdc,0xd7,0x71,0x3f,0x50,
0xf7,0xbd,0x23,0x9f,0x24,0x7a,0x62,0x92,0xc7,0xd5,0xda,0xff,0x8e,0x2d,0x6f,0x4b,
0xe1,0x75,0x5d,0xbf,0xcf,0x9d,0xff,0xfe,0x8f,0xba,0x79,0x83,0xec,0x2c,0xc1,0x7f,
0x47,0x7c,0xfb,0xb4,0xc1,0xb7,0x4d,0xa7,0xda,0xa4,0x43,0x0b,0xf0,0x7d,0xbe,0x6f,
0xee,0x7b,0x1e,0x98,0x87,0xe1,0x43,0xcf,0xa3,0xf0,0xbb,0xcc,0x77,0x9e,0xc9,0xcc,
0xf7,0xe1,0xf7,0x33,0xf2,0x7c,0xa6,0x31,0x4b,0xe1,0xf3,0x82,0xe9,0x9e,0xfa,0xe5,
0x3c,0x72,0xcb,0xd5,0xe5,0xbb,0xf5,0x8c,0xa6,0xae,0x63,0xdc,0xd4,0x6d,0x7c,0x62,
0xf1,0x5f,0xf5,0x91,0xe6,0x9e,0xdc,0x78,0xbf,0xe9,0xa8,0x9f,0xbe,0xb0,0x9f,0xf0,
0x2d,0xfb,0x91,0x6c,0xd7,0xba,0xc9,0x55,0xd3,0xe3,0xc7,0xc1,0x2d,0x44,0xff,0xef,
0x9c,0xa5,0xb2,0x85,0x7d,0x91,0xa5,0x6c,0x47,0xa7,0xf7,0xdf,0x7b,0x76,0x8d,0xfe,
0x77,0x87,0xfc,0x29,0xd6,0xaf,0xf9,0x27,0x73,0x3a,0xf1,0xf3,0x8f,0x66,0x87,0x4e,
0xb3,0x56,0xeb,0x89,0x8d,0x72,0xc3,0x1c,0x29,0x7a,0xef,0xf3,0x5a,0x49,0xd3,0xff,
0x1b,0x2f,0x83,0xeb,0xb3,0xb5,0xf2,0x85,0xbb,0xae,0x56,0x52,0x19,0xfa,0x63,0xf7,
0x6c,0xe4,0xee,0x8d,0x28,0xb5,0x1f,0xbf,0x48,0x0f,0x71,0xac,0xfc,0x2d,0xd3,0xfa,
0x9f,0x93,0xeb,0x70,0xfb,0xfc,0xb7,0x5a,0x87,0x2c,0xee,0xbf,0xc3,0xde,0x73,0xe7,
0xa3,0xba,0x5c,0x87,0xaf,0xc7,0xcd,0x77,0x9c,0xf4,0x3d,0xef,0xb5,0xb1,0x8c,0x73,
0xda,0x44,0x90,0x75,0xda,0xb3,0xc8,0x4d,0x3f,0x94,0x30,0xee,0x71,0xc1,0xd1,0xf5,
0x3f,0xd3,0xb2,0x3c,0xd6,0x72,0x8d,0xcd,0xe6,0x44,0xfc,0xb7,0x24,0xc6,0xff,0xcd,
0x45,0x8f,0x3f,0xaf,0x62,0xe3,0xc4,0xfc,0x3d,0x09,0x3f,0xb3,0x9f,0xc8,0x2e,0x53,
0xaf,0x75,0xbf,0x81,0x69,0xcb,0x7c,0xf2,0xea,0xe3,0xff,0xe6,0x1c,0x8b,0xd6,0x53,
0xf2,0x76,0xb4,0x79,0xff,0x2d,0xb7,0x6e,0x0c,0xef,0x8b,0xc4,0xb2,0x5c,0x3f,0xc0,
0x97,0x89,0x75,0xbf,0xf0,0xbf,0xcb,0x48,0x5d,0xd0,0x62,0xdc,0x3d,0x63,0x7d,0xea,
0xb6,0xcb,0x72,0xca,0x1c,0xd0,0xf6,0xe8,0x56,0xd9,0x68,0x36,0xca,0x46,0xbb,0x51,
0x42,0x5b,0xea,0xf8,0xbf,0x2f,0xb5,0x0c,0x2b,0xb4,0xad,0x5f,0x4a,0x19,0x0e,0x4b,
0xa3,0xbd,0xa4,0x6d,0xe0,0x0b,0xfa,0x5f,0x77,0xff,0xd7,0x37,0x91,0x6b,0xe6,0xb3,
0xfd,0xc9,0xe3,0xb8,0x69,0x1e,0xe3,0xff,0x72,0xf5,0xbf,0x8d,0xda,0xf2,0xaf,0xb3,
0x8d,0x5a,0x9f,0x6b,0x89,0xee,0x03,0xeb,0x2f,0xf9,0xbb,0x78,0x2f,0x5f,0x6f,0x7b,
0x9c,0xa8,0xaf,0xfd,0x50,0x59,0xbf,0xcd,0x83,0xef,0xc3,0x67,0x5a,0xfe,0x89,0xcc,
0x98,0x6e,0x13,0xfe,0xab,0x7e,0xff,0x95,0x72,0x6c,0xfd,0xbd,0x09,0xf1,0xfb,0x3f,
0xfc,0xbd,0xba,0xd3,0xfd,0x37,0x35,0xcf,0xd8,0x3c,0xef,0xff,0xf8,0xc1,0x94,0x7a,
0x8f,0x49,0xa9,0xdb,0xf1,0x91,0xbb,0xfe,0x56,0x70,0x9f,0xc9,0xee,0xe8,0xf7,0xbb,
0xc3,0xd8,0xfa,0xf5,0x5c,0xfc,0x42,0x7f,0x6f,0xe4,0xb4,0x69,0x55,0xd7,0xf6,0x4a,
0xb7,0xfe,0xf7,0x82,0xd6,0xd1,0x8e,0x9a,0x5a,0xd9,0xaf,0x75,0xad,0x7d,0x76,0x9f,
0xec,0x2d,0xf1,0xfe,0x0f,0xb7,0x5f,0x56,0xc8,0x72,0x5d,0x6e,0x29,0x65,0x58,0xa5,
0xad,0xe0,0xed,0xf2,0xb5,0xd6,0xb6,0x6a,0x35,0x53,0x75,0xad,0x52,0xb7,0xbf,0x65,
0xda,0x71,0xdc,0x38,0x8f,0xfb,0x3f,0x7e,0x25,0x6f,0xfb,0xfb,0x48,0x9a,0xd4,0x79,
0xe9,0xda,0xaf,0xae,0xdd,0x38,0x16,0xb8,0xb6,0xe9,0x13,0x5f,0x87,0x73,0x8e,0x7b,
0xb1,0x04,0x1d,0x57,0x4a,0xfd,0x70,0x32,0x7c,0x9c,0x79,0x18,0xe0,0xbf,0x6a,0xf5,
0x5f,0xea,0xfb,0x6c,0x6b,0xfa,0xbd,0x67,0x12,0xf7,0xff,0x16,0xf1,0xdf,0xd4,0x3c,
0x77,0x32,0xf3,0xbb,0xff,0x77,0x32,0xf5,0xf4,0xfd,0xc1,0xea,0x12,0xb7,0x63,0x32,
0xb3,0x41,0xb2,0xcf,0x80,0x19,0x4f,0xdc,0x17,0xbb,0xdf,0xb8,0x9e,0x86,0x9f,0xca,
0xa7,0xfa,0xd9,0xfe,0xc4,0xbd,0xb7,0xe3,0x81,0xbb,0x4e,0xba,0x4e,0xea,0xa5,0xd5,
0x74,0xa9,0x03,0x3b,0xf5,0xbf,0x97,0xb5,0x5d,0xd8,0x20,0xf5,0xba,0xdd,0x8e,0x33,
0x66,0x73,0x29,0xf7,0xff,0x86,0xae,0x9f,0x7c,0x85,0xcc,0x5c,0x86,0x8f,0xe5,0x7f,
0x8a,0x33,0xe0,0x4c,0x65,0x58,0x2d,0xa1,0x37,0xe0,0xfe,0x84,0x01,0x4b,0xdd,0x7e,
0x7f,0x2f,0x71,0xe2,0x38,0x6e,0x98,0xc7,0xfd,0xbf,0x6f,0xdb,0x77,0xc5,0xea,0xdf,
0x80,0x8b,0xa6,0x3b,0x18,0x9e,0xd6,0x5e,0x1d,0xcb,0x5f,0x7f,0x73,0xf5,0xb8,0x97,
0xaf,0xaf,0xe3,0xd2,0x10,0x3c,0x31,0xf8,0xaf,0x3a,0xfd,0x97,0xf6,0xd9,0x2f,0xd9,
0xe7,0x86,0x7c,0x28,0x89,0xe7,0xbf,0xf8,0xe7,0x61,0xfd,0xc2,0xae,0x94,0xdd,0xe6,
0xac,0xb4,0xe7,0xfd,0x37,0xf5,0xbc,0x91,0x81,0xf5,0xab,0xbd,0x4f,0x4a,0x7c,0xfe,
0x4b,0x38,0x9e,0xf2,0x19,0x33,0x75,0x99,0xdc,0xb5,0xa9,0xb4,0xdb,0x31,0x10,0xee,
0xf5,0xf3,0xec,0x0d,0x47,0x13,0xcf,0x8b,0x39,0xa4,0xdb,0xb7,0x52,0xcf,0xe9,0x9f,
0xca,0xbb,0xd6,0x8d,0xa8,0x3e,0x94,0x78,0xf6,0xca,0xe8,0xfa,0xbd,0xea,0xb7,0xdd,
0x7a,0xae,0xbb,0x7b,0xfe,0x6f,0x4a,0xaf,0xe9,0xd6,0x76,0x70,0x7b,0xd0,0xae,0x6d,
0xc9,0x36,0xa5,0xdd,0x5c,0x4c,0xfb,0xfc,0x97,0x0d,0x6d,0xfe,0xd9,0x2f,0x1f,0x15,
0x29,0xc3,0x72,0x6d,0x55,0xfe,0x0f,0xf9,0x89,0xb7,0xe3,0x4c,0x65,0x58,0x2b,0x9b,
0x65,0xa7,0xec,0xd5,0x36,0x67,0xd2,0x7f,0x69,0xb7,0xdf,0xd1,0x54,0xf8,0x1c,0x9f,
0xb0,0xc6,0xef,0x93,0x52,0x9e,0xff,0xf2,0x81,0xbc,0x65,0x3f,0x94,0x2d,0xa6,0x2e,
0x68,0x35,0x83,0x7a,0xbc,0x72,0xf5,0xb9,0x37,0xda,0x73,0xf8,0xef,0xb5,0xeb,0xff,
0x88,0xe7,0x37,0xf2,0xfe,0xb4,0xe9,0x3f,0x91,0xdf,0xda,0x8c,0xb6,0x03,0xcf,0xcb,
0x0d,0xef,0xbf,0xe9,0xcb,0xfc,0x83,0xd6,0x0f,0xe7,0x73,0x3d,0x3e,0x75,0xa9,0xec,
0xc7,0x25,0xce,0xb1,0x22,0xba,0x67,0xae,0x30,0xbf,0x96,0x9f,0xdb,0xf7,0x64,0xb9,
0xef,0x93,0x98,0xfe,0xe9,0x1a,0x71,0xf7,0x4b,0x5c,0xd7,0xfa,0x5f,0xbf,0x0c,0x9a,
0xc1,0x60,0x40,0xb7,0x37,0x4e,0xab,0xc9,0xa4,0x2e,0xc1,0x47,0xf2,0x4f,0xae,0xf5,
0x3b,0xc3,0xbd,0x2c,0xff,0xaa,0xb5,0xbf,0x7f,0xd6,0x5a,0xe8,0x6f,0x8a,0xdc,0xeb,
0xb2,0x22,0xaa,0x01,0x1e,0x88,0xf9,0x4f,0x16,0x60,0x2f,0xae,0x91,0x75,0x25,0x1c,
0xa3,0x3f,0xd8,0x5f,0x07,0x1f,0x9b,0x8d,0xe1,0x11,0xd3,0x12,0x0e,0x67,0x1e,0xd5,
0x3c,0xc7,0x71,0x55,0xea,0xbf,0x46,0xb9,0x68,0xaf,0xeb,0xb9,0x79,0x53,0x86,0x71,
0xde,0x3c,0xc6,0xbf,0xe4,0xf2,0xa9,0xbc,0x67,0xdf,0x91,0xdf,0xdb,0x35,0x89,0xb1,
0x26,0x2b,0xf5,0x4c,0x5e,0x65,0xb6,0xc8,0x51,0xad,0xff,0x74,0xa9,0x13,0xa6,0x2f,
0x73,0xb9,0x9e,0x2b,0xab,0x44,0x9c,0x1b,0x6c,0x5a,0x37,0xad,0x49,0x7d,0x1e,0x7e,
0xaa,0xbe,0x7a,0xc7,0xfe,0xa1,0x04,0xbf,0xae,0x90,0x3f,0xda,0x5f,0xcb,0x07,0x5a,
0xa6,0xc2,0xb5,0xfc,0xd1,0xfe,0x4e,0x59,0xab,0x75,0x1a,0x6d,0x5d,0x16,0x3c,0x4f,
0x79,0x95,0xa6,0xc6,0xee,0x95,0x6f,0xcd,0x55,0xe9,0x56,0xd7,0x25,0xfb,0x60,0x6f,
0xcb,0x4d,0xd3,0x23,0xd7,0xcc,0x05,0x6d,0xcf,0xda,0xb9,0xdd,0x21,0xbf,0x52,0xc3,
0xfd,0x8b,0xbc,0xa5,0x2d,0xdd,0x55,0x89,0x4f,0xdc,0xa8,0xe4,0x7f,0x93,0xff,0x90,
0xb7,0xe5,0x7d,0xdd,0xdf,0xeb,0x7c,0xaf,0x72,0x7c,0x5f,0xff,0x51,0xad,0xf8,0x89,
0x58,0xf9,0x5c,0xbe,0x4a,0xb4,0x80,0xf7,0x96,0x68,0x40,0xb7,0x8f,0xd7,0x26,0x8e,
0xe3,0x1a,0xbb,0x5e,0x02,0x5b,0xa3,0xf5,0xf4,0xb9,0xe7,0x5e,0xa9,0x7f,0x6f,0xfe,
0x68,0x56,0x05,0x35,0x66,0x5f,0x78,0xce,0x74,0x87,0xf7,0xb4,0x4d,0xfc,0xa2,0x4a,
0xae,0xb7,0xfd,0x90,0x1f,0xb3,0xf2,0x2c,0x3f,0xf6,0xe5,0x71,0x26,0x37,0x1e,0x66,
0x3c,0x3f,0x46,0xa6,0x90,0x7b,0x45,0xaf,0x57,0xc6,0x79,0x18,0x3c,0xd4,0x65,0x7d,
0x97,0xbf,0x76,0xf9,0x7c,0x09,0xf8,0x6f,0xa6,0xe7,0x15,0x36,0xcb,0x75,0x6d,0xbf,
0xdc,0xc4,0x81,0xfe,0xde,0xd1,0x5e,0xd3,0x1a,0x34,0x98,0x5a,0xf9,0x42,0xcf,0xf9,
0xcf,0xcc,0x1a,0x3d,0x17,0x92,0xb8,0xeb,0xee,0xab,0xcc,0x4a,0x65,0x9d,0x84,0x66,
0x87,0x1f,0xb3,0x76,0x5a,0xd9,0xaf,0x75,0xbd,0x1a,0x9d,0x67,0xab,0xd9,0x27,0xf5,
0xa6,0x45,0x97,0x33,0x1c,0x5b,0x66,0x8b,0xfe,0x6e,0x9f,0x7e,0x16,0xea,0x3c,0x5b,
0x65,0x8f,0x39,0x26,0x27,0x95,0xfd,0x66,0xbb,0xfe,0xbc,0x4e,0x97,0xb5,0xca,0xdf,
0x13,0x56,0xb8,0xae,0x35,0x7a,0x5e,0x66,0xec,0x46,0xd9,0x6e,0xf6,0xe8,0x7a,0x0e,
0xca,0x57,0xe6,0x73,0x9d,0xfe,0x33,0x59,0x33,0xad,0x5c,0xab,0xfd,0x32,0x56,0x2a,
0xeb,0x74,0x1d,0x3b,0x74,0xda,0xe3,0xe6,0x94,0xb2,0x6f,0x8e,0xed,0xc8,0xfa,0xd5,
0x18,0x77,0xef,0xfe,0x71,0x39,0xa3,0xed,0xf6,0x93,0x3a,0xef,0x76,0x9d,0x27,0xa3,
0x8e,0xde,0x68,0x77,0xca,0x37,0xa6,0x21,0xb8,0x62,0xae,0x29,0x0d,0xfa,0xef,0x9d,
0xb2,0x51,0x7f,0x9f,0xb1,0x5a,0xeb,0xd2,0x7d,0x54,0x6f,0xdc,0x33,0x9f,0x5a,0xa4,
0xc5,0x3f,0xa7,0xee,0x9c,0x7e,0x9f,0xea,0x62,0xf7,0x40,0x1d,0x54,0x13,0xed,0xd4,
0xf6,0xe9,0x7a,0xfd,0xab,0xf0,0x1b,0xf9,0x85,0x7a,0xec,0x2d,0x9f,0x9f,0xe9,0xbf,
0xb2,0xf9,0x59,0xf4,0x9b,0xb7,0xf5,0xd3,0xf7,0xd5,0x65,0x9f,0xc9,0x06,0x9d,0x7e,
0xa3,0x18,0xb5,0xdb,0xef,0xb4,0xfe,0xf9,0x0b,0xcd,0xbb,0x6a,0x48,0x77,0x9d,0x6f,
0xab,0x6c,0x53,0x42,0x6f,0xcc,0x77,0xfd,0x27,0xbf,0xd6,0x69,0x56,0xaa,0xeb,0xb2,
0xfe,0x9b,0x6a,0x01,0x1f,0xf7,0xe3,0x86,0x4f,0x5b,0xdd,0xbf,0xf6,0x0b,0xf5,0x98,
0xdb,0xbf,0xcb,0x75,0x3b,0x57,0xce,0xb2,0x8f,0x37,0xe9,0x3e,0xab,0x0d,0xea,0xcc,
0xc9,0xe0,0xb0,0xd9,0x1b,0xec,0x32,0x3b,0x83,0x7d,0xe6,0x68,0xd8,0x68,0x2e,0x87,
0x4d,0x99,0xd3,0xe1,0x41,0xf3,0x65,0xb8,0xd1,0xe8,0xa2,0x8c,0x09,0x8c,0x62,0x8d,
0x0d,0xc4,0x84,0x41,0x18,0xb1,0xd9,0xec,0x08,0x6b,0xcd,0xd9,0xb0,0xdd,0xdc,0x0e,
0x27,0x16,0xe7,0xfa,0x5e,0x34,0x26,0xef,0xa9,0xf7,0xcf,0x93,0xac,0xd3,0xa2,0xb1,
0x78,0xf7,0x2b,0x7a,0x0e,0xdd,0xd5,0xf5,0x3f,0xcc,0xb8,0x71,0x39,0x93,0xae,0x3f,
0xa7,0xaa,0xfd,0x37,0xc3,0x68,0x4c,0x3f,0x16,0xb3,0xc5,0xb6,0xaa,0x0f,0x07,0xde,
0x40,0xff,0xdd,0x0e,0xfa,0xb5,0xce,0x76,0xc5,0xd4,0x6b,0x1d,0x6e,0xbf,0xec,0x36,
0xbb,0x64,0x57,0x11,0x76,0xab,0x5b,0x0e,0x9b,0x93,0x72,0xde,0x5c,0x56,0x37,0x5c,
0x92,0xb3,0xea,0x8f,0xc3,0xe6,0x90,0x1c,0xf3,0xf7,0x70,0x65,0xef,0xc9,0x9f,0xbe,
0x4c,0x3d,0x47,0xd5,0x7b,0xf5,0xe6,0x42,0x70,0x59,0xeb,0x88,0x0d,0x3a,0xff,0x21,
0xb3,0x77,0xd6,0xf5,0x7c,0xad,0xf3,0x1c,0xf5,0xf7,0x92,0xd4,0xcb,0x09,0x73,0x58,
0x9d,0xb9,0xbb,0xe8,0xb4,0xbb,0xf4,0xb3,0x7d,0x3a,0x8d,0x7b,0x2e,0xde,0x25,0x2d,
0x57,0xb6,0x5f,0x76,0xf6,0xed,0xf8,0xca,0x7c,0x2d,0x07,0x7d,0x99,0x2e,0x6a,0x19,
0xaf,0x04,0x4d,0xbe,0x9c,0x07,0x74,0x39,0xfb,0xe5,0x88,0xce,0x7f,0xd1,0xb4,0xba,
0x3e,0x5e,0xf5,0x5c,0x83,0xfe,0xfe,0x6b,0xd9,0xac,0xee,0x5b,0x67,0x3f,0x93,0xf5,
0x5a,0xb7,0xdb,0x2c,0x3b,0xa6,0xf5,0x3e,0x4c,0xa5,0x56,0x5b,0xa5,0x7b,0x74,0x8a,
0x2d,0xea,0xa8,0xb5,0x5a,0xf3,0xd5,0x7a,0x52,0x91,0x7c,0xac,0x75,0xb0,0x75,0x3a,
0xd5,0x66,0x6d,0xcb,0x7e,0xa9,0x9e,0xdb,0xa4,0xb5,0xba,0xb5,0xfa,0xbb,0x4f,0x75,
0x2e,0xb5,0xb3,0xfe,0xbc,0x5d,0x1d,0xf7,0xb5,0xb2,0x5d,0xff,0x6d,0xf4,0x77,0xcb,
0xf5,0xb3,0x15,0x3a,0xcd,0x46,0xd9,0x69,0xbf,0x51,0xd7,0x5d,0xf2,0xcf,0xd8,0xbc,
0x69,0x86,0x24,0xdd,0x71,0xdc,0xad,0xfb,0x75,0xaf,0x3a,0xee,0x40,0x70,0xd0,0x1c,
0x0a,0xf4,0x98,0x85,0x97,0x32,0xd7,0xc3,0x1b,0xa6,0x23,0x6c,0x31,0x17,0xc2,0x06,
0x75,0x59,0xa3,0xb9,0x1a,0x76,0x9a,0xde,0xb0,0x27,0xd3,0x1e,0x36,0xeb,0xcf,0x27,
0xcd,0xf1,0xf0,0xa8,0x3a,0x71,0x3a,0xc7,0xf5,0xb3,0xb3,0x3a,0x4d,0xa7,0xb6,0x7d,
0xc7,0xc3,0xa7,0x5a,0x0f,0x7a,0xb9,0x40,0x63,0x47,0x22,0xbf,0x05,0x8f,0x32,0x51,
0x7d,0x2d,0xe3,0xfc,0xb6,0xd4,0xce,0x29,0xd7,0xff,0xe3,0xfa,0xb8,0x9f,0x86,0xcf,
0xab,0xdc,0x7f,0xd3,0xe3,0xfe,0x96,0x66,0xdb,0xcc,0x1d,0x45,0xef,0x8b,0x7e,0x9d,
0x18,0x09,0x86,0xfc,0x98,0xb6,0x16,0x3d,0xef,0xcf,0xab,0xd3,0xea,0xf3,0x7d,0x9a,
0x85,0x9c,0xd5,0xcf,0x2f,0x9a,0x96,0xa0,0x5d,0xcf,0xb3,0x2e,0xff,0x1c,0x4b,0xe7,
0x9b,0x0b,0xea,0x9d,0x16,0x9d,0xbf,0x4f,0x97,0x33,0x32,0x6d,0x99,0x97,0x4c,0x53,
0xe0,0xee,0x2f,0x6d,0x31,0x1d,0xfa,0xb3,0xeb,0x37,0xbd,0x2a,0x17,0xe6,0x58,0x4f,
0x83,0x69,0xd4,0xf9,0xae,0x04,0x2d,0xba,0xae,0x66,0x75,0xd4,0x79,0xad,0xa3,0xd5,
0x17,0x9d,0xfe,0xac,0x7e,0x7e,0x51,0x97,0xdf,0xee,0x97,0xdf,0x9e,0x62,0x3b,0xce,
0x68,0xfd,0xae,0x49,0xcb,0x7e,0xdd,0x97,0xe9,0x8a,0x4e,0x5f,0xaf,0xde,0x3b,0x24,
0xbb,0xad,0xfa,0x46,0xd9,0x6b,0xf7,0xa8,0xe1,0x0e,0x28,0x7b,0xb4,0x36,0xb7,0x4d,
0x1d,0xb5,0x41,0x6b,0x61,0x35,0x6a,0x9e,0xad,0xea,0xaa,0xaf,0x0a,0xfa,0x1e,0x92,
0xfe,0xab,0xf5,0x73,0xed,0x92,0x2f,0xd4,0x81,0x6e,0xae,0x62,0xff,0x0b,0x75,0x69,
0x5b,0xd4,0x6d,0x3b,0x65,0xb7,0xc6,0x59,0x6e,0xab,0xfe,0xa6,0x46,0x7f,0xef,0xea,
0x83,0xdb,0xf4,0xf7,0xae,0x0c,0x75,0x72,0xcc,0x9e,0x96,0x3a,0x7b,0x52,0xff,0xc6,
0xd4,0xc9,0x09,0xdb,0xa0,0xfb,0xf2,0x8a,0xb4,0x99,0x6e,0x75,0x5d,0xe1,0x33,0x58,
0xe3,0xc7,0xf1,0x42,0x70,0xde,0x34,0xea,0x36,0x5e,0xd4,0xbf,0x39,0x57,0xc2,0xab,
0xe6,0x7a,0xd8,0x9a,0x69,0x8d,0xd1,0x16,0xb6,0x67,0xba,0xc3,0xbe,0xcc,0x50,0x38,
0x92,0x19,0x09,0x07,0x33,0x37,0xd5,0x79,0xdd,0xe1,0xcd,0xcc,0x40,0xa8,0xe7,0x6e,
0xcd,0x5d,0xfd,0xdd,0x40,0xa6,0x27,0xbc,0xa1,0xd3,0x25,0xe7,0x9b,0x9a,0xff,0x86,
0xe9,0xd1,0x69,0x46,0x6b,0x1e,0x9a,0xc9,0x9a,0xef,0x33,0x2f,0x4b,0x70,0xdc,0x4b,
0xdf,0x3e,0x9d,0xf4,0x6d,0xc8,0x09,0xad,0x37,0x65,0xdb,0xa4,0xa3,0xaf,0xf1,0x39,
0x76,0x5f,0x3d,0x5e,0xb9,0xf1,0x2f,0x0b,0x71,0x5f,0xe2,0x09,0x75,0xe2,0x59,0x6d,
0xef,0x5c,0xf4,0xf7,0x5c,0xf7,0x2e,0xd0,0xfd,0x3a,0xd5,0xe2,0xbf,0xdb,0x66,0x48,
0xcf,0xa7,0x5e,0x75,0xda,0x8d,0x7c,0x7f,0xe6,0x74,0xda,0xbd,0xf7,0xba,0x75,0xba,
0x5b,0xfe,0x7a,0x7f,0x7f,0xd4,0x07,0xea,0x5c,0x58,0xf8,0x2e,0x89,0xf8,0x32,0x3b,
0x75,0x9a,0x2e,0xf7,0xae,0x08,0x9d,0xa6,0x5f,0xe7,0xcd,0xad,0xa7,0x7d,0xd6,0xf5,
0x74,0x99,0x1e,0x9d,0xa7,0x37,0xe8,0xd6,0x7f,0xdf,0x28,0x3a,0xad,0xeb,0x77,0x75,
0xde,0xeb,0x8e,0x2f,0x3f,0x98,0x79,0x3b,0xae,0x38,0x17,0xab,0xff,0xce,0x68,0x1b,
0xf9,0x78,0xf6,0xb9,0xea,0x76,0xaf,0xba,0x6c,0x8f,0xaf,0x65,0xed,0xd4,0x5a,0xdb,
0x0e,0xfd,0xff,0xaf,0xf4,0xe7,0x7d,0xde,0x6f,0x2e,0x07,0xf5,0xdf,0x7b,0x12,0x9f,
0xaa,0x1d,0xd5,0x8c,0xc5,0xfc,0x77,0x28,0x9a,0x6b,0x7f,0x6c,0xae,0x1d,0xea,0xcc,
0x64,0xb2,0xbf,0xd5,0xfa,0xb4,0x5f,0xd7,0x7e,0xcd,0x5e,0xd9,0xe7,0xcb,0x73,0x5c,
0x5d,0xd7,0x20,0x8d,0x5a,0xde,0x1b,0xd1,0xfb,0x89,0x6e,0x9b,0x61,0xdd,0xae,0x9b,
0x7e,0x3f,0x74,0x78,0x5f,0xbb,0x6d,0xed,0x57,0xd7,0xe5,0xee,0x01,0x76,0x75,0x8d,
0x71,0x3f,0xd6,0xe4,0x51,0xe6,0x89,0xb6,0x45,0x1f,0x86,0x63,0x99,0x7b,0x35,0xa3,
0x99,0x3b,0x35,0x7a,0x2c,0x8a,0x30,0xaa,0x8e,0xbb,0x1f,0x8e,0x67,0x1e,0xd6,0x4c,
0x98,0x09,0x75,0xd8,0x58,0xa8,0xf5,0x2c,0x9d,0xef,0x61,0xcd,0xe3,0xcc,0x77,0x35,
0xdf,0x65,0x1e,0xd7,0x3c,0xcc,0x8c,0x85,0xf7,0xd4,0x6f,0xa3,0x33,0xcc,0x3f,0xaa,
0xf3,0xdf,0xd3,0xcf,0x27,0x74,0x7d,0xcf,0x8a,0xd7,0xfd,0xbc,0xe7,0x5c,0x5b,0x55,
0xeb,0x72,0xc1,0xf8,0x92,0xac,0xc7,0x2d,0xdc,0x7d,0xf6,0x4b,0xdb,0x7f,0x45,0xda,
0xce,0xfe,0x79,0x14,0x4d,0xd1,0xb8,0xf7,0x1b,0xda,0x16,0xe9,0x5b,0x92,0xef,0x05,
0x1c,0xc9,0x9e,0x67,0xc1,0x60,0x41,0x7f,0xe6,0x74,0x06,0x83,0xec,0x7b,0xc3,0x6e,
0x7b,0x86,0xd5,0x71,0xae,0x1f,0x74,0x70,0xda,0xbb,0xc4,0xe2,0xcb,0x1c,0xf4,0x0c,
0x47,0xf3,0xb8,0xdf,0x0d,0xcd,0xb9,0x9e,0x01,0x9d,0xc7,0xbd,0xe7,0xcc,0x4d,0x3b,
0x98,0x72,0xda,0xdc,0xf2,0x7b,0xd4,0x11,0x1d,0xd2,0x6c,0x9a,0xe5,0x9c,0xd6,0x0d,
0xdd,0x35,0xb1,0x63,0x76,0xbf,0x4c,0x8f,0xb3,0x58,0x36,0x07,0x0a,0x7e,0x5b,0x1b,
0xb5,0x6e,0x73,0x0e,0x2c,0xf6,0x79,0x71,0x03,0xd6,0xfa,0xe5,0xee,0x2f,0x92,0x23,
0x72,0x4c,0xbe,0x55,0xcf,0x5d,0xd6,0xef,0x4d,0x87,0x96,0xf7,0x56,0x62,0x3b,0x73,
0xfb,0x38,0xbb,0x3f,0x73,0xfb,0x31,0xfb,0xb9,0xfb,0xfd,0xdd,0xf0,0xbe,0x99,0x08,
0x1f,0x6b,0xdb,0xea,0x59,0x41,0xbd,0xeb,0xa5,0xfe,0xfc,0xdc,0xdf,0x7f,0xf0,0xb4,
0xe6,0xe9,0x9c,0xf8,0xfb,0xc7,0x6a,0xb2,0x3c,0xd3,0x79,0x1c,0xee,0xdf,0xcf,0x6b,
0x5e,0x28,0xd9,0x7b,0x5e,0x67,0x9b,0x3f,0x7b,0xfd,0xdf,0xad,0xf3,0xa5,0xff,0xb7,
0xaf,0xcf,0x45,0xf7,0x81,0xdd,0xe3,0xba,0xfa,0x1b,0xe0,0xbf,0xa2,0xcf,0xfc,0x97,
0xec,0xfb,0xf2,0x2e,0xfa,0xfb,0xbb,0x7b,0xdd,0x35,0x1a,0xbe,0x03,0x0b,0xf8,0x5d,
0x1a,0xf0,0xf7,0x92,0x76,0xf8,0xba,0xb8,0xab,0xd3,0x35,0xd9,0x7a,0x7f,0xaf,0xe9,
0x37,0x55,0xf7,0x8c,0xf5,0x6f,0xb4,0x5c,0xa7,0xfd,0xf3,0x4c,0x72,0xed,0x86,0xf4,
0xef,0x4a,0x8b,0xfa,0x1b,0xcd,0x93,0xe8,0x5e,0xd7,0x97,0x55,0xd0,0xbf,0xfa,0x32,
0x5f,0xa7,0xd3,0x7a,0x66,0x30,0xa6,0x75,0xba,0xbb,0x7c,0x1f,0xab,0xdc,0x7f,0xad,
0xd2,0xa2,0xdf,0xbf,0xb3,0x55,0xf0,0x0e,0x82,0x63,0xb1,0xe7,0xfb,0x64,0xdd,0xd8,
0x1a,0x3d,0xdf,0x67,0x84,0xef,0x48,0xec,0xbb,0x72,0xcb,0xef,0x93,0xde,0xe8,0x99,
0x95,0x57,0xfd,0xfe,0x6a,0xa8,0xfa,0x77,0xe5,0x1c,0x8f,0xae,0x91,0x5c,0x8e,0x9e,
0xdb,0x94,0xfe,0x1e,0xd8,0xd1,0xe8,0xde,0xd7,0x89,0x4c,0xf5,0x8c,0x21,0x7e,0x11,
0xdd,0xc7,0xfa,0x9d,0xef,0x87,0x78,0xa0,0x2e,0xbe,0xcb,0x77,0x73,0x49,0xfa,0xaf,
0xf0,0x59,0x34,0xdd,0xd1,0x3b,0xf6,0xbe,0x95,0x93,0x55,0x76,0x2e,0xe5,0xde,0xb9,
0xdc,0x18,0x3d,0xb7,0xf6,0x6a,0xf4,0x8c,0xc7,0x1b,0xd1,0x33,0x1e,0x6f,0x2d,0xf1,
0xef,0xc1,0x48,0xfe,0x39,0xba,0xed,0x91,0xdb,0x92,0xef,0xa6,0x3e,0xb6,0x44,0xde,
0x91,0x53,0xa7,0x7f,0xc7,0xea,0xfd,0x31,0xba,0x16,0x8d,0xa3,0x1a,0x92,0x52,0xc6,
0x4a,0x8c,0xa9,0xeb,0x1e,0x99,0xec,0x3d,0xfe,0xcf,0xab,0xa2,0x4e,0xe7,0xc6,0xca,
0x3d,0xc9,0x8e,0x27,0xc9,0xbc,0xde,0x7d,0x11,0x6f,0xb8,0xff,0xa6,0x31,0xac,0xe7,
0x63,0x87,0x7f,0x56,0x61,0x63,0xf6,0x79,0xd6,0x4b,0xe4,0x1d,0xa3,0xb9,0xf7,0xd2,
0x9f,0x89,0x5c,0xe9,0x68,0xce,0x3f,0xe7,0x3b,0x4b,0x57,0x91,0x67,0x7d,0x67,0x19,
0x2a,0xa1,0xad,0x59,0x9c,0xb6,0xfc,0xfa,0xae,0xf9,0xe7,0x82,0x67,0xcb,0xd2,0x90,
0x2f,0xdf,0x29,0x7b,0x64,0xc9,0xbe,0xb3,0xe1,0xb8,0xcd,0xbe,0xcb,0x75,0xea,0xfa,
0x6e,0x69,0xcf,0x19,0x76,0xcf,0x34,0x19,0x57,0xd7,0x3d,0x56,0xd7,0xb9,0xeb,0x65,
0x2f,0xaa,0xc6,0x75,0x8f,0xa3,0xb1,0xc0,0x5c,0xa7,0x7b,0xfd,0xfd,0x97,0x1d,0x2b,
0x39,0x96,0xba,0x8f,0xdd,0x3d,0x4f,0x2d,0xdb,0x66,0x76,0x6d,0xae,0x93,0x6f,0xf8,
0x7b,0xfb,0xde,0x84,0x1c,0x97,0xb8,0xe7,0x3a,0xe6,0xf1,0x3c,0xf5,0x51,0x75,0xc9,
0x83,0x68,0x0c,0xec,0x77,0x55,0xf2,0xdc,0xa6,0x17,0xd1,0x58,0x3a,0x75,0x9d,0x1b,
0x63,0x92,0xc1,0x75,0x6f,0xa6,0xff,0x66,0x7a,0x5e,0xe1,0xa3,0xe8,0x9a,0x46,0xfa,
0xe7,0x59,0x67,0xdf,0x67,0xda,0xe2,0xeb,0x37,0xbc,0xcf,0x74,0x69,0xe6,0x98,0x1e,
0xb7,0xd3,0xaf,0xe4,0xb9,0x5c,0xbf,0xc4,0x78,0xf4,0x6c,0x93,0xc9,0x62,0xcf,0x0f,
0xae,0x80,0xeb,0x26,0xa3,0xef,0xf5,0x18,0xd7,0xea,0xf0,0x5f,0x31,0xff,0x4d,0xe3,
0x65,0x34,0x16,0xd3,0xf5,0x67,0x95,0xf8,0xbd,0x91,0x21,0xff,0x1c,0x10,0xd7,0xf6,
0xbb,0xa8,0xe7,0xd4,0x59,0xf5,0xe2,0x89,0xd7,0xfa,0x5d,0xf6,0x4b,0x25,0x27,0xf2,
0x9e,0xbb,0x9a,0x7f,0xbe,0xfa,0xc8,0xfc,0x3c,0xe7,0xea,0x74,0xbe,0xbf,0xf3,0x59,
0x55,0xb4,0x5f,0x1d,0xcf,0x73,0xae,0xd3,0xb2,0xa9,0xeb,0x32,0xa3,0xf8,0x05,0xff,
0xcd,0xdb,0x7f,0x33,0x7f,0xbf,0x7c,0x9b,0x79,0xde,0x63,0x36,0xfb,0xf4,0x7c,0xbb,
0xa1,0x5e,0x6c,0xf1,0xd7,0xc3,0x4e,0x15,0x7d,0x27,0x14,0x79,0x95,0xbe,0xd6,0x53,
0x72,0x2e,0xef,0xb8,0xeb,0xd2,0xed,0xaf,0x47,0xde,0x9e,0xe7,0xbd,0x4a,0xee,0x99,
0x9c,0xd9,0xb6,0xeb,0xb3,0xaa,0xe8,0x93,0x88,0xdf,0x0f,0x96,0x1b,0x57,0xf7,0xa0,
0x94,0x77,0x4e,0x00,0xfe,0x9b,0xa7,0xff,0x8a,0x39,0xf1,0x69,0xb6,0x8f,0xcc,0xd7,
0x13,0xe7,0xd7,0x47,0x36,0xe8,0xcf,0xd1,0x2e,0x7f,0xbe,0x66,0xdd,0xd8,0x18,0xf5,
0x11,0x1c,0xc6,0x69,0x33,0xbc,0xc3,0xb5,0x3e,0xea,0xd7,0xb9,0xe2,0xfb,0x75,0x3a,
0x5f,0xf1,0x3d,0x39,0xf7,0xb2,0xd7,0xe8,0xdc,0x7d,0x99,0x51,0x7f,0x44,0x15,0x3d,
0xb3,0x29,0x7c,0x19,0x8d,0x37,0x71,0x7f,0x77,0x1f,0x9a,0x37,0xfa,0x5e,0x09,0xfc,
0x57,0x75,0xfe,0x2b,0xfe,0x9d,0x5d,0xc0,0x71,0xef,0xd2,0x17,0xf5,0xa9,0xb6,0x46,
0x7d,0xaa,0x97,0xa2,0xfe,0xd4,0xb3,0x51,0x5f,0x6a,0xdd,0x92,0x6f,0x5b,0x1f,0x8b,
0x7c,0xff,0x6d,0xd4,0x4f,0xdc,0x1c,0xf5,0x1d,0x77,0x2d,0xe0,0x38,0xc8,0xc8,0x73,
0x99,0xec,0x33,0xd6,0x27,0xab,0xef,0x99,0x9c,0xfe,0x39,0x26,0x93,0xd1,0x7d,0x61,
0xae,0x5f,0x8e,0x31,0xc4,0xf8,0x6f,0x09,0xfa,0xaf,0x28,0xb9,0xf7,0xe5,0x65,0x9f,
0xd1,0x73,0xbf,0x0c,0xd7,0xa3,0xa7,0xc6,0x9f,0x74,0xc6,0xc6,0xbb,0x34,0x9b,0xa9,
0xb1,0x30,0x8e,0x7a,0x7b,0x2a,0x36,0x0e,0xa5,0x90,0x74,0x6d,0xf2,0xa3,0x32,0xdb,
0x32,0x72,0xef,0x31,0xcc,0xd2,0x92,0x1f,0x7f,0xd3,0x1a,0x1b,0x23,0xd3,0xbf,0xe0,
0xdf,0xa7,0xbb,0xf9,0x6b,0x73,0xd9,0xb1,0x25,0xb9,0x77,0x81,0x55,0xdf,0x33,0xd6,
0x5f,0xe6,0x9f,0x43,0x97,0x6b,0x37,0xe0,0x02,0xfc,0xb7,0xb8,0xfe,0x7b,0x18,0x4e,
0x44,0xed,0x9d,0x97,0x55,0x30,0xa6,0xbe,0xf0,0xf9,0x65,0xf7,0x69,0xeb,0xcc,0x38,
0x6e,0xce,0xed,0x97,0xf8,0x3b,0x5c,0x27,0xab,0xfe,0x5d,0x39,0x05,0xe3,0x4d,0x18,
0x5b,0x07,0x55,0x38,0xfe,0x39,0x7b,0x0d,0xe8,0x71,0x54,0x67,0xa8,0xbe,0x76,0x51,
0xee,0xfe,0xca,0xa9,0x67,0xa0,0x65,0xc7,0x2e,0x16,0x7f,0x46,0xed,0x52,0x22,0xf7,
0x1c,0xdd,0xf1,0xe8,0x79,0xbc,0xc9,0x77,0x53,0xbf,0x58,0x22,0xef,0xf4,0x7a,0x9e,
0xbf,0x37,0x6c,0x42,0x5d,0x47,0xbf,0x04,0x2c,0xdd,0xfb,0x3f,0xdc,0xbd,0x97,0xe3,
0xd1,0xb5,0xa2,0xa5,0xf3,0x2e,0xbe,0xc2,0xf7,0xd2,0x7f,0x97,0x7b,0xce,0x50,0xe4,
0x95,0x6c,0xdd,0x72,0x2c,0x73,0xbf,0xe8,0xf3,0xbe,0xd3,0xb6,0xc9,0xef,0x9a,0xd9,
0x96,0x71,0xdf,0xb7,0x41,0xb3,0xeb,0x9b,0xc8,0x97,0x23,0x3b,0x2e,0x2e,0x57,0xc6,
0x97,0x4b,0xf6,0xbd,0x0d,0x09,0xcf,0xf9,0xeb,0xbb,0xb4,0x5f,0xe1,0xf5,0xf2,0x5f,
0xb1,0x67,0xb7,0x4e,0x98,0xaa,0xbc,0x76,0x0e,0x65,0xa8,0xcf,0xbd,0x48,0x78,0x2e,
0xfb,0xcc,0x61,0xce,0x59,0x78,0x33,0xfd,0x57,0x74,0x8c,0x58,0xbe,0x8e,0xc3,0xfb,
0x4c,0x5f,0x13,0xcf,0x51,0x9f,0x03,0xfc,0x37,0x6f,0x46,0xb3,0xcf,0x68,0x0b,0xb3,
0xcf,0x68,0x7b,0x5a,0x25,0xf7,0x42,0xe1,0xb9,0xa9,0x76,0xeb,0xa3,0xfc,0xf3,0xd5,
0x39,0x07,0x01,0xff,0x2d,0xd6,0xf3,0xfe,0xb3,0xcf,0x38,0x9a,0xc8,0xbf,0x13,0xfa,
0x05,0x5e,0x5a,0xf0,0x7b,0xc0,0x72,0xef,0x90,0x70,0x8e,0xcb,0xbd,0x07,0x8c,0x7e,
0x08,0xc0,0x7f,0xd5,0xfa,0xfe,0xf3,0x6c,0x5f,0xc2,0x98,0xef,0x33,0x98,0x88,0xfa,
0x3e,0xbf,0xe7,0x1a,0x63,0xd1,0x77,0xb8,0x3e,0x4d,0xf4,0xeb,0x8c,0xbd,0xf6,0xef,
0xc9,0x01,0xfc,0xf7,0x3a,0xfb,0xaf,0xb4,0x71,0x6f,0xb9,0xb1,0xbd,0xd9,0xb1,0x8b,
0xdf,0x57,0xd7,0xfd,0x5a,0xaf,0x30,0x46,0x2e,0xfe,0x6e,0x6a,0x37,0x56,0x2e,0x72,
0x5b,0x86,0x71,0x90,0x80,0xff,0xde,0x64,0xff,0x95,0x3e,0x8e,0x2e,0xdb,0xce,0xce,
0xfb,0x32,0x36,0x16,0x26,0xee,0xcd,0x99,0x79,0x51,0xc2,0x98,0xed,0xe2,0x4c,0xc6,
0xd6,0x37,0x31,0x35,0xfe,0x26,0x36,0x46,0x86,0x71,0xc0,0x80,0xff,0xf0,0x1f,0x00,
0xe0,0x3f,0xfc,0x07,0x00,0xf8,0x0f,0xff,0x01,0x00,0xfe,0xc3,0x7f,0x00,0x80,0xff,
0xf0,0x1f,0x00,0xe0,0x3f,0xfc,0x07,0x00,0xf8,0x0f,0xff,0x01,0x00,0xfe,0xc3,0x7f,
0x00,0x80,0xff,0xf0,0x1f,0x00,0xe0,0x3f,0xfc,0x07,0x00,0xf8,0x0f,0xff,0x01,0x00,
0xfe,0xc3,0x7f,0x00,0x80,0xff,0xf0,0x1f,0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,
0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xc0,0x7f,0x00,0x00,0xf8,
0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,0x80,0xff,0x00,
0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,0xff,0xe1,0x3f,
0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,
0xff,0xe1,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,
0xff,0x00,0x00,0xff,0xe1,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,
0x00,0xfc,0xc7,0xfe,0x07,0x00,0xfc,0x07,0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,
0x00,0xfe,0x03,0x00,0xc0,0x7f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,
0x3f,0x00,0x00,0xfc,0x07,0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,
0x00,0xc0,0x7f,0x00,0x80,0xff,0xf0,0x1f,0x00,0xe0,0x3f,0xfc,0x07,0x00,0xf8,0x0f,
0xff,0x01,0x00,0xfe,0xc3,0x7f,0x00,0x80,0xff,0xf0,0x1f,0x00,0xe0,0x3f,0xfc,0x07,
0x00,0xf8,0x0f,0xff,0x01,0x00,0xfe,0xc3,0x7f,0x00,0x80,0xff,0xf0,0x1f,0x00,0xe0,
0x3f,0xfc,0x07,0x00,0xf8,0x0f,0xff,0x01,0x00,0xfe,0xc3,0x7f,0x00,0x80,0xff,0xd8,
0xff,0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xc0,0x7f,0x00,
0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,0x80,
0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xc0,0x7f,0x00,0x00,0xf8,0x0f,
0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,0xff,0xe1,0x3f,0x00,0xc0,
0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,0xff,0xe1,
0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,
0x00,0xff,0xe1,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,
0x00,0xc0,0x7f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,0x00,0x00,
0xfc,0x07,0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xc0,0x7f,
0x00,0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,
0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,0xff,0xe1,0x3f,0x00,0xc0,
0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,0xff,0xe1,
0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,
0x00,0xff,0xe1,0x3f,0x00,0xc0,0x7f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,
0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,0x80,0xff,0x00,0x00,0x96,0xb6,0xff,0x86,0xf1,
0x1f,0x00,0x50,0xff,0x03,0x00,0xc0,0x7f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,
0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,
0xfe,0x03,0x00,0xc0,0x7f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,
0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,
0xff,0xe1,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,
0xff,0x00,0x00,0xff,0xe1,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,
0x00,0xfc,0x87,0xff,0x00,0x00,0xff,0xe1,0x3f,0x00,0xc0,0x7f,0xec,0x7f,0x00,0xc0,
0x7f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,
0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xc0,0x7f,0x00,0x00,
0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,0xf8,0x0f,
0xff,0x01,0x00,0xfe,0xc3,0x7f,0x00,0x80,0xff,0xf0,0x1f,0x00,0xe0,0x3f,0xfc,0x07,
0x00,0xf8,0x0f,0xff,0x01,0x00,0xfe,0xc3,0x7f,0x00,0x80,0xff,0xf0,0x1f,0x00,0xe0,
0x3f,0xfc,0x07,0x00,0xf8,0x0f,0xff,0x01,0x00,0xfe,0xc3,0x7f,0x00,0x80,0xff,0xf0,
0x1f,0x00,0xe0,0x3f,0xfc,0x07,0x00,0xf8,0x8f,0xfd,0x0f,0x00,0xf8,0x0f,0x00,0x00,
0xff,0x01,0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,
0x00,0x00,0xfe,0x03,0x00,0xc0,0x7f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,
0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,0x80,0xff,0x00,0x00,0xff,0xe1,0x3f,0x00,0xc0,
0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,0xff,0xe1,
0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,
0x00,0xff,0xe1,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,
0x87,0xff,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,0x80,0xff,
0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xc0,0x7f,0x00,0x00,0xf8,0x0f,0x00,
0x00,0xff,0x01,0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,0x80,0xff,0x00,0x00,0xf0,
0x1f,0x00,0x00,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,0xff,0xe1,0x3f,0x00,0xc0,
0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,0xff,0xe1,
0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,
0x00,0xff,0xe1,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,
0x07,0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xc0,0x7f,0x00,
0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,0x80,
0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xc0,0x7f,0x00,0x80,0xff,0xf0,
0x1f,0x00,0xe0,0x3f,0xfc,0x07,0x00,0xf8,0x0f,0xff,0x01,0x00,0xfe,0xc3,0x7f,0x00,
0x80,0xff,0xf0,0x1f,0x00,0xe0,0x3f,0xfc,0x07,0x00,0xf8,0x0f,0xff,0x01,0x00,0xfe,
0xc3,0x7f,0x00,0x80,0xff,0xf0,0x1f,0x00,0xe0,0x3f,0xfc,0x07,0x00,0xf8,0x0f,0xff,
0x01,0x00,0xfe,0xc3,0x7f,0x00,0x80,0xff,0xf0,0x1f,0x00,0xe0,0x3f,0x00,0x00,0xfc,
0x07,0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xc0,0x7f,0x00,
0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,0x80,
0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,0xff,
0xe1,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,
0x00,0x00,0xff,0xe1,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,
0xfc,0x87,0xff,0x00,0x00,0xff,0xe1,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,
0xfe,0x03,0x00,0xfc,0xc7,0xfe,0x07,0x00,0xfc,0x07,0x00,0x80,0xff,0x00,0x00,0xf0,
0x1f,0x00,0x00,0xfe,0x03,0x00,0xc0,0x7f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,
0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,
0xfe,0x03,0x00,0xc0,0x7f,0x00,0x80,0xff,0xf0,0x1f,0x00,0xe0,0x3f,0xfc,0x07,0x00,
0xf8,0x0f,0xff,0x01,0x00,0xfe,0xc3,0x7f,0x00,0x80,0xff,0xf0,0x1f,0x00,0xe0,0x3f,
0xfc,0x07,0x00,0xf8,0x0f,0xff,0x01,0x00,0xfe,0xc3,0x7f,0x00,0x80,0xff,0xf0,0x1f,
0x00,0xe0,0x3f,0xfc,0x07,0x00,0xf8,0x0f,0xff,0x01,0x00,0xfe,0xc3,0x7f,0x00,0x80,
0xff,0xd8,0xff,0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xc0,
0x7f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,0x00,0x00,0xfc,0x07,
0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,0xc0,0x7f,0x00,0x00,
0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,0xff,0xe1,0x3f,
0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,
0xff,0xe1,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,
0xff,0x00,0x00,0xff,0xe1,0x3f,0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0x00,0x00,
0xfe,0x03,0x00,0xc0,0x7f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,
0x00,0x00,0xfc,0x07,0x00,0x80,0xff,0x00,0x00,0xf0,0x1f,0x00,0x00,0xfe,0x03,0x00,
0xc0,0x7f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xff,0x01,0x00,0xe0,0x3f,0x00,0xc0,0x7f,
0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,0xff,0xe1,0x3f,
0x00,0xc0,0x7f,0xf8,0x0f,0x00,0xf0,0x1f,0xfe,0x03,0x00,0xfc,0x87,0xff,0x00,0x00,
0xff,0x95,0xe0,0xbf,0x11,0x19,0x31,0x00,0x00,0x95,0xa3,0x82,0xfe,0x0b,0x74,0xfd,
0x00,0x00,0x95,0x62,0x51,0xfd,0xf7,0x38,0x11,0xf6,0x3f,0x00,0x54,0xd6,0x7f,0x8f,
0x6d,0xdc,0x49,0xe5,0xf5,0xdf,0xa3,0x44,0xa8,0x7b,0x03,0x40,0x65,0x79,0x64,0xe3,
0x4e,0x2a,0xaf,0xff,0x26,0x12,0xb9,0x1d,0xdc,0x36,0x00,0x00,0x15,0x43,0x26,0x6c,
0xdc,0x49,0xf8,0x0f,0x00,0xf0,0x5f,0x39,0xf2,0x30,0x91,0xdb,0xe2,0xd6,0x0f,0x00,
0x50,0x29,0x1e,0xda,0xb8,0x93,0xca,0xeb,0xbf,0xf1,0x44,0x86,0x83,0x61,0x03,0x00,
0x50,0x31,0x64,0xdc,0xc6,0x9d,0x54,0x5e,0xff,0x8d,0x25,0x32,0x2c,0x6e,0xfd,0x00,
0x00,0x95,0x62,0xcc,0xc6,0x9d,0x54,0x5e,0xff,0x3d,0x48,0x64,0x48,0x86,0x0c,0x00,
0x40,0xe5,0x78,0x60,0xe3,0x4e,0x2a,0xaf,0xff,0xee,0x27,0xc2,0xbe,0x07,0x80,0xca,
0x72,0xdf,0xc6,0x9d,0x54,0x5e,0xff,0xdd,0x4b,0x64,0x50,0x06,0x0d,0x00,0x40,0xe5,
0xb8,0x67,0xe3,0x4e,0x2a,0xaf,0xff,0xee,0x26,0xa2,0xeb,0xb7,0x00,0x00,0x95,0xe3,
0xae,0x8d,0x3b,0xa9,0xbc,0xfe,0xbb,0x93,0xc8,0x80,0x0c,0x18,0x00,0x80,0xca,0x71,
0xc7,0xc6,0x9d,0x54,0x5e,0xff,0x8d,0x24,0xa2,0xeb,0xb7,0x00,0x00,0x95,0x63,0xc4,
0xc6,0x9d,0x54,0x5e,0xff,0xdd,0x4e,0xa4,0x5f,0xfa,0x0d,0x00,0x40,0xe5,0xb8,0x6d,
0xe3,0x4e,0x5a,0x64,0xff,0x59,0x00,0x80,0xca,0x31,0x6c,0x87,0x65,0x2a,0xe5,0xf5,
0xdf,0x60,0x22,0xb7,0xe4,0x96,0x05,0x00,0xa8,0x1c,0xbe,0x1f,0x24,0x9f,0xf2,0xfa,
0x6f,0x20,0x11,0xf6,0x3d,0x00,0x54,0x16,0x7f,0x1d,0x30,0x6f,0xa4,0x72,0xfb,0xaf,
0x3f,0x96,0x3e,0xe9,0xb3,0x00,0x00,0x95,0xc3,0xb7,0x83,0xa3,0x74,0x95,0xd9,0x7f,
0xde,0x79,0xf1,0xb0,0xff,0x01,0xa0,0xd2,0x44,0xb9,0x5a,0xf6,0xfa,0xdf,0xcd,0x64,
0x2c,0x00,0x40,0x85,0x89,0x72,0xae,0xec,0xfd,0x1f,0x3d,0x89,0xb0,0xef,0x01,0xa0,
0x72,0x24,0x7d,0x54,0x57,0x66,0xff,0x2d,0xd3,0x75,0x74,0xc7,0xd2,0x23,0xbd,0xd2,
0x6b,0x01,0x00,0x16,0x9f,0x1e,0x1b,0xb7,0x51,0x67,0xd9,0xed,0xb7,0x4c,0x7d,0xd7,
0x99,0x48,0x37,0xc7,0x01,0x00,0x2a,0x80,0x1a,0xcf,0xc6,0x5d,0x74,0x69,0x11,0xfc,
0xd7,0x2f,0x37,0x0a,0xd2,0xe5,0xea,0xa0,0x00,0x00,0x8b,0x48,0x97,0x2d,0x34,0xd1,
0xa9,0x45,0xf0,0x9f,0x6b,0x01,0x77,0x14,0xe4,0x86,0x74,0x73,0x3c,0x00,0x60,0x91,
0xe8,0x56,0xf7,0x15,0x5a,0xe8,0xc2,0xa2,0xd8,0x6f,0x99,0x0c,0xe9,0xba,0xda,0xa6,
0xa5,0x43,0x7d,0xdc,0xcd,0xb1,0x01,0x80,0x32,0xd2,0x2d,0x5d,0xce,0x3f,0xb6,0xd0,
0x3f,0x2d,0x8b,0x64,0x3f,0x97,0x5b,0xd2,0x4a,0x08,0x21,0x55,0x93,0x93,0x8b,0xe8,
0xbf,0x65,0xd2,0x2d,0xd7,0x08,0x21,0xa4,0x2a,0x72,0x76,0x51,0xed,0xe7,0xd2,0x21,
0x17,0x09,0x21,0xa4,0xe2,0x39,0xbd,0xe8,0xf6,0x73,0xe9,0x92,0x0b,0x52,0x4f,0x08,
0x21,0x15,0xcb,0x29,0x39,0x22,0xb5,0x15,0xf1,0x9f,0x4b,0xb3,0x1c,0x27,0x84,0x90,
0x8a,0xe4,0x88,0x1c,0xd2,0x2c,0xab,0x60,0xda,0xe5,0x9c,0x1c,0x56,0x03,0x13,0x42,
0xc8,0xe2,0xc5,0x99,0xef,0xb0,0xcf,0xb2,0x8a,0xa7,0x5b,0xae,0x68,0x5d,0xf4,0x98,
0xec,0x23,0x84,0x90,0xb2,0xe5,0x80,0x1c,0xf4,0xde,0x3b,0x92,0xcf,0x32,0x42,0x08,
0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,
0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,
0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x54,
0x79,0xfe,0x3f,0x57,0x9d,0xaa,0x31};

View File

@ -1,33 +1,18 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Unzip - borrowed from the GPP
*
* softdev July 2006
* Michniewski 2008
* Tantric September 2008
*
* unzip.cpp
*
* File unzip routines
***************************************************************************/
****************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
extern "C" {
#include "../sz/7zCrc.h"
#include "../sz/7zIn.h"
#include "../sz/7zExtract.h"
}
#include "snes9xGX.h"
#include "dvd.h"
#include "smbop.h"
#include "fileop.h"
#include "video.h"
#include "menudraw.h"
#include "ftfont.h"
#include "unzip.h"
/*
@ -44,25 +29,25 @@ extern "C" {
u32
FLIP32 (u32 b)
{
unsigned int c;
unsigned int c;
c = (b & 0xff000000) >> 24;
c |= (b & 0xff0000) >> 8;
c |= (b & 0xff00) << 8;
c |= (b & 0xff) << 24;
c = (b & 0xff000000) >> 24;
c |= (b & 0xff0000) >> 8;
c |= (b & 0xff00) << 8;
c |= (b & 0xff) << 24;
return c;
return c;
}
u16
FLIP16 (u16 b)
{
u16 c;
u16 c;
c = (b & 0xff00) >> 8;
c |= (b & 0xff) << 8;
c = (b & 0xff00) >> 8;
c |= (b & 0xff) << 8;
return c;
return c;
}
/****************************************************************************
@ -73,487 +58,127 @@ FLIP16 (u16 b)
int
IsZipFile (char *buffer)
{
unsigned int *check;
unsigned int *check;
check = (unsigned int *) buffer;
check = (unsigned int *) buffer;
if (check[0] == PKZIPID)
return 1;
if (check[0] == PKZIPID)
return 1;
return 0;
return 0;
}
/*****************************************************************************
* UnZipBuffer
*
* It should be noted that there is a limit of 5MB total size for any ROM
******************************************************************************/
/*****************************************************************************
* unzip
*
* It should be noted that there is a limit of 5MB total size for any ROM
******************************************************************************/
int
UnZipBuffer (unsigned char *outbuffer, int method)
UnZipBuffer (unsigned char *outbuffer, u64 discoffset, short where, FILE* filehandle)
{
PKZIPHEADER pkzip;
int zipoffset = 0;
int zipchunk = 0;
char out[ZIPCHUNK];
z_stream zs;
int res;
int bufferoffset = 0;
int readoffset = 0;
int have = 0;
char readbuffer[ZIPCHUNK];
u64 discoffset = 0;
PKZIPHEADER pkzip;
int zipoffset = 0;
int zipchunk = 0;
char out[ZIPCHUNK];
z_stream zs;
int res;
int bufferoffset = 0;
int have = 0;
char readbuffer[2048];
char msg[128];
// Read Zip Header
switch (method)
{
case METHOD_SD:
case METHOD_USB:
fseek(fatfile, 0, SEEK_SET);
fread (readbuffer, 1, ZIPCHUNK, fatfile);
break;
case METHOD_DVD:
discoffset = dvddir;
dvd_read (readbuffer, ZIPCHUNK, discoffset);
break;
case METHOD_SMB:
SMB_ReadFile(readbuffer, ZIPCHUNK, 0, smbfile);
break;
}
/*** Read Zip Header ***/
switch (where) {
case 0: // SD Card
fseek(filehandle, 0, SEEK_SET);
fread (readbuffer, 1, 2048, filehandle); break;
case 1: // DVD
dvd_read (readbuffer, 2048, discoffset); break;
}
/*** Copy PKZip header to local, used as info ***/
memcpy (&pkzip, readbuffer, sizeof (PKZIPHEADER));
memcpy (&pkzip, readbuffer, sizeof (PKZIPHEADER));
pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);
ShowProgress ((char *)"Loading...", 0, pkzip.uncompressedSize);
pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);
sprintf (msg, "Unzipping %d bytes ... Wait",
pkzip.uncompressedSize);
ShowAction (msg);
/*** Prepare the zip stream ***/
memset (&zs, 0, sizeof (z_stream));
zs.zalloc = Z_NULL;
zs.zfree = Z_NULL;
zs.opaque = Z_NULL;
zs.avail_in = 0;
zs.next_in = Z_NULL;
res = inflateInit2 (&zs, -MAX_WBITS);
memset (&zs, 0, sizeof (z_stream));
zs.zalloc = Z_NULL;
zs.zfree = Z_NULL;
zs.opaque = Z_NULL;
zs.avail_in = 0;
zs.next_in = Z_NULL;
res = inflateInit2 (&zs, -MAX_WBITS);
if (res != Z_OK)
return 0;
if (res != Z_OK)
return 0;
/*** Set ZipChunk for first pass ***/
zipoffset =
(sizeof (PKZIPHEADER) + FLIP16 (pkzip.filenameLength) +
FLIP16 (pkzip.extraDataLength));
zipchunk = ZIPCHUNK - zipoffset;
zipoffset =
(sizeof (PKZIPHEADER) + FLIP16 (pkzip.filenameLength) +
FLIP16 (pkzip.extraDataLength));
zipchunk = ZIPCHUNK - zipoffset;
/*** Now do it! ***/
do
{
zs.avail_in = zipchunk;
zs.next_in = (Bytef *) & readbuffer[zipoffset];
do
{
zs.avail_in = zipchunk;
zs.next_in = (Bytef *) & readbuffer[zipoffset];
/*** Now inflate until input buffer is exhausted ***/
do
{
zs.avail_out = ZIPCHUNK;
zs.next_out = (Bytef *) & out;
do
{
zs.avail_out = ZIPCHUNK;
zs.next_out = (Bytef *) & out;
res = inflate (&zs, Z_NO_FLUSH);
res = inflate (&zs, Z_NO_FLUSH);
if (res == Z_MEM_ERROR)
{
inflateEnd (&zs);
return 0;
}
if (res == Z_MEM_ERROR)
{
inflateEnd (&zs);
return 0;
}
have = ZIPCHUNK - zs.avail_out;
if (have)
{
have = ZIPCHUNK - zs.avail_out;
if (have)
{
/*** Copy to normal block buffer ***/
memcpy (&outbuffer[bufferoffset], &out, have);
bufferoffset += have;
}
}
while (zs.avail_out == 0);
memcpy (&outbuffer[bufferoffset], &out, have);
bufferoffset += have;
}
// Readup the next 2k block
zipoffset = 0;
zipchunk = ZIPCHUNK;
switch (method)
{
case METHOD_SD:
case METHOD_USB:
fread (readbuffer, 1, ZIPCHUNK, fatfile);
break;
case METHOD_DVD:
readoffset += ZIPCHUNK;
dvd_read (readbuffer, ZIPCHUNK, discoffset+readoffset);
break;
case METHOD_SMB:
readoffset += ZIPCHUNK;
SMB_ReadFile(readbuffer, ZIPCHUNK, readoffset, smbfile);
break;
}
ShowProgress ((char *)"Loading...", bufferoffset, pkzip.uncompressedSize);
}
while (res != Z_STREAM_END);
while (zs.avail_out == 0);
inflateEnd (&zs);
/*** Readup the next 2k block ***/
zipoffset = 0;
zipchunk = ZIPCHUNK;
switch (where) {
case 0: // SD Card
fread (readbuffer, 1, 2048, filehandle); break;
case 1: // DVD
discoffset += 2048;
dvd_read (readbuffer, 2048, discoffset); break;
}
}
while (res != Z_STREAM_END);
if (res == Z_STREAM_END)
{
if (pkzip.uncompressedSize == (u32) bufferoffset)
return bufferoffset;
else
return pkzip.uncompressedSize;
}
inflateEnd (&zs);
if (res == Z_STREAM_END)
{
if (pkzip.uncompressedSize == (u32) bufferoffset)
return bufferoffset;
else
return pkzip.uncompressedSize;
}
return 0;
return 0;
}
/****************************************************************************
* GetFirstZipFilename
*
* Returns the filename of the first file in the zipped archive
* The idea here is to do the least amount of work required
***************************************************************************/
char *
GetFirstZipFilename (int method)
{
char * firstFilename = NULL;
char tempbuffer[ZIPCHUNK];
// read start of ZIP
switch (method)
{
case METHOD_SD: // SD Card
case METHOD_USB: // USB
LoadFATFile (tempbuffer, ZIPCHUNK);
break;
case METHOD_DVD: // DVD
LoadDVDFile ((unsigned char *)tempbuffer, ZIPCHUNK);
break;
case METHOD_SMB: // From SMB
LoadSMBFile (tempbuffer, ZIPCHUNK);
break;
}
tempbuffer[28] = 0; // truncate - filename length is 2 bytes long (bytes 26-27)
int namelength = tempbuffer[26]; // filename length starts 26 bytes in
firstFilename = &tempbuffer[30]; // first filename of a ZIP starts 31 bytes in
firstFilename[namelength] = 0; // truncate at filename length
return firstFilename;
}
/****************************************************************************
* 7z functions
***************************************************************************/
typedef struct _SzFileInStream
{
ISzInStream InStream;
u64 offset; // offset of the file
unsigned int len; // length of the file
u64 pos; // current position of the file pointer
} SzFileInStream;
// 7zip error list
char szerrormsg[][30] = {
"7z: Data error",
"7z: Out of memory",
"7z: CRC Error",
"7z: Not implemented",
"7z: Fail",
"7z: Archive error",
"7z: Dictionary too large",
};
SZ_RESULT SzRes;
SzFileInStream SzArchiveStream;
CArchiveDatabaseEx SzDb;
ISzAlloc SzAllocImp;
ISzAlloc SzAllocTempImp;
UInt32 SzBlockIndex = 0xFFFFFFFF;
size_t SzBufferSize;
size_t SzOffset;
size_t SzOutSizeProcessed;
CFileItem *SzF;
char sz_buffer[2048];
int szMethod = 0;
/****************************************************************************
* Is7ZipFile
*
* Returns 1 when 7z signature is found
****************************************************************************/
int
Is7ZipFile (char *buffer)
{
unsigned int *check;
check = (unsigned int *) buffer;
// 7z signature
static Byte Signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
int i;
for(i = 0; i < 6; i++)
if(buffer[i] != Signature[i])
return 0;
return 1; // 7z archive found
}
// display an error message
void SzDisplayError(SZ_RESULT res)
{
WaitPrompt(szerrormsg[(res - 1)]);
}
// function used by the 7zip SDK to read data from SD/USB/DVD/SMB
SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize)
{
// the void* object is a SzFileInStream
SzFileInStream *s = (SzFileInStream *) object;
// calculate offset
u64 offset = (u64) (s->offset + s->pos);
if (maxRequiredSize > 2048)
maxRequiredSize = 2048;
// read data
switch (szMethod)
{
case METHOD_SD:
case METHOD_USB:
fseek(fatfile, offset, SEEK_SET);
fread(sz_buffer, 1, maxRequiredSize, fatfile);
break;
case METHOD_DVD:
dvd_safe_read(sz_buffer, maxRequiredSize, offset);
break;
case METHOD_SMB:
SMB_ReadFile(sz_buffer, maxRequiredSize, offset, smbfile);
break;
}
*buffer = sz_buffer;
*processedSize = maxRequiredSize;
s->pos += *processedSize;
if(maxRequiredSize > 1024) // only show progress for large reads
// this isn't quite right, but oh well
ShowProgress ((char *)"Loading...", s->pos, filelist[selection].length);
return SZ_OK;
}
// function used by the 7zip SDK to change the filepointer
SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
{
// the void* object is a SzFileInStream
SzFileInStream *s = (SzFileInStream *) object;
// check if the 7z SDK wants to move the pointer to somewhere after the EOF
if (pos >= s->len)
{
WaitPrompt((char *) "7z: Error - attempt to read after EOF!");
return SZE_FAIL;
}
// save new position and return
s->pos = pos;
return SZ_OK;
}
/****************************************************************************
* SzParse
*
* Opens a 7z file, and parses it
* Right now doesn't parse 7z, since we'll always use the first file
* But it could parse the entire 7z for full browsing capability
***************************************************************************/
int SzParse(char * filepath, int method)
{
int nbfiles = 0;
// save the offset and the length of this file inside the archive stream structure
SzArchiveStream.offset = filelist[selection].offset;
SzArchiveStream.len = filelist[selection].length;
SzArchiveStream.pos = 0;
// open file
switch (method)
{
case METHOD_SD:
case METHOD_USB:
fatfile = fopen (filepath, "rb");
if(!fatfile)
return 0;
break;
case METHOD_SMB:
smbfile = OpenSMBFile(filepath);
if(!smbfile)
return 0;
break;
}
// set szMethod to current chosen load method
szMethod = method;
// set handler functions for reading data from FAT/SMB/DVD
SzArchiveStream.InStream.Read = SzFileReadImp;
SzArchiveStream.InStream.Seek = SzFileSeekImp;
// set default 7Zip SDK handlers for allocation and freeing memory
SzAllocImp.Alloc = SzAlloc;
SzAllocImp.Free = SzFree;
SzAllocTempImp.Alloc = SzAllocTemp;
SzAllocTempImp.Free = SzFreeTemp;
// prepare CRC and 7Zip database structures
InitCrcTable();
SzArDbExInit(&SzDb);
// open the archive
SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp,
&SzAllocTempImp);
if (SzRes != SZ_OK)
{
SzDisplayError(SzRes);
// free memory used by the 7z SDK
SzClose();
}
else // archive opened successfully
{
if(SzDb.Database.NumFiles > 0)
{
// Parses the 7z into a full file listing
// erase all previous entries
memset(&filelist, 0, sizeof(FILEENTRIES) * MAXFILES);
// add '..' folder in case the user wants exit the 7z
strncpy(filelist[0].displayname, "..", 2);
filelist[0].flags = 1;
filelist[0].offset = dvddir;
filelist[0].length = dvddirlength;
// get contents and parse them into file list structure
unsigned int SzI, SzJ;
SzJ = 1;
for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++)
{
SzF = SzDb.Database.Files + SzI;
// skip directories
if (SzF->IsDirectory)
continue;
// do not exceed MAXFILES to avoid possible buffer overflows
if (SzJ == (MAXFILES - 1))
break;
// parse information about this file to the dvd file list structure
strncpy(filelist[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...)
filelist[SzJ].filename[MAXJOLIET] = 0; // terminate string
strncpy(filelist[SzJ].displayname, SzF->Name, MAXDISPLAY+1); // crop name for display
filelist[SzJ].length = SzF->Size; // filesize
filelist[SzJ].offset = SzI; // the extraction function identifies the file with this number
filelist[SzJ].flags = 0; // only files will be displayed (-> no flags)
SzJ++;
}
// update maxfiles and select the first entry
offset = selection = 0;
nbfiles = SzJ;
}
else
{
SzArDbExFree(&SzDb, SzAllocImp.Free);
}
}
// close file
switch (method)
{
case METHOD_SD:
case METHOD_USB:
fclose(fatfile);
break;
case METHOD_SMB:
SMB_CloseFile (smbfile);
break;
}
return nbfiles;
}
/****************************************************************************
* SzClose
*
* Closes a 7z file
***************************************************************************/
void SzClose()
{
if(SzDb.Database.NumFiles > 0)
SzArDbExFree(&SzDb, SzAllocImp.Free);
}
/****************************************************************************
* SzExtractFile
*
* Extracts the given file # into the buffer specified
* Must parse the 7z BEFORE running this function
***************************************************************************/
int SzExtractFile(int i, unsigned char *buffer)
{
// prepare some variables
SzBlockIndex = 0xFFFFFFFF;
SzOffset = 0;
// Unzip the file
SzRes = SzExtract2(
&SzArchiveStream.InStream,
&SzDb,
i, // index of file
&SzBlockIndex, // index of solid block
&buffer,
&SzBufferSize,
&SzOffset, // offset of stream for required file in *outBuffer
&SzOutSizeProcessed, // size of file in *outBuffer
&SzAllocImp,
&SzAllocTempImp);
// close 7Zip archive and free memory
SzClose();
// check for errors
if(SzRes != SZ_OK)
{
// display error message
SzDisplayError(SzRes);
return 0;
}
else
{
return SzOutSizeProcessed;
}
}

View File

@ -1,26 +1,15 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Unzip - borrowed from the GPP
*
* softdev July 2006
* Michniewski 2008
* Tantric September 2008
*
* unzip.h
*
* File unzip routines
****************************************************************************/
#ifndef _UNZIP_
#define _UNZIP_
#include <smb.h>
extern int IsZipFile (char *buffer);
char * GetFirstZipFilename(int method);
int UnZipBuffer (unsigned char *outbuffer, int method);
int SzParse(char * filepath, int method);
int SzExtractFile(int i, unsigned char *buffer);
void SzClose();
int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, short where, FILE* filehandle);
/*
* Zip file header definition
*/

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,28 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
* Snes9x 1.50
*
* Nintendo Gamecube Video
*
* This is a modified renderer from the Genesis Plus Project.
* Well - you didn't expect me to write another one did ya ? -;)
*
* softdev July 2006
* Michniewski 2008
*
* video.h
*
* Video routines
***************************************************************************/
****************************************************************************/
#ifndef _GCVIDEOH_
#define _GCVIDEOH_
//#include <gccore.h>
#include <ogcsys.h>
#include "snes9x.h"
void InitGCVideo ();
void ResetVideo_Emu ();
void ResetVideo_Menu ();
void ReInitGCVideo();
void clearscreen (int colour = COLOR_WHITE);
void showscreen ();
void setGFX ();
void update_video (int width, int height);
void clearscreen (int colour = COLOR_BLACK);
void showscreen ();
void zoom (float speed);
void zoom_reset ();
extern bool progressive;
#ifdef _DEBUG_VIDEO
// log stuff
extern FILE * debughandle;
#endif
void UpdatePadsCB();
#endif

726
source/smb/DES.c Normal file
View File

@ -0,0 +1,726 @@
/* ========================================================================== **
*
* DES.c
*
* Copyright:
* Copyright (C) 2003, 2004 by Christopher R. Hertel
*
* Email: crh@ubiqx.mn.org
*
* $Id: DES.c,v 0.6 2004/05/30 05:41:20 crh Exp $
*
* -------------------------------------------------------------------------- **
*
* Description:
*
* Implements DES encryption, but not decryption.
* DES is used to create LM password hashes and both LM and NTLM Responses.
*
* -------------------------------------------------------------------------- **
*
* License:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* -------------------------------------------------------------------------- **
*
* Notes:
*
* This implementation was created by studying many existing examples
* found in Open Source, in the public domain, and in various documentation.
* The SMB protocol makes minimal use of the DES function, so this is a
* minimal implementation. That which is not required has been removed.
*
* The SMB protocol uses the DES algorithm as a hash function, not an
* encryption function. The auth_DEShash() implemented here is a one-way
* function. The reverse is not implemented in this module. Also, there
* is no attempt at making this either fast or efficient. There is no
* need, as the auth_DEShash() function is used for generating the LM
* Response from a 7-byte key and an 8-byte challenge. It is not intended
* for use in encrypting large blocks of data or data streams.
*
* As stated above, this implementation is based on studying existing work
* in the public domain or under Open Source (specifically LGPL) license.
* The code, however, is written from scratch. Obviously, I make no claim
* with regard to those earlier works (except to claim that I am grateful
* to the previous implementors whose work I studied). See the list of
* references below for resources I used.
*
* References:
* I read through the libmcrypt code to see how they put the pieces
* together. See: http://mcrypt.hellug.gr/
* Libmcrypt is available under the terms of the LGPL.
*
* The libmcrypt implementation includes the following credits:
* written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted
* from the 1977 public-domain program by Jim Gillogly
* Modified for additional speed - 6 December 1988 Phil Karn
* Modified for parameterized key schedules - Jan 1991 Phil Karn
* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*
* See also Phil Karn's privacy and security page:
* http://www.ka9q.net/privacy.html
*
* I relied heavily upon:
* Applied Cryptography, Second Edition:
* Protocols, Algorithms, and Source Code in C
* by Bruce Schneier. ISBN 0-471-11709-9, John Wiley & Sons, Inc., 1996
* Particularly Chapter 12.
*
* Here's one more DES resource, which I found quite helpful (aside from
* the Clinton jokes):
* http://www.aci.net/kalliste/des.htm
*
* Finally, the use of DES in SMB is covered in:
* Implementing CIFS - the Common Internet File System
* by your truly. ISBN 0-13-047116-X, Prentice Hall PTR., August 2003
* Section 15.3, in particular.
* (Online at: http://ubiqx.org/cifs/SMB.html#SMB.8.3)
*
* ========================================================================== **
*/
#include "DES.h"
/* -------------------------------------------------------------------------- **
* Static Constants:
*/
/* Initial permutation map.
* In the first step of DES, the bits of the initial plaintext are rearranged
* according to the map given below. This map and those like it are read by
* the Permute() function (below) which uses the maps as a guide when moving
* bits from one place to another.
*
* Note that the values here are all one less than those shown in Schneier.
* That's because C likes to start counting from 0, not 1.
*
* According to Schneier (Ch12, pg 271), the purpose of the initial
* permutation was to make it easier to load plaintext and ciphertext into
* a DES ecryption chip. I have no idea why that would be the case.
*/
static const uint8_t InitialPermuteMap[64] =
{
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7,
56, 48, 40, 32, 24, 16, 8, 0,
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6
};
/* Key permutation map.
* Like the input data and encryption result, the key is permuted before
* the algorithm really gets going. The original algorithm called for an
* eight-byte key in which each byte contained a parity bit. During the
* key permutiation, the parity bits were discarded. The DES algorithm,
* as used with SMB, does not make use of the parity bits. Instead, SMB
* passes 7-byte keys to DES. For DES implementations that expect parity,
* the parity bits must be added. In this case, however, we're just going
* to start with a 7-byte (56 bit) key. KeyPermuteMap, below, is adjusted
* accordingly and, of course, each entry in the map is reduced by 1 with
* respect to the documented values because C likes to start counting from
* 0, not 1.
*/
static const uint8_t KeyPermuteMap[56] =
{
49, 42, 35, 28, 21, 14, 7, 0,
50, 43, 36, 29, 22, 15, 8, 1,
51, 44, 37, 30, 23, 16, 9, 2,
52, 45, 38, 31, 55, 48, 41, 34,
27, 20, 13, 6, 54, 47, 40, 33,
26, 19, 12, 5, 53, 46, 39, 32,
25, 18, 11, 4, 24, 17, 10, 3,
};
/* Key rotation table.
* At the start of each round of encryption, the key is split and each
* 28-bit half is rotated left. The number of bits of rotation per round
* is given in the table below.
*/
static const uint8_t KeyRotation[16] =
{ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
/* Key compression table.
* This table is used to select 48 of the 56 bits of the key.
* The left and right halves of the source text are each 32 bits,
* but they are expanded to 48 bits and the results are XOR'd
* against the compressed (48-bit) key.
*/
static const uint8_t KeyCompression[48] =
{
13, 16, 10, 23, 0, 4, 2, 27,
14, 5, 20, 9, 22, 18, 11, 3,
25, 7, 15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54, 29, 39,
50, 44, 32, 47, 43, 48, 38, 55,
33, 52, 45, 41, 49, 35, 28, 31
};
/* Data expansion table.
* This table is used after the data block (64-bits) has been split
* into two 32-bit (4-byte) halves (generally denoted L and R).
* Each 32-bit half is "expanded", using this table, to a 48 bit
* data block, which is then XOR'd with the 48 bit subkey for the
* round.
*/
static const uint8_t DataExpansion[48] =
{
31, 0, 1, 2, 3, 4, 3, 4,
5, 6, 7, 8, 7, 8, 9, 10,
11, 12, 11, 12, 13, 14, 15, 16,
15, 16, 17, 18, 19, 20, 19, 20,
21, 22, 23, 24, 23, 24, 25, 26,
27, 28, 27, 28, 29, 30, 31, 0
};
/* The (in)famous S-boxes.
* These are used to perform substitutions.
* Six bits worth of input will return four bits of output.
* The four bit values are stored in these tables. Each table has
* 64 entries...and 6 bits provides a number between 0 and 63.
* There are eight S-boxes, one per 6 bits of a 48-bit value.
* Thus, 48 bits are reduced to 32 bits. Obviously, this step
* follows the DataExpansion step.
*
* Note that the literature generally shows this as 8 arrays each
* with four rows and 16 colums. There is a complex formula for
* mapping the 6 bit input values to the correct row and column.
* I've pre-computed that mapping, and the tables below provide
* direct 6-bit input to 4-bit output. See pp 274-274 in Schneier.
*/
static const uint8_t SBox[8][64] =
{
{ /* S0 */
14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13
},
{ /* S1 */
15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9
},
{ /* S2 */
10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12
},
{ /* S3 */
7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14
},
{ /* S4 */
2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3
},
{ /* S5 */
12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13
},
{ /* S6 */
4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12
},
{ /* S7 */
13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
}
};
/* P-Box permutation.
* This permutation is applied to the result of the S-Box Substitutions.
* It's a straight-forward re-arrangement of the bits.
*/
static const uint8_t PBox[32] =
{
15, 6, 19, 20, 28, 11, 27, 16,
0, 14, 22, 25, 4, 17, 30, 9,
1, 7, 23, 13, 31, 26, 2, 8,
18, 12, 29, 5, 21, 10, 3, 24
};
/* Final permutation map.
* This is supposed to be the inverse of the Initial Permutation,
* but there's been a bit of fiddling done.
* As always, the values given are one less than those in the literature
* (because C starts counting from 0, not 1). In addition, the penultimate
* step in DES is to swap the left and right hand sides of the ciphertext.
* The inverse of the Initial Permutation is then applied to produce the
* final result.
* To save a step, the map below does the left/right swap as well as the
* inverse permutation.
*/
static const uint8_t FinalPermuteMap[64] =
{
7, 39, 15, 47, 23, 55, 31, 63,
6, 38, 14, 46, 22, 54, 30, 62,
5, 37, 13, 45, 21, 53, 29, 61,
4, 36, 12, 44, 20, 52, 28, 60,
3, 35, 11, 43, 19, 51, 27, 59,
2, 34, 10, 42, 18, 50, 26, 58,
1, 33, 9, 41, 17, 49, 25, 57,
0, 32, 8, 40, 16, 48, 24, 56
};
/* -------------------------------------------------------------------------- **
* Macros:
*
* CLRBIT( STR, IDX )
* Input: STR - (uchar *) pointer to an array of 8-bit bytes.
* IDX - (int) bitwise index of a bit within the STR array
* that is to be cleared (that is, given a value of 0).
* Notes: This macro clears a bit within an array of bits (which is
* built within an array of bytes).
* - The macro converts to an assignment of the form A &= B.
* - The string of bytes is viewed as an array of bits, read from
* highest order bit first. The highest order bit of a byte
* would, therefore, be bit 0 (within that byte).
*
* SETBIT( STR, IDX )
* Input: STR - (uchar *) pointer to an array of 8-bit bytes.
* IDX - (int) bitwise index of a bit within the STR array
* that is to be set (that is, given a value of 1).
* Notes: This macro sets a bit within an array of bits (which is
* built within an array of bytes).
* - The macro converts to an assignment of the form A |= B.
* - The string of bytes is viewed as an array of bits, read from
* highest order bit first. The highest order bit of a byte
* would, therefore, be bit 0 (within that byte).
*
* GETBIT( STR, IDX )
* Input: STR - (uchar *) pointer to an array of 8-bit bytes.
* IDX - (int) bit-wise index of a bit within the STR array
* that is to be read.
* Output: True (1) if the indexed bit was set, else false (0).
*
* -------------------------------------------------------------------------- **
*/
#define CLRBIT( STR, IDX ) ( (STR)[(IDX)/8] &= ~(0x01 << (7 - ((IDX)%8))) )
#define SETBIT( STR, IDX ) ( (STR)[(IDX)/8] |= (0x01 << (7 - ((IDX)%8))) )
#define GETBIT( STR, IDX ) (( ((STR)[(IDX)/8]) >> (7 - ((IDX)%8)) ) & 0x01)
/* -------------------------------------------------------------------------- **
* Static Functions:
*/
static void Permute( uchar *dst,
const uchar *src,
const uint8_t *map,
const int mapsize )
/* ------------------------------------------------------------------------ **
* Performs a DES permutation, which re-arranges the bits in an array of
* bytes.
*
* Input: dst - Destination into which to put the re-arranged bits.
* src - Source from which to read the bits.
* map - Permutation map.
* mapsize - Number of bytes represented by the <map>. This also
* represents the number of bytes to be copied to <dst>.
*
* Output: none.
*
* Notes: <src> and <dst> must not point to the same location.
*
* - No checks are done to ensure that there is enough room
* in <dst>, or that the bit numbers in <map> do not exceed
* the bits available in <src>. A good reason to make this
* function static (private).
*
* - The <mapsize> value is in bytes. All permutations in DES
* use tables that are a multiple of 8 bits, so there is no
* need to handle partial bytes. (Yes, I know that there
* are some machines out there that still use bytes of a size
* other than 8 bits. For our purposes we'll stick with 8-bit
* bytes.)
*
* ------------------------------------------------------------------------ **
*/
{
int bitcount;
int i;
/* Clear all bits in the destination.
*/
for( i = 0; i < mapsize; i++ )
dst[i] = 0;
/* Set destination bit if the mapped source bit it set. */
bitcount = mapsize * 8;
for( i = 0; i < bitcount; i++ )
{
if( GETBIT( src, map[i] ) )
SETBIT( dst, i );
}
} /* Permute */
static void KeyShift( uchar *key, const int numbits )
/* ------------------------------------------------------------------------ **
* Split the 56-bit key in half & left rotate each half by <numbits> bits.
*
* Input: key - The 56-bit key to be split-rotated.
* numbits - The number of bits by which to rotate the key.
*
* Output: none.
*
* Notes: There are probably several better ways to implement this.
*
* ------------------------------------------------------------------------ **
*/
{
int i;
uchar keep = key[0]; /* Copy the highest order bits of the key. */
/* Repeat the shift process <numbits> times.
*/
for( i = 0; i < numbits; i++ )
{
int j;
/* Shift the entire thing, byte by byte.
*/
for( j = 0; j < 7; j++ )
{
if( j && (key[j] & 0x80) ) /* If the top bit of this byte is set. */
key[j-1] |= 0x01; /* ...shift it to last byte's low bit. */
key[j] <<= 1; /* Then left-shift the whole byte. */
}
/* Now move the high-order bits of each 28-bit half-key to their
* correct locations.
* Bit 27 is the lowest order bit of the first half-key.
* Before the shift, it was the highest order bit of the 2nd half-key.
*/
if( GETBIT( key, 27 ) ) /* If bit 27 is set... */
{
CLRBIT( key, 27 ); /* ...clear bit 27. */
SETBIT( key, 55 ); /* ...set lowest order bit of 2nd half-key. */
}
/* We kept the highest order bit of the first half-key in <keep>.
* If it's set, copy it to bit 27.
*/
if( keep & 0x80 )
SETBIT( key, 27 );
/* Rotate the <keep> byte too, in case <numbits> is 2 and there's
* a second round coming.
*/
keep <<= 1;
}
} /* KeyShift */
static void sbox( uchar *dst, const uchar *src )
/* ------------------------------------------------------------------------ **
* Perform S-Box substitutions.
*
* Input: dst - Destination byte array into which the S-Box substituted
* bitmap will be written.
* src - Source byte array.
*
* Output: none.
*
* Notes: It's really not possible (for me, anyway) to understand how
* this works without reading one or more detailed explanations.
* Quick overview, though:
*
* After the DataExpansion step (in which a 32-bit bit array is
* expanded to a 48-bit bit array) the expanded data block is
* XOR'd with 48-bits worth of key. That 48 bits then needs to
* be condensed back into 32 bits.
*
* The S-Box substitution handles the data reduction by breaking
* the 48-bit value into eight 6-bit values. For each of these
* 6-bit values there is a table (an S-Box table). The table
* contains 64 possible values. Conveniently, a 6-bit integer
* can represent a value between 0 and 63.
*
* So, if you think of the 48-bit bit array as an array of 6-bit
* integers, you use S-Box table 0 with the 0th 6-bit value.
* Table 1 is used with the 6-bit value #1, and so on until #7.
* Within each table, the correct substitution is found based
* simply on the value of the 6-bit integer.
*
* Well, the original algorithm (and most documentation) don't
* make it so simple. There's a complex formula for mapping
* the 6-bit values to the correct substitution. Fortunately,
* those lookups can be precomputed (and have been for this
* implementation). See pp 274-274 in Schneier.
*
* Oh, and the substitute values are all 4-bit values, so each
* 6-bits gets reduced to 4-bits resulting in a 32-bit bit array.
*
* ------------------------------------------------------------------------ **
*/
{
int i;
/* Clear the destination array.
*/
for( i = 0; i < 4; i++ )
dst[i] = 0;
/* For each set of six input bits...
*/
for( i = 0; i < 8; i++ )
{
int j;
int Snum;
int bitnum;
/* Extract the 6-bit integer from the source.
* This will be the lookup key within the SBox[i] array.
*/
for( Snum = j = 0, bitnum = (i * 6); j < 6; j++, bitnum++ )
{
Snum <<= 1;
Snum |= GETBIT( src, bitnum );
}
/* Find the correct value in the correct SBox[]
* and copy it into the destination.
* Left shift the nibble four bytes for even values of <i>.
*/
if( 0 == (i%2) )
dst[i/2] |= ((SBox[i][Snum]) << 4);
else
dst[i/2] |= SBox[i][Snum];
}
} /* sbox */
static void xor( uchar *dst, const uchar *a, const uchar *b, const int count )
/* ------------------------------------------------------------------------ **
* Perform an XOR operation on two byte arrays.
*
* Input: dst - Destination array to which the result will be written.
* a - The first string of bytes.
* b - The second string of bytes.
* count - Number of bytes to XOR against one another.
*
* Output: none.
*
* Notes: This function operates on whole byte chunks. There's no need
* to XOR partial bytes so no need to write code to handle it.
*
* - This function essentially implements dst = a ^ b; for byte
* arrays.
*
* - <dst> may safely point to the same location as <a> or <b>.
*
* ------------------------------------------------------------------------ **
*/
{
int i;
for( i = 0; i < count; i++ )
dst[i] = a[i] ^ b[i];
} /* xor */
/* -------------------------------------------------------------------------- **
* Functions:
*/
uchar *auth_DESkey8to7( uchar *dst, const uchar *key )
/* ------------------------------------------------------------------------ **
* Compress an 8-byte DES key to its 7-byte form.
*
* Input: dst - Pointer to a memory location (minimum 7 bytes) to accept
* the compressed key.
* key - Pointer to an 8-byte DES key. See the notes below.
*
* Output: A pointer to the compressed key (same as <dst>) or NULL if
* either <src> or <dst> were NULL.
*
* Notes: There are no checks done to ensure that <dst> and <key> point
* to sufficient space. Please be carefull.
*
* The two pointers, <dst> and <key> may point to the same
* memory location. Internally, a temporary buffer is used and
* the results are copied back to <dst>.
*
* The DES algorithm uses 8 byte keys by definition. The first
* step in the algorithm, however, involves removing every eigth
* bit to produce a 56-bit key (seven bytes). SMB authentication
* skips this step and uses 7-byte keys. The <auth_DEShash()>
* algorithm in this module expects 7-byte keys. This function
* is used to convert an 8-byte DES key into a 7-byte SMB DES key.
*
* ------------------------------------------------------------------------ **
*/
{
int i;
uchar tmp[7];
static const uint8_t map8to7[56] =
{
0, 1, 2, 3, 4, 5, 6,
8, 9, 10, 11, 12, 13, 14,
16, 17, 18, 19, 20, 21, 22,
24, 25, 26, 27, 28, 29, 30,
32, 33, 34, 35, 36, 37, 38,
40, 41, 42, 43, 44, 45, 46,
48, 49, 50, 51, 52, 53, 54,
56, 57, 58, 59, 60, 61, 62
};
if( (NULL == dst) || (NULL == key) )
return( NULL );
Permute( tmp, key, map8to7, 7 );
for( i = 0; i < 7; i++ )
dst[i] = tmp[i];
return( dst );
} /* auth_DESkey8to7 */
uchar *auth_DEShash( uchar *dst, const uchar *key, const uchar *src )
/* ------------------------------------------------------------------------ **
* DES encryption of the input data using the input key.
*
* Input: dst - Destination buffer. It *must* be at least eight bytes
* in length, to receive the encrypted result.
* key - Encryption key. Exactly seven bytes will be used.
* If your key is shorter, ensure that you pad it to seven
* bytes.
* src - Source data to be encrypted. Exactly eight bytes will
* be used. If your source data is shorter, ensure that
* you pad it to eight bytes.
*
* Output: A pointer to the encrpyted data (same as <dst>).
*
* Notes: In SMB, the DES function is used as a hashing function rather
* than an encryption/decryption tool. When used for generating
* the LM hash the <src> input is the known value "KGS!@#$%" and
* the key is derived from the password entered by the user.
* When used to generate the LM or NTLM response, the <key> is
* derived from the LM or NTLM hash, and the challenge is used
* as the <src> input.
* See: http://ubiqx.org/cifs/SMB.html#SMB.8.3
*
* - This function is called "DEShash" rather than just "DES"
* because it is only used for creating LM hashes and the
* LM/NTLM responses. For all practical purposes, however, it
* is a full DES encryption implementation.
*
* - This DES implementation does not need to be fast, nor is a
* DES decryption function needed. The goal is to keep the
* code small, simple, and well documented.
*
* - The input values are copied and refiddled within the module
* and the result is not written to <dst> until the very last
* step, so it's okay if <dst> points to the same memory as
* <key> or <src>.
*
* ------------------------------------------------------------------------ **
*/
{
int i; /* Loop counter. */
uchar K[7]; /* Holds the key, as we manipulate it. */
uchar D[8]; /* The data block, as we manipulate it. */
/* Create the permutations of the key and the source.
*/
Permute( K, key, KeyPermuteMap, 7 );
Permute( D, src, InitialPermuteMap, 8 );
/* DES encryption proceeds in 16 rounds.
* The stuff inside the loop is known in the literature as "function f".
*/
for( i = 0; i < 16; i++ )
{
int j;
uchar *L = D; /* The left 4 bytes (half) of the data block. */
uchar *R = &(D[4]); /* The right half of the ciphertext block. */
uchar Rexp[6]; /* Expanded right half. */
uchar Rn[4]; /* New value of R, as we manipulate it. */
uchar SubK[6]; /* The 48-bit subkey. */
/* Generate the subkey for this round.
*/
KeyShift( K, KeyRotation[i] );
Permute( SubK, K, KeyCompression, 6 );
/* Expand the right half (R) of the data block to 48 bytes,
* then XOR the result with the Subkey for this round.
*/
Permute( Rexp, R, DataExpansion, 6 );
xor( Rexp, Rexp, SubK, 6 );
/* S-Box substitutions, P-Box permutation, and final XOR.
* The S-Box substitutions return a 32-bit value, which is then
* run through the 32-bit to 32-bit P-Box permutation. The P-Box
* result is then XOR'd with the left-hand half of the key.
* (Rexp is used as a temporary variable between the P-Box & XOR).
*/
sbox( Rn, Rexp );
Permute( Rexp, Rn, PBox, 4 );
xor( Rn, L, Rexp, 4 );
/* The previous R becomes the new L,
* and Rn is moved into R ready for the next round.
*/
for( j = 0; j < 4; j++ )
{
L[j] = R[j];
R[j] = Rn[j];
}
}
/* The encryption is complete.
* Now reverse-permute the ciphertext to produce the final result.
* We actually combine two steps here. The penultimate step is to
* swap the positions of L and R in the result of the 16 rounds,
* after which the reverse of the Initial Permutation is applied.
* To save a step, the FinalPermuteMap applies both the L/R swap
* and the inverse of the Initial Permutation.
*/
Permute( dst, D, FinalPermuteMap, 8 );
return( dst );
} /* auth_DEShash */
/* ========================================================================== */

179
source/smb/DES.h Normal file
View File

@ -0,0 +1,179 @@
#ifndef AUTH_DES_H
#define AUTH_DES_H
/* ========================================================================== **
*
* DES.h
*
* Copyright:
* Copyright (C) 2003, 2004 by Christopher R. Hertel
*
* Email: crh@ubiqx.mn.org
*
* $Id: DES.h,v 0.5 2004/05/30 02:31:47 crh Exp $
*
* -------------------------------------------------------------------------- **
*
* Description:
*
* Implements DES encryption, but not decryption.
* DES is used to create LM password hashes and both LM and NTLM Responses.
*
* -------------------------------------------------------------------------- **
*
* License:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* -------------------------------------------------------------------------- **
*
* Notes:
*
* This implementation was created by studying many existing examples
* found in Open Source, in the public domain, and in various documentation.
* The SMB protocol makes minimal use of the DES function, so this is a
* minimal implementation. That which is not required has been removed.
*
* The SMB protocol uses the DES algorithm as a hash function, not an
* encryption function. The auth_DEShash() implemented here is a one-way
* function. The reverse is not implemented in this module. Also, there
* is no attempt at making this either fast or efficient. There is no
* need, as the auth)DEShash() function is used for generating the LM
* Response from a 7-byte key and an 8-byte challenge. It is not intended
* for use in encrypting large blocks of data or data streams.
*
* As stated above, this implementation is based on studying existing work
* in the public domain or under Open Source (specifically LGPL) license.
* The code, however, is written from scratch. Obviously, I make no claim
* with regard to those earlier works (except to claim that I am grateful
* to the previous implementors whose work I studied). See the list of
* references below for resources I used.
*
* References:
* I read through the libmcrypt code to see how they put the pieces
* together. See: http://mcrypt.hellug.gr/
* Libmcrypt is available under the terms of the LGPL.
*
* The libmcrypt implementation includes the following credits:
* written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted
* from the 1977 public-domain program by Jim Gillogly
* Modified for additional speed - 6 December 1988 Phil Karn
* Modified for parameterized key schedules - Jan 1991 Phil Karn
* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
* All modifications are placed under the license of libmcrypt.
*
* See also Phil Karn's privacy and security page:
* http://www.ka9q.net/privacy.html
*
* I relied heavily upon:
* Applied Cryptography, Second Edition:
* Protocols, Algorithms, and Source Code in C
* by Bruce Schneier. ISBN 0-471-11709-9, John Wiley & Sons, Inc., 1996
* Particularly Chapter 12.
*
* Here's one more DES resource, which I found quite helpful (aside from
* the Clinton jokes):
* http://www.aci.net/kalliste/des.htm
*
* Finally, the use of DES in SMB is covered in:
* Implementing CIFS - the Common Internet File System
* by your truly. ISBN 0-13-047116-X, Prentice Hall PTR., August 2003
* Section 15.3, in particular.
* (Online at: http://ubiqx.org/cifs/SMB.html#SMB.8.3)
*
* ========================================================================== **
*/
//#include "auth_common.h"
#include <stdio.h>
typedef unsigned char uchar;
typedef unsigned char uint8_t;
/* -------------------------------------------------------------------------- **
* Functions:
*/
uchar *auth_DESkey8to7( uchar *dst, const uchar *key );
/* ------------------------------------------------------------------------ **
* Compress an 8-byte DES key to its 7-byte form.
*
* Input: dst - Pointer to a memory location (minimum 7 bytes) to accept
* the compressed key.
* key - Pointer to an 8-byte DES key. See the notes below.
*
* Output: A pointer to the compressed key (same as <dst>) or NULL if
* either <src> or <dst> were NULL.
*
* Notes: There are no checks done to ensure that <dst> and <key> point
* to sufficient space. Please be carefull.
*
* The two pointers, <dst> and <key> may point to the same
* memory location. Internally, a temporary buffer is used and
* the results are copied back to <dst>.
*
* The DES algorithm uses 8 byte keys by definition. The first
* step in the algorithm, however, involves removing every eigth
* bit to produce a 56-bit key (seven bytes). SMB authentication
* skips this step and uses 7-byte keys. The <auth_DEShash()>
* algorithm in this module expects 7-byte keys. This function
* is used to convert an 8-byte DES key into a 7-byte SMB DES key.
*
* ------------------------------------------------------------------------ **
*/
uchar *auth_DEShash( uchar *dst, const uchar *key, const uchar *src );
/* ------------------------------------------------------------------------ **
* DES encryption of the input data using the input key.
*
* Input: dst - Destination buffer. It *must* be at least eight bytes
* in length, to receive the encrypted result.
* key - Encryption key. Exactly seven bytes will be used.
* If your key is shorter, ensure that you pad it to seven
* bytes.
* src - Source data to be encrypted. Exactly eight bytes will
* be used. If your source data is shorter, ensure that
* you pad it to eight bytes.
*
* Output: A pointer to the encrpyted data (same as <dst>).
*
* Notes: In SMB, the DES function is used as a hashing function rather
* than an encryption/decryption tool. When used for generating
* the LM hash the <src> input is the known value "KGS!@#$%" and
* the key is derived from the password entered by the user.
* When used to generate the LM or NTLM response, the <key> is
* derived from the LM or NTLM hash, and the challenge is used
* as the <src> input.
* See: http://ubiqx.org/cifs/SMB.html#SMB.8.3
*
* - This function is called "DEShash" rather than just "DES"
* because it is only used for creating LM hashes and the
* LM/NTLM responses. For all practical purposes, however, it
* is a full DES encryption implementation.
*
* - This DES implementation does not need to be fast, nor is a
* DES decryption function needed. The goal is to keep the
* code small, simple, and well documented.
*
* - The input values are copied and refiddled within the module
* and the result is not written to <dst> until the very last
* step, so it's okay if <dst> points to the same memory as
* <key> or <src>.
*
* ------------------------------------------------------------------------ **
*/
/* ========================================================================== */
#endif /* AUTH_DES_H */

169
source/smb/LMhash.c Normal file
View File

@ -0,0 +1,169 @@
/* ========================================================================== **
*
* LMhash.c
*
* Copyright:
* Copyright (C) 2004 by Christopher R. Hertel
*
* Email: crh@ubiqx.mn.org
*
* $Id: LMhash.c,v 0.1 2004/05/30 02:26:31 crh Exp $
*
* -------------------------------------------------------------------------- **
*
* Description:
*
* Implemention of the LAN Manager hash (LM hash) and LM response
* algorithms.
*
* -------------------------------------------------------------------------- **
*
* License:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* -------------------------------------------------------------------------- **
*
* Notes:
*
* This module implements the LM hash. The NT hash is simply the MD4() of
* the password, so we don't need a separate implementation of that. This
* module also implements the LM response, which can be combined with the
* NT hash to produce the NTLM response.
*
* This implementation was created based on the description in my own book.
* The book description was, in turn, written after studying many existing
* examples in various documentation. Jeremy Allison and Andrew Tridgell
* deserve lots of credit for having figured out the secrets of Lan Manager
* authentication many years ago.
*
* See:
* Implementing CIFS - the Common Internet File System
* by your truly. ISBN 0-13-047116-X, Prentice Hall PTR., August 2003
* Section 15.3, in particular.
* (Online at: http://ubiqx.org/cifs/SMB.html#SMB.8.3)
*
* ========================================================================== **
*/
#include "DES.h"
#include "LMhash.h"
/* -------------------------------------------------------------------------- **
* Static Constants:
*
* SMB_LMhash_Magic - This is the plaintext "magic string" that is used to
* generate the LM Hash from the user's password. This
* value was a Microsoft "secret" for many years.
*/
static const uchar SMB_LMhash_Magic[8] =
{ 'K', 'G', 'S', '!', '@', '#', '$', '%' };
/* -------------------------------------------------------------------------- **
* Functions:
*/
uchar *auth_LMhash( uchar *dst, const uchar *pwd, const int pwdlen )
/* ------------------------------------------------------------------------ **
* Generate an LM Hash from the input password.
*
* Input: dst - Pointer to a location to which to write the LM Hash.
* Requires 16 bytes minimum.
* pwd - Source password. Should be in OEM charset (extended
* ASCII) format in all upper-case, but this
* implementation doesn't really care. See the notes
* below.
* pwdlen - Length, in bytes, of the password. Normally, this
* will be strlen( pwd ).
*
* Output: Pointer to the resulting LM hash (same as <dst>).
*
* Notes: This function does not convert the input password to upper
* case. The upper-case conversion should be done before the
* password gets this far. DOS codepage handling and such
* should be taken into consideration. Rather than attempt to
* work out all those details here, the function assumes that
* the password is in the correct form before it reaches this
* point.
*
* ------------------------------------------------------------------------ **
*/
{
int i,
max14;
uint8_t tmp_pwd[14] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
/* Copy at most 14 bytes of <pwd> into <tmp_pwd>.
* If the password is less than 14 bytes long
* the rest will be nul padded.
*/
max14 = pwdlen > 14 ? 14 : pwdlen;
for( i = 0; i < max14; i++ )
tmp_pwd[i] = pwd[i];
/* The password is split into two 7-byte keys, each of which
* are used to DES-encrypt the magic string. The results are
* concatonated to produce the 16-byte LM Hash.
*/
(void)auth_DEShash( dst, tmp_pwd, SMB_LMhash_Magic );
(void)auth_DEShash( &dst[8], &tmp_pwd[7], SMB_LMhash_Magic );
/* Return a pointer to the result.
*/
return( dst );
} /* auth_LMhash */
uchar *auth_LMresponse( uchar *dst, const uchar *hash, const uchar *challenge )
/* ------------------------------------------------------------------------ **
* Generate the LM (or NTLM) response from the password hash and challenge.
*
* Input: dst - Pointer to memory into which to write the response.
* Must have 24 bytes available.
* hash - Pointer to the 16-byte password hash.
* challenge - Pointer to the 8-byte challenge.
*
* Output: A pointer to the 24-byte response (same as <dst>).
*
* Notes: The function does not check the lengths of the input or output
* parameters. The byte sizes given above must be respected by
* calling function.
*
* ------------------------------------------------------------------------ **
*/
{
uchar tmp[7] =
{ hash[14], hash[15], 0,0,0,0,0 }; /* 3rd key is nul-padded. */
/* It's painfully simple...
* The challenge is DES encrypted three times.
* The first time, the first 7 bytes of the hash are used.
* The second time, the second 7 bytes of the hash are used.
* The third time, the two remaining hash bytes plus five nuls are used.
* The three 8-byte results are concatonated to form the 24-byte response.
*/
(void)auth_DEShash( dst, hash, challenge );
(void)auth_DEShash( &dst[8], &hash[7], challenge );
(void)auth_DEShash( &dst[16], tmp, challenge );
/* Return the result.
*/
return( dst );
} /* auth_LMresponse */
/* ========================================================================== */

115
source/smb/LMhash.h Normal file
View File

@ -0,0 +1,115 @@
#ifndef AUTH_LMHASH_H
#define AUTH_LMHASH_H
/* ========================================================================== **
*
* LMhash.h
*
* Copyright:
* Copyright (C) 2004 by Christopher R. Hertel
*
* Email: crh@ubiqx.mn.org
*
* $Id: LMhash.h,v 0.1 2004/05/30 02:26:31 crh Exp $
*
* -------------------------------------------------------------------------- **
*
* Description:
*
* Implemention of the LAN Manager hash (LM hash) and LM response
* algorithms.
*
* -------------------------------------------------------------------------- **
*
* License:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* -------------------------------------------------------------------------- **
*
* Notes:
*
* This module implements the LM hash. The NT hash is simply the MD4() of
* the password, so we don't need a separate implementation of that. This
* module also implements the LM response, which can be combined with the
* NT hash to produce the NTLM response.
*
* This implementation was created based on the description in my own book.
* The book description was, in turn, written after studying many existing
* examples in various documentation. Jeremy Allison and Andrew Tridgell
* deserve lots of credit for having figured out the secrets of Lan Manager
* authentication many years ago.
*
* See:
* Implementing CIFS - the Common Internet File System
* by your truly. ISBN 0-13-047116-X, Prentice Hall PTR., August 2003
* Section 15.3, in particular.
* (Online at: http://ubiqx.org/cifs/SMB.html#SMB.8.3)
*
* ========================================================================== **
*/
/* -------------------------------------------------------------------------- **
* Functions:
*/
uchar *auth_LMhash( uchar *dst, const uchar *pwd, const int pwdlen );
/* ------------------------------------------------------------------------ **
* Generate an LM Hash from the input password.
*
* Input: dst - Pointer to a location to which to write the LM Hash.
* Requires 16 bytes minimum.
* pwd - Source password. Should be in OEM charset (extended
* ASCII) format in all upper-case, but this
* implementation doesn't really care. See the notes
* below.
* pwdlen - Length, in bytes, of the password. Normally, this
* will be strlen( pwd ).
*
* Output: Pointer to the resulting LM hash (same as <dst>).
*
* Notes: This function does not convert the input password to upper
* case. The upper-case conversion should be done before the
* password gets this far. DOS codepage handling and such
* should be taken into consideration. Rather than attempt to
* work out all those details here, the function assumes that
* the password is in the correct form before it reaches this
* point.
*
* ------------------------------------------------------------------------ **
*/
uchar *auth_LMresponse( uchar *dst, const uchar *hash, const uchar *challenge );
/* ------------------------------------------------------------------------ **
* Generate the LM (or NTLM) response from the password hash and challenge.
*
* Input: dst - Pointer to memory into which to write the response.
* Must have 24 bytes available.
* hash - Pointer to the 16-byte password hash.
* challenge - Pointer to the 8-byte challenge.
*
* Output: A pointer to the 24-byte response (same as <dst>).
*
* Notes: The function does not check the lengths of the input or output
* parameters. The byte sizes given above must be respected by
* calling function.
*
* ------------------------------------------------------------------------ **
*/
/* ========================================================================== */
#endif /* AUTH_LMHASH_H */

112
source/smb/readme1st.txt Normal file
View File

@ -0,0 +1,112 @@
TinySMB-GC 0.1
May 2006
Developer Documentation
What is TinySMB-GC?
TinySMB-GC is a minimal implementation of the SMB protocol for the Nintendo Gamecube.
What does it do?
Essentially, TinySMB-GC enables network share support. This means that it will allow the
GameCube to connect to a shared folder on a Windows XP or linux samba box, and perform
basic file functions.
Known Restrictions
TinySMB-GC only supports the LM1.2X002 protocol. THIS IS NOT THE MOST SECURE!
However, it does NOT transmit your password over the wire, so it's reasonably safe.
How do I use it?
TinySMB-GC is developed with devkitPPC and libOGC, therefore you should be using this
development environment. Put simply, it won't work with anything else!
TinySMB-GC uses the TCP-raw form of SMB on port 445.
The Functions.
int SMB_Init (char *user, /*** The logon user - MUST have share access rights ***/
char *password, /*** PLEASE USE PASSWORD SECURITY! ***/
char *client, /*** Machine ID, whatever you want to call the GC ***/
char *server, /*** Machine ID of share server ***/
char *share, /*** Share ID ***/
char *IP); /*** IP of share server ***/
SMB_Init is used to establish the connection, authenticate and attach to the share.
Obviously, this must be called successfully before any other function.
void SMB_Destroy ();
SMB_Destroy takes care of releasing the internal socket of TinySMB-GC and should be
called when the SMB functions are no longer required.
int SMB_FindFirst (char *filename, /*** The file mask to search for ***/
unsigned short flags, /*** Search criteria flags ***/
SMBDIRENTRY * sdir); /*** An SMBDIRENTRY to hold directory information ***/
Similar to MS-Windows, to search for a file or directory, use this function to determine if the
file already exists. The SMBDIRENTRY simply holds basic information on each entry retrieved.
int SMB_FindNext (SMBDIRENTRY * sdir);
Called to continue a search started with SMB_FindFirst.
int SMB_FindClose ();
When all searches have completed, call SMB_FindClose to dispense with the search handle.
SMBFILE SMB_Open (char *filename, /*** The filename to open ***/
unsigned short access, /*** Access method ***/
unsigned short creation); /*** Creation flags ***/
This call will open a file on the share. Both reading and writing are supported.
Look at smb.h for information on the access and creation flags.
void SMB_Close (SMBFILE sfid);
Close a file previously opened with SMB_Open
int SMB_Read (char *buffer, int size, int offset, SMBFILE sfile);
Read from the file opened with SMB_Open.
int SMB_Write (char *buffer, int size, int offset, SMBFILE sfile);
Write to the file opened with SMB_Open.
NOTE: The offset value provides the missing seek function. However, the onus
is on the developer to maintain the offset value when reading / writing
sequentially.
You should also be aware that these functions should only be used to read/write
blocks up to 62Kbytes. Although it allows reading and writing of 4Gb files, it
does not support blocks larger then 16-bit - go figure!
Credits
TinySMB-GC Copyright softdev@tehskeen.com
Please respect this copyright!
NOTE WELL: This software is released under GPL 2.1
YOU MAY NOT STEAL IT AND HIDE IT IN YOUR
CLOSED SOURCE PRODUCT.
libOGC shagkur
devkitPPC wntrmute
CIFS Info Christopher R Hertel
http://www.ubiqx.com
Storage Networking Industry Association
http://www.snia.com
Ethereal - Packet Capture
http://www.ethereal.com
Thanks
Cedy_NL, for testing and helping get this off the ground.
brakken, web hosting and promotion.
Everyone who has participated in the Genesis Plus Project - keep up the good work !

932
source/smb/smb.c Normal file
View File

@ -0,0 +1,932 @@
/****************************************************************************
* TinySMB-GC
*
* Nintendo Gamecube SaMBa implementation.
*
* Copyright softdev@tehskeen.com
*
* Authentication modules, LMhash and DES are
*
* Copyright Christopher R Hertel.
* http://www.ubiqx.org
*
* You WILL find Ethereal, available from http://www.ethereal.com
* invaluable for debugging each new SAMBA implementation.
*
* Recommended Reading
* Implementing CIFS - Christopher R Hertel
* SNIA CIFS Documentation - http://www.snia.org
*
* License:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
****************************************************************************/
#include <gccore.h>
#include <network.h>
#include "smb.h"
#include "DES.h"
#include "LMhash.h"
#include <ctype.h>
/**
* A few little bits for libOGC
*/
typedef int SOCKET;
#define recv net_recv
#define send net_send
#define closesocket net_close
#define connect net_connect
#define setsockopt net_setsockopt
#define socket net_socket
/**
* Client and server SMB
*/
NBTSMB c;
NBTSMB s;
SMBSESSION session;
SOCKET smbsock;
static struct sockaddr_in smbs;
static int smbcheckbytes = 0;
/**
* SMB Endian aware supporting functions
*
* SMB always uses Intel Little-Endian values, so htons etc are
* of little or no use :) ... Thanks M$
*/
/*** get unsigned char ***/
static unsigned char
getUChar (unsigned char *buffer, int offset)
{
return buffer[offset];
}
/*** set unsigned char ***/
static void
setUChar (unsigned char *buffer, int offset, unsigned char value)
{
buffer[offset] = value;
}
/*** get unsigned short ***/
static unsigned short
getUShort (unsigned char *buffer, int offset)
{
unsigned short t;
t = buffer[offset];
t |= (buffer[offset + 1] << 8);
return t;
}
/*** set unsigned short ***/
static void
setUShort (unsigned char *buffer, int offset, unsigned short value)
{
buffer[offset] = value & 0xff;
buffer[offset + 1] = (value & 0xff00) >> 8;
}
/*** get unsigned int ***/
static unsigned int
getUInt (unsigned char *buffer, int offset)
{
unsigned int t;
t = buffer[offset];
t |= (buffer[offset + 1] << 8);
t |= (buffer[offset + 2] << 16);
t |= (buffer[offset + 3] << 24);
return t;
}
/*** set unsigned int ***/
static void
setUInt (unsigned char *buffer, int offset, int value)
{
buffer[offset] = value & 0xff;
buffer[offset + 1] = (value & 0xff00) >> 8;
buffer[offset + 2] = (value & 0xff0000) >> 16;
buffer[offset + 3] = (value & 0xff000000) >> 24;
}
/**
* MakeSMBHdr
*
* Generate the SMB header for each request.
* Uses 'c' NBTSMB
*/
static void
MakeSMBHdr (unsigned char command)
{
int pos = 0;
/*** Clear client packet ***/
memset (&c, 0, sizeof (c));
/*** Add protocol SMB ***/
setUInt (c.smb, pos, SMB_PROTO);
pos += 4;
setUChar (c.smb, pos, command);
pos++;
pos++; /*** Error class ***/
pos++; /*** Reserved ***/
pos += 2; /*** Error Code ***/
setUChar (c.smb, pos, 0x8);
pos++; /*** Flags == 8 == Case Insensitive ***/
setUShort (c.smb, pos, 0x1);
pos += 2; /*** Flags2 == 1 == LFN ***/
pos += 2; /*** Process ID High ***/
pos += 8; /*** Signature ***/
pos += 2; /*** Reserved ***/
setUShort (c.smb, pos, session.TID);
pos += 2;
setUShort (c.smb, pos, session.PID);
pos += 2;
setUShort (c.smb, pos, session.UID);
pos += 2;
setUShort (c.smb, pos, session.MID);
}
/**
* MakeTRANS2Hdr
*/
static void
MakeTRANS2Hdr (unsigned char subcommand)
{
setUChar (c.smb, T2_WORD_CNT, 15);
setUShort (c.smb, T2_MAXPRM_CNT, 10);
setUShort (c.smb, T2_MAXBUFFER, session.MaxBuffer);
setUChar (c.smb, T2_SSETUP_CNT, 1);
setUShort (c.smb, T2_SUB_CMD, subcommand);
}
/**
* SMBCheck
*
* Do very basic checking on the return SMB
*/
static int
SMBCheck (unsigned char command, int readlen)
{
int ret;
memset (&s, 0, sizeof (s));
smbcheckbytes = ret = recv (smbsock, (char *) &s, readlen, 0);
if (ret < 12)
return 0;
/*** Do basic SMB Header checks ***/
ret = getUInt (s.smb, 0);
if (ret != SMB_PROTO)
return BAD_PROTOCOL;
if (getUChar (s.smb, 4) != command)
return SMB_BAD_COMMAND;
ret = getUInt (s.smb, SMB_OFFSET_NTSTATUS);
if (ret)
return SMB_ERROR;
return SMB_SUCCESS;
}
/**
* SMB_NegotiateProtocol
*
* The only protocol we admit to is 'DOS LANMAN 2.1'
*/
static int
SMB_NegotiateProtocol ()
{
int pos;
int bcpos;
int ret;
char proto[] = "\2LM1.2X002"; /*** Seems to work with Samba and XP Home ***/
unsigned short bytecount;
/*** Clear session variables ***/
memset (&session, 0, sizeof (session));
session.PID = 0xdead;
session.MID = 1;
MakeSMBHdr (SMB_NEG_PROTOCOL);
pos = SMB_HEADER;
pos++; /*** Add word count ***/
bcpos = pos;
pos += 2; /*** Byte count - when known ***/
strcpy (&c.smb[pos], proto);
pos += strlen (proto) + 1;
/*** Update byte count ***/
setUShort (c.smb, bcpos, (pos - bcpos) - 2);
/*** Set NBT information ***/
c.msg = SESS_MSG;
c.length = htons (pos);
pos += 4;
ret = send (smbsock, (char *) &c, pos, 0);
/*** Check response ***/
if (SMBCheck (SMB_NEG_PROTOCOL, sizeof (s)) == SMB_SUCCESS)
{
pos = SMB_HEADER;
/*** Collect information ***/
if (getUChar (s.smb, pos) != 13)
return SMB_PROTO_FAIL;
pos++;
if (getUShort (s.smb, pos))
return SMB_PROTO_FAIL;
pos += 2;
if (getUShort (s.smb, pos) != 3)
return SMB_NOT_USER;
pos += 2;
session.MaxBuffer = getUShort (s.smb, pos);
pos += 2;
if (session.MaxBuffer > 2916)
session.MaxBuffer = 2916;
session.MaxMpx = getUShort (s.smb, pos);
pos += 2;
session.MaxVCS = getUShort (s.smb, pos);
pos += 2;
pos += 2; /*** Raw Mode ***/
pos += 4; /*** Session Key ***/
pos += 6; /*** Time information ***/
if (getUShort (s.smb, pos) != 8)
return SMB_BAD_KEYLEN;
pos += 2;
pos += 2; /*** Reserved ***/
bytecount = getUShort (s.smb, pos);
pos += 2;
/*** Copy challenge key ***/
memcpy (&session.challenge, &s.smb[pos], 8);
pos += 8;
/*** Primary domain ***/
strcpy (session.p_domain, &s.smb[pos]);
return SMB_SUCCESS;
}
return 0;
}
/**
* SMB_SetupAndX
*
* Setup the SMB session, including authentication with the
* magic 'LM Response'
*/
static int
SMB_SetupAndX (char *user, char *password)
{
int pos;
int bcpos;
char pwd[24], LMh[24], LMr[24];
int i, ret;
MakeSMBHdr (SMB_SETUP_ANDX);
pos = SMB_HEADER;
setUChar (c.smb, pos, 10);
pos++; /*** Word Count ***/
setUChar (c.smb, pos, 0xff);
pos++; /*** Next AndX ***/
pos++; /*** Reserved ***/
pos += 2; /*** Next AndX Offset ***/
setUShort (c.smb, pos, session.MaxBuffer);
pos += 2;
setUShort (c.smb, pos, session.MaxMpx);
pos += 2;
setUShort (c.smb, pos, session.MaxVCS);
pos += 2;
pos += 4; /*** Session key, unknown at this point ***/
setUShort (c.smb, pos, 24);
pos += 2; /*** Password length ***/
pos += 4; /*** Reserved ***/
bcpos = pos;
pos += 2; /*** Byte count ***/
/*** The magic 'LM Response' ***/
strcpy (pwd, password);
for (i = 0; i < strlen (pwd); i++)
pwd[i] = toupper (pwd[i]);
auth_LMhash (LMh, pwd, strlen (pwd));
auth_LMresponse (LMr, LMh, session.challenge);
/*** Build information ***/
memcpy (&c.smb[pos], LMr, 24);
pos += 24;
/*** Account ***/
strcpy (pwd, user);
for (i = 0; i < strlen (user); i++)
pwd[i] = toupper (pwd[i]);
memcpy (&c.smb[pos], pwd, strlen (pwd));
pos += strlen (pwd) + 1;
/*** Primary Domain ***/
memcpy (&c.smb[pos], &session.p_domain, strlen (session.p_domain));
pos += strlen (session.p_domain) + 1;
/*** Native OS ***/
strcpy (pwd, "Unix (libOGC)");
memcpy (&c.smb[pos], pwd, strlen (pwd));
pos += strlen (pwd) + 1;
/*** Native LAN Manager ***/
strcpy (pwd, "Nintendo GameCube 0.1");
memcpy (&c.smb[pos], pwd, strlen (pwd));
pos += strlen (pwd) + 1;
/*** Update byte count ***/
setUShort (c.smb, bcpos, (pos - bcpos) - 2);
c.msg = SESS_MSG;
c.length = htons (pos);
pos += 4;
ret = send (smbsock, (char *) &c, pos, 0);
if (SMBCheck (SMB_SETUP_ANDX, sizeof (s)) == SMB_SUCCESS)
{
/*** Collect UID ***/
session.UID = getUShort (s.smb, SMB_OFFSET_UID);
return SMB_SUCCESS;
}
return 0;
}
/**
* SMB_TreeAndX
*
* Finally, connect to the remote share
*/
static int
SMB_TreeAndX (char *server, char *share)
{
int pos, bcpos, ret;
char path[256];
MakeSMBHdr (SMB_TREEC_ANDX);
pos = SMB_HEADER;
setUChar (c.smb, pos, 4);
pos++; /*** Word Count ***/
setUChar (c.smb, pos, 0xff);
pos++; /*** Next AndX ***/
pos++; /*** Reserved ***/
pos += 2; /*** Next AndX Offset ***/
pos += 2; /*** Flags ***/
setUShort (c.smb, pos, 1);
pos += 2; /*** Password Length ***/
bcpos = pos;
pos += 2;
pos++; /*** NULL Password ***/
/*** Build server share path ***/
strcpy (path, "\\\\");
strcat (path, server);
strcat (path, "\\");
strcat (path, share);
for (ret = 0; ret < strlen (path); ret++)
path[ret] = toupper (path[ret]);
memcpy (&c.smb[pos], path, strlen (path));
pos += strlen (path) + 1;
/*** Service ***/
strcpy (path, "?????");
memcpy (&c.smb[pos], path, strlen (path));
pos += strlen (path) + 1;
/*** Update byte count ***/
setUShort (c.smb, bcpos, (pos - bcpos) - 2);
c.msg = SESS_MSG;
c.length = htons (pos);
pos += 4;
ret = send (smbsock, (char *) &c, pos, 0);
if (SMBCheck (SMB_TREEC_ANDX, sizeof (s)) == SMB_SUCCESS)
{
/*** Collect Tree ID ***/
session.TID = getUShort (s.smb, SMB_OFFSET_TID);
return SMB_SUCCESS;
}
return 0;
}
/**
* SMB_FindFirst
*
* Uses TRANS2 to support long filenames
*/
int
SMB_FindFirst (char *filename, unsigned short flags, SMBDIRENTRY * sdir)
{
int pos;
int ret;
int bpos;
MakeSMBHdr (SMB_TRANS2);
MakeTRANS2Hdr (SMB_FIND_FIRST2);
pos = T2_BYTE_CNT + 2;
bpos = pos;
pos += 3; /*** Padding ***/
setUShort (c.smb, pos, flags);
pos += 2; /*** Flags ***/
setUShort (c.smb, pos, 1);
pos += 2; /*** Count ***/
setUShort (c.smb, pos, 6);
pos += 2; /*** Internal Flags ***/
setUShort (c.smb, pos, 260);
pos += 2; /*** Level of Interest ***/
pos += 4; /*** Storage Type == 0 ***/
memcpy (&c.smb[pos], filename, strlen (filename));
pos += strlen (filename) + 1; /*** Include padding ***/
/*** Update counts ***/
setUShort (c.smb, T2_PRM_CNT, 13 + strlen (filename));
setUShort (c.smb, T2_SPRM_CNT, 13 + strlen (filename));
setUShort (c.smb, T2_SPRM_OFS, 68);
setUShort (c.smb, T2_SDATA_OFS, 81 + strlen (filename));
setUShort (c.smb, T2_BYTE_CNT, pos - bpos);
c.msg = SESS_MSG;
c.length = htons (pos);
pos += 4;
ret = send (smbsock, (char *) &c, pos, 0);
session.sid = 0;
session.count = 0;
session.eos = 1;
if (SMBCheck (SMB_TRANS2, sizeof (s)) == SMB_SUCCESS)
{
/*** Get parameter offset ***/
pos = getUShort (s.smb, SMB_HEADER + 9);
session.sid = getUShort (s.smb, pos);
pos += 2;
session.count = getUShort (s.smb, pos);
pos += 2;
session.eos = getUShort (s.smb, pos);
pos += 2;
pos += 46;
if (session.count)
{
sdir->size_low = getUInt (s.smb, pos);
pos += 4;
sdir->size_high = getUInt (s.smb, pos);
pos += 4;
pos += 8;
sdir->attributes = getUInt (s.smb, pos);
pos += 38;
strcpy (sdir->name, &s.smb[pos]);
return SMB_SUCCESS;
}
}
return 0;
}
/**
* SMB_FindNext
*/
int
SMB_FindNext (SMBDIRENTRY * sdir)
{
int pos;
int ret;
int bpos;
if (session.eos)
return 0;
if (session.sid == 0)
return 0;
MakeSMBHdr (SMB_TRANS2);
MakeTRANS2Hdr (SMB_FIND_NEXT2);
pos = T2_BYTE_CNT + 2;
bpos = pos;
pos += 3; /*** Padding ***/
setUShort (c.smb, pos, session.sid);
pos += 2; /*** Search ID ***/
setUShort (c.smb, pos, 1);
pos += 2; /*** Count ***/
setUShort (c.smb, pos, 260);
pos += 2; /*** Level of Interest ***/
pos += 4; /*** Storage Type == 0 ***/
setUShort (c.smb, pos, 12);
pos += 2; /*** Search flags ***/
pos++;
/*** Update counts ***/
setUShort (c.smb, T2_PRM_CNT, 13);
setUShort (c.smb, T2_SPRM_CNT, 13);
setUShort (c.smb, T2_SPRM_OFS, 68);
setUShort (c.smb, T2_SDATA_OFS, 81);
setUShort (c.smb, T2_BYTE_CNT, pos - bpos);
c.msg = SESS_MSG;
c.length = htons (pos);
pos += 4;
ret = send (smbsock, (char *) &c, pos, 0);
if (SMBCheck (SMB_TRANS2, sizeof (s)) == SMB_SUCCESS)
{
/*** Get parameter offset ***/
pos = getUShort (s.smb, SMB_HEADER + 9);
session.count = getUShort (s.smb, pos);
pos += 2;
session.eos = getUShort (s.smb, pos);
pos += 2;
pos += 44;
if (session.count)
{
sdir->size_low = getUInt (s.smb, pos);
pos += 4;
sdir->size_high = getUInt (s.smb, pos);
pos += 4;
pos += 8;
sdir->attributes = getUInt (s.smb, pos);
pos += 38;
strcpy (sdir->name, &s.smb[pos]);
return SMB_SUCCESS;
}
}
return 0;
}
/**
* SMB_FindClose
*/
int
SMB_FindClose ()
{
int pos = SMB_HEADER;
int ret;
if (session.sid == 0)
return 0;
MakeSMBHdr (SMB_FIND_CLOSE2);
setUChar (c.smb, pos, 1);
pos++; /*** Word Count ***/
setUShort (c.smb, pos, session.sid);
pos += 2;
pos += 2; /*** Byte Count ***/
c.msg = SESS_MSG;
c.length = htons (pos);
pos += 4;
ret = send (smbsock, (char *) &c, pos, 0);
return SMBCheck (SMB_FIND_CLOSE2, sizeof (s));
}
/**
* SMB_Open
*/
SMBFILE
SMB_Open (char *filename, unsigned short access, unsigned short creation)
{
int pos = SMB_HEADER;
int bpos, ret;
char realfile[256];
unsigned short fid;
MakeSMBHdr (SMB_OPEN_ANDX);
setUChar (c.smb, pos, 15);
pos++; /*** Word Count ***/
setUChar (c.smb, pos, 0xff);
pos++; /*** Next AndX ***/
pos += 3; /*** Next AndX Offset ***/
pos += 2; /*** Flags ***/
setUShort (c.smb, pos, access);
pos += 2; /*** Access mode ***/
setUShort (c.smb, pos, 0x6);
pos += 2; /*** Type of file ***/
pos += 2; /*** Attributes ***/
pos += 4; /*** File time - don't care - let server decide ***/
setUShort (c.smb, pos, creation);
pos += 2; /*** Creation flags ***/
pos += 4; /*** Allocation size ***/
pos += 8; /*** Reserved ***/
pos += 2; /*** Byte Count ***/
bpos = pos;
if (filename[0] != '\\')
{
strcpy (realfile, "\\");
strcat (realfile, filename);
}
else
strcpy (realfile, filename);
memcpy (&c.smb[pos], realfile, strlen (realfile));
pos += strlen (realfile) + 1;
setUShort (c.smb, bpos - 2, (pos - bpos));
c.msg = SESS_MSG;
c.length = htons (pos);
pos += 4;
ret = send (smbsock, (char *) &c, pos, 0);
if (SMBCheck (SMB_OPEN_ANDX, sizeof (s)) == SMB_SUCCESS)
{
/*** Check file handle ***/
fid = getUShort (s.smb, SMB_HEADER + 5);
if (fid)
return fid;
}
return 0;
}
/**
* SMB_Close
*/
void
SMB_Close (SMBFILE sfid)
{
int pos, ret;
MakeSMBHdr (SMB_CLOSE);
pos = SMB_HEADER;
setUChar (c.smb, pos, 3);
pos++; /** Word Count **/
setUShort (c.smb, pos, sfid);
pos += 2;
setUInt (c.smb, pos, 0xffffffff);
pos += 4; /*** Last Write ***/
pos += 2; /*** Byte Count ***/
c.msg = SESS_MSG;
c.length = htons (pos);
pos += 4;
ret = send (smbsock, (char *) &c, pos, 0);
SMBCheck (SMB_CLOSE, sizeof (s));
}
/**
* SMB_Read
*/
int
SMB_Read (char *buffer, int size, int offset, SMBFILE sfile)
{
int pos, ret, ofs;
unsigned short length = 0;
MakeSMBHdr (SMB_READ_ANDX);
pos = SMB_HEADER;
/*** Don't let the size exceed! ***/
if (size > 62 * 1024)
return 0;
setUChar (c.smb, pos, 10);
pos++; /*** Word count ***/
setUChar (c.smb, pos, 0xff);
pos++;
pos += 3; /*** Reserved, Next AndX Offset ***/
setUShort (c.smb, pos, sfile);
pos += 2; /*** FID ***/
setUInt (c.smb, pos, offset);
pos += 4; /*** Offset ***/
setUShort (c.smb, pos, size & 0xffff);
pos += 2;
setUShort (c.smb, pos, size & 0xffff);
pos += 2;
setUInt (c.smb, pos, 0);
pos += 4;
pos += 2; /*** Remaining ***/
pos += 2; /*** Byte count ***/
c.msg = SESS_MSG;
c.length = htons (pos);
pos += 4;
ret = send (smbsock, (char *) &c, pos, 0);
/*** SMBCheck should now only read up to the end of a standard header ***/
if (SMBCheck (SMB_READ_ANDX, SMB_HEADER + 27 + 4) == SMB_SUCCESS)
{
/*** Retrieve data length for this packet ***/
length = getUShort (s.smb, SMB_HEADER + 11);
/*** Retrieve offset to data ***/
ofs = getUShort (s.smb, SMB_HEADER + 13);
/*** Default offset, with no padding is 59, so grab any outstanding padding ***/
if (ofs > 59)
{
char pad[1024];
ret = recv (smbsock, pad, ofs - 59, 0);
}
/*** Finally, go grab the data ***/
ofs = 0;
if (length)
{
while (((ret = recv (smbsock, buffer + ofs, length, 0)) > 0))
{
ofs += ret;
if (ofs == length)
break;
}
}
return ofs;
}
return 0;
}
/**
* SMB_Write
*/
int
SMB_Write (char *buffer, int size, int offset, SMBFILE sfile)
{
int pos, ret;
int blocks64;
MakeSMBHdr (SMB_WRITE_ANDX);
pos = SMB_HEADER;
setUChar (c.smb, pos, 12);
pos++; /*** Word Count ***/
setUChar (c.smb, pos, 0xff);
pos += 2; /*** Next AndX ***/
pos += 2; /*** Next AndX Offset ***/
setUShort (c.smb, pos, sfile);
pos += 2;
setUInt (c.smb, pos, offset);
pos += 4;
pos += 4; /*** Reserved ***/
pos += 2; /*** Write Mode ***/
pos += 2; /*** Remaining ***/
blocks64 = size >> 16;
setUShort (c.smb, pos, blocks64);
pos += 2; /*** Length High ***/
setUShort (c.smb, pos, size & 0xffff);
pos += 2; /*** Length Low ***/
setUShort (c.smb, pos, 59);
pos += 2; /*** Data Offset ***/
setUShort (c.smb, pos, size & 0xffff);
pos += 2; /*** Data Byte Count ***/
c.msg = SESS_MSG;
c.length = htons (pos + size);
/*** Will this fit in a single send? ***/
if (size <= 2916)
{
memcpy (&c.smb[pos], buffer, size);
pos += size;
}
else
{
memcpy (&c.smb[pos], buffer, 2916);
pos += 2916;
}
pos += 4;
/*** Send Header Information ***/
ret = send (smbsock, (char *) &c, pos, 0);
if (size > 2916)
{
/*** Send the data ***/
ret = send (smbsock, buffer + 2916, size - 2916, 0);
}
if (SMBCheck (SMB_WRITE_ANDX, sizeof (s)) == SMB_SUCCESS)
{
return (int) getUShort (s.smb, SMB_HEADER + 5);
}
return 0;
}
/****************************************************************************
* Primary setup, logon and connection all in one :)
****************************************************************************/
int
SMB_Init (char *user, char *password, char *client,
char *server, char *share, char *IP)
{
int ret;
int nodelay;
/*** Create the global socket ***/
smbsock = socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
/*** Switch off Nagle, ON TCP_NODELAY ***/
nodelay = 1;
ret = setsockopt (smbsock, IPPROTO_TCP, TCP_NODELAY,
(char *) &nodelay, sizeof (char));
/*** Attempt to connect to the server IP ***/
memset (&smbs, 0, sizeof (client));
smbs.sin_family = AF_INET;
smbs.sin_port = htons (445);
smbs.sin_addr.s_addr = inet_addr (IP);
ret = connect (smbsock, (struct sockaddr *) &smbs, sizeof (smbs));
if (ret)
{
closesocket (smbsock);
return 0;
}
if (SMB_NegotiateProtocol () == SMB_SUCCESS)
{
if (SMB_SetupAndX (user, password) == SMB_SUCCESS)
{
if (SMB_TreeAndX (server, share) == SMB_SUCCESS)
return SMB_SUCCESS;
}
}
return 0;
}
/****************************************************************************
* SMB_Destroy
*
* Probably NEVER called on GameCube, but here for completeness
****************************************************************************/
void
SMB_Destroy ()
{
if (smbsock)
closesocket (smbsock);
}

219
source/smb/smb.h Normal file
View File

@ -0,0 +1,219 @@
/****************************************************************************
* TinySMB-GC
*
* Nintendo Gamecube SaMBa implementation.
*
* Copyright softdev@tehskeen.com
*
* Authentication modules, LMhash and DES are
*
* Copyright Christopher R Hertel.
* http://www.ubiqx.org
*
* You WILL find Ethereal, available from http://www.ethereal.com
* invaluable for debugging each new SAMBA implementation.
*
* Recommended Reading
* Implementing CIFS - Christopher R Hertel
* SNIA CIFS Documentation - http://www.snia.org
*
* License:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
****************************************************************************/
#ifndef NBTSMB_INC
#define NBTSMB_INC
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
* NBT/SMB Wrapper
*/
typedef struct
{
unsigned char msg; /*** NBT Message ***/
unsigned char flags; /*** Not much here really ***/
unsigned short length; /*** Length, excluding NBT ***/
char smb[2916]; /*** GC Actual is 2920 bytes ***/
}
NBTSMB;
/**
* Session Information
*/
typedef struct
{
unsigned short TID;
unsigned short PID;
unsigned short UID;
unsigned short MID;
unsigned short sKey;
unsigned short MaxBuffer;
unsigned short MaxMpx;
unsigned short MaxVCS;
unsigned char challenge[10];
char p_domain[64];
unsigned short sid;
unsigned short count;
unsigned short eos;
}
SMBSESSION;
/*** SMB_FILEENTRY
SMB Long Filename Directory Entry
***/
typedef struct
{
unsigned int size_low;
unsigned int size_high;
unsigned int attributes;
char name[256];
}
SMBDIRENTRY;
/***
* SMB File Handle
*/
typedef unsigned short SMBFILE;
#define SMB_HEADER 32 /*** SMB Headers are always 32 bytes long ***/
#define SMB_PROTO 0x424d53ff
/**
* Field offsets.
*/
#define SMB_OFFSET_CMD 4
#define SMB_OFFSET_NTSTATUS 5
#define SMB_OFFSET_ECLASS 5
#define SMB_OFFSET_ECODE 7
#define SMB_OFFSET_FLAGS 9
#define SMB_OFFSET_FLAGS2 10
#define SMB_OFFSET_EXTRA 12
#define SMB_OFFSET_TID 24
#define SMB_OFFSET_PID 26
#define SMB_OFFSET_UID 28
#define SMB_OFFSET_MID 30
/**
* Message / Commands
*/
#define SESS_MSG 0x00
#define SMB_NEG_PROTOCOL 0x72
#define SMB_SETUP_ANDX 0x73
#define SMB_TREEC_ANDX 0x75
/**
* SMBTrans2
*/
#define SMB_TRANS2 0x32
#define SMB_OPEN2 0
#define SMB_FIND_FIRST2 1
#define SMB_FIND_NEXT2 2
#define SMB_QUERY_FS_INFO 3
#define SMB_QUERY_PATH_INFO 5
#define SMB_SET_PATH_INFO 6
#define SMB_QUERY_FILE_INFO 7
#define SMB_SET_FILE_INFO 8
#define SMB_CREATE_DIR 13
#define SMB_FIND_CLOSE2 0x34
/**
* File I/O
*/
#define SMB_OPEN_ANDX 0x2d
#define SMB_WRITE_ANDX 0x2f
#define SMB_READ_ANDX 0x2e
#define SMB_CLOSE 4
/**
* SMB File Access Modes
*/
#define SMB_OPEN_READING 0
#define SMB_OPEN_WRITING 1
#define SMB_OPEN_READWRITE 2
#define SMB_OPEN_COMPATIBLE 0
#define SMB_DENY_READWRITE 0x10
#define SMB_DENY_WRITE 0x20
#define SMB_DENY_READ 0x30
#define SMB_DENY_NONE 0x40
/**
* SMB File Open Function
*/
#define SMB_OF_OPEN 1
#define SMB_OF_TRUNCATE 2
#define SMB_OF_CREATE 16
/**
* FileSearch
*/
#define SMB_SRCH_DIRECTORY 16
#define SMB_SRCH_READONLY 1
#define SMB_SRCH_HIDDEN 2
#define SMB_SRCH_SYSTEM 4
#define SMB_SRCH_VOLUME 8
/**
* SMB Error codes
*/
#define SMB_SUCCESS 1
#define BAD_PROTOCOL -1
#define SMB_ERROR -2
#define SMB_BAD_COMMAND -3
#define SMB_PROTO_FAIL -4
#define SMB_NOT_USER -5
#define SMB_BAD_KEYLEN -6
/**
* TRANS2 Offsets
*/
#define T2_WORD_CNT SMB_HEADER
#define T2_PRM_CNT T2_WORD_CNT + 1
#define T2_DATA_CNT T2_PRM_CNT + 2
#define T2_MAXPRM_CNT T2_DATA_CNT + 2
#define T2_MAXBUFFER T2_MAXPRM_CNT + 2
#define T2_SETUP_CNT T2_MAXBUFFER + 2
#define T2_SPRM_CNT T2_SETUP_CNT + 10
#define T2_SPRM_OFS T2_SPRM_CNT + 2
#define T2_SDATA_CNT T2_SPRM_OFS + 2
#define T2_SDATA_OFS T2_SDATA_CNT + 2
#define T2_SSETUP_CNT T2_SDATA_OFS + 2
#define T2_SUB_CMD T2_SSETUP_CNT + 2
#define T2_BYTE_CNT T2_SUB_CMD + 2
/**
* Prototypes
*/
/*** Session ***/
int SMB_Init (char *user, char *password, char *client,
char *server, char *share, char *IP);
void SMB_Destroy ();
/*** File Find ***/
int SMB_FindFirst (char *filename, unsigned short flags, SMBDIRENTRY * sdir);
int SMB_FindNext (SMBDIRENTRY * sdir);
int SMB_FindClose ();
/*** File I/O ***/
SMBFILE SMB_Open (char *filename, unsigned short access,
unsigned short creation);
void SMB_Close (SMBFILE sfid);
int SMB_Read (char *buffer, int size, int offset, SMBFILE sfile);
int SMB_Write (char *buffer, int size, int offset, SMBFILE sfile);
#endif

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef _3D_H_
#define _3D_H_
@ -186,7 +167,6 @@ typedef struct
GLint texture_size;
uint32 num_textures; // 1 if max_texture_size == 256, 2 otherwise
GLuint textures [2];
bool8 initialized;
} OpenGLData;
extern OpenGLData OpenGL;

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef _65c816_h_
#define _65c816_h_

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifdef __DJGPP
#include <allegro.h>
#undef TRUE
@ -182,7 +163,7 @@ extern int32 env_counter_table[32];
int spc_is_dumping=0;
int spc_is_dumping_temp;
uint8 spc_dump_dsp[0x100];
uint8 spc_dump_dsp[0x100];
#ifdef DEBUGGER
void S9xTraceSoundDSP (const char *s, int i1 = 0, int i2 = 0, int i3 = 0,
@ -192,15 +173,19 @@ void S9xTraceSoundDSP (const char *s, int i1 = 0, int i2 = 0, int i3 = 0,
bool8 S9xInitAPU ()
{
IAPU.RAM = (uint8 *) malloc (0x10000);
if (!IAPU.RAM)
IAPU.ShadowRAM = (uint8 *) malloc (0x10000);
IAPU.CachedSamples = (uint8 *) malloc (0x40000);
if (!IAPU.RAM || !IAPU.ShadowRAM || !IAPU.CachedSamples)
{
S9xDeinitAPU ();
return (FALSE);
}
memset(IAPU.RAM, 0, 0x10000);
memset(IAPU.ShadowRAM, 0, 0x10000);
memset(IAPU.CachedSamples, 0, 0x40000);
return (TRUE);
}
@ -211,19 +196,27 @@ void S9xDeinitAPU ()
free ((char *) IAPU.RAM);
IAPU.RAM = NULL;
}
if (IAPU.ShadowRAM)
{
free ((char *) IAPU.ShadowRAM);
IAPU.ShadowRAM = NULL;
}
if (IAPU.CachedSamples)
{
free ((char *) IAPU.CachedSamples);
IAPU.CachedSamples = NULL;
}
}
EXTERN_C uint8 APUROM [64];
void S9xResetAPU ()
{
int i;
Settings.APUEnabled = Settings.NextAPUEnabled;
if(Settings.APUEnabled)
APU.Flags &= ~HALTED_FLAG;
ZeroMemory(spc_dump_dsp, 0x100);
ZeroMemory(IAPU.RAM, 0x100);
memset(IAPU.RAM+0x20, 0xFF, 0x20);
@ -236,17 +229,19 @@ void S9xResetAPU ()
memcpy(IAPU.RAM+(i<<8), IAPU.RAM, 0x100);
}
memcpy (IAPU.ShadowRAM, IAPU.RAM, 0x10000);
ZeroMemory (IAPU.CachedSamples, 0x40000);
ZeroMemory (APU.OutPorts, 4);
IAPU.DirectPage = IAPU.RAM;
memmove (APU.ExtraRAM, &IAPU.RAM [0xffc0], sizeof (APUROM));
memmove (&IAPU.RAM [0xffc0], APUROM, sizeof (APUROM));
memmove (APU.ExtraRAM, APUROM, sizeof (APUROM));
IAPU.PC = IAPU.RAM + IAPU.RAM [0xfffe] + (IAPU.RAM [0xffff] << 8);
APU.Cycles = 0;
APU.OldCycles = -99999999; // For shapshot compatibility
APURegisters.YA.W = 0;
APURegisters.X = 0;
APURegisters.S = 0xef;
APURegisters.P = 0x02;
APURegisters.S = 0xff;
APURegisters.P = 0;
S9xAPUUnpackStatus ();
APURegisters.PC = 0;
IAPU.APUExecuting = Settings.APUEnabled;
@ -259,7 +254,7 @@ void S9xResetAPU ()
IAPU.APUTimerCounter = 0;
APU.ShowROM = TRUE;
IAPU.RAM [0xf1] = 0x80;
for (i = 0; i < 3; i++)
{
APU.TimerEnabled [i] = FALSE;
@ -269,18 +264,18 @@ void S9xResetAPU ()
}
for (int j = 0; j < 0x80; j++)
APU.DSP [j] = 0;
IAPU.TwoCycles = IAPU.OneCycle * 2;
for (i = 0; i < 256; i++)
S9xAPUCycles [i] = S9xAPUCycleLengths [i] * IAPU.OneCycle;
APU.DSP [APU_ENDX] = 0;
APU.DSP [APU_KOFF] = 0;
APU.DSP [APU_KON] = 0;
APU.DSP [APU_FLG] = APU_MUTE | APU_ECHO_DISABLED;
APU.KeyedChannels = 0;
S9xResetSound (TRUE);
S9xSetEchoEnable (0);
}
@ -323,7 +318,7 @@ void S9xSetAPUDSP (uint8 byte)
}
else
S9xSetSoundMute (FALSE);
SoundData.noise_rate = env_counter_table[byte & 0x1f];
}
break;
@ -375,7 +370,7 @@ void S9xSetAPUDSP (uint8 byte)
{
#ifdef DEBUGGER
if (Settings.TraceSoundDSP)
S9xTraceSoundDSP ("[%d] Master volume left:%d\n",
S9xTraceSoundDSP ("[%d] Master volume left:%d\n",
ICPU.Scanline, (signed char) byte);
#endif
S9xSetMasterVolume ((signed char) byte,
@ -425,7 +420,7 @@ void S9xSetAPUDSP (uint8 byte)
#endif
byte = 0;
break;
case APU_KOFF:
// if (byte)
{
@ -439,10 +434,10 @@ void S9xSetAPUDSP (uint8 byte)
if ((byte & mask) != 0)
{
#ifdef DEBUGGER
if (Settings.TraceSoundDSP)
S9xTraceSoundDSP ("%d,", c);
#endif
#endif
if (APU.KeyedChannels & mask)
{
{
@ -489,7 +484,7 @@ void S9xSetAPUDSP (uint8 byte)
{
uint8 mask = 1;
#ifdef DEBUGGER
if (Settings.TraceSoundDSP)
S9xTraceSoundDSP ("[%d] Key on:", ICPU.Scanline);
#endif
@ -500,7 +495,7 @@ void S9xSetAPUDSP (uint8 byte)
#ifdef DEBUGGER
if (Settings.TraceSoundDSP)
S9xTraceSoundDSP ("%d,", c);
#endif
#endif
// Pac-In-Time requires that channels can be key-on
// regardeless of their current state.
if((APU.DSP [APU_KOFF] & mask) ==0)
@ -522,7 +517,7 @@ void S9xSetAPUDSP (uint8 byte)
}
spc_is_dumping_temp = byte;
return;
case APU_VOL_LEFT + 0x00:
case APU_VOL_LEFT + 0x10:
case APU_VOL_LEFT + 0x20:
@ -536,7 +531,7 @@ void S9xSetAPUDSP (uint8 byte)
{
#ifdef DEBUGGER
if (Settings.TraceSoundDSP)
S9xTraceSoundDSP ("[%d] %d volume left: %d\n",
S9xTraceSoundDSP ("[%d] %d volume left: %d\n",
ICPU.Scanline, reg>>4, (signed char) byte);
#endif
S9xSetSoundVolume (reg >> 4, (signed char) byte,
@ -556,14 +551,14 @@ void S9xSetAPUDSP (uint8 byte)
{
#ifdef DEBUGGER
if (Settings.TraceSoundDSP)
S9xTraceSoundDSP ("[%d] %d volume right: %d\n",
S9xTraceSoundDSP ("[%d] %d volume right: %d\n",
ICPU.Scanline, reg >>4, (signed char) byte);
#endif
S9xSetSoundVolume (reg >> 4, (signed char) APU.DSP [reg - 1],
(signed char) byte);
}
break;
case APU_P_LOW + 0x00:
case APU_P_LOW + 0x10:
case APU_P_LOW + 0x20:
@ -579,7 +574,7 @@ void S9xSetAPUDSP (uint8 byte)
#endif
S9xSetSoundHertz (reg >> 4, ((byte + (APU.DSP [reg + 1] << 8)) & FREQUENCY_MASK) * 8);
break;
case APU_P_HIGH + 0x00:
case APU_P_HIGH + 0x10:
case APU_P_HIGH + 0x20:
@ -593,10 +588,10 @@ void S9xSetAPUDSP (uint8 byte)
S9xTraceSoundDSP ("[%d] %d freq high: %d\n",
ICPU.Scanline, reg>>4, byte);
#endif
S9xSetSoundHertz (reg >> 4,
S9xSetSoundHertz (reg >> 4,
(((byte << 8) + APU.DSP [reg - 1]) & FREQUENCY_MASK) * 8);
break;
case APU_SRCN + 0x00:
case APU_SRCN + 0x10:
case APU_SRCN + 0x20:
@ -611,7 +606,7 @@ void S9xSetAPUDSP (uint8 byte)
ICPU.Scanline, reg>>4, byte);
#endif
break;
case APU_ADSR1 + 0x00:
case APU_ADSR1 + 0x10:
case APU_ADSR1 + 0x20:
@ -628,12 +623,12 @@ void S9xSetAPUDSP (uint8 byte)
ICPU.Scanline, reg>>4, byte);
#endif
{
S9xFixEnvelope (reg >> 4, APU.DSP [reg + 2], byte,
S9xFixEnvelope (reg >> 4, APU.DSP [reg + 2], byte,
APU.DSP [reg + 1]);
}
}
break;
case APU_ADSR2 + 0x00:
case APU_ADSR2 + 0x10:
case APU_ADSR2 + 0x20:
@ -646,7 +641,7 @@ void S9xSetAPUDSP (uint8 byte)
{
#ifdef DEBUGGER
if (Settings.TraceSoundDSP)
S9xTraceSoundDSP ("[%d] %d adsr2: %02x\n",
S9xTraceSoundDSP ("[%d] %d adsr2: %02x\n",
ICPU.Scanline, reg>>4, byte);
#endif
{
@ -655,7 +650,7 @@ void S9xSetAPUDSP (uint8 byte)
}
}
break;
case APU_GAIN + 0x00:
case APU_GAIN + 0x10:
case APU_GAIN + 0x20:
@ -677,7 +672,7 @@ void S9xSetAPUDSP (uint8 byte)
}
}
break;
case APU_ENVX + 0x00:
case APU_ENVX + 0x10:
case APU_ENVX + 0x20:
@ -687,7 +682,7 @@ void S9xSetAPUDSP (uint8 byte)
case APU_ENVX + 0x60:
case APU_ENVX + 0x70:
break;
case APU_OUTX + 0x00:
case APU_OUTX + 0x10:
case APU_OUTX + 0x20:
@ -697,7 +692,7 @@ void S9xSetAPUDSP (uint8 byte)
case APU_OUTX + 0x60:
case APU_OUTX + 0x70:
break;
case APU_DIR:
#ifdef DEBUGGER
if (Settings.TraceSoundDSP)
@ -705,7 +700,7 @@ void S9xSetAPUDSP (uint8 byte)
ICPU.Scanline, byte);
#endif
break;
case APU_PMON:
if (byte != APU.DSP [APU_PMON])
{
@ -735,7 +730,7 @@ void S9xSetAPUDSP (uint8 byte)
S9xSetFrequencyModulationEnable (byte);
}
break;
case APU_EON:
if (byte != APU.DSP [APU_EON])
{
@ -765,18 +760,18 @@ void S9xSetAPUDSP (uint8 byte)
S9xSetEchoEnable (byte);
}
break;
case APU_EFB:
S9xSetEchoFeedback ((signed char) byte);
break;
case APU_ESA:
break;
case APU_EDL:
S9xSetEchoDelay (byte & 0xf);
break;
case APU_C0:
case APU_C1:
case APU_C2:
@ -792,10 +787,10 @@ void S9xSetAPUDSP (uint8 byte)
//printf ("Write %02x to unknown APU register %02x\n", byte, reg);
break;
}
KeyOnPrev|=KeyOn;
KeyOn=0;
if (reg < 0x80)
APU.DSP [reg] = byte;
}
@ -861,13 +856,13 @@ void S9xSetAPUControl (uint8 byte)
APU.TimerEnabled [0] = byte & 1;
APU.TimerEnabled [1] = (byte & 2) >> 1;
APU.TimerEnabled [2] = (byte & 4) >> 2;
if (byte & 0x10)
IAPU.RAM [0xF4] = IAPU.RAM [0xF5] = 0;
if (byte & 0x20)
IAPU.RAM [0xF6] = IAPU.RAM [0xF7] = 0;
if (byte & 0x80)
{
if (!APU.ShowROM)
@ -890,7 +885,7 @@ void S9xSetAPUControl (uint8 byte)
void S9xSetAPUTimer (uint16 Address, uint8 byte)
{
IAPU.RAM [Address] = byte;
switch (Address)
{
case 0xfa:
@ -911,21 +906,12 @@ void S9xSetAPUTimer (uint16 Address, uint8 byte)
}
}
void S9xAPUExecute (void)
void S9xUpdateAPUTimer (void)
{
while ((CPU.Cycles << SNES_APU_ACCURACY) >= IAPU.NextAPUTimerPos)
while ((CPU.Cycles << SNES_APUTIMER_ACCURACY) >= IAPU.NextAPUTimerPos)
{
// catch up the APU timers
if (IAPU.APUExecuting)
{
while (APU.Cycles < IAPU.NextAPUTimerPos)
APU_EXECUTE1();
}
else
APU.Cycles = IAPU.NextAPUTimerPos;
IAPU.NextAPUTimerPos += SNES_APUTIMER2_CYCLE_SCALED;
IAPU.NextAPUTimerPos += SNES_APUTIMER2_CYCLE_SHIFT;
if (APU.TimerEnabled [2])
{
APU.Timer [2] ++;
@ -933,17 +919,17 @@ void S9xAPUExecute (void)
{
IAPU.RAM [0xff] = (IAPU.RAM [0xff] + 1) & 0xf;
APU.Timer [2] = 0;
#ifdef SPC700_SHUTDOWN
#ifdef SPC700_SHUTDOWN
IAPU.WaitCounter++;
IAPU.APUExecuting = TRUE;
#endif
#endif
}
}
if (++IAPU.APUTimerCounter == 8)
{
IAPU.APUTimerCounter = 0;
if (APU.TimerEnabled [0])
{
APU.Timer [0]++;
@ -951,10 +937,10 @@ void S9xAPUExecute (void)
{
IAPU.RAM [0xfd] = (IAPU.RAM [0xfd] + 1) & 0xf;
APU.Timer [0] = 0;
#ifdef SPC700_SHUTDOWN
#ifdef SPC700_SHUTDOWN
IAPU.WaitCounter++;
IAPU.APUExecuting = TRUE;
#endif
#endif
}
}
@ -965,23 +951,14 @@ void S9xAPUExecute (void)
{
IAPU.RAM [0xfe] = (IAPU.RAM [0xfe] + 1) & 0xf;
APU.Timer [1] = 0;
#ifdef SPC700_SHUTDOWN
#ifdef SPC700_SHUTDOWN
IAPU.WaitCounter++;
IAPU.APUExecuting = TRUE;
#endif
#endif
}
}
}
}
// catch up the current cycles
if (IAPU.APUExecuting)
{
while (APU.Cycles < (CPU.Cycles << SNES_APU_ACCURACY))
APU_EXECUTE1();
}
else
APU.Cycles = (CPU.Cycles << SNES_APU_ACCURACY);
}
uint8 S9xGetAPUDSP ()
@ -1004,18 +981,10 @@ uint8 S9xGetAPUDSP ()
case APU_OUTX + 0x50:
case APU_OUTX + 0x60:
case APU_OUTX + 0x70:
if(Settings.FakeMuteFix)
{
// hack that is off by default: fixes Terranigma desync
return (0);
}
else
{
if (SoundData.channels [reg >> 4].state == SOUND_SILENT)
return (0);
return (int8) (SoundData.channels [reg >> 4].out_sample >> 8);
}
case APU_ENVX + 0x00:
case APU_ENVX + 0x10:
case APU_ENVX + 0x20:
@ -1025,7 +994,7 @@ uint8 S9xGetAPUDSP ()
case APU_ENVX + 0x60:
case APU_ENVX + 0x70:
return (S9xGetEnvelopeHeight (reg >> 4));
case APU_ENDX:
// To fix speech in Magical Drop 2 6/11/00
// APU.DSP [APU_ENDX] = 0;
@ -1034,6 +1003,6 @@ uint8 S9xGetAPUDSP ()
default:
break;
}
return (byte);
}

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef _apu_h_
#define _apu_h_
@ -177,8 +158,8 @@ struct SIAPU
uint8 *WaitAddress1;
uint8 *WaitAddress2;
uint32 WaitCounter;
uint8 *ShadowRAM; // unused
uint8 *CachedSamples; // unused
uint8 *ShadowRAM;
uint8 *CachedSamples;
uint8 _Carry;
uint8 _Zero;
uint8 _Overflow;
@ -192,7 +173,7 @@ struct SIAPU
struct SAPU
{
int32 OldCycles; // unused
int32 Cycles;
bool8 ShowROM;
uint32 Flags;
uint8 KeyedChannels;
@ -203,7 +184,6 @@ struct SAPU
uint16 TimerTarget [3];
bool8 TimerEnabled [3];
bool8 TimerValueWritten [3];
int32 Cycles;
};
EXTERN_C struct SAPU APU;
@ -236,7 +216,7 @@ void S9xSetAPUControl (uint8 byte);
void S9xSetAPUDSP (uint8 byte);
uint8 S9xGetAPUDSP ();
void S9xSetAPUTimer (uint16 Address, uint8 byte);
void S9xAPUExecute (void);
void S9xUpdateAPUTimer (void);
bool8 S9xInitSound (int quality, bool8 stereo, int buffer_size);
void S9xOpenCloseSoundTracingFile (bool8);
void S9xPrintAPUState ();

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,83 +142,85 @@
**********************************************************************************/
#include "snes9x.h"
#include "spc700.h"
#include "apu.h"
#include "soundux.h"
#include "cpuexec.h"
#ifdef SPCTOOL
#include "spctool/spc700.h"
#endif
#ifdef DEBUGGER
extern int32 env_counter_table[32];
FILE *apu_trace = NULL;
static char *S9xMnemonics [256] = {
"NOP", "TCALL 0", "SET1 $%02X.0", "BBS $%02X.0,$%04X",
"OR A,$%02X", "OR A,!$%04X", "OR A,(X)", "OR A,[$%02X+X]",
"OR A,#$%02X", "OR $%02X,$%02X", "OR1 C,$%04X.%d", "ASL $%02X",
"MOV !$%04X,Y", "PUSH PSW", "TSET1 !$%04X", "BRK",
"BPL $%04X", "TCALL 1", "CLR1 $%02X.0", "BBC $%02X.0,$%04X",
"OR A,$%02X+X", "OR A,!$%04X+X", "OR A,!$%04X+Y", "OR A,[$%02X]+Y",
"OR $%02X,#$%02X", "OR (X),(Y)", "DECW $%02X", "ASL $%02X+X",
"ASL A", "DEC X", "CMP X,!$%04X", "JMP [!$%04X+X]",
"CLRP", "TCALL 2", "SET1 $%02X.1", "BBS $%02X.1,$%04X",
"AND A,$%02X", "AND A,!$%04X", "AND A,(X)", "AND A,[$%02X+X]",
"AND A,#$%02X", "AND $%02X,$%02X", "OR1 C,/$%04X.%d", "ROL $%02X",
"ROL !$%04X", "PUSH A", "CBNE $%02X,$%04X", "BRA $%04X",
"BMI $%04X", "TCALL 3", "CLR1 $%02X.1", "BBC $%02X.1,$%04X",
"AND A,$%02X+X", "AND A,!$%04X+X", "AND A,!$%04X+Y", "AND A,[$%02X]+Y",
"AND $%02X,#$%02X", "AND (X),(Y)", "INCW $%02X", "ROL $%02X+X",
"ROL A", "INC X", "CMP X,$%02X", "CALL !$%04X",
"SETP", "TCALL 4", "SET1 $%02X.2", "BBS $%02X.2,$%04X",
"EOR A,$%02X", "EOR A,!$%04X", "EOR A,(X)", "EOR A,[$%02X+X]",
"EOR A,#$%02X", "EOR $%02X,$%02X", "AND1 C,$%04X.%d", "LSR $%02X",
"LSR !$%04X", "PUSH X", "TCLR1 !$%04X", "PCALL $%02X",
"BVC $%04X", "TCALL 5", "CLR1 $%02X.2", "BBC $%02X.2,$%04X",
"EOR A,$%02X+X", "EOR A,!$%04X+X", "EOR A,!$%04X+Y", "EOR A,[$%02X]+Y",
"EOR $%02X,#$%02X", "EOR (X),(Y)", "CMPW YA,$%02X", "LSR $%02X+X",
"LSR A", "MOV X,A", "CMP Y,!$%04X", "JMP !$%04X",
"CLRC", "TCALL 6", "SET1 $%02X.3", "BBS $%02X.3,$%04X",
"CMP A,$%02X", "CMP A,!$%04X", "CMP A,(X)", "CMP A,[$%02X+X]",
"CMP A,#$%02X", "CMP $%02X,$%02X", "AND1 C,/$%04X.%d", "ROR $%02X",
"ROR !$%04X", "PUSH Y", "DBNZ $%02X,$%04X", "RET",
"BVS $%04X", "TCALL 7", "CLR1 $%02X.3", "BBC $%02X.3,$%04X",
"CMP A,$%02X+X", "CMP A,!$%04X+X", "CMP A,!$%04X+Y", "CMP A,[$%02X]+Y",
"CMP $%02X,#$%02X", "CMP (X),(Y)", "ADDW YA,$%02X", "ROR $%02X+X",
"ROR A", "MOV A,X", "CMP Y,$%02X", "RET1",
"SETC", "TCALL 8", "SET1 $%02X.4", "BBS $%02X.4,$%04X",
"ADC A,$%02X", "ADC A,!$%04X", "ADC A,(X)", "ADC A,[$%02X+X]",
"ADC A,#$%02X", "ADC $%02X,$%02X", "EOR1 C,$%04X.%d", "DEC $%02X",
"DEC !$%04X", "MOV Y,#$%02X", "POP PSW", "MOV $%02X,#$%02X",
"BCC $%04X", "TCALL 9", "CLR1 $%02X.4", "BBC $%02X.4,$%04X",
"ADC A,$%02X+X", "ADC A,!$%04X+X", "ADC A,!$%04X+Y", "ADC A,[$%02X]+Y",
"ADC $%02X,#$%02X", "ADC (X),(Y)", "SUBW YA,$%02X", "DEC $%02X+X",
"DEC A", "MOV X,SP", "DIV YA,X", "XCN A",
"EI", "TCALL 10", "SET1 $%02X.5", "BBS $%02X.5,$%04X",
"SBC A,$%02X", "SBC A,!$%04X", "SBC A,(X)", "SBC A,[$%02X+X]",
"SBC A,#$%02X", "SBC $%02X,$%02X", "MOV1 C,$%04X.%d", "INC $%02X",
"INC !$%04X", "CMP Y,#$%02X", "POP A", "MOV (X)+,A",
"BCS $%04X", "TCALL 11", "CLR1 $%02X.5", "BBC $%02X.5,$%04X",
"SBC A,$%02X+X", "SBC A,!$%04X+X", "SBC A,!$%04X+Y", "SBC A,[$%02X]+Y",
"SBC $%02X,#$%02X", "SBC (X),(Y)", "MOVW YA,$%02X", "INC $%02X+X",
"INC A", "MOV SP,X", "DAS A", "MOV A,(X)+",
"DI", "TCALL 12", "SET1 $%02X.6", "BBS $%02X.6,$%04X",
"MOV $%02X,A", "MOV !$%04X,A", "MOV (X),A", "MOV [$%02X+X],A",
"CMP X,#$%02X", "MOV !$%04X,X", "MOV1 $%04X.%d,C", "MOV $%02X,Y",
"ASL !$%04X", "MOV X,#$%02X", "POP X", "MUL YA",
"BNE $%04X", "TCALL 13", "CLR1 $%02X.6", "BBC $%02X.6,$%04X",
"MOV $%02X+X,A", "MOV !$%04X+X,A", "MOV !$%04X+Y,A", "MOV [$%02X]+Y,A",
"MOV $%02X,X", "MOV $%02X+Y,X", "MOVW $%02X,YA", "MOV $%02X+X,Y",
"DEC Y", "MOV A,Y", "CBNE $%02X+X,$%04X", "DAA A",
"CLRV", "TCALL 14", "SET1 $%02X.7", "BBS $%02X.7,$%04X",
"MOV A,$%02X", "MOV A,!$%04X", "MOV A,(X)", "MOV A,[$%02X+X]",
"MOV A,#$%02X", "MOV X,!$%04X", "NOT1 $%04X.%d", "MOV Y,$%02X",
"MOV Y,!$%04X", "NOTC", "POP Y", "SLEEP",
"BEQ $%04X", "TCALL 15", "CLR1 $%02X.7", "BBC $%02X.7,$%04X",
"MOV A,$%02X+X", "MOV A,!$%04X+X", "MOV A,!$%04X+Y", "MOV A,[$%02X]+Y",
"MOV X,$%02X", "MOV X,$%02X+Y", "MOV $%02X,$%02X", "MOV Y,$%02X+X",
"NOP", "TCALL 0", "SET1 $%02X.0", "BBS $%02X.0,$%04X",
"OR A,$%02X", "OR A,!$%04X", "OR A,(X)", "OR A,[$%02X+X]",
"OR A,#$%02X", "OR $%02X,$%02X", "OR1 C,$%04X.%d", "ASL $%02X",
"MOV !$%04X,Y", "PUSH PSW", "TSET1 !$%04X", "BRK",
"BPL $%04X", "TCALL 1", "CLR1 $%02X.0", "BBC $%02X.0,$%04X",
"OR A,$%02X+X", "OR A,!$%04X+X", "OR A,!$%04X+Y", "OR A,[$%02X]+Y",
"OR $%02X,#$%02X", "OR (X),(Y)", "DECW $%02X", "ASL $%02X+X",
"ASL A", "DEC X", "CMP X,!$%04X", "JMP [!$%04X+X]",
"CLRP", "TCALL 2", "SET1 $%02X.1", "BBS $%02X.1,$%04X",
"AND A,$%02X", "AND A,!$%04X", "AND A,(X)", "AND A,[$%02X+X]",
"AND A,#$%02X", "AND $%02X,$%02X", "OR1 C,/$%04X.%d", "ROL $%02X",
"ROL !$%04X", "PUSH A", "CBNE $%02X,$%04X", "BRA $%04X",
"BMI $%04X", "TCALL 3", "CLR1 $%02X.1", "BBC $%02X.1,$%04X",
"AND A,$%02X+X", "AND A,!$%04X+X", "AND A,!$%04X+Y", "AND A,[$%02X]+Y",
"AND $%02X,#$%02X", "AND (X),(Y)", "INCW $%02X", "ROL $%02X+X",
"ROL A", "INC X", "CMP X,$%02X", "CALL !$%04X",
"SETP", "TCALL 4", "SET1 $%02X.2", "BBS $%02X.2,$%04X",
"EOR A,$%02X", "EOR A,!$%04X", "EOR A,(X)", "EOR A,[$%02X+X]",
"EOR A,#$%02X", "EOR $%02X,$%02X", "AND1 C,$%04X.%d", "LSR $%02X",
"LSR !$%04X", "PUSH X", "TCLR1 !$%04X", "PCALL $%02X",
"BVC $%04X", "TCALL 5", "CLR1 $%02X.2", "BBC $%02X.2,$%04X",
"EOR A,$%02X+X", "EOR A,!$%04X+X", "EOR A,!$%04X+Y", "EOR A,[$%02X]+Y",
"EOR $%02X,#$%02X", "EOR (X),(Y)", "CMPW YA,$%02X", "LSR $%02X+X",
"LSR A", "MOV X,A", "CMP Y,!$%04X", "JMP !$%04X",
"CLRC", "TCALL 6", "SET1 $%02X.3", "BBS $%02X.3,$%04X",
"CMP A,$%02X", "CMP A,!$%04X", "CMP A,(X)", "CMP A,[$%02X+X]",
"CMP A,#$%02X", "CMP $%02X,$%02X", "AND1 C,/$%04X.%d", "ROR $%02X",
"ROR !$%04X", "PUSH Y", "DBNZ $%02X,$%04X", "RET",
"BVS $%04X", "TCALL 7", "CLR1 $%02X.3", "BBC $%02X.3,$%04X",
"CMP A,$%02X+X", "CMP A,!$%04X+X", "CMP A,!$%04X+Y", "CMP A,[$%02X]+Y",
"CMP $%02X,#$%02X", "CMP (X),(Y)", "ADDW YA,$%02X", "ROR $%02X+X",
"ROR A", "MOV A,X", "CMP Y,$%02X", "RET1",
"SETC", "TCALL 8", "SET1 $%02X.4", "BBS $%02X.4,$%04X",
"ADC A,$%02X", "ADC A,!$%04X", "ADC A,(X)", "ADC A,[$%02X+X]",
"ADC A,#$%02X", "ADC $%02X,$%02X", "EOR1 C,$%04X.%d", "DEC $%02X",
"DEC !$%04X", "MOV Y,#$%02X", "POP PSW", "MOV $%02X,#$%02X",
"BCC $%04X", "TCALL 9", "CLR1 $%02X.4", "BBC $%02X.4,$%04X",
"ADC A,$%02X+X", "ADC A,!$%04X+X", "ADC A,!$%04X+Y", "ADC A,[$%02X]+Y",
"ADC $%02X,#$%02X", "ADC (X),(Y)", "SUBW YA,$%02X", "DEC $%02X+X",
"DEC A", "MOV X,SP", "DIV YA,X", "XCN A",
"EI", "TCALL 10", "SET1 $%02X.5", "BBS $%02X.5,$%04X",
"SBC A,$%02X", "SBC A,!$%04X", "SBC A,(X)", "SBC A,[$%02X+X]",
"SBC A,#$%02X", "SBC $%02X,$%02X", "MOV1 C,$%04X.%d", "INC $%02X",
"INC !$%04X", "CMP Y,#$%02X", "POP A", "MOV (X)+,A",
"BCS $%04X", "TCALL 11", "CLR1 $%02X.5", "BBC $%02X.5,$%04X",
"SBC A,$%02X+X", "SBC A,!$%04X+X", "SBC A,!$%04X+Y", "SBC A,[$%02X]+Y",
"SBC $%02X,#$%02X", "SBC (X),(Y)", "MOVW YA,$%02X", "INC $%02X+X",
"INC A", "MOV SP,X", "DAS A", "MOV A,(X)+",
"DI", "TCALL 12", "SET1 $%02X.6", "BBS $%02X.6,$%04X",
"MOV $%02X,A", "MOV !$%04X,A", "MOV (X),A", "MOV [$%02X+X],A",
"CMP X,#$%02X", "MOV !$%04X,X", "MOV1 $%04X.%d,C", "MOV $%02X,Y",
"ASL !$%04X", "MOV X,#$%02X", "POP X", "MUL YA",
"BNE $%04X", "TCALL 13", "CLR1 $%02X.6", "BBC $%02X.6,$%04X",
"MOV $%02X+X,A", "MOV !$%04X+X,A", "MOV !$%04X+Y,A", "MOV [$%02X]+Y,A",
"MOV $%02X,X", "MOV $%02X+Y,X", "MOVW $%02X,YA", "MOV $%02X+X,Y",
"DEC Y", "MOV A,Y", "CBNE $%02X+X,$%04X", "DAA A",
"CLRV", "TCALL 14", "SET1 $%02X.7", "BBS $%02X.7,$%04X",
"MOV A,$%02X", "MOV A,!$%04X", "MOV A,(X)", "MOV A,[$%02X+X]",
"MOV A,#$%02X", "MOV X,!$%04X", "NOT1 $%04X.%d", "MOV Y,$%02X",
"MOV Y,!$%04X", "NOTC", "POP Y", "SLEEP",
"BEQ $%04X", "TCALL 15", "CLR1 $%02X.7", "BBC $%02X.7,$%04X",
"MOV A,$%02X+X", "MOV A,!$%04X+X", "MOV A,!$%04X+Y", "MOV A,[$%02X]+Y",
"MOV X,$%02X", "MOV X,$%02X+Y", "MOV $%02X,$%02X", "MOV Y,$%02X+X",
"INC Y", "MOV Y,A", "DBNZ Y,$%04X", "STOP"
};
@ -346,7 +331,7 @@ void S9xTraceSoundDSP (const char *s, int i1 = 0, int i2 = 0, int i3 = 0,
int S9xTraceAPU ()
{
char buffer [200];
uint8 b = S9xAPUOPrint (buffer, IAPU.PC - IAPU.RAM);
if (apu_trace == NULL)
apu_trace = fopen ("apu_trace.log", "wb");
@ -361,7 +346,7 @@ int S9xAPUOPrint (char *buffer, uint16 Address)
uint8 *p = IAPU.RAM + Address;
int mode = Modes [*p];
int bytes = ModesToBytes [mode];
switch (bytes)
{
case 1:
@ -422,8 +407,8 @@ int S9xAPUOPrint (char *buffer, uint16 Address)
APUCheckCarry () ? 'C' : 'c',
CPU.V_Counter,
CPU.Cycles,
APU.Cycles >> SNES_APU_ACCURACY);
APU.Cycles);
return (bytes);
}
@ -493,7 +478,7 @@ void S9xPrintAPUState ()
printf ("left: %d, right: %d, ",
ch->volume_left, ch->volume_right);
static char* envelope [] =
static char* envelope [] =
{
"silent", "attack", "decay", "sustain", "release", "gain",
"inc_lin", "inc_bent", "dec_lin", "dec_exp"

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,152 +142,162 @@
**********************************************************************************/
#ifndef _apumemory_h_
#define _apumemory_h_
START_EXTERN_C
extern uint8 W4;
extern uint8 APUROM[64];
END_EXTERN_C
static INLINE uint8 apu_get_reg (uint8 Address)
{
switch (Address)
{
case 0xf0: // -w TEST
return 0;
case 0xf1: // -w CONTROL
return 0;
case 0xf2: // rw DSPADDR
return (IAPU.RAM[Address]);
case 0xf3: // rw DSPDATA
return (S9xGetAPUDSP());
case 0xf4: // r- CPUI0
case 0xf5: // r- CPUI1
case 0xf6: // r- CPUI2
case 0xf7: // r- CPUI3
#ifdef SPC700_SHUTDOWN
IAPU.WaitAddress2 = IAPU.WaitAddress1;
IAPU.WaitAddress1 = IAPU.PC;
#endif
return (IAPU.RAM[Address]);
case 0xf8: // rw - Normal RAM
case 0xf9: // rw - Normal RAM
return (IAPU.RAM[Address]);
case 0xfa: // -w T0TARGET
case 0xfb: // -w T1TARGET
case 0xfc: // -w T2TARGET
return 0;
case 0xfd: // r- T0OUT
case 0xfe: // r- T1OUT
case 0xff: // r- T2OUT
#ifdef SPC700_SHUTDOWN
IAPU.WaitAddress2 = IAPU.WaitAddress1;
IAPU.WaitAddress1 = IAPU.PC;
#endif
uint8 t = IAPU.RAM[Address] & 0xF;
IAPU.RAM[Address] = 0;
return (t);
}
return 0;
}
static INLINE void apu_set_reg (uint8 byte, uint8 Address)
{
switch (Address)
{
case 0xf0: // -w TEST
//printf("Write %02X to APU 0xF0!\n", byte);
return;
case 0xf1: // -w CONTROL
S9xSetAPUControl(byte);
return;
case 0xf2: // rw DSPADDR
IAPU.RAM[Address] = byte;
return;
case 0xf3: // rw DSPDATA
S9xSetAPUDSP(byte);
return;
case 0xf4: // -w CPUO0
case 0xf5: // -w CPUO1
case 0xf6: // -w CPUO2
case 0xf7: // -w CPUO3
APU.OutPorts[Address - 0xf4] = byte;
return;
case 0xf8: // rw - Normal RAM
case 0xf9: // rw - Normal RAM
IAPU.RAM[Address] = byte;
return;
case 0xfa: // -w T0TARGET
case 0xfb: // -w T1TARGET
case 0xfc: // -w T2TARGET
IAPU.RAM[Address] = byte;
if (byte == 0)
APU.TimerTarget[Address - 0xfa] = 0x100;
else
APU.TimerTarget[Address - 0xfa] = byte;
return;
case 0xfd: // r- T0OUT
case 0xfe: // r- T1OUT
case 0xff: // r- T2OUT
return;
}
}
INLINE uint8 S9xAPUGetByteZ (uint8 Address)
{
if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM)
return (apu_get_reg(Address));
if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM)
{
if (Address >= 0xf4 && Address <= 0xf7)
{
#ifdef SPC700_SHUTDOWN
IAPU.WaitAddress2 = IAPU.WaitAddress1;
IAPU.WaitAddress1 = IAPU.PC;
#endif
return (IAPU.RAM [Address]);
}
if (Address >= 0xfd)
{
#ifdef SPC700_SHUTDOWN
IAPU.WaitAddress2 = IAPU.WaitAddress1;
IAPU.WaitAddress1 = IAPU.PC;
#endif
uint8 t = IAPU.RAM [Address];
IAPU.RAM [Address] = 0;
return (t);
}
else
return (IAPU.DirectPage[Address]);
if (Address == 0xf3)
return (S9xGetAPUDSP ());
return (IAPU.RAM [Address]);
}
else
return (IAPU.DirectPage [Address]);
}
INLINE void S9xAPUSetByteZ (uint8 byte, uint8 Address)
{
if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM)
apu_set_reg(byte, Address);
{
if (Address == 0xf3)
S9xSetAPUDSP (byte);
else
if (Address >= 0xf4 && Address <= 0xf7)
APU.OutPorts [Address - 0xf4] = byte;
else
if (Address == 0xf1)
S9xSetAPUControl (byte);
else
if (Address < 0xfd)
{
IAPU.RAM [Address] = byte;
if (Address >= 0xfa)
{
if (byte == 0)
APU.TimerTarget [Address - 0xfa] = 0x100;
else
APU.TimerTarget [Address - 0xfa] = byte;
}
}
}
else
IAPU.DirectPage[Address] = byte;
IAPU.DirectPage [Address] = byte;
}
INLINE uint8 S9xAPUGetByte (uint32 Address)
{
Address &= 0xffff;
if (Address <= 0xff && Address >= 0xf0)
return (apu_get_reg(Address & 0xff));
{
if (Address >= 0xf4 && Address <= 0xf7)
{
#ifdef SPC700_SHUTDOWN
IAPU.WaitAddress2 = IAPU.WaitAddress1;
IAPU.WaitAddress1 = IAPU.PC;
#endif
return (IAPU.RAM [Address]);
}
else
if (Address == 0xf3)
return (S9xGetAPUDSP ());
if (Address >= 0xfd)
{
#ifdef SPC700_SHUTDOWN
IAPU.WaitAddress2 = IAPU.WaitAddress1;
IAPU.WaitAddress1 = IAPU.PC;
#endif
uint8 t = IAPU.RAM [Address];
IAPU.RAM [Address] = 0;
return (t);
}
return (IAPU.RAM [Address]);
}
else
return (IAPU.RAM[Address]);
return (IAPU.RAM [Address]);
}
INLINE void S9xAPUSetByte (uint8 byte, uint32 Address)
{
Address &= 0xffff;
if (Address <= 0xff && Address >= 0xf0)
apu_set_reg(byte, Address & 0xff);
{
if (Address == 0xf3)
S9xSetAPUDSP (byte);
else
if (Address >= 0xf4 && Address <= 0xf7)
APU.OutPorts [Address - 0xf4] = byte;
else
if (Address == 0xf1)
S9xSetAPUControl (byte);
else
if (Address < 0xfd)
{
IAPU.RAM [Address] = byte;
if (Address >= 0xfa)
{
if (byte == 0)
APU.TimerTarget [Address - 0xfa] = 0x100;
else
APU.TimerTarget [Address - 0xfa] = byte;
}
}
}
else
{
#if 0
if (Address >= 0x2500 && Address <= 0x2504)
printf ("%06d %04x <- %02x\n", ICPU.Scanline, Address, byte);
if (Address == 0x26c6)
{
extern FILE *apu_trace;
extern FILE *trace;
APU.Flags |= TRACE_FLAG;
CPU.Flags |= TRACE_FLAG;
if (apu_trace == NULL)
apu_trace = fopen ("aputrace.log", "wb");
if (trace == NULL)
trace = fopen ("trace.log", "wb");
printf ("TRACING SWITCHED ON\n");
}
#endif
if (Address < 0xffc0)
IAPU.RAM[Address] = byte;
IAPU.RAM [Address] = byte;
else
{
APU.ExtraRAM[Address - 0xffc0] = byte;
APU.ExtraRAM [Address - 0xffc0] = byte;
if (!APU.ShowROM)
IAPU.RAM[Address] = byte;
IAPU.RAM [Address] = byte;
}
}
}
#endif
#endif // _apumemory_h_

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
// Anonymous wrote:
// Large thanks to John Weidman for all his initial research
// Thanks to Seph3 for his modem notes
@ -246,9 +227,9 @@ static int is_bsx(unsigned char *);
static void BSX_Map_SNES(void)
{
// These maps will be partially overwritten
int c;
// Banks 00->3F and 80->BF
for (c = 0; c < 0x400; c += 16)
{
@ -256,7 +237,7 @@ static void BSX_Map_SNES(void)
Map[c + 1] = Map[c + 0x801] = RAM;
BlockIsRAM[c + 0] = BlockIsRAM[c + 0x800] = TRUE;
BlockIsRAM[c + 1] = BlockIsRAM[c + 0x801] = TRUE;
Map[c + 2] = Map[c + 0x802] = (uint8 *) MAP_PPU;
Map[c + 3] = Map[c + 0x803] = (uint8 *) MAP_PPU;
Map[c + 4] = Map[c + 0x804] = (uint8 *) MAP_CPU;
@ -269,9 +250,9 @@ static void BSX_Map_SNES(void)
static void BSX_Map_LoROM(void)
{
// These maps will be partially overwritten
int i, c;
// Banks 00->3F and 80->BF
for (c = 0; c < 0x400; c += 16)
{
@ -282,16 +263,16 @@ static void BSX_Map_LoROM(void)
BlockIsROM[i] = BlockIsROM[i + 0x800] = !BSX.write_enable;
}
}
// Banks 40->7F and C0->FF
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 8; i++)
Map[i + 0x400] = Map[i + 0xC00] = &MapROM[(c << 11) % FlashSize];
for (i = c + 8; i < c + 16; i++)
Map[i + 0x400] = Map[i + 0xC00] = &MapROM[(c << 11) % FlashSize] - 0x8000;
for (i = c; i < c + 16; i++)
{
BlockIsRAM[i + 0x400] = BlockIsRAM[i + 0xC00] = BSX.write_enable;
@ -303,9 +284,9 @@ static void BSX_Map_LoROM(void)
static void BSX_Map_HiROM(void)
{
// These maps will be partially overwritten
int i, c;
// Banks 00->3F and 80->BF
for (c = 0; c < 0x400; c += 16)
{
@ -316,7 +297,7 @@ static void BSX_Map_HiROM(void)
BlockIsROM[i] = BlockIsROM[i + 0x800] = !BSX.write_enable;
}
}
// Banks 40->7F and C0->FF
for (c = 0; c < 0x400; c += 16)
{
@ -332,7 +313,7 @@ static void BSX_Map_HiROM(void)
static void BSX_Map_MMC(void)
{
int c;
// Banks 01->0E:5000-5FFF
for (c = 0x010; c < 0x0F0; c += 16)
{
@ -344,7 +325,7 @@ static void BSX_Map_MMC(void)
static void BSX_Map_FlashIO(void)
{
int c;
if (BSX.MMC[0x0C] || BSX.MMC[0x0D])
{
// Bank C0:0000, 2AAA, 5555, FF00-FF1F
@ -360,7 +341,7 @@ static void BSX_Map_FlashIO(void)
static void BSX_Map_SRAM(void)
{
int c;
// Banks 10->17:5000-5FFF
for (c = 0x100; c < 0x180; c += 16)
{
@ -373,9 +354,9 @@ static void BSX_Map_SRAM(void)
static void map_psram_mirror_sub(uint32 bank)
{
int i, c;
bank <<= 4;
if (BSX.MMC[0x02])
{
for (c = 0; c < 0x100; c += 16)
@ -394,10 +375,10 @@ static void map_psram_mirror_sub(uint32 bank)
{
for (i = c; i < c + 8; i++)
Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE];
for (i = c + 8; i < c + 16; i++)
Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE] - 0x8000;
for (i = c; i < c + 16; i++)
{
BlockIsRAM[i + bank] = TRUE;
@ -410,7 +391,7 @@ static void map_psram_mirror_sub(uint32 bank)
static void BSX_Map_PSRAM(void)
{
int c;
// Banks 70->77:0000-FFFF
// FIXME: could be toggled by $03
for (c = 0; c < 0x80; c++)
@ -419,7 +400,7 @@ static void BSX_Map_PSRAM(void)
BlockIsRAM[c + 0x700] = TRUE;
BlockIsROM[c + 0x700] = FALSE;
}
// Banks 20->3F:6000-7FFF mirrors 70->77:6000-7FFF
for (c = 0x200; c < 0x400; c += 16)
{
@ -430,15 +411,15 @@ static void BSX_Map_PSRAM(void)
BlockIsROM[c + 6] = FALSE;
BlockIsROM[c + 7] = FALSE;
}
if (!BSX.MMC[0x05])
// Banks 40->4F:0000-FFFF mirrors 70->77:0000-7FFF
map_psram_mirror_sub(0x40);
if (!BSX.MMC[0x06])
// Banks 50->5F:0000-FFFF mirrors 70->77:0000-7FFF
map_psram_mirror_sub(0x50);
// FIXME
if (!BSX.MMC[0x03])
// Banks 60->6F:0000-FFFF mirrors 70->77:0000-7FFF (?)
@ -448,7 +429,7 @@ static void BSX_Map_PSRAM(void)
static void BSX_Map_BIOS(void)
{
int i,c;
// Banks 00->1F:8000-FFFF
if (BSX.MMC[0x07])
{
@ -462,7 +443,7 @@ static void BSX_Map_BIOS(void)
}
}
}
// Banks 80->9F:8000-FFFF
if (BSX.MMC[0x08])
{
@ -481,7 +462,7 @@ static void BSX_Map_BIOS(void)
static void BSX_Map_RAM(void)
{
int c;
// Banks 7E->7F
for (c = 0; c < 16; c++)
{
@ -497,9 +478,9 @@ static void BSX_Map_RAM(void)
static void BSX_Map_Dirty(void)
{
// for the quick bank change
int i, c;
// Banks 00->1F and 80->9F:8000-FFFF
if (BSX.MMC[0x02])
{
@ -534,21 +515,21 @@ static void BSX_Map(void)
for (int i = 0; i < 32; i++)
printf("BS: MMC %02X: %d\n", i, BSX.MMC[i]);
#endif
memcpy(BSX.prevMMC, BSX.MMC, sizeof(BSX.MMC));
// Do a quick bank change
if (BSX.dirty2 && !BSX.dirty)
{
BSX_Map_Dirty();
BSX_Map_BIOS();
BSX.dirty2 = FALSE;
Memory.map_WriteProtectROM();
Memory.WriteProtectROM();
return;
}
if (BSX.MMC[0x01])
{
MapROM = PSRAM;
@ -559,27 +540,27 @@ static void BSX_Map(void)
MapROM = FlashROM;
FlashSize = FLASH_SIZE;
}
BSX_Map_SNES();
if (BSX.MMC[0x02])
BSX_Map_HiROM();
else
BSX_Map_LoROM();
BSX_Map_PSRAM();
BSX_Map_SRAM();
BSX_Map_RAM();
BSX_Map_BIOS();
BSX_Map_FlashIO();
BSX_Map_MMC();
// Monitor new register changes
BSX.dirty = FALSE;
BSX.dirty2 = FALSE;
Memory.map_WriteProtectROM();
Memory.WriteProtectROM();
}
static uint8 BSX_Get_Bypass_FlashIO(uint16 offset)
@ -613,17 +594,17 @@ uint8 S9xGetBSX(uint32 address)
uint8 bank = (address >> 16) & 0xFF;
uint16 offset = address & 0xFFFF;
uint8 t = 0;
// MMC
if ((bank >= 0x01 && bank <= 0x0E) && (offset == 0x5000))
return BSX.MMC[bank];
// Flash IO
if (bank == 0xC0)
{
// default: read-through mode
t = BSX_Get_Bypass_FlashIO(offset);
// note: may be more registers, purposes unknown
switch (offset)
{
@ -631,12 +612,12 @@ uint8 S9xGetBSX(uint32 address)
if (BSX.flash_enable)
t = 0x80; // status register?
break;
case 0x5555:
if (BSX.flash_enable)
t = 0x80; // ???
break;
case 0xFF00:
case 0xFF02:
case 0xFF04:
@ -653,7 +634,7 @@ uint8 S9xGetBSX(uint32 address)
break;
}
}
return t;
}
@ -661,7 +642,7 @@ void S9xSetBSX(uint8 byte, uint32 address)
{
uint8 bank = (address >> 16) & 0xFF;
uint16 offset = address & 0xFFFF;
// MMC
if ((bank >= 0x01 && bank <= 0x0E) && (offset == 0x5000))
{
@ -684,7 +665,7 @@ void S9xSetBSX(uint8 byte, uint32 address)
BSX.dirty = TRUE;
}
break;
case 0x07:
case 0x08:
if (BSX.MMC[bank] != byte)
@ -693,7 +674,7 @@ void S9xSetBSX(uint8 byte, uint32 address)
BSX.dirty2 = TRUE;
}
break;
case 0x0E:
BSX.MMC[bank] = byte;
if (byte && (BSX.dirty || BSX.dirty2))
@ -701,13 +682,13 @@ void S9xSetBSX(uint8 byte, uint32 address)
break;
}
}
// Flash IO
if (bank == 0xC0)
{
BSX.old_write = BSX.new_write;
BSX.new_write = address;
// ???: double writes to the desired address will bypass
// flash registers
if (BSX.old_write == BSX.new_write && BSX.write_enable)
@ -715,7 +696,7 @@ void S9xSetBSX(uint8 byte, uint32 address)
BSX_Set_Bypass_FlashIO(offset, byte);
return;
}
// flash command handling
// note: incomplete
switch (offset)
@ -730,16 +711,16 @@ void S9xSetBSX(uint8 byte, uint32 address)
BSX.read_enable = TRUE;
}
break;
case 0x2AAA:
BSX.flash_command <<= 8;
BSX.flash_command |= byte;
break;
case 0x5555:
BSX.flash_command <<= 8;
BSX.flash_command |= byte;
switch (BSX.flash_command & 0xFFFFFF)
{
case 0xAA55F0:
@ -748,7 +729,7 @@ void S9xSetBSX(uint8 byte, uint32 address)
BSX.write_enable = FALSE;
BSX.read_enable = FALSE;
break;
case 0xAA55A0:
// enable writing to flash
BSX.old_write = 0;
@ -757,20 +738,20 @@ void S9xSetBSX(uint8 byte, uint32 address)
BSX.write_enable = TRUE;
BSX_Map();
break;
case 0xAA5570:
// turn on write-protection
BSX.write_enable = FALSE;
BSX_Map();
break;
case 0xAA5580:
case 0xAA5510:
// ???
break;
}
break;
}
}
@ -779,7 +760,7 @@ void S9xSetBSX(uint8 byte, uint32 address)
uint8 S9xGetBSXPPU(uint16 address)
{
uint8 t = 0;
if (address >= 0x2188 && address <= 0x219F)
{
// known read registers
@ -789,44 +770,44 @@ uint8 S9xGetBSXPPU(uint16 address)
case 0x2188:
t = BSX.PPU[0x2188];
break;
// Test register high? (r/w)
case 0x2189:
t = BSX.PPU[0x2189];
break;
case 0x218A:
t = BSX.PPU[0x218A];
break;
case 0x218C:
t = BSX.PPU[0x218C];
break;
// Transmission number low? (r/w)
case 0x218E:
t = BSX.PPU[0x218E];
break;
// Transmission number high? (r/w)
case 0x218F:
t = BSX.PPU[0x218F];
break;
// Status register? (r)
case 0x2190:
t = BSX.PPU[0x2190];
break;
// Data register? (r/w)
case 0x2192:
t = BSX.PPU[0x2192];
// test
t = BSX.test2192[BSX.out_index++];
if (BSX.out_index == 32)
BSX.out_index = 0;
BSX_RTC.ticks++;
if (BSX_RTC.ticks >= 1000)
{
@ -845,45 +826,45 @@ uint8 S9xGetBSXPPU(uint16 address)
}
if (BSX_RTC.hours >= 24)
BSX_RTC.hours = 0;
BSX.test2192[10] = BSX_RTC.seconds;
BSX.test2192[11] = BSX_RTC.minutes;
BSX.test2192[12] = BSX_RTC.hours;
break;
// Transmission status? (r/w)
case 0x2193:
// Data ready when bits 2/3 clear?
t = BSX.PPU[0x2193] & ~0x0C;
break;
// Reset? (r/w)
case 0x2194:
t = BSX.PPU[0x2194];
break;
// Unknown (r)
case 0x2196:
t = BSX.PPU[0x2196];
break;
// Unknown (r/w)
case 0x2197:
t = BSX.PPU[0x2197];
break;
// Modem protocol? (r/w)
case 0x2199:
t = BSX.PPU[0x2199];
break;
default:
t = OpenBus;
break;
}
}
return t;
}
@ -898,68 +879,68 @@ void S9xSetBSXPPU(uint8 byte, uint16 address)
case 0x2188:
BSX.PPU[0x2188] = byte;
break;
// Test register high? (r/w)
case 0x2189:
BSX.PPU[0x2189] = byte;
break;
case 0x218A:
BSX.PPU[0x218A] = byte;
break;
case 0x218B:
BSX.PPU[0x218B] = byte;
break;
case 0x218C:
BSX.PPU[0x218C] = byte;
break;
// Transmission number low? (r/w)
case 0x218E:
BSX.PPU[0x218E] = byte;
break;
// Transmission number high? (r/w)
case 0x218F:
BSX.PPU[0x218F] = byte;
// ?
BSX.PPU[0x218E] >>= 1;
BSX.PPU[0x218E] = BSX.PPU[0x218F] - BSX.PPU[0x218E];
BSX.PPU[0x218F] >>= 1;
BSX.PPU[0x2190] = 0x80; // ?
break;
// Strobe assert? (w)
case 0x2191:
BSX.PPU[0x2191] = byte;
BSX.out_index = 0;
break;
// Data register? (r/w)
case 0x2192:
BSX.PPU[0x2192] = 0x01; // ?
BSX.PPU[0x2190] = 0x80; // ?
break;
// Transmission status? (r/w)
case 0x2193:
BSX.PPU[0x2193] = byte;
break;
// Reset? (r/w)
case 0x2194:
BSX.PPU[0x2194] = byte;
break;
// Unknown (r/w)
case 0x2197:
BSX.PPU[0x2197] = byte;
break;
// Modem protocol? (r/w)
case 0x2199:
// Lots of modem strings written here when
@ -970,35 +951,27 @@ void S9xSetBSXPPU(uint8 byte, uint16 address)
}
}
uint8 * S9xGetBasePointerBSX(uint32 address)
uint8 * S9xGetPasePointerBSX(uint32 address)
{
return MapROM;
}
static bool8 BSX_LoadBIOS(void)
{
return FALSE; // We're not loading the BIOS!
#ifndef NGC
FILE *fp;
char path[_MAX_PATH + 1], name[_MAX_PATH + 1];
char path[_MAX_PATH + 1];
bool8 r = FALSE;
strcpy(path, S9xGetDirectory(BIOS_DIR));
strcat(path, SLASH_STR);
strcpy(name, path);
strcat(name, "BS-X.bin");
fp = fopen(name, "rb");
if (!fp)
{
strcpy(name, path);
strcat(name, "BS-X.bios");
fp = fopen(name, "rb");
}
strcat(path, "BS-X.bios");
fp = fopen(path, "rb");
if (fp)
{
size_t size;
size = fread((void *) BIOSROM, 1, BIOS_SIZE, fp);
fclose(fp);
if (size == BIOS_SIZE)
@ -1011,61 +984,65 @@ static bool8 BSX_LoadBIOS(void)
else
printf("BS: BIOS not found!\n");
#endif
return r;
#else
return false;
#endif
}
void S9xInitBSX(void)
{
Settings.BS = FALSE;
if (!memcmp(&Memory.ROM[0x7FC0], "Satellaview BS-X ", 21))
if (!memcmp(&ROM[0x7FC0], "Satellaview BS-X ", 21))
{
// BS-X itself
Settings.BS = TRUE;
Settings.BSXItself = TRUE;
Memory.LoROM = TRUE;
Memory.HiROM = FALSE;
memmove(BIOSROM, Memory.ROM, BIOS_SIZE);
memmove(BIOSROM, ROM, BIOS_SIZE);
FlashMode = FALSE;
FlashSize = FLASH_SIZE;
BSX.bootup = TRUE;
}
else
{
Settings.BSXItself = FALSE;
int r1, r2;
r1 = (is_bsx(Memory.ROM + 0x7FC0) == 1);
r2 = (is_bsx(Memory.ROM + 0xFFC0) == 1);
r1 = (is_bsx(ROM + 0x7FC0) == 1);
r2 = (is_bsx(ROM + 0xFFC0) == 1);
Settings.BS = (r1 | r2) ? TRUE : FALSE;
if (Settings.BS)
{
// BS games
Memory.LoROM = r1 ? TRUE : FALSE;
Memory.HiROM = r2 ? TRUE : FALSE;
uint8 *header = r1 ? Memory.ROM + 0x7FC0 : Memory.ROM + 0xFFC0;
uint8 *header = r1 ? ROM + 0x7FC0 : ROM + 0xFFC0;
FlashMode = (header[0x18] & 0xEF) == 0x20 ? FALSE : TRUE;
FlashSize = (header[0x19] & 0x20) ? PSRAM_SIZE : FLASH_SIZE;
#ifdef BSX_DEBUG
for (int i = 0; i <= 0x1F; i++)
printf("BS: ROM Header %02X: %02X\n", i, header[i]);
printf("BS: FlashMode: %d, FlashSize: %x\n", FlashMode, FlashSize);
#endif
BSX.bootup = Settings.BSXBootup;
if (!BSX_LoadBIOS())
{
BSX.bootup = FALSE;
@ -1073,18 +1050,18 @@ void S9xInitBSX(void)
}
}
}
if (Settings.BS)
{
MapROM = NULL;
FlashROM = Memory.ROM;
FlashROM = ROM;
time_t t;
struct tm *tmr;
time(&t);
tmr = localtime(&t);
BSX_RTC.ticks = 0;
memcpy(BSX.test2192, init2192, sizeof(init2192));
BSX.test2192[10] = BSX_RTC.seconds = tmr->tm_sec;
@ -1100,12 +1077,12 @@ void S9xInitBSX(void)
void S9xResetBSX(void)
{
if (Settings.BSXItself)
memset(Memory.ROM, 0, FLASH_SIZE);
memset(ROM, 0, FLASH_SIZE);
memset(BSX.PPU, 0, sizeof(BSX.PPU));
memset(BSX.MMC, 0, sizeof(BSX.MMC));
memset(BSX.prevMMC, 0, sizeof(BSX.prevMMC));
BSX.dirty = FALSE;
BSX.dirty2 = FALSE;
BSX.flash_enable = FALSE;
@ -1114,22 +1091,22 @@ void S9xResetBSX(void)
BSX.flash_command = 0;
BSX.old_write = 0;
BSX.new_write = 0;
BSX.out_index = 0;
memset(BSX.output, 0, sizeof(BSX.output));
// starting from the bios
if (BSX.bootup)
BSX.MMC[0x07] = BSX.MMC[0x08] = 0x80;
else
{
BSX.MMC[0x02] = FlashMode ? 0x80: 0;
// per bios: run from psram or flash card
if (FlashSize == PSRAM_SIZE)
{
memcpy(PSRAM, FlashROM, PSRAM_SIZE);
BSX.MMC[0x01] = 0x80;
BSX.MMC[0x03] = 0x80;
BSX.MMC[0x04] = 0x80;
@ -1142,10 +1119,10 @@ void S9xResetBSX(void)
BSX.MMC[0x05] = 0x80;
BSX.MMC[0x06] = 0x80;
}
BSX.MMC[0x0E] = 0x80;
}
BSX_Map();
}
@ -1153,17 +1130,17 @@ void S9xFixBSXAfterSnapshotLoad(void)
{
uint8 temp[16];
bool8 pd1, pd2;
pd1 = BSX.dirty;
pd2 = BSX.dirty2;
memcpy(temp, BSX.MMC, sizeof(BSX.MMC));
memcpy(BSX.MMC, BSX.prevMMC, sizeof(BSX.MMC));
BSX_Map();
memcpy(BSX.MMC, temp, sizeof(BSX.MMC));
BSX.dirty = pd1;
BSX.dirty2 = pd2;
BSX.dirty2 = pd2;
}
static bool valid_normal_bank(unsigned char bankbyte)

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef _BSX_H_
#define _BSX_H_
@ -183,17 +164,15 @@ struct SBSX
uint8 test2192[32];
};
START_EXTERN_C
extern struct SBSX BSX;
uint8 S9xGetBSX(uint32);
void S9xSetBSX(uint8, uint32);
uint8 S9xGetBSXPPU(uint16);
void S9xSetBSXPPU(uint8, uint16);
uint8 * S9xGetBasePointerBSX(uint32);
uint8 * S9xGetPasePointerBSX(uint32);
void S9xInitBSX(void);
void S9xResetBSX(void);
void S9xFixBSXAfterSnapshotLoad(void);
END_EXTERN_C
#endif

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -158,8 +141,6 @@
Nintendo Co., Limited and its subsidiary companies.
**********************************************************************************/
#include <math.h>
#include <stdlib.h>
#include "c4.h"
@ -183,22 +164,22 @@ void C4TransfWireFrame ()
c4x = (double) C4WFXVal;
c4y = (double) C4WFYVal;
c4z = (double) C4WFZVal - 0x95;
// Rotate X
tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128;
c4y2 = c4y * cos (tanval) - c4z * sin (tanval);
c4z2 = c4y * sin (tanval) + c4z * cos (tanval);
// Rotate Y
tanval = -(double)C4WFY2Val*3.14159265*2/128;
c4x2 = c4x * cos (tanval) + c4z2 * sin (tanval);
c4z = c4x * - sin (tanval) + c4z2 * cos (tanval);
// Rotate Z
tanval = -(double) C4WFDist * 3.14159265*2 / 128;
c4x = c4x2 * cos (tanval) - c4y2 * sin (tanval);
c4y = c4x2 * sin (tanval) + c4y2 * cos (tanval);
// Scale
C4WFXVal = (short) (c4x*(double)C4WFScale/(0x90*(c4z+0x95))*0x95);
C4WFYVal = (short) (c4y*(double)C4WFScale/(0x90*(c4z+0x95))*0x95);
@ -209,22 +190,22 @@ void C4TransfWireFrame2 ()
c4x = (double)C4WFXVal;
c4y = (double)C4WFYVal;
c4z = (double)C4WFZVal;
// Rotate X
tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128;
c4y2 = c4y * cos (tanval) - c4z * sin (tanval);
c4z2 = c4y * sin (tanval) + c4z * cos (tanval);
// Rotate Y
tanval = -(double) C4WFY2Val * 3.14159265 * 2 / 128;
c4x2 = c4x * cos (tanval) + c4z2 * sin (tanval);
c4z = c4x * -sin (tanval) + c4z2 * cos (tanval);
// Rotate Z
tanval = -(double)C4WFDist * 3.14159265 * 2 / 128;
c4x = c4x2 * cos (tanval) - c4y2 * sin (tanval);
c4y = c4x2 * sin (tanval) + c4y2 * cos (tanval);
// Scale
C4WFXVal =(short)(c4x * (double)C4WFScale / 0x100);
C4WFYVal =(short)(c4y * (double)C4WFScale / 0x100);
@ -240,21 +221,21 @@ void C4CalcWireFrame ()
C4WFYVal = (short) (256 * (double) C4WFYVal / abs (C4WFXVal));
if (C4WFXVal < 0)
C4WFXVal = -256;
else
else
C4WFXVal = 256;
}
else
{
if (C4WFYVal != 0)
if (C4WFYVal != 0)
{
C4WFDist = abs(C4WFYVal)+1;
C4WFXVal = (short) (256 * (double)C4WFXVal / abs (C4WFYVal));
if (C4WFYVal < 0)
C4WFYVal = -256;
else
else
C4WFYVal = 256;
}
else
else
C4WFDist = 0;
}
}
@ -267,19 +248,19 @@ short C41FDistVal;
void C4Op1F ()
{
if (C41FXVal == 0)
if (C41FXVal == 0)
{
if (C41FYVal > 0)
if (C41FYVal > 0)
C41FAngleRes = 0x80;
else
else
C41FAngleRes = 0x180;
}
else
else
{
tanval = (double) C41FYVal / C41FXVal;
C41FAngleRes = (short) (atan (tanval) / (3.141592675 * 2) * 512);
C41FAngleRes = C41FAngleRes;
if (C41FXVal< 0)
if (C41FXVal< 0)
C41FAngleRes += 0x100;
C41FAngleRes &= 0x1FF;
}
@ -302,7 +283,7 @@ void C4Op0D()
#ifdef ZSNES_C4
EXTERN_C void C4LoaDMem(char *C4RAM)
{
memmove(C4RAM+(READ_WORD(C4RAM+0x1f45)&0x1fff),
memmove(C4RAM+(READ_WORD(C4RAM+0x1f45)&0x1fff),
C4GetMemPointer(READ_3WORD(C4RAM+0x1f40)),
READ_WORD(C4RAM+0x1f43));
}

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -158,8 +141,6 @@
Nintendo Co., Limited and its subsidiary companies.
**********************************************************************************/
#ifndef _C4_H_
#define _C4_H_

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -158,9 +141,6 @@
Nintendo Co., Limited and its subsidiary companies.
**********************************************************************************/
#ifndef ZSNES_C4
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@ -214,7 +194,7 @@ static void C4ConvOAM(void){
int16 SprX, SprY;
uint8 SprName, SprAttr;
uint8 SprCount;
globalX=READ_WORD(Memory.C4RAM+0x0621);
globalY=READ_WORD(Memory.C4RAM+0x0623);
OAMptr2=Memory.C4RAM+0x200+(Memory.C4RAM[0x626]>>2);
@ -228,59 +208,62 @@ static void C4ConvOAM(void){
if(Memory.C4RAM[0x0620]!=0){
SprCount=128-Memory.C4RAM[0x626];
uint8 offset=(Memory.C4RAM[0x626]&3)*2;
uint8 *srcptr=Memory.C4RAM+0x220;
for(int i=Memory.C4RAM[0x0620]; i>0 && SprCount>0; i--, srcptr+=16){
SprX=READ_WORD(srcptr)-globalX;
SprY=READ_WORD(srcptr+2)-globalY;
SprName=srcptr[5];
SprAttr=srcptr[4] | srcptr[0x06]; // XXX: mask bits?
for(int prio=0x30; prio>=0; prio-=0x10){
uint8 *srcptr=Memory.C4RAM+0x220;
for(int i=Memory.C4RAM[0x0620]; i>0 && SprCount>0; i--, srcptr+=16){
if((srcptr[4]&0x30)!=prio) continue;
SprX=READ_WORD(srcptr)-globalX;
SprY=READ_WORD(srcptr+2)-globalY;
SprName=srcptr[5];
SprAttr=srcptr[4] | srcptr[0x06]; // XXX: mask bits?
uint8 *sprptr=C4GetMemPointer(READ_3WORD(srcptr+7));
if(*sprptr!=0){
int16 X, Y;
for(int SprCnt=*sprptr++; SprCnt>0 && SprCount>0; SprCnt--, sprptr+=4){
X=(int8)sprptr[1];
if(SprAttr&0x40){ // flip X
X=-X-((sprptr[0]&0x20)?16:8);
}
X+=SprX;
if(X>=-16 && X<=272){
Y=(int8)sprptr[2];
if(SprAttr&0x80){
Y=-Y-((sprptr[0]&0x20)?16:8);
uint8 *sprptr=C4GetMemPointer(READ_3WORD(srcptr+7));
if(*sprptr!=0){
int16 X, Y;
for(int SprCnt=*sprptr++; SprCnt>0 && SprCount>0; SprCnt--, sprptr+=4){
X=(int8)sprptr[1];
if(SprAttr&0x40){ // flip X
X=-X-((sprptr[0]&0x20)?16:8);
}
Y+=SprY;
if(Y>=-16 && Y<=224){
OAMptr[0]=X&0xff;
OAMptr[1]=(uint8)Y;
OAMptr[2]=SprName+sprptr[3];
OAMptr[3]=SprAttr^(sprptr[0]&0xc0); // XXX: Carry from SprName addition?
*OAMptr2 &= ~(3<<offset);
if(X&0x100) *OAMptr2 |= 1<<offset;
if(sprptr[0]&0x20) *OAMptr2 |= 2<<offset;
OAMptr+=4;
SprCount--;
offset=(offset+2)&6;
if(offset==0) OAMptr2++;
X+=SprX;
if(X>=-16 && X<=272){
Y=(int8)sprptr[2];
if(SprAttr&0x80){
Y=-Y-((sprptr[0]&0x20)?16:8);
}
Y+=SprY;
if(Y>=-16 && Y<=224){
OAMptr[0]=X&0xff;
OAMptr[1]=(uint8)Y;
OAMptr[2]=SprName+sprptr[3];
OAMptr[3]=SprAttr^(sprptr[0]&0xc0); // XXX: Carry from SprName addition?
*OAMptr2 &= ~(3<<offset);
if(X&0x100) *OAMptr2 |= 1<<offset;
if(sprptr[0]&0x20) *OAMptr2 |= 2<<offset;
OAMptr+=4;
SprCount--;
offset=(offset+2)&6;
if(offset==0) OAMptr2++;
}
}
}
} else if(SprCount>0){
OAMptr[0]=(uint8)SprX;
OAMptr[1]=(uint8)SprY;
OAMptr[2]=SprName;
OAMptr[3]=SprAttr;
*OAMptr2 &= ~(3<<offset);
if(SprX&0x100) *OAMptr2 |= 3<<offset;
else *OAMptr2 |= 2<<offset;
OAMptr+=4;
SprCount--;
offset=(offset+2)&6;
if(offset==0) OAMptr2++;
}
} else if(SprCount>0){
// XXX: Should we be testing -16<=SprX<=272 and -16<=SprY<=224?
OAMptr[0]=(uint8)SprX;
OAMptr[1]=(uint8)SprY;
OAMptr[2]=SprName;
OAMptr[3]=SprAttr;
*OAMptr2 &= ~(3<<offset);
if(SprX&0x100) *OAMptr2 |= 3<<offset;
else *OAMptr2 |= 2<<offset;
OAMptr+=4;
SprCount--;
offset=(offset+2)&6;
if(offset==0) OAMptr2++;
}
}
}
// XXX: Copy to OAM? I doubt it.
}
static void C4DoScaleRotate(int row_padding){
@ -351,7 +334,7 @@ static void C4DoScaleRotate(int row_padding){
// already have the fractional parts.
int32 LineX=(Cx<<12) - Cx*A - Cx*B;
int32 LineY=(Cy<<12) - Cy*C - Cy*D;
// Start loop
uint32 X, Y;
uint8 byte;
@ -380,7 +363,7 @@ static void C4DoScaleRotate(int row_padding){
bit=0x80;
outidx+=32;
}
X+=A; // Add 1 to output x => add an A and a C
Y+=C;
}
@ -533,7 +516,7 @@ static void C4BitPlaneWave(){
0x0600, 0x0602, 0x0604, 0x0606, 0x0608, 0x060A, 0x060C, 0x060E,
0x0800, 0x0802, 0x0804, 0x0806, 0x0808, 0x080A, 0x080C, 0x080E
};
uint8 *dst=Memory.C4RAM;
uint32 waveptr=Memory.C4RAM[0x1f83];
uint16 mask1=0xc0c0;
@ -602,7 +585,7 @@ static void C4SprDisintegrate()
#ifdef DEBUGGER
if((Cx&~1)!=width/2 || (Cy&~1)!=height/2) printf("Center is not middle of image for disintegrate! (%d, %d) != (%d, %d)\n", Cx, Cy, width/2, height/2);
#endif
scaleX=(int16)READ_WORD(Memory.C4RAM+0x1f86);
scaleY=(int16)READ_WORD(Memory.C4RAM+0x1f8f);
StartX=-Cx*scaleX+(Cx<<8);
@ -610,7 +593,7 @@ static void C4SprDisintegrate()
src=Memory.C4RAM+0x600;
memset(Memory.C4RAM, 0, width*height/2);
for(uint32 y=StartY, i=0; i<height; i++, y+=scaleY)
{
for(uint32 x=StartX, j=0; j<width; j++, x+=scaleX)
@ -682,7 +665,7 @@ static void S9xC4ProcessSprites()
#endif
C4BitPlaneWave();
break;
default:
#ifdef DEBUGGER
printf ("Unknown C4 sprite command (%02x)\n", Memory.C4RAM [0x1f4d]);
@ -696,7 +679,7 @@ void S9xSetC4 (uint8 byte, uint16 Address)
int i;
Memory.C4RAM [Address-0x6000] = byte;
if (Address == 0x7f4f)
if (Address == 0x7f4f)
{
if(Memory.C4RAM[0x1f4d]==0x0e && byte<0x40 && (byte&3)==0)
{
@ -782,7 +765,6 @@ void S9xSetC4 (uint8 byte, uint16 Address)
#endif
C41FXVal=READ_WORD(Memory.C4RAM+0x1f80);
C41FYVal=READ_WORD(Memory.C4RAM+0x1f83);
//C4Op15(); // optimized to:
C41FDist=(int16)sqrt((double)C41FXVal*C41FXVal + (double)C41FYVal*C41FYVal);
WRITE_WORD(Memory.C4RAM+0x1f80, C41FDist);
break;
@ -819,10 +801,10 @@ void S9xSetC4 (uint8 byte, uint16 Address)
if(y>=0)
{
left = SAR((int32)tan1*y, 16) -
READ_WORD(Memory.C4RAM+0x1f80) +
READ_WORD(Memory.C4RAM+0x1f80) +
READ_WORD(Memory.C4RAM+0x1f86);
right = SAR((int32)tan2*y, 16) -
READ_WORD(Memory.C4RAM+0x1f80) +
READ_WORD(Memory.C4RAM+0x1f80) +
READ_WORD(Memory.C4RAM+0x1f86) +
READ_WORD(Memory.C4RAM+0x1f93);
@ -860,7 +842,7 @@ void S9xSetC4 (uint8 byte, uint16 Address)
printf("25 Multiply!\n");
if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 25 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]);
#endif
{
{
int32 foo=READ_3WORD(Memory.C4RAM+0x1f80);
int32 bar=READ_3WORD(Memory.C4RAM+0x1f83);
foo*=bar;
@ -946,7 +928,7 @@ void S9xSetC4 (uint8 byte, uint16 Address)
if(byte != 0) printf("C4 load: non-0 written to $7f47! Wrote %02x\n", byte);
if(READ_WORD(Memory.C4RAM+0x1f45) < 0x6000 || (READ_WORD(Memory.C4RAM+0x1f45) + READ_WORD(Memory.C4RAM+0x1f43)) > 0x6c00) printf("C4 load: Dest unusual! It's %04x\n", READ_WORD(Memory.C4RAM+0x1f45));
#endif
memmove(Memory.C4RAM+(READ_WORD(Memory.C4RAM+0x1f45)&0x1fff),
memmove(Memory.C4RAM+(READ_WORD(Memory.C4RAM+0x1f45)&0x1fff),
C4GetMemPointer(READ_3WORD(Memory.C4RAM+0x1f40)),
READ_WORD(Memory.C4RAM+0x1f43));
}
@ -1085,4 +1067,4 @@ int16 C4CosTable[512] = {
32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568,
32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765
};
#endif

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#include "snes9x.h"
#include "memmap.h"
#include "ppu.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -158,8 +141,6 @@
Nintendo Co., Limited and its subsidiary companies.
**********************************************************************************/
#ifndef FOO_H
#define FOO_H
@ -202,7 +183,7 @@ typedef struct {
uint8 type;
uint8 multi_press:2;
uint8 button_norpt:1;
union {
union {
struct {
@ -258,7 +239,7 @@ typedef struct {
uint8 threshold; // (threshold+1)/256% deflection is a
// button press
} joypad;
struct {
uint8 idx:3; // Pseudo-pointer number 0-7
uint8 speed_type:2; // 0=variable, 1=slow, 2=med, 3=fast
@ -329,7 +310,7 @@ const char **S9xGetAllSnes9xCommands(void);
s9xcommand_t S9xGetMapping(uint32 id);
void S9xUnmapID(uint32 id);
/*
/*
* Button mapping functions. If a button is mapped with poll=TRUE, then
* S9xPollButton will be called whenever snes9x feels a need for that mapping.
* Otherwise, snes9x will assume you will call S9xReportButton() whenever the
@ -339,7 +320,7 @@ void S9xUnmapID(uint32 id);
bool S9xMapButton(uint32 id, s9xcommand_t mapping, bool poll);
void S9xReportButton(uint32 id, bool pressed);
/*
/*
* Pointer mapping functions. If a button is mapped with poll=TRUE, then
* S9xPollPointer will be called whenever snes9x feels a need for that mapping.
* Otherwise, snes9x will assume you will call S9xReportPointer() whenever the
@ -354,7 +335,7 @@ void S9xReportButton(uint32 id, bool pressed);
bool S9xMapPointer(uint32 id, s9xcommand_t mapping, bool poll);
void S9xReportPointer(uint32 id, int16 x, int16 y);
/*
/*
* Axis mapping functions. If a button is mapped with poll=TRUE, then
* S9xPollAxis will be called whenever snes9x feels a need for that mapping.
* Otherwise, snes9x will assume you will call S9xReportAxis() whenever the
@ -397,14 +378,6 @@ bool S9xPollAxis(uint32 id, int16 *value);
*/
void S9xHandlePortCommand(s9xcommand_t cmd, int16 data1, int16 data2);
/*
* Called before already-read SNES joypad data is being used by the game
* if your port defines SNES_JOY_READ_CALLBACKS
*/
#ifdef SNES_JOY_READ_CALLBACKS
void S9xOnSNESPadRead();
#endif
/* These are for your use */
s9xcommand_t S9xGetPortCommandT(const char *name);
char *S9xGetPortCommandName(s9xcommand_t command);
@ -439,9 +412,7 @@ struct SControlSnapshot {
uint8 dummy2[4];
uint8 mouse_speed[2];
uint8 justifier_select;
uint8 dummy3[8];
bool8 pad_read, pad_read_last;
uint8 internal[60]; // yes, we need to save this!
uint8 dummy3[10];
};
void S9xControlPreSave(struct SControlSnapshot *s);

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -158,15 +141,13 @@
Nintendo Co., Limited and its subsidiary companies.
**********************************************************************************/
/*
* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
*
* (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
* Jerremy Koot (jkoot@snes9x.com)
*
* Super FX C emulator code
* Super FX C emulator code
* (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
* Gary Henderson.
* Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#include "snes9x.h"
#include "memmap.h"
#include "ppu.h"
@ -181,9 +162,6 @@
#include "obc1.h"
#include "bsx.h"
#include "snapshot.h"
#ifndef NGC
#include "logger.h"
#endif
#ifndef ZSNES_FX
@ -225,17 +203,12 @@ void S9xSoftResetCPU ()
CPU.NMIActive = FALSE;
CPU.IRQActive = FALSE;
CPU.WaitingForInterrupt = FALSE;
CPU.InDMA = FALSE;
CPU.InHDMA = FALSE;
CPU.InDMAorHDMA = FALSE;
CPU.InWRAMDMAorHDMA = FALSE;
CPU.HDMARanInDMA = 0;
CPU.InDMA = CPU.InWRAM_DMA = FALSE;
CPU.PCBase = NULL;
CPU.PBPCAtOpcodeStart = 0xffffffff;
CPU.WaitAddress = 0xffffffff;
CPU.WaitCounter = 0;
CPU.Cycles = 182; // Or 188. This is the cycle count just after the jump to the Reset Vector.
CPU.PrevCycles = -1;
CPU.V_Counter = 0;
CPU.MemSpeed = SLOW_ONE_CYCLE;
CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2;
@ -243,7 +216,7 @@ void S9xSoftResetCPU ()
CPU.AutoSaveTimer = 0;
CPU.SRAMModified = FALSE;
CPU.BRKTriggered = FALSE;
CPU.IRQPending = 0;
//CPU.TriedInterleavedMode2 = FALSE; // Reset when ROM image loaded
Timings.InterlaceField = FALSE;
Timings.H_Max = Timings.H_Max_Master;
@ -262,7 +235,7 @@ void S9xSoftResetCPU ()
ICPU.S9xOpcodes = S9xOpcodesE1;
ICPU.S9xOpLengths = S9xOpLengthsM1X1;
ICPU.CPUExecuting = TRUE;
S9xUnpackStatus();
}
@ -271,10 +244,7 @@ void S9xResetCPU ()
S9xSoftResetCPU ();
Registers.SL = 0xFF;
Registers.P.W = 0;
Registers.A.W = 0;
Registers.X.W = 0;
Registers.Y.W = 0;
SetFlags (MemoryFlag | IndexFlag | IRQ | Emulation);
SetFlags (MemoryFlag | IndexFlag | IRQ | Emulation);
ClearFlags (Decimal);
}
@ -289,7 +259,6 @@ END_EXTERN_C
void S9xReset (void)
{
#ifndef NGC
ResetLogger();
S9xResetSaveTimer (FALSE);
#endif
@ -313,6 +282,7 @@ void S9xReset (void)
S9xSA1Init ();
if (Settings.C4)
S9xInitC4 ();
#ifndef NGC
S9xInitCheatData ();
#endif

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef _CPUADDR_H_
#define _CPUADDR_H_
@ -302,7 +283,7 @@ STATIC inline uint32 AbsoluteLongSlow (AccessMode a) { // l
// JSR l pushes the old bank in the middle of loading the new.
// OpenBus needs to be set to account for this.
if(a==JSR) OpenBus = Registers.PB;
addr |= Immediate8Slow(a)<<16;
return addr;
}

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#include "snes9x.h"
#include "memmap.h"
#include "cpuops.h"
@ -182,17 +163,10 @@ extern struct FxInit_s SuperFX;
void S9xMainLoop (void)
{
if(ICPU.SavedAtOp)
{
ICPU.SavedAtOp = FALSE;
Registers.PCw = CPU.PBPCAtOpcodeStart;
if(CPU.PCBase)
CPU.Cycles -= CPU.MemSpeed;
goto doOp;
}
for (;;)
{
APU_EXECUTE();
if (CPU.Flags)
{
if (CPU.Flags & NMI_FLAG)
@ -206,11 +180,11 @@ void S9xMainLoop (void)
CPU.WaitingForInterrupt = FALSE;
Registers.PCw++;
}
S9xOpcode_NMI();
}
}
#ifdef DEBUGGER
if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG))
{
@ -228,33 +202,26 @@ void S9xMainLoop (void)
}
}
#endif
CHECK_SOUND();
if (CPU.Flags & IRQ_FLAG)
if (CPU.Flags & IRQ_PENDING_FLAG)
{
if (CPU.IRQPending)
// FIXME: In case of IRQ during WRAM refresh
CPU.IRQPending = 0;
else
if (CPU.WaitingForInterrupt)
{
if (CPU.WaitingForInterrupt)
{
CPU.WaitingForInterrupt = FALSE;
Registers.PCw++;
}
if (CPU.IRQActive && !Settings.DisableIRQ)
{
if (!CheckFlag(IRQ))
// in IRQ handler $4211 is supposed to be read, so IRQ_FLAG should be cleared.
S9xOpcode_IRQ();
}
else
CPU.Flags &= ~IRQ_FLAG;
CPU.WaitingForInterrupt = FALSE;
Registers.PCw++;
}
}
if (CPU.IRQActive && !Settings.DisableIRQ)
{
if (!CheckFlag(IRQ))
S9xOpcode_IRQ();
}
else
CPU.Flags &= ~IRQ_PENDING_FLAG;
}
if (CPU.Flags & SCAN_KEYS_FLAG)
break;
@ -272,16 +239,14 @@ void S9xMainLoop (void)
}
#endif
}
#ifdef CPU_SHUTDOWN
CPU.PBPCAtOpcodeStart = Registers.PBPC;
#endif
doOp:
register uint8 Op;
register struct SOpcodes *Opcodes;
CPU.PrevCycles = CPU.Cycles;
if (CPU.PCBase)
{
Op = CPU.PCBase[Registers.PCw];
@ -294,7 +259,7 @@ void S9xMainLoop (void)
OpenBus = Op;
Opcodes = S9xOpcodesSlow;
}
if ((Registers.PCw&MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE)
{
uint8 *oldPCBase = CPU.PCBase;
@ -303,29 +268,23 @@ void S9xMainLoop (void)
if (oldPCBase!=CPU.PCBase || (Registers.PCw&~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK))
Opcodes = S9xOpcodesSlow;
}
Registers.PCw++;
(*Opcodes[Op].S9xOpcode)();
if(ICPU.SavedAtOp)
{
ICPU.SavedAtOp = false;
continue;
}
S9xAPUExecute();
S9xUpdateAPUTimer();
if (SA1.Executing)
S9xSA1MainLoop();
while (CPU.Cycles >= CPU.NextEvent)
if (CPU.Cycles >= CPU.NextEvent)
S9xDoHEventProcessing();
}
S9xPackStatus();
APURegisters.PC = IAPU.PC - IAPU.RAM;
S9xAPUPackStatus();
if (CPU.Flags & SCAN_KEYS_FLAG)
{
#ifdef DEBUGGER
@ -339,11 +298,11 @@ void S9xMainLoop (void)
void S9xSetIRQ (uint32 source)
{
CPU.IRQActive |= source;
CPU.Flags |= IRQ_FLAG;
CPU.Flags |= IRQ_PENDING_FLAG;
if (CPU.WaitingForInterrupt)
{
// Force IRQ to trigger immediately after WAI -
// Force IRQ to trigger immediately after WAI -
// Final Fantasy Mystic Quest crashes without this.
CPU.WaitingForInterrupt = FALSE;
Registers.PCw++;
@ -357,10 +316,6 @@ void S9xClearIRQ (uint32 source)
void S9xDoHEventProcessing (void)
{
#ifdef DEBUGGER
char mes[256];
#endif
#ifdef CPU_SHUTDOWN
CPU.WaitCounter++;
#endif
@ -368,23 +323,17 @@ void S9xDoHEventProcessing (void)
{
case HC_HBLANK_START_EVENT:
S9xCheckMissingHTimerPosition(Timings.HBlankStart);
break;
case HC_HDMA_START_EVENT:
if (IPPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
{
#ifdef DEBUGGER
sprintf(mes, "*** HDMA HC:%04d, Channel:%02x", CPU.Cycles, IPPU.HDMA);
S9xTraceMessage(mes);
#endif
IPPU.HDMA = S9xDoHDMA(IPPU.HDMA);
}
S9xCheckMissingHTimerPosition(Timings.HDMAStart);
break;
case HC_HCOUNTER_MAX_EVENT:
#ifndef ZSNES_FX
if (Settings.SuperFX)
@ -403,12 +352,14 @@ void S9xDoHEventProcessing (void)
#endif
CPU.Cycles -= Timings.H_Max;
IAPU.NextAPUTimerPos -= (Timings.H_Max << SNES_APU_ACCURACY);
APU.Cycles -= (Timings.H_Max << SNES_APU_ACCURACY);
IAPU.NextAPUTimerPos -= (Timings.H_Max << SNES_APUTIMER_ACCURACY);
if (IAPU.APUExecuting)
APU.Cycles -= Timings.H_Max;
else
APU.Cycles = 0;
if ((Timings.NMITriggerPos != 0xffff) && (Timings.NMITriggerPos >= Timings.H_Max))
Timings.NMITriggerPos -= Timings.H_Max;
ICPU.Scanline++;
CPU.V_Counter++;
@ -416,9 +367,9 @@ void S9xDoHEventProcessing (void)
{
CPU.V_Counter = 0;
Timings.InterlaceField ^= 1;
// From byuu:
// [NTSC]
// [NTSC]
// interlace mode has 525 scanlines: 263 on the even frame, and 262 on the odd.
// non-interlace mode has 524 scanlines: 262 scanlines on both even and odd frames.
// [PAL] <PAL info is unverified on hardware>
@ -428,15 +379,15 @@ void S9xDoHEventProcessing (void)
Timings.V_Max = Timings.V_Max_Master + 1; // 263 (NTSC), 313?(PAL)
else
Timings.V_Max = Timings.V_Max_Master; // 262 (NTSC), 312?(PAL)
Memory.FillRAM[0x213F] ^= 0x80;
PPU.RangeTimeOver = 0;
// FIXME: reading $4210 will wait 2 cycles, then perform reading, then wait 4 more cycles.
Memory.FillRAM[0x4210] = Model->_5A22;
CPU.Flags &= ~NMI_FLAG;
Timings.NMITriggerPos = 0xffff;
ICPU.Frame++;
PPU.HVBeamCounterLatched = 0;
CPU.Flags |= SCAN_KEYS_FLAG;
@ -452,7 +403,7 @@ void S9xDoHEventProcessing (void)
Timings.H_Max = Timings.H_Max_Master - ONE_DOT_CYCLE; // HC=1360
else
Timings.H_Max = Timings.H_Max_Master; // HC=1364
if (Model->_5A22 == 2)
{
if (CPU.V_Counter != 240 || IPPU.Interlace || !Timings.InterlaceField) // V=240
@ -465,7 +416,7 @@ void S9xDoHEventProcessing (void)
}
else
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v1;
S9xCheckMissingHTimerPosition(0);
if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) // VBlank starts from V=225(240).
@ -484,7 +435,7 @@ void S9xDoHEventProcessing (void)
PPU.OAMAddr = PPU.SavedOAMAddr;
uint8 tmp = 0;
if (PPU.OAMPriorityRotation)
tmp = (PPU.OAMAddr & 0xFE) >> 1;
if ((PPU.OAMFlip & 1) || PPU.FirstSprite!=tmp)
@ -492,7 +443,7 @@ void S9xDoHEventProcessing (void)
PPU.FirstSprite = tmp;
IPPU.OBJChanged = TRUE;
}
PPU.OAMFlip = 0;
}
@ -507,47 +458,44 @@ void S9xDoHEventProcessing (void)
}
}
if (CPU.V_Counter == PPU.ScreenHeight + 3) // FIXME: not true
{
if (Memory.FillRAM[0x4200] & 1)
S9xDoAutoJoypad();
}
S9xDoAutoJoypad();
if (CPU.V_Counter == FIRST_VISIBLE_LINE) // V=1
S9xStartScreenRefresh();
CPU.NextEvent = -1;
break;
case HC_HDMA_INIT_EVENT:
if (CPU.V_Counter == 0)
S9xStartHDMA();
S9xCheckMissingHTimerPosition(Timings.HDMAInit);
break;
case HC_RENDER_EVENT:
if (CPU.V_Counter >= FIRST_VISIBLE_LINE && CPU.V_Counter <= PPU.ScreenHeight)
RenderLine((uint8)(CPU.V_Counter - FIRST_VISIBLE_LINE));
RenderLine(CPU.V_Counter - FIRST_VISIBLE_LINE);
S9xCheckMissingHTimerPosition(Timings.RenderPos);
break;
case HC_WRAM_REFRESH_EVENT:
#ifdef DEBUGGER
sprintf(mes, "*** WRAM Refresh HC:%04d", CPU.Cycles);
S9xTraceMessage(mes);
#endif
S9xCheckMissingHTimerHalt(Timings.WRAMRefreshPos, SNES_WRAM_REFRESH_CYCLES);
CPU.Cycles += SNES_WRAM_REFRESH_CYCLES;
S9xAPUExecute();
S9xCheckMissingHTimerPosition(Timings.WRAMRefreshPos);
if (!CPU.InDMA)
{
S9xCheckMissingHTimerPositionRange(Timings.WRAMRefreshPos, SNES_WRAM_REFRESH_CYCLES);
CPU.Cycles += SNES_WRAM_REFRESH_CYCLES;
S9xUpdateAPUTimer();
APU_EXECUTE();
}
else
S9xCheckMissingHTimerPosition(Timings.WRAMRefreshPos);
break;
case HC_IRQ_1_3_EVENT:
@ -561,9 +509,9 @@ void S9xDoHEventProcessing (void)
else
if (PPU.VTimerEnabled && (CPU.V_Counter == PPU.VTimerPosition))
S9xSetIRQ(PPU_V_BEAM_IRQ_SOURCE);
break;
}
S9xReschedule();
}

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef _CPUEXEC_H_
#define _CPUEXEC_H_
@ -176,7 +157,7 @@ struct SOpcodes {
struct SICPU
{
uint8 *Speed; // unused
uint8 *Speed;
struct SOpcodes *S9xOpcodes;
uint8 *S9xOpLengths;
uint8 _Carry;
@ -189,7 +170,6 @@ struct SICPU
uint32 Frame;
uint32 Scanline;
uint32 FrameAdvanceCount;
bool8 SavedAtOp;
};
START_EXTERN_C
@ -239,9 +219,9 @@ STATIC inline void CLEAR_IRQ_SOURCE (uint32 M)
{
CPU.IRQActive &= ~M;
if (!CPU.IRQActive)
CPU.Flags &= ~IRQ_FLAG;
CPU.Flags &= ~IRQ_PENDING_FLAG;
}
STATIC inline void S9xFixCycles ()
{
if (CheckEmulation ())

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef _CPUMACRO_H_
#define _CPUMACRO_H_
@ -245,10 +226,10 @@
mOPC(OP, Memory, ADDR, WRAP, FUNC)
#define bOP(OP, REL, COND, CHK, E) \
#define bOP(OP, COND, CHK, E) \
static void Op##OP (void) { \
pair newPC; \
newPC.W = REL(JUMP); \
newPC.W = Relative(JUMP); \
BranchCheck##CHK (); \
if(COND){ \
AddCycles(ONE_CYCLE); \
@ -309,7 +290,7 @@ STATIC inline void ADC (uint8 Work8) {
ICPU._Carry = Ans16 >= 0x100;
if (~(Registers.AL ^ Work8) &
if (~(Registers.AL ^ Work8) &
(Work8 ^ (uint8) Ans16) & 0x80)
SetOverflow();
else

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
/*****************************************************************************/
/* CPU-S9xOpcodes.CPP */
/* This file contains all the opcodes */
@ -181,7 +162,7 @@
#include "dsp1.h"
#ifdef SA1_OPCODES
#define AddCycles(n) {}
#define AddCycles(n)
#else
#define AddCycles(n) CPU.Cycles+=n
#endif
@ -830,10 +811,10 @@ static void OpA9M0 (void) {
static void OpA9Slow (void) {
if(CheckMemory()) {
Registers.AL = Immediate8Slow(READ);
Registers.AL = Immediate8(READ);
SetZN(Registers.AL);
} else {
Registers.A.W = Immediate16Slow(READ);
Registers.A.W = Immediate16(READ);
SetZN(Registers.A.W);
}
}
@ -1523,39 +1504,51 @@ mOPM (0CSlow, AbsoluteSlow, WRAP_BANK, TSB)
#ifndef SA1_OPCODES
inline void CPUShutdown()
{
if (Settings.Shutdown && Registers.PBPC == CPU.WaitAddress)
if (Settings.Shutdown && Registers.PBPC == CPU.WaitAddress)
{
// Don't skip cycles with a pending NMI or IRQ - could cause delayed
// interrupt. Interrupts are delayed for a few cycles already, but
// the delay could allow the shutdown code to cycle skip again.
// Was causing screen flashing on Top Gear 3000.
if (CPU.WaitCounter == 0 &&
!(CPU.Flags & (IRQ_PENDING_FLAG | NMI_FLAG)))
{
// Don't skip cycles with a pending NMI or IRQ - could cause delayed interrupt.
if (CPU.WaitCounter == 0 && !(CPU.Flags & (IRQ_FLAG | NMI_FLAG)))
CPU.WaitAddress = 0xffffffff;
if (Settings.SA1)
S9xSA1ExecuteDuringSleep ();
CPU.Cycles = CPU.NextEvent;
S9xUpdateAPUTimer();
if (IAPU.APUExecuting)
{
ICPU.CPUExecuting = FALSE;
do
{
CPU.WaitAddress = 0xffffffff;
if (Settings.SA1)
S9xSA1ExecuteDuringSleep();
CPU.Cycles = CPU.NextEvent;
ICPU.CPUExecuting = FALSE;
S9xAPUExecute();
ICPU.CPUExecuting = TRUE;
}
else
if (CPU.WaitCounter >= 2)
CPU.WaitCounter = 1;
else
CPU.WaitCounter--;
APU_EXECUTE1();
} while (APU.Cycles < CPU.NextEvent);
ICPU.CPUExecuting = TRUE;
}
}
else
if (CPU.WaitCounter >= 2)
CPU.WaitCounter = 1;
else
CPU.WaitCounter--;
}
}
#else
inline void CPUShutdown()
{
if (Settings.Shutdown && Registers.PBPC == CPU.WaitAddress)
if (Settings.Shutdown && Registers.PBPC == CPU.WaitAddress)
{
if (CPU.WaitCounter >= 1)
{
if (CPU.WaitCounter >= 1)
{
SA1.Executing = FALSE;
SA1.CPUExecuting = FALSE;
}
else
CPU.WaitCounter++;
SA1.Executing = FALSE;
SA1.CPUExecuting = FALSE;
}
else
CPU.WaitCounter++;
}
}
#endif
#else
@ -1563,59 +1556,55 @@ inline void CPUShutdown()
#endif
/* BCC */
bOP(90E0, Relative, !CheckCarry(), 0, 0)
bOP(90E1, Relative, !CheckCarry(), 0, 1)
bOP(90Slow, RelativeSlow, !CheckCarry(), 0, CheckEmulation())
bOP(90E0, !CheckCarry(), 0, 0)
bOP(90E1, !CheckCarry(), 0, 1)
bOP(90Slow, !CheckCarry(), 0, CheckEmulation())
/* BCS */
bOP(B0E0, Relative, CheckCarry(), 0, 0)
bOP(B0E1, Relative, CheckCarry(), 0, 1)
bOP(B0Slow, RelativeSlow, CheckCarry(), 0, CheckEmulation())
bOP(B0E0, CheckCarry(), 0, 0)
bOP(B0E1, CheckCarry(), 0, 1)
bOP(B0Slow, CheckCarry(), 0, CheckEmulation())
/* BEQ */
bOP(F0E0, Relative, CheckZero(), 2, 0)
bOP(F0E1, Relative, CheckZero(), 2, 1)
bOP(F0Slow, RelativeSlow, CheckZero(), 2, CheckEmulation())
bOP(F0E0, CheckZero(), 2, 0)
bOP(F0E1, CheckZero(), 2, 1)
bOP(F0Slow, CheckZero(), 2, CheckEmulation())
/* BMI */
bOP(30E0, Relative, CheckNegative(), 1, 0)
bOP(30E1, Relative, CheckNegative(), 1, 1)
bOP(30Slow, RelativeSlow, CheckNegative(), 1, CheckEmulation())
bOP(30E0, CheckNegative(), 1, 0)
bOP(30E1, CheckNegative(), 1, 1)
bOP(30Slow, CheckNegative(), 1, CheckEmulation())
/* BNE */
bOP(D0E0, Relative, !CheckZero(), 1, 0)
bOP(D0E1, Relative, !CheckZero(), 1, 1)
bOP(D0Slow, RelativeSlow, !CheckZero(), 1, CheckEmulation())
bOP(D0E0, !CheckZero(), 1, 0)
bOP(D0E1, !CheckZero(), 1, 1)
bOP(D0Slow, !CheckZero(), 1, CheckEmulation())
/* BPL */
bOP(10E0, Relative, !CheckNegative(), 1, 0)
bOP(10E1, Relative, !CheckNegative(), 1, 1)
bOP(10Slow, RelativeSlow, !CheckNegative(), 1, CheckEmulation())
bOP(10E0, !CheckNegative(), 1, 0)
bOP(10E1, !CheckNegative(), 1, 1)
bOP(10Slow, !CheckNegative(), 1, CheckEmulation())
/* BRA */
bOP(80E0, Relative, 1, X, 0)
bOP(80E1, Relative, 1, X, 1)
bOP(80Slow, RelativeSlow, 1, X, CheckEmulation())
bOP(80E0, 1, X, 0)
bOP(80E1, 1, X, 1)
bOP(80Slow, 1, X, CheckEmulation())
/* BVC */
bOP(50E0, Relative, !CheckOverflow(), 0, 0)
bOP(50E1, Relative, !CheckOverflow(), 0, 1)
bOP(50Slow, RelativeSlow, !CheckOverflow(), 0, CheckEmulation())
bOP(50E0, !CheckOverflow(), 0, 0)
bOP(50E1, !CheckOverflow(), 0, 1)
bOP(50Slow, !CheckOverflow(), 0, CheckEmulation())
/* BVS */
bOP(70E0, Relative, CheckOverflow(), 0, 0)
bOP(70E1, Relative, CheckOverflow(), 0, 1)
bOP(70Slow, RelativeSlow, CheckOverflow(), 0, CheckEmulation())
bOP(70E0, CheckOverflow(), 0, 0)
bOP(70E1, CheckOverflow(), 0, 1)
bOP(70Slow, CheckOverflow(), 0, CheckEmulation())
/* BRL */
static void Op82 (void) {
S9xSetPCBase(ICPU.ShiftedPB + RelativeLong(JUMP));
}
static void Op82Slow (void) {
S9xSetPCBase(ICPU.ShiftedPB + RelativeLongSlow(JUMP));
}
/*****************************************************************************/
/* Flag Instructions ******************************************************* */
@ -3045,9 +3034,9 @@ static void Op44X0 (void) {
static void Op44Slow (void) {
uint32 SrcBank;
OpenBus = Registers.DB = Immediate8Slow(NONE);
OpenBus = Registers.DB = Immediate8(NONE);
ICPU.ShiftedDB = Registers.DB << 16;
OpenBus = SrcBank = Immediate8Slow(NONE);
OpenBus = SrcBank = Immediate8(NONE);
S9xSetByte(OpenBus=S9xGetByte ((SrcBank << 16) + Registers.X.W),
ICPU.ShiftedDB + Registers.Y.W);
@ -3205,9 +3194,15 @@ static void OpCB (void) {
// XXX: FIXME
if(Settings.Shutdown){
SA1.Cycles = SA1.NextEvent;
SA1.Executing = FALSE;
//S9xAPUExecute(); // FIXME
SA1.Executing = TRUE;
if (IAPU.APUExecuting)
{
SA1.Executing = FALSE;
do
{
APU_EXECUTE1 ();
} while (APU.Cycles < SA1.NextEvent);
SA1.Executing = TRUE;
}
}
#endif
#else // SA1_OPCODES
@ -3223,15 +3218,20 @@ static void OpCB (void) {
if (Settings.Shutdown)
{
CPU.Cycles = CPU.NextEvent;
ICPU.CPUExecuting = FALSE;
S9xAPUExecute();
ICPU.CPUExecuting = TRUE;
}
else
S9xUpdateAPUTimer();
if (IAPU.APUExecuting)
{
ICPU.CPUExecuting = FALSE;
do
{
APU_EXECUTE1 ();
} while (APU.Cycles < CPU.NextEvent);
ICPU.CPUExecuting = TRUE;
}
} else {
AddCycles(TWO_CYCLES);
#else
AddCycles(TWO_CYCLES);
#endif
}
}
#endif // SA1_OPCODES
}
@ -3248,10 +3248,9 @@ extern FILE *trace;
extern FILE *trace2;
#endif
static void Op42 (void) {
#ifdef DEBUGGER
uint8 byte = (uint8)
#ifndef NGC
uint8 byte = S9xGetWord(Registers.PBPC);
#endif
S9xGetWord(Registers.PBPC);
Registers.PCw++;
#ifdef DEBUGGER
// Hey, let's use this to trigger debug modes
@ -3611,7 +3610,7 @@ struct SOpcodes S9xOpcodesSlow[256] = {
{Op73Slow}, {Op74Slow}, {Op75Slow}, {Op76Slow}, {Op77Slow},
{Op78}, {Op79Slow}, {Op7ASlow}, {Op7B}, {Op7CSlow},
{Op7DSlow}, {Op7ESlow}, {Op7FSlow}, {Op80Slow}, {Op81Slow},
{Op82Slow}, {Op83Slow}, {Op84Slow}, {Op85Slow}, {Op86Slow},
{Op82}, {Op83Slow}, {Op84Slow}, {Op85Slow}, {Op86Slow},
{Op87Slow}, {Op88Slow}, {Op89Slow}, {Op8ASlow}, {Op8BSlow},
{Op8CSlow}, {Op8DSlow}, {Op8ESlow}, {Op8FSlow}, {Op90Slow},
{Op91Slow}, {Op92Slow}, {Op93Slow}, {Op94Slow}, {Op95Slow},

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef _CPUOPS_H_
#define _CPUOPS_H_
void S9xOpcode_NMI ();

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -158,8 +141,6 @@
Nintendo Co., Limited and its subsidiary companies.
**********************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@ -454,7 +435,7 @@ bool S9xLoadCrosshairFile(int idx, const char *filename){
int i, r;
char *s;
FILE *fp;
if(idx<1 || idx>31) return false;
if((s=(char *)calloc(15*15+1, sizeof(char)))==NULL){
fprintf(stderr, "S9xLoadCrosshairFile: malloc error while reading ");

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -158,8 +141,6 @@
Nintendo Co., Limited and its subsidiary companies.
**********************************************************************************/
#ifndef CROSSHAIRS_H
#define CROSSHAIRS_H

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#include "snes9x.h"
uint8 add32_32 [32][32] = {

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#include <string.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
@ -189,6 +170,12 @@ static void WhatsUsed ();
EXTERN_C SDMA DMA[8];
extern struct SCheatData Cheat;
#ifdef SPCTOOL
#include "spctool/spc700.h"
extern "C" void TraceSPC (unsigned char *PC, unsigned short YA, unsigned char X,
SPCFlags PS, unsigned char *SP);
#endif
FILE *trace = NULL;
FILE *trace2 = NULL;
struct SBreakPoint S9xBreakpoint[6];
@ -236,7 +223,7 @@ char *HelpMessage[] = {
"bs [Number] [Address] - Enable/Disable Breakpoint",
" [Enable example: BS #2 $02:8002]",
" [Disable example: BS #2]",
"c - Dump SNES colour palette",
"c - Dump SNES colour palette",
"W - Show what SNES hardware features a ROM is using",
" which might not be implemented yet.",
"w - Show some SNES hardware features used so far in this frame",
@ -731,7 +718,7 @@ uint8 S9xOPrint (char *Line, uint8 Bank, uint16 Address)
break;
}
// XXX:
sprintf (Line, "%-44s A:%04X X:%04X Y:%04X D:%04X DB:%02X S:%04X P:%c%c%c%c%c%c%c%c%c HC:%04d VC:%03d FC:%02d %02x",
sprintf (Line, "%-44s A:%04X X:%04X Y:%04X D:%04X DB:%02X S:%04X P:%c%c%c%c%c%c%c%c%c HC:%03d VC:%03ld %02x",
Line, Registers.A.W, Registers.X.W, Registers.Y.W,
Registers.D.W, Registers.DB, Registers.S.W,
CheckEmulation () ? 'E' : 'e',
@ -745,7 +732,6 @@ uint8 S9xOPrint (char *Line, uint8 Bank, uint16 Address)
CheckCarry () ? 'C' : 'c',
Cycles,
CPU.V_Counter,
IPPU.FrameCount,
CPU.IRQActive);
CPU.Cycles = Cycles;
@ -1243,7 +1229,7 @@ static void ProcessDebugCommand (char *Line)
S9xAddCheat (TRUE, TRUE, Address, Byte);
return;
}
if (strncasecmp (Line, "dump", 4) == 0)
{
int Count;
@ -1435,11 +1421,18 @@ static void ProcessDebugCommand (char *Line)
extern FILE *apu_trace;
if (APU.Flags & TRACE_FLAG)
{
#ifdef SPCTOOL
printf ("ENABLED\n");
_SetSPCDbg (TraceSPC); //Install debug handler
#endif
if (apu_trace == NULL)
apu_trace = fopen ("aputrace.log", "wb");
}
else
{
#ifdef SPCTOOL
_SetSPCDbg (NULL);
#endif
if (apu_trace)
{
fclose (apu_trace);
@ -1467,7 +1460,7 @@ static void ProcessDebugCommand (char *Line)
printf ("SPC700 sample addresses at 0x%04x:\n", APU.DSP [APU_DIR] << 8);
for (int i = 0; i < 256; i++)
{
uint8 *dir = IAPU.RAM +
uint8 *dir = IAPU.RAM +
(((APU.DSP [APU_DIR] << 8) +
i * 4) & 0xffff);
int addr = *dir + (*(dir + 1) << 8);
@ -1506,8 +1499,13 @@ static void ProcessDebugCommand (char *Line)
{
printf ("APU in-ports: %02X %02X %02X %02X\n",
IAPU.RAM [0xF4], IAPU.RAM [0xF5], IAPU.RAM [0xF6], IAPU.RAM [0xF7]);
#ifdef SPCTOOL
printf ("APU out-ports: %02X %02X %02X %02X\n",
_SPCOutP [0], _SPCOutP [1], _SPCOutP [2], _SPCOutP [3]);
#else
printf ("APU out-ports: %02X %02X %02X %02X\n",
APU.OutPorts [0], APU.OutPorts [1], APU.OutPorts [2], APU.OutPorts [3]);
#endif
printf ("ROM/RAM switch: %s\n", (IAPU.RAM [0xf1] & 0x80) ? "ROM" : "RAM");
for (int i = 0; i < 3; i++)
if (APU.TimerEnabled [i])
@ -1749,7 +1747,7 @@ static void ProcessDebugCommand (char *Line)
(Registers.P.W & 1) != 0 ? "C" : "c",
(Registers.P.W & 256) != 0 ? "E" : "e");
DPrint (String);
#endif
#endif
S9xOPrint (String, Bank, Address);
DPrint (String);
}
@ -1821,7 +1819,7 @@ static void WhatsUsed ()
printf ("Screen mode: %d, ", PPU.BGMode);
if (PPU.BGMode <= 1 && (Memory.FillRAM [0x2105] & 8))
printf ("(BG#2 Priority)");
printf ("Brightness: %d", PPU.Brightness);
if (Memory.FillRAM[0x2100] & 0x80)
printf (" (screen blanked)");
@ -1904,7 +1902,7 @@ static void WhatsUsed ()
{
printf ("BG%d: VOffset:%d, HOffset:%d, W:%d, H:%d, TS:%d, BA:0x%04x, TA:0x%04X\n",
i, PPU.BG[i].VOffset, PPU.BG[i].HOffset,
(PPU.BG[i].SCSize & 1) * 32 + 32,
(PPU.BG[i].SCSize & 1) * 32 + 32,
(PPU.BG[i].SCSize & 2) * 16 + 32,
PPU.BG[i].BGSize * 8 + 8,
PPU.BG[i].SCBase,
@ -1939,7 +1937,7 @@ static void WhatsUsed ()
printf ("OBJ,");
break;
}
switch ((Memory.FillRAM [0x2130] & 0x30) >> 4)
{
case 0: s = "always on"; break;
@ -1947,7 +1945,7 @@ static void WhatsUsed ()
case 2: s = "outside"; break;
case 3: s = "always off"; break;
}
printf ("\nSub-screen (%s): ", s);
for (i = 0; i < 5; i++)
if (Memory.FillRAM[0x212d] & (1 << i))

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef _DEBUG_H_
#define _DEBUG_H_

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef _DISPLAY_H_
#define _DISPLAY_H_
@ -169,11 +150,11 @@ START_EXTERN_C
void S9xSetPalette ();
void S9xTextMode ();
void S9xGraphicsMode ();
void S9xLoadConfigFiles(char **argv, int argc);
char *S9xParseArgs (char **argv, int argc);
void S9xParseArg (char **argv, int &index, int argc);
void S9xExtraUsage ();
void S9xLoadConfigFiles(char **argv, int argc);
char *S9xParseArgs (char **argv, int argc);
void S9xUsage ();
void S9xInitDisplay (int argc, char **argv);
void S9xDeinitDisplay ();
@ -190,7 +171,7 @@ void S9xNextController ();
bool8 S9xLoadROMImage (const char *string);
const char *S9xSelectFilename (const char *def, const char *dir,
const char *ext, const char *title);
const char *S9xStringInput(const char *message);
const char *S9xChooseFilename (bool8 read_only);
bool8 S9xOpenSnapshotFile (const char *base, bool8 read_only, STREAM *file);
void S9xCloseSnapshotFile (STREAM file);

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef _DMA_H_
#define _DMA_H_
@ -168,7 +149,7 @@ START_EXTERN_C
void S9xResetDMA ();
uint8 S9xDoHDMA (uint8);
void S9xStartHDMA ();
bool8 S9xDoDMA (uint8);
void S9xDoDMA (uint8);
END_EXTERN_C
#endif

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -158,14 +141,11 @@
Nintendo Co., Limited and its subsidiary companies.
**********************************************************************************/
#include "snes9x.h"
#include "dsp1.h"
#include "missing.h"
#include "memmap.h"
#include <math.h>
#include <assert.h>
#include "dsp1emu.c.inc"
#include "dsp2emu.c.inc"
@ -178,7 +158,7 @@ uint8 (*GetDSP)(uint16)=&DSP1GetByte;
void S9xInitDSP1 ()
{
static bool8 init = FALSE;
if (!init)
{
InitDSP ();
@ -189,14 +169,14 @@ void S9xInitDSP1 ()
void S9xResetDSP1 ()
{
S9xInitDSP1 ();
DSP1.waiting4command = TRUE;
DSP1.in_count = 0;
DSP1.out_count = 0;
DSP1.in_index = 0;
DSP1.out_index = 0;
DSP1.first_parameter = TRUE;
DSP4.waiting4command = TRUE;
//printf("DSP-4 Reset\n");
}
@ -204,7 +184,7 @@ void S9xResetDSP1 ()
uint8 S9xGetDSP (uint16 address)
{
uint8 t;
#ifdef DEBUGGER
if (Settings.TraceDSP)
{
@ -212,7 +192,7 @@ uint8 S9xGetDSP (uint16 address)
S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String);
}
#endif
t=(*GetDSP)(address);
//DSP1GetByte(address);
return (t);
@ -234,14 +214,14 @@ void S9xSetDSP (uint8 byte, uint16 address)
void DSP1SetByte(uint8 byte, uint16 address)
{
if (address < DSP1.boundary)
if( (address & 0xf000) == 0x6000 || (address & 0x7fff) < 0x4000 )
{
// if ((address & 1) == 0)
// {
if((DSP1.command==0x0A||DSP1.command==0x1A)&&DSP1.out_count!=0)
{
DSP1.out_count--;
DSP1.out_index++;
DSP1.out_index++;
return;
}
else if (DSP1.waiting4command)
@ -275,7 +255,7 @@ void DSP1SetByte(uint8 byte, uint16 address)
case 0x0a: DSP1.in_count = 1; break;
case 0x3a:
case 0x2a:
case 0x1a:
case 0x1a:
DSP1. command =0x1a;
DSP1.in_count = 1; break;
case 0x16:
@ -338,7 +318,7 @@ void DSP1SetByte(uint8 byte, uint16 address)
DSP1.first_parameter = FALSE;
DSP1.in_index++;
}
if (DSP1.waiting4command ||
(DSP1.first_parameter && byte == 0x80))
{
@ -369,9 +349,9 @@ void DSP1SetByte(uint8 byte, uint16 address)
case 0x00: // Multiple
Op00Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op00Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
DSPOp00 ();
DSP1.out_count = 2;
DSP1.output [0] = Op00Result&0xFF;
DSP1.output [1] = (Op00Result>>8)&0xFF;
@ -380,111 +360,111 @@ void DSP1SetByte(uint8 byte, uint16 address)
case 0x20: // Multiple
Op20Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op20Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
DSPOp20 ();
DSP1.out_count = 2;
DSP1.output [0] = Op20Result&0xFF;
DSP1.output [1] = (Op20Result>>8)&0xFF;
break;
case 0x30:
case 0x10: // Inverse
Op10Coefficient = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op10Exponent = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
DSPOp10 ();
DSP1.out_count = 4;
DSP1.output [0] = (uint8) (((int16) Op10CoefficientR)&0xFF);
DSP1.output [1] = (uint8) ((((int16) Op10CoefficientR)>>8)&0xFF);
DSP1.output [2] = (uint8) (((int16) Op10ExponentR)&0xff);
DSP1.output [3] = (uint8) ((((int16) Op10ExponentR)>>8)&0xff);
break;
case 0x24:
case 0x04: // Sin and Cos of angle
Op04Angle = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op04Radius = (uint16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
DSPOp04 ();
DSP1.out_count = 4;
DSP1.output [0] = (uint8) (Op04Sin&0xFF);
DSP1.output [1] = (uint8) ((Op04Sin>>8)&0xFF);
DSP1.output [2] = (uint8) (Op04Cos&0xFF);
DSP1.output [3] = (uint8) ((Op04Cos>>8)&0xFF);
break;
case 0x08: // Radius
Op08X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op08Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op08Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp08 ();
DSP1.out_count = 4;
DSP1.output [0] = (uint8) (((int16) Op08Ll)&0xFF);
DSP1.output [1] = (uint8) ((((int16) Op08Ll)>>8)&0xFF);
DSP1.output [0] = (uint8) (((int16) Op08Ll)&0xFF);
DSP1.output [1] = (uint8) ((((int16) Op08Ll)>>8)&0xFF);
DSP1.output [2] = (uint8) (((int16) Op08Lh)&0xFF);
DSP1.output [3] = (uint8) ((((int16) Op08Lh)>>8)&0xFF);
break;
case 0x18: // Range
Op18X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op18Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op18Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
Op18R = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
DSPOp18 ();
DSP1.out_count = 2;
DSP1.output [0] = (uint8) (Op18D&0xFF);
DSP1.output [1] = (uint8) ((Op18D>>8)&0xFF);
break;
case 0x38: // Range
Op38X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op38Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op38Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
Op38R = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
DSPOp38 ();
DSP1.out_count = 2;
DSP1.output [0] = (uint8) (Op38D&0xFF);
DSP1.output [1] = (uint8) ((Op38D>>8)&0xFF);
break;
case 0x28: // Distance (vector length)
Op28X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op28Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op28Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp28 ();
DSP1.out_count = 2;
DSP1.output [0] = (uint8) (Op28R&0xFF);
DSP1.output [1] = (uint8) ((Op28R>>8)&0xFF);
break;
case 0x2c:
case 0x0c: // Rotate (2D rotate)
Op0CA = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op0CX1 = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op0CY1 = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp0C ();
DSP1.out_count = 4;
DSP1.output [0] = (uint8) (Op0CX2&0xFF);
DSP1.output [1] = (uint8) ((Op0CX2>>8)&0xFF);
DSP1.output [2] = (uint8) (Op0CY2&0xFF);
DSP1.output [3] = (uint8) ((Op0CY2>>8)&0xFF);
break;
case 0x3c:
case 0x1c: // Polar (3D rotate)
Op1CZ = (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
@ -494,9 +474,9 @@ void DSP1SetByte(uint8 byte, uint16 address)
Op1CXBR = (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
Op1CYBR = (DSP1.parameters [8]|(DSP1.parameters[9]<<8));
Op1CZBR = (DSP1.parameters [10]|(DSP1.parameters[11]<<8));
DSPOp1C ();
DSP1.out_count = 6;
DSP1.output [0] = (uint8) (Op1CXAR&0xFF);
DSP1.output [1] = (uint8) ((Op1CXAR>>8)&0xFF);
@ -505,7 +485,7 @@ void DSP1SetByte(uint8 byte, uint16 address)
DSP1.output [4] = (uint8) (Op1CZAR&0xFF);
DSP1.output [5] = (uint8) ((Op1CZAR>>8)&0xFF);
break;
case 0x32:
case 0x22:
case 0x12:
@ -517,9 +497,9 @@ void DSP1SetByte(uint8 byte, uint16 address)
Op02LES = (short)(DSP1.parameters [8]|(DSP1.parameters[9]<<8));
Op02AAS = (unsigned short)(DSP1.parameters [10]|(DSP1.parameters[11]<<8));
Op02AZS = (unsigned short)(DSP1.parameters [12]|(DSP1.parameters[13]<<8));
DSPOp02 ();
DSP1.out_count = 8;
DSP1.output [0] = (uint8) (Op02VOF&0xFF);
DSP1.output [1] = (uint8) ((Op02VOF>>8)&0xFF);
@ -530,15 +510,15 @@ void DSP1SetByte(uint8 byte, uint16 address)
DSP1.output [6] = (uint8) (Op02CY&0xFF);
DSP1.output [7] = (uint8) ((Op02CY>>8)&0xFF);
break;
case 0x3a: //1a Mirror
case 0x2a: //1a Mirror
case 0x1a: // Raster mode 7 matrix data
case 0x0a:
Op0AVS = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8));
DSPOp0A ();
DSP1.out_count = 8;
DSP1.output [0] = (uint8) (Op0AA&0xFF);
DSP1.output [2] = (uint8) (Op0AB&0xFF);
@ -550,7 +530,7 @@ void DSP1SetByte(uint8 byte, uint16 address)
DSP1.output [7] = (uint8) ((Op0AD>>8)&0xFF);
DSP1.in_index=0;
break;
case 0x16:
case 0x26:
case 0x36:
@ -558,9 +538,9 @@ void DSP1SetByte(uint8 byte, uint16 address)
Op06X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op06Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op06Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp06 ();
DSP1.out_count = 6;
DSP1.output [0] = (uint8) (Op06H&0xff);
DSP1.output [1] = (uint8) ((Op06H>>8)&0xFF);
@ -569,23 +549,23 @@ void DSP1SetByte(uint8 byte, uint16 address)
DSP1.output [4] = (uint8) (Op06M&0xFF);
DSP1.output [5] = (uint8) ((Op06M>>8)&0xFF);
break;
case 0x1e:
case 0x2e:
case 0x3e:
case 0x0e: // Target
Op0EH = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op0EV = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
DSPOp0E ();
DSP1.out_count = 4;
DSP1.output [0] = (uint8) (Op0EX&0xFF);
DSP1.output [1] = (uint8) ((Op0EX>>8)&0xFF);
DSP1.output [2] = (uint8) (Op0EY&0xFF);
DSP1.output [3] = (uint8) ((Op0EY>>8)&0xFF);
break;
// Extra commands used by Pilot Wings
case 0x05:
case 0x35:
@ -595,30 +575,30 @@ void DSP1SetByte(uint8 byte, uint16 address)
Op01Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op01Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
Op01Xr = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
DSPOp01 ();
break;
case 0x15:
case 0x15:
case 0x11: // Set attitude matrix B
Op11m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op11Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op11Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
Op11Xr = (int16) (DSP1.parameters [7]|(DSP1.parameters[7]<<8));
DSPOp11 ();
break;
case 0x25:
case 0x21: // Set attitude matrix C
Op21m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op21Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op21Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
Op21Xr = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
DSPOp21 ();
break;
case 0x09:
case 0x39:
case 0x3d:
@ -626,9 +606,9 @@ void DSP1SetByte(uint8 byte, uint16 address)
Op0DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op0DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op0DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp0D ();
DSP1.out_count = 6;
DSP1.output [0] = (uint8) (Op0DF&0xFF);
DSP1.output [1] = (uint8) ((Op0DF>>8)&0xFF);
@ -637,15 +617,15 @@ void DSP1SetByte(uint8 byte, uint16 address)
DSP1.output [4] = (uint8) (Op0DU&0xFF);
DSP1.output [5] = (uint8) ((Op0DU>>8)&0xFF);
break;
case 0x19:
case 0x1d: // Objective matrix B
Op1DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op1DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op1DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp1D ();
DSP1.out_count = 6;
DSP1.output [0] = (uint8) (Op1DF&0xFF);
DSP1.output [1] = (uint8) ((Op1DF>>8)&0xFF);
@ -654,15 +634,15 @@ void DSP1SetByte(uint8 byte, uint16 address)
DSP1.output [4] = (uint8) (Op1DU&0xFF);
DSP1.output [5] = (uint8) ((Op1DU>>8)&0xFF);
break;
case 0x29:
case 0x2d: // Objective matrix C
Op2DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op2DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op2DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp2D ();
DSP1.out_count = 6;
DSP1.output [0] = (uint8) (Op2DF&0xFF);
DSP1.output [1] = (uint8) ((Op2DF>>8)&0xFF);
@ -671,15 +651,15 @@ void DSP1SetByte(uint8 byte, uint16 address)
DSP1.output [4] = (uint8) (Op2DU&0xFF);
DSP1.output [5] = (uint8) ((Op2DU>>8)&0xFF);
break;
case 0x33:
case 0x03: // Subjective matrix A
Op03F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op03L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op03U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp03 ();
DSP1.out_count = 6;
DSP1.output [0] = (uint8) (Op03X&0xFF);
DSP1.output [1] = (uint8) ((Op03X>>8)&0xFF);
@ -688,14 +668,14 @@ void DSP1SetByte(uint8 byte, uint16 address)
DSP1.output [4] = (uint8) (Op03Z&0xFF);
DSP1.output [5] = (uint8) ((Op03Z>>8)&0xFF);
break;
case 0x13: // Subjective matrix B
Op13F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op13L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op13U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp13 ();
DSP1.out_count = 6;
DSP1.output [0] = (uint8) (Op13X&0xFF);
DSP1.output [1] = (uint8) ((Op13X>>8)&0xFF);
@ -704,14 +684,14 @@ void DSP1SetByte(uint8 byte, uint16 address)
DSP1.output [4] = (uint8) (Op13Z&0xFF);
DSP1.output [5] = (uint8) ((Op13Z>>8)&0xFF);
break;
case 0x23: // Subjective matrix C
Op23F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op23L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op23U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp23 ();
DSP1.out_count = 6;
DSP1.output [0] = (uint8) (Op23X&0xFF);
DSP1.output [1] = (uint8) ((Op23X>>8)&0xFF);
@ -720,55 +700,55 @@ void DSP1SetByte(uint8 byte, uint16 address)
DSP1.output [4] = (uint8) (Op23Z&0xFF);
DSP1.output [5] = (uint8) ((Op23Z>>8)&0xFF);
break;
case 0x3b:
case 0x0b:
Op0BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op0BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op0BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp0B ();
DSP1.out_count = 2;
DSP1.output [0] = (uint8) (Op0BS&0xFF);
DSP1.output [1] = (uint8) ((Op0BS>>8)&0xFF);
break;
case 0x1b:
Op1BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op1BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op1BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp1B ();
DSP1.out_count = 2;
DSP1.output [0] = (uint8) (Op1BS&0xFF);
DSP1.output [1] = (uint8) ((Op1BS>>8)&0xFF);
break;
case 0x2b:
Op2BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op2BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op2BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
DSPOp2B ();
DSP1.out_count = 2;
DSP1.output [0] = (uint8) (Op2BS&0xFF);
DSP1.output [1] = (uint8) ((Op2BS>>8)&0xFF);
break;
case 0x34:
case 0x14:
case 0x14:
Op14Zr = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
Op14Xr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
Op14Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
Op14U = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
Op14F = (int16) (DSP1.parameters [8]|(DSP1.parameters[9]<<8));
Op14L = (int16) (DSP1.parameters [10]|(DSP1.parameters[11]<<8));
DSPOp14 ();
DSP1.out_count = 6;
DSP1.output [0] = (uint8) (Op14Zrr&0xFF);
DSP1.output [1] = (uint8) ((Op14Zrr>>8)&0xFF);
@ -777,30 +757,30 @@ void DSP1SetByte(uint8 byte, uint16 address)
DSP1.output [4] = (uint8) (Op14Yrr&0xFF);
DSP1.output [5] = (uint8) ((Op14Yrr>>8)&0xFF);
break;
case 0x27:
case 0x2F:
Op2FUnknown = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
DSPOp2F ();
DSP1.out_count = 2;
DSP1.output [0] = (uint8)(Op2FSize&0xFF);
DSP1.output [1] = (uint8)((Op2FSize>>8)&0xFF);
break;
case 0x07:
case 0x0F:
Op0FRamsize = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
DSPOp0F ();
DSP1.out_count = 2;
DSP1.output [0] = (uint8)(Op0FPass&0xFF);
DSP1.output [1] = (uint8)((Op0FPass>>8)&0xFF);
break;
default:
break;
}
@ -813,7 +793,9 @@ void DSP1SetByte(uint8 byte, uint16 address)
uint8 DSP1GetByte(uint16 address)
{
uint8 t;
if (address < DSP1.boundary)
if ((address & 0xf000) == 0x6000 ||
// (address >= 0x8000 && address < 0xc000))
(address&0x7fff) < 0x4000)
{
if (DSP1.out_count)
{
@ -898,7 +880,7 @@ void DSP2SetByte(uint8 byte, uint16 address)
// DSP1.first_parameter = FALSE;
DSP1.in_index++;
}
if (DSP1.in_count==DSP1.in_index)
{
//DSP1.parameters [DSP1.in_index] |= (byte << 8);
@ -1034,7 +1016,7 @@ void DSP4SetByte(uint8 byte, uint16 address)
InitDSP4();
DSP4_init=TRUE;
}
if (address < DSP1.boundary)
if ((address & 0xf000) == 0x6000 || (address >= 0x8000 && address < 0xc000))
{
dsp4_byte=byte;
dsp4_address=address;
@ -1044,7 +1026,7 @@ void DSP4SetByte(uint8 byte, uint16 address)
uint8 DSP4GetByte(uint16 address)
{
if (address < DSP1.boundary)
if ((address & 0xf000) == 0x6000 || (address >= 0x8000 && address < 0xc000))
{
dsp4_address=address;
DSP4_GetByte();

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef _DSP1_H_
#define _DSP1_H_
@ -180,16 +161,6 @@ void DSP3_Reset();
void DSP4SetByte(uint8 byte, uint16 address);
uint8 DSP4GetByte(uint16 address);
enum
{
M_DSP1_LOROM_S,
M_DSP1_LOROM_L,
M_DSP1_HIROM,
M_DSP2_LOROM,
M_DSP3_LOROM,
M_DSP4_LOROM
};
struct SDSP1 {
uint8 version;
bool8 waiting4command;
@ -201,22 +172,14 @@ struct SDSP1 {
uint32 out_index;
uint8 parameters [512];
uint8 output [512];
uint8 temp_save_data [406];
uint32 maptype;
uint32 boundary;
};
START_EXTERN_C
void S9xResetDSP1 ();
uint8 S9xGetDSP (uint16 Address);
void S9xSetDSP (uint8 Byte, uint16 Address);
void S9xPreSaveDSP1();
void S9xPostLoadDSP1();
END_EXTERN_C
extern struct SDSP1 DSP1;
END_EXTERN_C
#endif

View File

@ -1213,182 +1213,3 @@ void DSPOp2F()
{
Op2FSize=0x100;
}
// FIXME: many of these are unnecessary to save. But some of them are necessary, like Matrix* and maybe VPlane_*
// TODO: move the necessary ones into a global structure so it's not as ugly to save
#define SAVE_OR_LOAD_THE_VARIABLES() \
S(Op00Multiplicand); \
S(Op00Multiplier); \
S(Op00Result); \
S(Op20Multiplicand); \
S(Op20Multiplier); \
S(Op20Result); \
S(Op10Coefficient); \
S(Op10Exponent); \
S(Op10CoefficientR); \
S(Op10ExponentR); \
S(Op04Angle); \
S(Op04Radius); \
S(Op04Sin); \
S(Op04Cos); \
S(Op0CA); \
S(Op0CX1); \
S(Op0CY1); \
S(Op0CX2); \
S(Op0CY2); \
S(CentreX); \
S(CentreY); \
S(VOffset); \
S(VPlane_C); \
S(VPlane_E); \
S(SinAas); \
S(CosAas); \
S(SinAzs); \
S(CosAzs); \
S(SinAZS); \
S(CosAZS); \
S(SecAZS_C1); \
S(SecAZS_E1); \
S(SecAZS_C2); \
S(SecAZS_E2); \
S(Nx); S(Ny); S(Nz); \
S(Gx); S(Gy); S(Gz); \
S(C_Les); S(E_Les); S(G_Les); \
S(Op02FX); \
S(Op02FY); \
S(Op02FZ); \
S(Op02LFE); \
S(Op02LES); \
S(Op02AAS); \
S(Op02AZS); \
S(Op02VOF); \
S(Op02VVA); \
S(Op02CX); \
S(Op02CY); \
S(Op0AVS); \
S(Op0AA); \
S(Op0AB); \
S(Op0AC); \
S(Op0AD); \
S(Op06X); \
S(Op06Y); \
S(Op06Z); \
S(Op06H); \
S(Op06V); \
S(Op06M); \
S(matrixC); \
S(matrixB); \
S(matrixA); \
S(Op01m); \
S(Op01Zr); \
S(Op01Xr); \
S(Op01Yr); \
S(Op11m); \
S(Op11Zr); \
S(Op11Xr); \
S(Op11Yr); \
S(Op21m); \
S(Op21Zr); \
S(Op21Xr); \
S(Op21Yr); \
S(Op0DX); \
S(Op0DY); \
S(Op0DZ); \
S(Op0DF); \
S(Op0DL); \
S(Op0DU); \
S(Op1DX); \
S(Op1DY); \
S(Op1DZ); \
S(Op1DF); \
S(Op1DL); \
S(Op1DU); \
S(Op2DX); \
S(Op2DY); \
S(Op2DZ); \
S(Op2DF); \
S(Op2DL); \
S(Op2DU); \
S(Op03F); \
S(Op03L); \
S(Op03U); \
S(Op03X); \
S(Op03Y); \
S(Op03Z); \
S(Op13F); \
S(Op13L); \
S(Op13U); \
S(Op13X); \
S(Op13Y); \
S(Op13Z); \
S(Op23F); \
S(Op23L); \
S(Op23U); \
S(Op23X); \
S(Op23Y); \
S(Op23Z); \
S(Op14Zr); \
S(Op14Xr); \
S(Op14Yr); \
S(Op14U); \
S(Op14F); \
S(Op14L); \
S(Op14Zrr); \
S(Op14Xrr); \
S(Op14Yrr); \
S(Op0EH); \
S(Op0EV); \
S(Op0EX); \
S(Op0EY); \
S(Op0BX); \
S(Op0BY); \
S(Op0BZ); \
S(Op0BS); \
S(Op1BX); \
S(Op1BY); \
S(Op1BZ); \
S(Op1BS); \
S(Op2BX); \
S(Op2BY); \
S(Op2BZ); \
S(Op2BS); \
S(Op08X); S(Op08Y); S(Op08Z); S(Op08Ll); S(Op08Lh); \
S(Op18X); S(Op18Y); S(Op18Z); S(Op18R); S(Op18D); \
S(Op38X); S(Op38Y); S(Op38Z); S(Op38R); S(Op38D); \
S(Op28X); \
S(Op28Y); \
S(Op28Z); \
S(Op28R); \
S(Op1CX); S(Op1CY); S(Op1CZ); \
S(Op1CXBR); S(Op1CYBR); S(Op1CZBR); S(Op1CXAR); S(Op1CYAR); S(Op1CZAR); \
S(Op1CX1); \
S(Op1CY1); \
S(Op1CZ1); \
S(Op1CX2); \
S(Op1CY2); \
S(Op1CZ2); \
S(Op0FRamsize); \
S(Op0FPass); \
S(Op2FUnknown); \
S(Op2FSize); \
// end
void S9xPreSaveDSP1()
{
int i = 0;
#define S(x) {memcpy(DSP1.temp_save_data + i, &(x), sizeof(x)); i += sizeof(x);}
SAVE_OR_LOAD_THE_VARIABLES();
#undef S
assert(i == sizeof(DSP1.temp_save_data));
}
void S9xPostLoadDSP1()
{
int i = 0;
#define S(x) {memcpy(&(x), DSP1.temp_save_data + i, sizeof(x)); i += sizeof(x);}
SAVE_OR_LOAD_THE_VARIABLES();
#undef S
assert(i == sizeof(DSP1.temp_save_data));
}

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -160,8 +143,6 @@
uint16 DSP2Op09Word1=0;
uint16 DSP2Op09Word2=0;
bool DSP2Op05HasLen=false;
@ -220,7 +201,7 @@ void DSP2_Op01 ()
{
// Op01 size is always 32 bytes input and output.
// The hardware does strange things if you vary the size.
int j;
unsigned char c0, c1, c2, c3;
unsigned char *p1 = DSP1.parameters;
@ -318,7 +299,7 @@ void DSP2_Op0D()
if ( (pixel_offset&1) == 0 )
pixelarray[i] = DSP1.parameters[pixel_offset>>1] >> 4;
else
pixelarray[i] = DSP1.parameters[pixel_offset>>1] & 0x0f;
pixelarray[i] = DSP1.parameters[pixel_offset>>1] & 0x0f;
}
for ( i=0; i < DSP2Op0DOutLen; i++ )

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#ifndef __cplusplus
//C++ in C
typedef unsigned char bool;
@ -1125,7 +1106,9 @@ void DSP3_OP1E_D( int16 move, int16 *lo, int16 *hi )
void DSP3_OP1E_D1( int16 move, int16 *lo, int16 *hi )
{
//uint32 dataOfs = ((move << 1) + 0x03b2) & 0x03ff;
#ifndef NGC
uint32 dataOfs = ((move << 1) + 0x03b2) & 0x03ff;
#endif
int16 Lo;
int16 Hi;
@ -1249,7 +1232,7 @@ void DSP3_Command()
void DSP3SetByte(uint8 byte, uint16 address)
{
if (address < DSP1.boundary)
if ((address & 0xC000) == 0x8000)
{
if (DSP3_SR & 0x04)
{
@ -1260,20 +1243,20 @@ void DSP3SetByte(uint8 byte, uint16 address)
{
DSP3_SR ^= 0x10;
if (DSP3_SR & 0x10)
if (DSP3_SR & 0x10)
DSP3_DR = (DSP3_DR & 0xff00) + byte;
else
{
DSP3_DR = (DSP3_DR & 0x00ff) + (byte << 8);
(*SetDSP3)();
}
}
}
}
}
uint8 DSP3GetByte(uint16 address)
{
if (address < DSP1.boundary)
if ((address & 0xC000) == 0x8000)
{
uint8 byte;
@ -1286,7 +1269,7 @@ uint8 DSP3GetByte(uint16 address)
{
DSP3_SR ^= 0x10;
if (DSP3_SR & 0x10)
if (DSP3_SR & 0x10)
byte = (uint8) (DSP3_DR);
else
{

View File

@ -1,7 +1,7 @@
/**********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
@ -12,16 +12,12 @@
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com),
Nach (n-a-c-h@users.sourceforge.net), and
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
@ -114,30 +110,17 @@
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
HQ2x filter
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2007 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
@ -159,8 +142,6 @@
**********************************************************************************/
#include "snes9x.h"
#include "memmap.h"
#include <string.h>

Some files were not shown because too many files have changed in this diff Show More