mirror of
https://github.com/Polprzewodnikowy/N64FlashcartMenu.git
synced 2024-11-27 04:54:14 +01:00
Merge branch 'develop' into add-rom-patcher
This commit is contained in:
commit
f505135c97
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -21,6 +21,7 @@
|
|||||||
- [ ] Improvement (non-breaking change that adds a new feature)
|
- [ ] Improvement (non-breaking change that adds a new feature)
|
||||||
- [ ] Bug fix (fixes an issue)
|
- [ ] Bug fix (fixes an issue)
|
||||||
- [ ] Breaking change (breaking change)
|
- [ ] Breaking change (breaking change)
|
||||||
|
- [ ] Documentation Improvement
|
||||||
- [ ] Config and build (change in the configuration and build system, has no impact on code or features)
|
- [ ] Config and build (change in the configuration and build system, has no impact on code or features)
|
||||||
|
|
||||||
## Checklist:
|
## Checklist:
|
||||||
|
31
.github/workflows/build.yml
vendored
31
.github/workflows/build.yml
vendored
@ -11,6 +11,9 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build-menu:
|
build-menu:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -68,21 +71,31 @@ jobs:
|
|||||||
name: SC64
|
name: SC64
|
||||||
path: ./output/sc64menu.n64
|
path: ./output/sc64menu.n64
|
||||||
|
|
||||||
# - name: Delete rolling-release tag and release
|
|
||||||
# uses: dev-drprasad/delete-tag-and-release@v1.0
|
|
||||||
# if: github.ref == 'refs/heads/main'
|
|
||||||
# with:
|
|
||||||
# github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
# tag_name: rolling-release
|
|
||||||
# continue-on-error: true
|
|
||||||
|
|
||||||
- name: Upload rolling release
|
- name: Upload rolling release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
if: github.ref == 'refs/heads/main'
|
if: github.ref == 'refs/heads/main'
|
||||||
with:
|
with:
|
||||||
name: Rolling release
|
name: Rolling release
|
||||||
body: Rolling release built from latest commit on `main` branch.
|
body: Rolling release built from latest commit on `main` branch.
|
||||||
tag_name: rolling-release
|
tag_name: 'rolling_release'
|
||||||
|
make_latest: true
|
||||||
|
files: |
|
||||||
|
./output/N64FlashcartMenu.n64
|
||||||
|
./output/menu.bin
|
||||||
|
# ./output/OS64.v64
|
||||||
|
# ./output/OS64P.v64
|
||||||
|
./output/sc64menu.n64
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Upload dev rolling release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
if: github.ref == 'refs/heads/develop'
|
||||||
|
with:
|
||||||
|
name: 'Rolling pre-release'
|
||||||
|
body: Experimental pre-release built from latest commit on `develop` branch.
|
||||||
|
target_commitish: develop
|
||||||
|
tag_name: 'rolling_pre-release'
|
||||||
|
prerelease: true
|
||||||
files: |
|
files: |
|
||||||
./output/N64FlashcartMenu.n64
|
./output/N64FlashcartMenu.n64
|
||||||
./output/menu.bin
|
./output/menu.bin
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
# Ignore generated files in the libdragon FS
|
# Ignore generated files in the libdragon FS
|
||||||
/filesystem/FiraMonoBold.font64
|
/filesystem/FiraMonoBold.font64
|
||||||
|
/filesystem/*.wav64
|
||||||
|
|
||||||
# Ignore external development tools
|
# Ignore external development tools
|
||||||
/tools/*
|
/tools/*
|
||||||
|
2
Doxyfile
2
Doxyfile
@ -905,7 +905,7 @@ WARN_LOGFILE =
|
|||||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||||
# Note: If this tag is empty the current directory is searched.
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = README.md ./src
|
INPUT = README.md ./src ./docs
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
|
18
Makefile
18
Makefile
@ -79,17 +79,27 @@ SRCS = \
|
|||||||
FONTS = \
|
FONTS = \
|
||||||
FiraMonoBold.ttf
|
FiraMonoBold.ttf
|
||||||
|
|
||||||
|
SOUNDS = \
|
||||||
|
cursorsound.wav \
|
||||||
|
back.wav \
|
||||||
|
enter.wav \
|
||||||
|
error.wav \
|
||||||
|
settings.wav
|
||||||
|
|
||||||
OBJS = $(addprefix $(BUILD_DIR)/, $(addsuffix .o,$(basename $(SRCS))))
|
OBJS = $(addprefix $(BUILD_DIR)/, $(addsuffix .o,$(basename $(SRCS))))
|
||||||
MINIZ_OBJS = $(filter $(BUILD_DIR)/libs/miniz/%.o,$(OBJS))
|
MINIZ_OBJS = $(filter $(BUILD_DIR)/libs/miniz/%.o,$(OBJS))
|
||||||
SPNG_OBJS = $(filter $(BUILD_DIR)/libs/libspng/%.o,$(OBJS))
|
SPNG_OBJS = $(filter $(BUILD_DIR)/libs/libspng/%.o,$(OBJS))
|
||||||
DEPS = $(OBJS:.o=.d)
|
DEPS = $(OBJS:.o=.d)
|
||||||
|
|
||||||
FILESYSTEM = \
|
FILESYSTEM = \
|
||||||
$(addprefix $(FILESYSTEM_DIR)/, $(notdir $(FONTS:%.ttf=%.font64)))
|
$(addprefix $(FILESYSTEM_DIR)/, $(notdir $(FONTS:%.ttf=%.font64))) \
|
||||||
|
$(addprefix $(FILESYSTEM_DIR)/, $(notdir $(SOUNDS:%.wav=%.wav64)))
|
||||||
|
|
||||||
$(MINIZ_OBJS): N64_CFLAGS+=-DMINIZ_NO_TIME -fcompare-debug-second
|
$(MINIZ_OBJS): N64_CFLAGS+=-DMINIZ_NO_TIME -fcompare-debug-second
|
||||||
$(SPNG_OBJS): N64_CFLAGS+=-isystem $(SOURCE_DIR)/libs/miniz -DSPNG_USE_MINIZ -fcompare-debug-second
|
$(SPNG_OBJS): N64_CFLAGS+=-isystem $(SOURCE_DIR)/libs/miniz -DSPNG_USE_MINIZ -fcompare-debug-second
|
||||||
$(FILESYSTEM_DIR)/FiraMonoBold.font64: MKFONT_FLAGS+=-c 1 --size 16 -r 20-1FF -r 2026-2026 --ellipsis 2026,1
|
$(FILESYSTEM_DIR)/FiraMonoBold.font64: MKFONT_FLAGS+=-c 1 --size 16 -r 20-7F -r 80-1FF -r 2026-2026 --ellipsis 2026,1
|
||||||
|
$(FILESYSTEM_DIR)/%.wav64: AUDIOCONV_FLAGS=--wav-compress 1
|
||||||
|
|
||||||
|
|
||||||
$(@info $(shell mkdir -p ./$(FILESYSTEM_DIR) &> /dev/null))
|
$(@info $(shell mkdir -p ./$(FILESYSTEM_DIR) &> /dev/null))
|
||||||
|
|
||||||
@ -97,6 +107,10 @@ $(FILESYSTEM_DIR)/%.font64: $(ASSETS_DIR)/%.ttf
|
|||||||
@echo " [FONT] $@"
|
@echo " [FONT] $@"
|
||||||
@$(N64_MKFONT) $(MKFONT_FLAGS) -o $(FILESYSTEM_DIR) "$<"
|
@$(N64_MKFONT) $(MKFONT_FLAGS) -o $(FILESYSTEM_DIR) "$<"
|
||||||
|
|
||||||
|
$(FILESYSTEM_DIR)/%.wav64: $(ASSETS_DIR)/%.wav
|
||||||
|
@echo " [AUDIO] $@"
|
||||||
|
@$(N64_AUDIOCONV) $(AUDIOCONV_FLAGS) -o $(FILESYSTEM_DIR) "$<"
|
||||||
|
|
||||||
$(BUILD_DIR)/$(PROJECT_NAME).dfs: $(FILESYSTEM)
|
$(BUILD_DIR)/$(PROJECT_NAME).dfs: $(FILESYSTEM)
|
||||||
|
|
||||||
$(BUILD_DIR)/menu/views/credits.o: .FORCE
|
$(BUILD_DIR)/menu/views/credits.o: .FORCE
|
||||||
|
135
README.md
135
README.md
@ -25,9 +25,15 @@ An open source menu for N64 flashcarts.
|
|||||||
* Comprehensive ROM information display.
|
* Comprehensive ROM information display.
|
||||||
* Real Time Clock support.
|
* Real Time Clock support.
|
||||||
* Music playback (MP3).
|
* Music playback (MP3).
|
||||||
|
* Menu sound effects.
|
||||||
|
|
||||||
|
|
||||||
### Video showcase (as of Oct 12 2023)
|
## Documentation
|
||||||
|
* [Getting started guide](./docs/00_getting_started_sd.md)
|
||||||
|
* [Menu controls](./docs/01_menu_controls.md)
|
||||||
|
* [Developer guide](./docs/99_developer_guide.md)
|
||||||
|
|
||||||
|
## Video showcase (as of Oct 12 2023)
|
||||||
|
|
||||||
[![N64FlashcartMenu Showcase](http://img.youtube.com/vi/6CKImHTifDA/0.jpg)](http://www.youtube.com/watch?v=6CKImHTifDA "N64FlashcartMenu Showcase (Oct 12 2023)")
|
[![N64FlashcartMenu Showcase](http://img.youtube.com/vi/6CKImHTifDA/0.jpg)](http://www.youtube.com/watch?v=6CKImHTifDA "N64FlashcartMenu Showcase (Oct 12 2023)")
|
||||||
|
|
||||||
@ -40,123 +46,60 @@ An open source menu for N64 flashcarts.
|
|||||||
* Support as many common mods and features as possible.
|
* Support as many common mods and features as possible.
|
||||||
|
|
||||||
|
|
||||||
## Getting started
|
## Experimental features
|
||||||
Using your PC, insert the SD card and ensure it is formatted for compatibility (We recommend FAT32 in most instances).
|
These features are subject to change:
|
||||||
|
|
||||||
### Save files
|
|
||||||
By default, all save files (whether `FlashRam`, `SRAM` or `EEPROM`) use the `.sav` extension and match the filename of the ROM.
|
|
||||||
|
|
||||||
Each save file can be found in the `/saves` folder located in the same directory as the ROM and shares the same file name, apart from the extension.
|
|
||||||
|
|
||||||
If transfering a file from a different flashcart such as the ED64, it will be necessary to change the extension of the file to `sav`.
|
|
||||||
|
|
||||||
i.e. for `Glover (USA).eep` you would need to change the extension to `Glover (USA).sav`
|
|
||||||
|
|
||||||
**NOTE:** certain emulator saves or saves created for a different ROM version or region may be incompatible.
|
|
||||||
|
|
||||||
|
|
||||||
### ROM Boxart
|
### ROM Boxart
|
||||||
To use boxart, you need to place png files of size 158x112 in the folder `/menu/boxart` on the SD card.
|
To use boxart, place PNG files in the `/menu/boxart` folder on the SD card with the following dimensions:
|
||||||
|
* Standard covers: 158x112
|
||||||
|
* 64DD covers: 129x112
|
||||||
|
* Japanese covers: 112x158
|
||||||
|
|
||||||
Each file must be named according to the 2 letter ROM ID, or 3 letter ROM ID including media type.
|
Each file must be named according to the 2 letter ROM ID, or 3 letter ROM ID including media type.
|
||||||
i.e. for GoldenEye 2 letters, this would be `GE.png`.
|
i.e. for GoldenEye 2 letters, this would be `GE.png`.
|
||||||
i.e. for GoldenEye 3 letters, this would be `NGE.png`.
|
i.e. for GoldenEye 3 letters, this would be `NGE.png`.
|
||||||
A known set of PNG files using 2 letter ID's can be downloaded [here](https://mega.nz/file/6cNGwSqI#8X5ukb65n3YMlGaUtSOGXkKo9HxVnnMOgqn94Epcr7w).
|
You can download these boxart packs:
|
||||||
|
|
||||||
|
[American Boxart](https://mega.nz/file/6cNGwSqI#8X5ukb65n3YMlGaUtSOGXkKo9HxVnnMOgqn94Epcr7w)
|
||||||
|
|
||||||
### Emulator support
|
[European Boxart](https://mega.nz/file/O7AjDbRJ#VnVU10dq8HQvBUQptppI6PAcQMb8-Zembqav8WtAQ_M)
|
||||||
Emulators should be added to the `/menu/emulators` directory on the SD card.
|
|
||||||
|
[64DD Boxart](https://mega.nz/file/O3JzwD7B#BYl1aV-pbrJ-MxWUbM_K0yGVIRbmSoxJJZqQInRzZyM)
|
||||||
|
|
||||||
Menu currently supports the following emulators and associated ROM file names:
|
|
||||||
- **NES**: [neon64v2](https://github.com/hcs64/neon64v2) by *hcs64* - `neon64bu.rom`
|
|
||||||
- **SNES**: [sodium64](https://github.com/Hydr8gon/sodium64) by *Hydr8gon* - `sodium64.z64`
|
|
||||||
- **Game Boy** / **GB Color**: [gb64](https://lambertjamesd.github.io/gb64/romwrapper/romwrapper.html) by *lambertjamesd* - `gb.v64` / `gbc.v64`
|
|
||||||
- **Sega Master System** / **Sega Game Gear** / **Sg1000**: [TotalSMS](https://github.com/ITotalJustice/TotalSMS) - `TotalSMS.z64` (Currently broken)
|
|
||||||
|
|
||||||
### Menu Settings
|
### Menu Settings
|
||||||
The Menu creates a `config.ini` file in `sd:/menu/` which contains various settings that are used by the menu.
|
The Menu creates a `config.ini` file in `sd:/menu/` which contains various settings that are used by the menu.
|
||||||
Currently these are read-only (can be viewed in the menu by pressing `L` on the Joypad).
|
|
||||||
If required, you can manually adjust the file on the SD card using your computer.
|
If required, you can manually adjust the file on the SD card using your computer.
|
||||||
|
|
||||||
### SC64 Specific
|
|
||||||
- Ensure the cart has the latest [firmware](https://github.com/Polprzewodnikowy/SummerCart64/releases/latest) installed.
|
|
||||||
- Download the latest `sc64menu.n64` file from the releases page, then put it in the root directory of your SD card.
|
|
||||||
|
|
||||||
##### 64DD disk support
|
## Flashcart specific
|
||||||
For the ability to load and run 64DD disk images, you need to place required 64DD IPL dumps in the `/menu/64ddipl` folder on the SD card.
|
|
||||||
For more details follow [this guide on the 64dd.org website](https://64dd.org/tutorial_sc64.html).
|
|
||||||
|
|
||||||
Note: to load an expansion disk (e.g. F-Zero X) browse to the N64 ROM and load it (but not start it) and then browse to the DD expansion file and press the `R` button.
|
### SC64
|
||||||
|
* Ensure the cart has the latest [firmware](https://github.com/Polprzewodnikowy/SummerCart64/releases/latest) installed.
|
||||||
|
* Download the latest `sc64menu.n64` file from the [releases](https://github.com/Polprzewodnikowy/N64FlashcartMenu/releases/) page, then put it in the root directory of your SD card.
|
||||||
|
|
||||||
|
|
||||||
### 64drive Specific
|
### 64drive
|
||||||
- Ensure the cart has the latest [firmware](https://64drive.retroactive.be/support.php) installed.
|
* Ensure the cart has the latest [firmware](https://64drive.retroactive.be/support.php) installed.
|
||||||
- Download the latest `menu.bin` file from the releases page, then put it in the root directory of your SD card.
|
* Download the latest `menu.bin` file from the [releases](https://github.com/Polprzewodnikowy/N64FlashcartMenu/releases/) page, then put it in the root directory of your SD card.
|
||||||
|
|
||||||
|
|
||||||
### ED64 & ED64P Specific
|
### ED64 & ED64P
|
||||||
Currently not supported, but work is in progress (See [PR's](https://github.com/Polprzewodnikowy/N64FlashcartMenu/pulls)).
|
Currently not supported, but work is in progress (See [PR's](https://github.com/Polprzewodnikowy/N64FlashcartMenu/pulls)).
|
||||||
|
|
||||||
The aim is to replace [Altra64](https://github.com/networkfusion/altra64) and [ED64-UnofficialOS](https://github.com/n64-tools/ED64-UnofficialOS-binaries).
|
The aim is to replace [Altra64](https://github.com/networkfusion/altra64) and [ED64-UnofficialOS](https://github.com/n64-tools/ED64-UnofficialOS-binaries).
|
||||||
|
|
||||||
|
|
||||||
# Developer documentation
|
|
||||||
|
|
||||||
You can use a dev container in VSCode to ease development.
|
|
||||||
|
|
||||||
|
|
||||||
## To deploy:
|
|
||||||
### SC64
|
|
||||||
* Download the deployer [here](https://github.com/Polprzewodnikowy/SummerCart64/releases/download/v2.18.0/sc64-deployer-windows-v2.18.0.zip)
|
|
||||||
* Extract and place `sc64deployer.exe` in the `tools/sc64` directory.
|
|
||||||
|
|
||||||
Make sure that your firmware is compatible (currently v2.18.0+)
|
|
||||||
See: [here](https://github.com/Polprzewodnikowy/SummerCart64/blob/v2.18.0/docs/00_quick_startup_guide.md#firmware-backupupdate)
|
|
||||||
|
|
||||||
#### From the devcontainer
|
|
||||||
It is not currently possible to directly communicate with USB devices.
|
|
||||||
BUT, as a work around you can use a proxy TCP/IP connection
|
|
||||||
Set up a proxy: open a terminal window, `cd ./tools/sc64` and then `./sc64deployer.exe server`
|
|
||||||
|
|
||||||
Then in the dev container, use `make run` or `make run-debug`
|
|
||||||
|
|
||||||
|
|
||||||
#### From your host (Windows) OS
|
|
||||||
|
|
||||||
* Run `./localdeploy.bat` from the terminal
|
|
||||||
|
|
||||||
Toggle the N64 power switch to load the ROM.
|
|
||||||
|
|
||||||
`ms-vscode.makefile-tools` will help (installed automatically in dev container).
|
|
||||||
TODO: it does not yet work with `F5`: see https://devblogs.microsoft.com/cppblog/now-announcing-makefile-support-in-visual-studio-code/
|
|
||||||
WORKAROUND: in the dev container terminal, use make directly, i.e.: `make`
|
|
||||||
The ROM can be found in the `output` directory.
|
|
||||||
|
|
||||||
NOTE: a "release" version of the SC64 menu is called `sc64menu.n64` and can be created for when you want to add it directly to the SDCard. This is generated by running `make all` or running `make sc64`.
|
|
||||||
|
|
||||||
### Ares Emulator
|
|
||||||
For ease of development and debugging, the menu ROM is able to run in the Ares emulator (without most flashcart features).
|
|
||||||
|
|
||||||
* Ensure you have the Ares emulator on you computer.
|
|
||||||
* Load the `N64FlashcartMenu.n64` ROM.
|
|
||||||
|
|
||||||
### Others
|
|
||||||
* Add the required file to the correct folder on your SD card.
|
|
||||||
|
|
||||||
|
|
||||||
# Update Libdragon submodule
|
|
||||||
This repo currently uses the `preview` branch as a submodule at a specific commit.
|
|
||||||
To update to the latest version, use `git submodule update --remote ` from the terminal.
|
|
||||||
|
|
||||||
# Generate documentation
|
|
||||||
Run `doxygen` from the dev container terminal.
|
|
||||||
Make sure you fix the warnings before creating a PR!
|
|
||||||
Generated documentation is located in `output/docs` folder and auto published to the `gh-pages` branch when merged with `main`.
|
|
||||||
|
|
||||||
Once merged, they can be viewed [here](https://polprzewodnikowy.github.io/N64FlashcartMenu/)
|
|
||||||
|
|
||||||
# Open source software and licenses used
|
# Open source software and licenses used
|
||||||
- [libdragon](https://github.com/DragonMinded/libdragon) (UNLICENSE License)
|
|
||||||
- [libspng](https://github.com/randy408/libspng) (BSD 2-Clause License)
|
* [libdragon](https://github.com/DragonMinded/libdragon) (UNLICENSE License)
|
||||||
- [mini.c](https://github.com/univrsal/mini.c) (BSD 2-Clause License)
|
* [libspng](https://github.com/randy408/libspng) (BSD 2-Clause License)
|
||||||
- [minimp3](https://github.com/lieff/minimp3) (CC0 1.0 Universal)
|
* [mini.c](https://github.com/univrsal/mini.c) (BSD 2-Clause License)
|
||||||
- [miniz](https://github.com/richgel999/miniz) (MIT License)
|
* [minimp3](https://github.com/lieff/minimp3) (CC0 1.0 Universal)
|
||||||
|
* [miniz](https://github.com/richgel999/miniz) (MIT License)
|
||||||
|
|
||||||
|
## Sounds
|
||||||
|
See [License](https://pixabay.com/en/service/license-summary/) for the following sounds:
|
||||||
|
* [Cursor sound](https://pixabay.com/en/sound-effects/click-buttons-ui-menu-sounds-effects-button-7-203601/) by Skyscraper_seven (Free to use)
|
||||||
|
* [Actions (Enter, back) sound](https://pixabay.com/en/sound-effects/menu-button-user-interface-pack-190041/) by Liecio (Free to use)
|
||||||
|
* [Error sound](https://pixabay.com/en/sound-effects/error-call-to-attention-129258/) by Universfield (Free to use)
|
||||||
|
BIN
assets/back.wav
Normal file
BIN
assets/back.wav
Normal file
Binary file not shown.
BIN
assets/cursorsound.wav
Normal file
BIN
assets/cursorsound.wav
Normal file
Binary file not shown.
BIN
assets/enter.wav
Normal file
BIN
assets/enter.wav
Normal file
Binary file not shown.
BIN
assets/error.wav
Normal file
BIN
assets/error.wav
Normal file
Binary file not shown.
BIN
assets/settings.wav
Normal file
BIN
assets/settings.wav
Normal file
Binary file not shown.
82
docs/00_getting_started_sd.md
Normal file
82
docs/00_getting_started_sd.md
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
## First time setup of SD card
|
||||||
|
|
||||||
|
Using your PC, insert the SD card and ensure it is formatted for compatibility with your flashcart (*FAT32 and EXFAT are fully supported on the SC64*).
|
||||||
|
|
||||||
|
- Download the latest `sc64menu.n64` (assuming you are using an *sc64*) file from the [releases](https://github.com/Polprzewodnikowy/N64FlashcartMenu/releases/) page, then put it in the root directory of your SD card.
|
||||||
|
- Create a folder in the root of your SD card called `menu`.
|
||||||
|
- Place your ROMs on the SD Card, in any folder (**except for `menu`**).
|
||||||
|
|
||||||
|
|
||||||
|
### Emulator support
|
||||||
|
Emulators should be added to the `/menu/emulators` directory on the SD card.
|
||||||
|
|
||||||
|
Menu currently supports the following emulators and associated ROM file names:
|
||||||
|
- **NES**: [neon64v2](https://github.com/hcs64/neon64v2/releases) by *hcs64* - `neon64bu.rom`
|
||||||
|
- **SNES**: [sodium64](https://github.com/Hydr8gon/sodium64/releases) by *Hydr8gon* - `sodium64.z64`
|
||||||
|
- **Game Boy** / **GB Color**: [gb64](https://lambertjamesd.github.io/gb64/romwrapper/romwrapper.html) by *lambertjamesd* - `gb.v64` / `gbc.v64` ("Download Emulator" button)
|
||||||
|
|
||||||
|
|
||||||
|
### 64DD disk support
|
||||||
|
For the ability to load and run 64DD disk images, you need to place the required 64DD IPL dumps in the `/menu/64ddipl` folder on the SD card.
|
||||||
|
For more details, follow [this guide on the 64dd.org website](https://64dd.org/tutorial_sc64.html).
|
||||||
|
|
||||||
|
|
||||||
|
#### So what would the layout of the SD Card look like?
|
||||||
|
```plaintext
|
||||||
|
SD:\
|
||||||
|
│
|
||||||
|
├── sc64menu.n64
|
||||||
|
│
|
||||||
|
│
|
||||||
|
├── menu\
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ ├── 64ddipl\
|
||||||
|
│ │ ├── NDDE0.n64
|
||||||
|
│ │ ├── NDDJ2.n64
|
||||||
|
│ │ └── NDXJ0.n64
|
||||||
|
│ │
|
||||||
|
│ └── emulators
|
||||||
|
│ ├── neon64bu.rom
|
||||||
|
│ ├── sodium64.z64
|
||||||
|
│ ├── gb.v64
|
||||||
|
│ └── gbc.v64
|
||||||
|
│
|
||||||
|
├── (a rom).z64
|
||||||
|
├── (a rom).n64
|
||||||
|
├── (some folder with roms)\
|
||||||
|
│ └── (some folder with roms)\
|
||||||
|
| └── (Some supported ROM files)
|
||||||
|
│
|
||||||
|
├── (Some supported ROM files)
|
||||||
|
|
|
||||||
|
└── (Some folder with 64DD disk images)\
|
||||||
|
└── (Some 64DD disk images)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Save Files
|
||||||
|
All save files (whether `FlashRam`, `SRAM` or `EEPROM`) use the `.sav` extension and match the filename of a ROM.
|
||||||
|
|
||||||
|
Each save file can be found in the `/saves` folder located in the **same directory** as the ROM and shares the same file name, apart from the extension.
|
||||||
|
These files are created and modified when a "game" saves.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
├── (some folder with roms)\
|
||||||
|
├── a_rom.z64
|
||||||
|
├── b_rom.n64
|
||||||
|
└── saves\
|
||||||
|
├── a_rom.sav
|
||||||
|
└── b_rom.sav
|
||||||
|
```
|
||||||
|
|
||||||
|
### Transfering saves from an ED64
|
||||||
|
If transferring a file from a different flashcart, such as the ED64, it will be necessary to change the extension of the file to `sav`.
|
||||||
|
|
||||||
|
i.e. for `Glover (USA).eep` you would need to change the extension to `Glover (USA).sav`
|
||||||
|
|
||||||
|
You may also need to pad/trim the files to their original size:
|
||||||
|
- For EEPROM 4Kbit games, remove the padding.
|
||||||
|
- For others, use a tool such as Ninjiteu's N64 Save converter.
|
||||||
|
|
||||||
|
**NOTE:** certain emulator saves or saves created for a different ROM version or region may be incompatible.
|
14
docs/01_menu_controls.md
Normal file
14
docs/01_menu_controls.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
## Menu Controls
|
||||||
|
|
||||||
|
### Fast scroll
|
||||||
|
Use the C-Up and C-Down buttons
|
||||||
|
|
||||||
|
|
||||||
|
### DD ROMs
|
||||||
|
|
||||||
|
#### Expansion Disks
|
||||||
|
To load an expansion disk (e.g. F-Zero X) browse to the N64 ROM and load it (but not start it) and then browse to the DD expansion file and press the `R` button.
|
||||||
|
|
||||||
|
#### Disk swapping
|
||||||
|
This feature is not currently available in the menu.
|
||||||
|
|
69
docs/99_developer_guide.md
Normal file
69
docs/99_developer_guide.md
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
## Developer documentation
|
||||||
|
|
||||||
|
You can use a dev container in VSCode to ease development.
|
||||||
|
|
||||||
|
### A quickstart video tutorial on how to set up your environment
|
||||||
|
[![Devcontainer quickstart guide](http://img.youtube.com/vi/h05ufOsRgZU/0.jpg)](http://www.youtube.com/watch?v=h05ufOsRgZU "Devcontainer quickstart guide").
|
||||||
|
|
||||||
|
|
||||||
|
### To deploy:
|
||||||
|
#### SC64
|
||||||
|
* Download the deployer [here](https://github.com/Polprzewodnikowy/SummerCart64/releases/download/v2.18.0/sc64-deployer-windows-v2.18.0.zip)
|
||||||
|
* Extract and place `sc64deployer.exe` in the `tools/sc64` directory.
|
||||||
|
|
||||||
|
Make sure that your firmware is compatible (currently v2.18.0+)
|
||||||
|
See: [here](https://github.com/Polprzewodnikowy/SummerCart64/blob/v2.18.0/docs/00_quick_startup_guide.md#firmware-backupupdate)
|
||||||
|
|
||||||
|
##### From the devcontainer
|
||||||
|
It is not currently possible to directly communicate with USB devices.
|
||||||
|
BUT, as a workaround you can use a proxy TCP/IP connection
|
||||||
|
Set up a proxy: open a terminal window, `cd ./tools/sc64` and then `./sc64deployer.exe server`
|
||||||
|
|
||||||
|
Then in the dev container, use `make run` or `make run-debug`
|
||||||
|
|
||||||
|
|
||||||
|
##### From your host (Windows) OS
|
||||||
|
|
||||||
|
* Run `./localdeploy.bat` from the terminal
|
||||||
|
|
||||||
|
Toggle the N64 power switch to load the ROM.
|
||||||
|
|
||||||
|
`ms-vscode.makefile-tools` will help (installed automatically in dev container).
|
||||||
|
NOTE: it does not yet work with `F5`: see [this blog post](https://devblogs.microsoft.com/cppblog/now-announcing-makefile-support-in-visual-studio-code/)
|
||||||
|
WORKAROUND: in the dev container terminal, use make directly, i.e.: `make`
|
||||||
|
The ROM can be found in the `output` directory.
|
||||||
|
|
||||||
|
NOTE: a "release" version of the SC64 menu is called `sc64menu.n64` and can be created for when you want to add it directly to the SDCard. This is generated by running `make all` or running `make sc64`.
|
||||||
|
|
||||||
|
#### Ares Emulator
|
||||||
|
For ease of development and debugging, the menu ROM can run in the [Ares emulator](https://ares-emu.net/) (without most flashcart features).
|
||||||
|
|
||||||
|
* Ensure you have the Ares emulator on your computer.
|
||||||
|
* Load the `N64FlashcartMenu.n64` ROM.
|
||||||
|
|
||||||
|
#### Others
|
||||||
|
* Add the required file to the correct folder on your SD card.
|
||||||
|
|
||||||
|
|
||||||
|
## Update Libdragon submodule
|
||||||
|
This repo currently uses the `preview` branch as a submodule at a specific commit.
|
||||||
|
To update to the latest version, use `git submodule update --remote` from the terminal.
|
||||||
|
|
||||||
|
## Generate documentation
|
||||||
|
Run `doxygen` from the dev container terminal.
|
||||||
|
Make sure you fix the warnings before creating a PR!
|
||||||
|
Generated documentation is located in the `output/docs` folder and auto-published to the `gh-pages` branch when merged with `main`.
|
||||||
|
|
||||||
|
Once merged, they can be viewed [here](https://polprzewodnikowy.github.io/N64FlashcartMenu/)
|
||||||
|
|
||||||
|
### Test generated docs in the dev-container
|
||||||
|
Install Prerequisites:
|
||||||
|
```bash
|
||||||
|
apt-get install ruby-full build-essential zlib1g-dev
|
||||||
|
gem install jekyll bundler
|
||||||
|
```
|
||||||
|
|
||||||
|
You can then serve the webpage:
|
||||||
|
```bash
|
||||||
|
cd output/docs && jekyll serve
|
||||||
|
```
|
@ -1 +1 @@
|
|||||||
Subproject commit af650428e9615f4e08d8e7eae187929a90c15ccc
|
Subproject commit 9bae49994bf1c796f9939ea1aa7c133813b9053f
|
@ -170,7 +170,7 @@ static flashcart_err_t d64_load_save (char *save_path) {
|
|||||||
|
|
||||||
size_t save_size = f_size(&fil);
|
size_t save_size = f_size(&fil);
|
||||||
|
|
||||||
bool is_eeprom_save = (current_save_type == SAVE_TYPE_EEPROM_4K || current_save_type == SAVE_TYPE_EEPROM_16K);
|
bool is_eeprom_save = (current_save_type == SAVE_TYPE_EEPROM_4KBIT || current_save_type == SAVE_TYPE_EEPROM_16KBIT);
|
||||||
|
|
||||||
void *address = (void *) (SAVE_ADDRESS_DEV_B);
|
void *address = (void *) (SAVE_ADDRESS_DEV_B);
|
||||||
if (is_eeprom_save) {
|
if (is_eeprom_save) {
|
||||||
@ -212,27 +212,27 @@ static flashcart_err_t d64_set_save_type (flashcart_save_type_t save_type) {
|
|||||||
case FLASHCART_SAVE_TYPE_NONE:
|
case FLASHCART_SAVE_TYPE_NONE:
|
||||||
type = SAVE_TYPE_NONE;
|
type = SAVE_TYPE_NONE;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_EEPROM_4K:
|
case FLASHCART_SAVE_TYPE_EEPROM_4KBIT:
|
||||||
type = SAVE_TYPE_EEPROM_4K;
|
type = SAVE_TYPE_EEPROM_4KBIT;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_EEPROM_16K:
|
case FLASHCART_SAVE_TYPE_EEPROM_16KBIT:
|
||||||
type = SAVE_TYPE_EEPROM_16K;
|
type = SAVE_TYPE_EEPROM_16KBIT;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_SRAM:
|
case FLASHCART_SAVE_TYPE_SRAM_256KBIT:
|
||||||
type = SAVE_TYPE_SRAM;
|
type = SAVE_TYPE_SRAM_256KBIT;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_SRAM_BANKED:
|
case FLASHCART_SAVE_TYPE_SRAM_BANKED:
|
||||||
type = SAVE_TYPE_SRAM_BANKED;
|
type = SAVE_TYPE_SRAM_BANKED;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_SRAM_128K:
|
case FLASHCART_SAVE_TYPE_SRAM_1MBIT:
|
||||||
// NOTE: 64drive doesn't support 128 kiB SRAM save type, fallback to 32 kiB SRAM save type
|
// NOTE: 64drive doesn't support 128 kiB SRAM save type, fallback to 32 kiB SRAM save type
|
||||||
type = SAVE_TYPE_SRAM;
|
type = SAVE_TYPE_SRAM_256KBIT;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_FLASHRAM:
|
case FLASHCART_SAVE_TYPE_FLASHRAM_1MBIT:
|
||||||
type = SAVE_TYPE_FLASHRAM;
|
type = SAVE_TYPE_FLASHRAM_1MBIT;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_FLASHRAM_PKST2:
|
case FLASHCART_SAVE_TYPE_FLASHRAM_PKST2:
|
||||||
type = (device_variant == DEVICE_VARIANT_A) ? SAVE_TYPE_FLASHRAM_PKST2 : SAVE_TYPE_FLASHRAM;
|
type = (device_variant == DEVICE_VARIANT_A) ? SAVE_TYPE_FLASHRAM_PKST2 : SAVE_TYPE_FLASHRAM_1MBIT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return FLASHCART_ERR_ARGS;
|
return FLASHCART_ERR_ARGS;
|
||||||
|
@ -79,10 +79,10 @@ typedef enum {
|
|||||||
/** @brief Save Type Enumeration. */
|
/** @brief Save Type Enumeration. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SAVE_TYPE_NONE,
|
SAVE_TYPE_NONE,
|
||||||
SAVE_TYPE_EEPROM_4K,
|
SAVE_TYPE_EEPROM_4KBIT,
|
||||||
SAVE_TYPE_EEPROM_16K,
|
SAVE_TYPE_EEPROM_16KBIT,
|
||||||
SAVE_TYPE_SRAM,
|
SAVE_TYPE_SRAM_256KBIT,
|
||||||
SAVE_TYPE_FLASHRAM,
|
SAVE_TYPE_FLASHRAM_1MBIT,
|
||||||
SAVE_TYPE_SRAM_BANKED,
|
SAVE_TYPE_SRAM_BANKED,
|
||||||
SAVE_TYPE_FLASHRAM_PKST2,
|
SAVE_TYPE_FLASHRAM_PKST2,
|
||||||
} d64_save_type_t;
|
} d64_save_type_t;
|
||||||
|
@ -34,12 +34,12 @@ typedef enum {
|
|||||||
/** @brief Flashcart save type enumeration */
|
/** @brief Flashcart save type enumeration */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FLASHCART_SAVE_TYPE_NONE,
|
FLASHCART_SAVE_TYPE_NONE,
|
||||||
FLASHCART_SAVE_TYPE_EEPROM_4K,
|
FLASHCART_SAVE_TYPE_EEPROM_4KBIT,
|
||||||
FLASHCART_SAVE_TYPE_EEPROM_16K,
|
FLASHCART_SAVE_TYPE_EEPROM_16KBIT,
|
||||||
FLASHCART_SAVE_TYPE_SRAM,
|
FLASHCART_SAVE_TYPE_SRAM_256KBIT,
|
||||||
FLASHCART_SAVE_TYPE_SRAM_BANKED,
|
FLASHCART_SAVE_TYPE_SRAM_BANKED,
|
||||||
FLASHCART_SAVE_TYPE_SRAM_128K,
|
FLASHCART_SAVE_TYPE_SRAM_1MBIT,
|
||||||
FLASHCART_SAVE_TYPE_FLASHRAM,
|
FLASHCART_SAVE_TYPE_FLASHRAM_1MBIT,
|
||||||
FLASHCART_SAVE_TYPE_FLASHRAM_PKST2,
|
FLASHCART_SAVE_TYPE_FLASHRAM_PKST2,
|
||||||
__FLASHCART_SAVE_TYPE_END
|
__FLASHCART_SAVE_TYPE_END
|
||||||
} flashcart_save_type_t;
|
} flashcart_save_type_t;
|
||||||
|
@ -51,7 +51,7 @@ bool fatfs_get_file_sectors (char *path, uint32_t *address, address_type_t type,
|
|||||||
|
|
||||||
uint32_t cluster = fil.clust;
|
uint32_t cluster = fil.clust;
|
||||||
|
|
||||||
if (cluster >= fs->n_fatent) {
|
if ((cluster < 2) || (cluster >= fs->n_fatent)) {
|
||||||
error = true;
|
error = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -388,12 +388,12 @@ static flashcart_err_t sc64_load_save (char *save_path) {
|
|||||||
sc64_save_type_t type = (sc64_save_type_t) (value);
|
sc64_save_type_t type = (sc64_save_type_t) (value);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SAVE_TYPE_EEPROM_4K:
|
case SAVE_TYPE_EEPROM_4KBIT:
|
||||||
case SAVE_TYPE_EEPROM_16K:
|
case SAVE_TYPE_EEPROM_16KBIT:
|
||||||
address = (void *) (EEPROM_ADDRESS);
|
address = (void *) (EEPROM_ADDRESS);
|
||||||
break;
|
break;
|
||||||
case SAVE_TYPE_SRAM:
|
case SAVE_TYPE_SRAM_256KBIT:
|
||||||
case SAVE_TYPE_FLASHRAM:
|
case SAVE_TYPE_FLASHRAM_1MBIT:
|
||||||
case SAVE_TYPE_SRAM_BANKED:
|
case SAVE_TYPE_SRAM_BANKED:
|
||||||
address = (void *) (SRAM_FLASHRAM_ADDRESS);
|
address = (void *) (SRAM_FLASHRAM_ADDRESS);
|
||||||
break;
|
break;
|
||||||
@ -515,26 +515,26 @@ static flashcart_err_t sc64_set_save_type (flashcart_save_type_t save_type) {
|
|||||||
case FLASHCART_SAVE_TYPE_NONE:
|
case FLASHCART_SAVE_TYPE_NONE:
|
||||||
type = SAVE_TYPE_NONE;
|
type = SAVE_TYPE_NONE;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_EEPROM_4K:
|
case FLASHCART_SAVE_TYPE_EEPROM_4KBIT:
|
||||||
type = SAVE_TYPE_EEPROM_4K;
|
type = SAVE_TYPE_EEPROM_4KBIT;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_EEPROM_16K:
|
case FLASHCART_SAVE_TYPE_EEPROM_16KBIT:
|
||||||
type = SAVE_TYPE_EEPROM_16K;
|
type = SAVE_TYPE_EEPROM_16KBIT;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_SRAM:
|
case FLASHCART_SAVE_TYPE_SRAM_256KBIT:
|
||||||
type = SAVE_TYPE_SRAM;
|
type = SAVE_TYPE_SRAM_256KBIT;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_SRAM_BANKED:
|
case FLASHCART_SAVE_TYPE_SRAM_BANKED:
|
||||||
type = SAVE_TYPE_SRAM_BANKED;
|
type = SAVE_TYPE_SRAM_BANKED;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_SRAM_128K:
|
case FLASHCART_SAVE_TYPE_SRAM_1MBIT:
|
||||||
type = SAVE_TYPE_SRAM_128K;
|
type = SAVE_TYPE_SRAM_1MBIT;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_FLASHRAM:
|
case FLASHCART_SAVE_TYPE_FLASHRAM_1MBIT:
|
||||||
type = SAVE_TYPE_FLASHRAM;
|
type = SAVE_TYPE_FLASHRAM_1MBIT;
|
||||||
break;
|
break;
|
||||||
case FLASHCART_SAVE_TYPE_FLASHRAM_PKST2:
|
case FLASHCART_SAVE_TYPE_FLASHRAM_PKST2:
|
||||||
type = SAVE_TYPE_FLASHRAM;
|
type = SAVE_TYPE_FLASHRAM_1MBIT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return FLASHCART_ERR_ARGS;
|
return FLASHCART_ERR_ARGS;
|
||||||
|
@ -76,12 +76,12 @@ typedef enum {
|
|||||||
/** @brief The SC64 Save Type Enumeration. */
|
/** @brief The SC64 Save Type Enumeration. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SAVE_TYPE_NONE,
|
SAVE_TYPE_NONE,
|
||||||
SAVE_TYPE_EEPROM_4K,
|
SAVE_TYPE_EEPROM_4KBIT,
|
||||||
SAVE_TYPE_EEPROM_16K,
|
SAVE_TYPE_EEPROM_16KBIT,
|
||||||
SAVE_TYPE_SRAM,
|
SAVE_TYPE_SRAM_256KBIT,
|
||||||
SAVE_TYPE_FLASHRAM,
|
SAVE_TYPE_FLASHRAM_1MBIT,
|
||||||
SAVE_TYPE_SRAM_BANKED,
|
SAVE_TYPE_SRAM_BANKED,
|
||||||
SAVE_TYPE_SRAM_128K,
|
SAVE_TYPE_SRAM_1MBIT,
|
||||||
} sc64_save_type_t;
|
} sc64_save_type_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -21,6 +21,7 @@ static void actions_clear (menu_t *menu) {
|
|||||||
menu->actions.back = false;
|
menu->actions.back = false;
|
||||||
menu->actions.options = false;
|
menu->actions.options = false;
|
||||||
menu->actions.settings = false;
|
menu->actions.settings = false;
|
||||||
|
menu->actions.lz_context = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void actions_update_direction (menu_t *menu) {
|
static void actions_update_direction (menu_t *menu) {
|
||||||
@ -91,6 +92,8 @@ static void actions_update_buttons (menu_t *menu) {
|
|||||||
menu->actions.options = true;
|
menu->actions.options = true;
|
||||||
} else if (pressed.start) {
|
} else if (pressed.start) {
|
||||||
menu->actions.settings = true;
|
menu->actions.settings = true;
|
||||||
|
} else if (pressed.l || pressed.z) {
|
||||||
|
menu->actions.lz_context = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,12 +35,12 @@ static bool create_saves_subdirectory (path_t *path) {
|
|||||||
|
|
||||||
static flashcart_save_type_t convert_save_type (rom_save_type_t save_type) {
|
static flashcart_save_type_t convert_save_type (rom_save_type_t save_type) {
|
||||||
switch (save_type) {
|
switch (save_type) {
|
||||||
case SAVE_TYPE_EEPROM_4K: return FLASHCART_SAVE_TYPE_EEPROM_4K;
|
case SAVE_TYPE_EEPROM_4KBIT: return FLASHCART_SAVE_TYPE_EEPROM_4KBIT;
|
||||||
case SAVE_TYPE_EEPROM_16K: return FLASHCART_SAVE_TYPE_EEPROM_16K;
|
case SAVE_TYPE_EEPROM_16KBIT: return FLASHCART_SAVE_TYPE_EEPROM_16KBIT;
|
||||||
case SAVE_TYPE_SRAM: return FLASHCART_SAVE_TYPE_SRAM;
|
case SAVE_TYPE_SRAM_256KBIT: return FLASHCART_SAVE_TYPE_SRAM_256KBIT;
|
||||||
case SAVE_TYPE_SRAM_BANKED: return FLASHCART_SAVE_TYPE_SRAM_BANKED;
|
case SAVE_TYPE_SRAM_BANKED: return FLASHCART_SAVE_TYPE_SRAM_BANKED;
|
||||||
case SAVE_TYPE_SRAM_128K: return FLASHCART_SAVE_TYPE_SRAM_128K;
|
case SAVE_TYPE_SRAM_1MBIT: return FLASHCART_SAVE_TYPE_SRAM_1MBIT;
|
||||||
case SAVE_TYPE_FLASHRAM: return FLASHCART_SAVE_TYPE_FLASHRAM;
|
case SAVE_TYPE_FLASHRAM_1MBIT: return FLASHCART_SAVE_TYPE_FLASHRAM_1MBIT;
|
||||||
case SAVE_TYPE_FLASHRAM_PKST2: return FLASHCART_SAVE_TYPE_FLASHRAM_PKST2;
|
case SAVE_TYPE_FLASHRAM_PKST2: return FLASHCART_SAVE_TYPE_FLASHRAM_PKST2;
|
||||||
default: return FLASHCART_SAVE_TYPE_NONE;
|
default: return FLASHCART_SAVE_TYPE_NONE;
|
||||||
}
|
}
|
||||||
@ -166,19 +166,19 @@ cart_load_err_t cart_load_emulator (menu_t *menu, cart_load_emu_type_t emu_type,
|
|||||||
break;
|
break;
|
||||||
case CART_LOAD_EMU_TYPE_SNES:
|
case CART_LOAD_EMU_TYPE_SNES:
|
||||||
path_push(path, "sodium64.z64");
|
path_push(path, "sodium64.z64");
|
||||||
save_type = FLASHCART_SAVE_TYPE_SRAM;
|
save_type = FLASHCART_SAVE_TYPE_SRAM_256KBIT;
|
||||||
break;
|
break;
|
||||||
case CART_LOAD_EMU_TYPE_GAMEBOY:
|
case CART_LOAD_EMU_TYPE_GAMEBOY:
|
||||||
path_push(path, "gb.v64");
|
path_push(path, "gb.v64");
|
||||||
save_type = FLASHCART_SAVE_TYPE_FLASHRAM;
|
save_type = FLASHCART_SAVE_TYPE_FLASHRAM_1MBIT;
|
||||||
break;
|
break;
|
||||||
case CART_LOAD_EMU_TYPE_GAMEBOY_COLOR:
|
case CART_LOAD_EMU_TYPE_GAMEBOY_COLOR:
|
||||||
path_push(path, "gbc.v64");
|
path_push(path, "gbc.v64");
|
||||||
save_type = FLASHCART_SAVE_TYPE_FLASHRAM;
|
save_type = FLASHCART_SAVE_TYPE_FLASHRAM_1MBIT;
|
||||||
break;
|
break;
|
||||||
case CART_LOAD_EMU_TYPE_SEGA_GENERIC_8BIT:
|
case CART_LOAD_EMU_TYPE_SEGA_GENERIC_8BIT:
|
||||||
path_push(path, "TotalSMS.z64");
|
path_push(path, "TotalSMS.z64");
|
||||||
save_type = FLASHCART_SAVE_TYPE_SRAM;
|
save_type = FLASHCART_SAVE_TYPE_SRAM_256KBIT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ component_boxart_t *component_boxart_init (const char *storage_prefix, char *gam
|
|||||||
|
|
||||||
sprintf(file_name, "%.3s.png", game_code);
|
sprintf(file_name, "%.3s.png", game_code);
|
||||||
path_push(path, file_name);
|
path_push(path, file_name);
|
||||||
if (png_decoder_start(path_get(path), BOXART_WIDTH, BOXART_HEIGHT, png_decoder_callback, b) == PNG_OK) {
|
if (png_decoder_start(path_get(path), BOXART_WIDTH_MAX, BOXART_HEIGHT_MAX, png_decoder_callback, b) == PNG_OK) {
|
||||||
path_free(path);
|
path_free(path);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ component_boxart_t *component_boxart_init (const char *storage_prefix, char *gam
|
|||||||
// TODO: This is bad, we should only check for 3 letter codes
|
// TODO: This is bad, we should only check for 3 letter codes
|
||||||
sprintf(file_name, "%.2s.png", game_code + 1);
|
sprintf(file_name, "%.2s.png", game_code + 1);
|
||||||
path_push(path, file_name);
|
path_push(path, file_name);
|
||||||
if (png_decoder_start(path_get(path), BOXART_WIDTH, BOXART_HEIGHT, png_decoder_callback, b) == PNG_OK) {
|
if (png_decoder_start(path_get(path), BOXART_WIDTH_MAX, BOXART_HEIGHT_MAX, png_decoder_callback, b) == PNG_OK) {
|
||||||
path_free(path);
|
path_free(path);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
@ -65,15 +65,20 @@ void component_boxart_free (component_boxart_t *b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void component_boxart_draw (component_boxart_t *b) {
|
void component_boxart_draw (component_boxart_t *b) {
|
||||||
if (b && b->image && b->image->width == BOXART_WIDTH && b->image->height == BOXART_HEIGHT) {
|
int box_x = BOXART_X;
|
||||||
|
int box_y = BOXART_Y;
|
||||||
|
|
||||||
|
if (b && b->image && b->image->width <= BOXART_WIDTH_MAX && b->image->height <= BOXART_HEIGHT_MAX) {
|
||||||
rdpq_mode_push();
|
rdpq_mode_push();
|
||||||
rdpq_set_mode_copy(false);
|
rdpq_set_mode_copy(false);
|
||||||
rdpq_tex_blit(
|
if (b->image->height == BOXART_HEIGHT_MAX) {
|
||||||
b->image,
|
box_x = BOXART_X_JP;
|
||||||
BOXART_X,
|
box_y = BOXART_Y_JP;
|
||||||
BOXART_Y,
|
} else if (b->image->width == BOXART_WIDTH_DD && b->image->height == BOXART_HEIGHT_DD) {
|
||||||
NULL
|
box_x = BOXART_X_DD;
|
||||||
);
|
box_y = BOXART_Y_DD;
|
||||||
|
}
|
||||||
|
rdpq_tex_blit(b->image, box_x, box_y, NULL);
|
||||||
rdpq_mode_pop();
|
rdpq_mode_pop();
|
||||||
} else {
|
} else {
|
||||||
component_box_draw(
|
component_box_draw(
|
||||||
|
@ -118,7 +118,8 @@ void component_messagebox_draw (char *fmt, ...) {
|
|||||||
.height = VISIBLE_AREA_HEIGHT,
|
.height = VISIBLE_AREA_HEIGHT,
|
||||||
.align = ALIGN_CENTER,
|
.align = ALIGN_CENTER,
|
||||||
.valign = VALIGN_CENTER,
|
.valign = VALIGN_CENTER,
|
||||||
.wrap = WRAP_WORD
|
.wrap = WRAP_WORD,
|
||||||
|
.line_spacing = TEXT_LINE_SPACING_ADJUST,
|
||||||
}, FNT_DEFAULT, formatted, ¶graph_nbytes);
|
}, FNT_DEFAULT, formatted, ¶graph_nbytes);
|
||||||
|
|
||||||
if (formatted != buffer) {
|
if (formatted != buffer) {
|
||||||
@ -151,10 +152,11 @@ void component_main_text_draw (rdpq_align_t align, rdpq_valign_t valign, char *f
|
|||||||
.align = align,
|
.align = align,
|
||||||
.valign = valign,
|
.valign = valign,
|
||||||
.wrap = WRAP_ELLIPSES,
|
.wrap = WRAP_ELLIPSES,
|
||||||
|
.line_spacing = TEXT_LINE_SPACING_ADJUST,
|
||||||
},
|
},
|
||||||
FNT_DEFAULT,
|
FNT_DEFAULT,
|
||||||
VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL,
|
VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL,
|
||||||
VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL,
|
VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL,
|
||||||
formatted,
|
formatted,
|
||||||
nbytes
|
nbytes
|
||||||
);
|
);
|
||||||
@ -180,10 +182,11 @@ void component_actions_bar_text_draw (rdpq_align_t align, rdpq_valign_t valign,
|
|||||||
.align = align,
|
.align = align,
|
||||||
.valign = valign,
|
.valign = valign,
|
||||||
.wrap = WRAP_ELLIPSES,
|
.wrap = WRAP_ELLIPSES,
|
||||||
|
.line_spacing = TEXT_LINE_SPACING_ADJUST,
|
||||||
},
|
},
|
||||||
FNT_DEFAULT,
|
FNT_DEFAULT,
|
||||||
VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL,
|
VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL,
|
||||||
LAYOUT_ACTIONS_SEPARATOR_Y + BORDER_THICKNESS + TEXT_MARGIN_VERTICAL,
|
LAYOUT_ACTIONS_SEPARATOR_Y + BORDER_THICKNESS + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL,
|
||||||
formatted,
|
formatted,
|
||||||
nbytes
|
nbytes
|
||||||
);
|
);
|
||||||
|
@ -65,16 +65,38 @@
|
|||||||
#define MESSAGEBOX_MARGIN (32)
|
#define MESSAGEBOX_MARGIN (32)
|
||||||
|
|
||||||
#define TEXT_MARGIN_HORIZONTAL (10)
|
#define TEXT_MARGIN_HORIZONTAL (10)
|
||||||
#define TEXT_MARGIN_VERTICAL (7)
|
#define TEXT_MARGIN_VERTICAL (6)
|
||||||
|
#define TEXT_OFFSET_VERTICAL (1)
|
||||||
|
#define TEXT_LINE_SPACING_ADJUST (0)
|
||||||
|
|
||||||
/** @brief The boxart picture width. */
|
/** @brief The boxart picture width. */
|
||||||
#define BOXART_WIDTH (158)
|
#define BOXART_WIDTH (158)
|
||||||
/** @brief The boxart picture height. */
|
/** @brief The boxart picture height. */
|
||||||
#define BOXART_HEIGHT (112)
|
#define BOXART_HEIGHT (112)
|
||||||
|
|
||||||
|
/** @brief The boxart picture width (64DD). */
|
||||||
|
#define BOXART_WIDTH_DD (129)
|
||||||
|
/** @brief The boxart picture height. */
|
||||||
|
#define BOXART_HEIGHT_DD (112)
|
||||||
|
|
||||||
|
/** @brief The boxart picture maximum width. */
|
||||||
|
#define BOXART_WIDTH_MAX (158)
|
||||||
|
/** @brief The boxart picture maximum height. */
|
||||||
|
#define BOXART_HEIGHT_MAX (158)
|
||||||
|
|
||||||
/** @brief The box art position on the X axis. */
|
/** @brief The box art position on the X axis. */
|
||||||
#define BOXART_X (VISIBLE_AREA_X1 - BOXART_WIDTH - 24)
|
#define BOXART_X (VISIBLE_AREA_X1 - BOXART_WIDTH - 24)
|
||||||
/** @brief The box art position on the Y axis. */
|
/** @brief The box art position on the Y axis. */
|
||||||
#define BOXART_Y (LAYOUT_ACTIONS_SEPARATOR_Y - BOXART_HEIGHT - 24)
|
#define BOXART_Y (LAYOUT_ACTIONS_SEPARATOR_Y - BOXART_HEIGHT - 24)
|
||||||
|
/** @brief The box art position on the X axis for japanese caratules.*/
|
||||||
|
#define BOXART_X_JP (VISIBLE_AREA_X1 - BOXART_WIDTH_MAX + 21)
|
||||||
|
/** @brief The box art position on the Y axis for japanese caratules. */
|
||||||
|
#define BOXART_Y_JP (LAYOUT_ACTIONS_SEPARATOR_Y - BOXART_HEIGHT_MAX - 24)
|
||||||
|
|
||||||
|
/** @brief The box art position on the X axis for 64DD caratules.*/
|
||||||
|
#define BOXART_X_DD (VISIBLE_AREA_X1 - BOXART_WIDTH_DD - 23)
|
||||||
|
/** @brief The box art position on the Y axis for 64DD caratules. */
|
||||||
|
#define BOXART_Y_DD (LAYOUT_ACTIONS_SEPARATOR_Y - BOXART_HEIGHT_DD - 24)
|
||||||
|
|
||||||
/** @brief The scroll bar width. */
|
/** @brief The scroll bar width. */
|
||||||
#define LIST_SCROLLBAR_WIDTH (12)
|
#define LIST_SCROLLBAR_WIDTH (12)
|
||||||
@ -86,7 +108,7 @@
|
|||||||
#define LIST_SCROLLBAR_Y (VISIBLE_AREA_Y0)
|
#define LIST_SCROLLBAR_Y (VISIBLE_AREA_Y0)
|
||||||
|
|
||||||
/** @brief The maximum amount of file list entries. */
|
/** @brief The maximum amount of file list entries. */
|
||||||
#define LIST_ENTRIES (20)
|
#define LIST_ENTRIES (19)
|
||||||
/** @brief The maximum width available for a file list entry. */
|
/** @brief The maximum width available for a file list entry. */
|
||||||
#define FILE_LIST_MAX_WIDTH (480)
|
#define FILE_LIST_MAX_WIDTH (480)
|
||||||
#define FILE_LIST_HIGHLIGHT_WIDTH (VISIBLE_AREA_X1 - VISIBLE_AREA_X0 - LIST_SCROLLBAR_WIDTH)
|
#define FILE_LIST_HIGHLIGHT_WIDTH (VISIBLE_AREA_X1 - VISIBLE_AREA_X0 - LIST_SCROLLBAR_WIDTH)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "../components.h"
|
#include "../components.h"
|
||||||
#include "../fonts.h"
|
#include "../fonts.h"
|
||||||
|
#include "../sound.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
|
||||||
|
|
||||||
@ -41,6 +42,7 @@ bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm)
|
|||||||
} else {
|
} else {
|
||||||
cm->hide_pending = true;
|
cm->hide_pending = true;
|
||||||
}
|
}
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
} else if (menu->actions.enter) {
|
} else if (menu->actions.enter) {
|
||||||
if (cm->list[cm->selected].submenu) {
|
if (cm->list[cm->selected].submenu) {
|
||||||
cm->submenu = cm->list[cm->selected].submenu;
|
cm->submenu = cm->list[cm->selected].submenu;
|
||||||
@ -51,16 +53,19 @@ bool component_context_menu_process (menu_t *menu, component_context_menu_t *cm)
|
|||||||
cm->list[cm->selected].action(menu, cm->list[cm->selected].arg);
|
cm->list[cm->selected].action(menu, cm->list[cm->selected].arg);
|
||||||
top->hide_pending = true;
|
top->hide_pending = true;
|
||||||
}
|
}
|
||||||
|
sound_play_effect(SFX_ENTER);
|
||||||
} else if (menu->actions.go_up) {
|
} else if (menu->actions.go_up) {
|
||||||
cm->selected -= 1;
|
cm->selected -= 1;
|
||||||
if (cm->selected < 0) {
|
if (cm->selected < 0) {
|
||||||
cm->selected = 0;
|
cm->selected = 0;
|
||||||
}
|
}
|
||||||
|
sound_play_effect(SFX_CURSOR);
|
||||||
} else if (menu->actions.go_down) {
|
} else if (menu->actions.go_down) {
|
||||||
cm->selected += 1;
|
cm->selected += 1;
|
||||||
if (cm->selected >= cm->count) {
|
if (cm->selected >= cm->count) {
|
||||||
cm->selected = (cm->count - 1);
|
cm->selected = (cm->count - 1);
|
||||||
}
|
}
|
||||||
|
sound_play_effect(SFX_CURSOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -81,6 +86,7 @@ void component_context_menu_draw (component_context_menu_t *cm) {
|
|||||||
.height = VISIBLE_AREA_HEIGHT,
|
.height = VISIBLE_AREA_HEIGHT,
|
||||||
.align = ALIGN_CENTER,
|
.align = ALIGN_CENTER,
|
||||||
.valign = VALIGN_CENTER,
|
.valign = VALIGN_CENTER,
|
||||||
|
.line_spacing = TEXT_LINE_SPACING_ADJUST,
|
||||||
},
|
},
|
||||||
FNT_DEFAULT,
|
FNT_DEFAULT,
|
||||||
NULL
|
NULL
|
||||||
|
@ -71,6 +71,7 @@ void component_file_list_draw (entry_t *list, int entries, int selected) {
|
|||||||
.width = FILE_LIST_MAX_WIDTH - (TEXT_MARGIN_HORIZONTAL * 2),
|
.width = FILE_LIST_MAX_WIDTH - (TEXT_MARGIN_HORIZONTAL * 2),
|
||||||
.height = LAYOUT_ACTIONS_SEPARATOR_Y - VISIBLE_AREA_Y0 - (TEXT_MARGIN_VERTICAL * 2),
|
.height = LAYOUT_ACTIONS_SEPARATOR_Y - VISIBLE_AREA_Y0 - (TEXT_MARGIN_VERTICAL * 2),
|
||||||
.wrap = WRAP_ELLIPSES,
|
.wrap = WRAP_ELLIPSES,
|
||||||
|
.line_spacing = TEXT_LINE_SPACING_ADJUST,
|
||||||
},
|
},
|
||||||
FNT_DEFAULT,
|
FNT_DEFAULT,
|
||||||
file_list_layout
|
file_list_layout
|
||||||
@ -114,7 +115,7 @@ void component_file_list_draw (entry_t *list, int entries, int selected) {
|
|||||||
layout = rdpq_paragraph_builder_end();
|
layout = rdpq_paragraph_builder_end();
|
||||||
|
|
||||||
int highlight_height = (layout->bbox.y1 - layout->bbox.y0) / layout->nlines;
|
int highlight_height = (layout->bbox.y1 - layout->bbox.y0) / layout->nlines;
|
||||||
int highlight_y = VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + ((selected - starting_position) * highlight_height);
|
int highlight_y = VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL + ((selected - starting_position) * highlight_height);
|
||||||
|
|
||||||
component_box_draw(
|
component_box_draw(
|
||||||
FILE_LIST_HIGHLIGHT_X,
|
FILE_LIST_HIGHLIGHT_X,
|
||||||
@ -127,7 +128,7 @@ void component_file_list_draw (entry_t *list, int entries, int selected) {
|
|||||||
rdpq_paragraph_render(
|
rdpq_paragraph_render(
|
||||||
layout,
|
layout,
|
||||||
VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL,
|
VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL,
|
||||||
VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL
|
VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL
|
||||||
);
|
);
|
||||||
|
|
||||||
rdpq_paragraph_free(layout);
|
rdpq_paragraph_free(layout);
|
||||||
@ -138,6 +139,7 @@ void component_file_list_draw (entry_t *list, int entries, int selected) {
|
|||||||
.height = LAYOUT_ACTIONS_SEPARATOR_Y - VISIBLE_AREA_Y0 - (TEXT_MARGIN_VERTICAL * 2),
|
.height = LAYOUT_ACTIONS_SEPARATOR_Y - VISIBLE_AREA_Y0 - (TEXT_MARGIN_VERTICAL * 2),
|
||||||
.align = ALIGN_RIGHT,
|
.align = ALIGN_RIGHT,
|
||||||
.wrap = WRAP_ELLIPSES,
|
.wrap = WRAP_ELLIPSES,
|
||||||
|
.line_spacing = TEXT_LINE_SPACING_ADJUST,
|
||||||
},
|
},
|
||||||
FNT_DEFAULT,
|
FNT_DEFAULT,
|
||||||
NULL
|
NULL
|
||||||
@ -164,7 +166,7 @@ void component_file_list_draw (entry_t *list, int entries, int selected) {
|
|||||||
rdpq_paragraph_render(
|
rdpq_paragraph_render(
|
||||||
layout,
|
layout,
|
||||||
VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL,
|
VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL,
|
||||||
VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL
|
VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL
|
||||||
);
|
);
|
||||||
|
|
||||||
rdpq_paragraph_free(layout);
|
rdpq_paragraph_free(layout);
|
||||||
|
@ -67,6 +67,10 @@ static void menu_init (boot_params_t *boot_params) {
|
|||||||
|
|
||||||
sound_init_default();
|
sound_init_default();
|
||||||
|
|
||||||
|
JOYPAD_PORT_FOREACH (port) {
|
||||||
|
joypad_set_rumble_active(port, false);
|
||||||
|
}
|
||||||
|
|
||||||
menu = calloc(1, sizeof(menu_t));
|
menu = calloc(1, sizeof(menu_t));
|
||||||
assert(menu != NULL);
|
assert(menu != NULL);
|
||||||
|
|
||||||
@ -115,6 +119,11 @@ static void menu_init (boot_params_t *boot_params) {
|
|||||||
__boot_tvtype = TV_NTSC;
|
__boot_tvtype = TV_NTSC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sound_init_sfx();
|
||||||
|
if (menu->settings.sound_enabled) {
|
||||||
|
sound_use_sfx(true);
|
||||||
|
}
|
||||||
|
|
||||||
display_init(RESOLUTION_640x480, DEPTH_16_BPP, 2, GAMMA_NONE, FILTERS_DISABLED);
|
display_init(RESOLUTION_640x480, DEPTH_16_BPP, 2, GAMMA_NONE, FILTERS_DISABLED);
|
||||||
|
|
||||||
register_VI_handler(frame_counter_handler);
|
register_VI_handler(frame_counter_handler);
|
||||||
|
@ -88,6 +88,7 @@ typedef struct {
|
|||||||
bool back;
|
bool back;
|
||||||
bool options;
|
bool options;
|
||||||
bool settings;
|
bool settings;
|
||||||
|
bool lz_context;
|
||||||
} actions;
|
} actions;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -144,459 +145,459 @@ typedef struct {
|
|||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const match_t database[] = {
|
static const match_t database[] = {
|
||||||
MATCH_HOMEBREW_HEADER("ED"), // Homebrew header (ED)
|
MATCH_HOMEBREW_HEADER("ED"), // Homebrew header (ED)
|
||||||
|
|
||||||
MATCH_CHECK_CODE(0x000000004CBC3B56, SAVE_TYPE_SRAM, FEAT_EXP_PAK_REQUIRED | FEAT_64DD_CONVERSION), // DMTJ 64DD cartridge conversion
|
MATCH_CHECK_CODE(0x000000004CBC3B56, SAVE_TYPE_SRAM_256KBIT, FEAT_EXP_PAK_REQUIRED | FEAT_64DD_CONVERSION), // DMTJ 64DD cartridge conversion
|
||||||
|
|
||||||
MATCH_CHECK_CODE(0x0DD4ABABB5A2A91E, SAVE_TYPE_EEPROM_16K, FEAT_EXP_PAK_REQUIRED), // DK Retail kiosk demo
|
MATCH_CHECK_CODE(0x0DD4ABABB5A2A91E, SAVE_TYPE_EEPROM_16KBIT, FEAT_EXP_PAK_REQUIRED), // DK Retail kiosk demo
|
||||||
MATCH_CHECK_CODE(0xEB85EBC9596682AF, SAVE_TYPE_FLASHRAM, FEAT_NONE), // Doubutsu Banchou
|
MATCH_CHECK_CODE(0xEB85EBC9596682AF, SAVE_TYPE_FLASHRAM_1MBIT, FEAT_NONE), // Doubutsu Banchou
|
||||||
MATCH_CHECK_CODE(0x9A746EBF2802EA99, SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Toon panic
|
MATCH_CHECK_CODE(0x9A746EBF2802EA99, SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Toon panic
|
||||||
MATCH_CHECK_CODE(0x21548CA921548CA9, SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Mini racers
|
MATCH_CHECK_CODE(0x21548CA921548CA9, SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Mini racers
|
||||||
MATCH_CHECK_CODE(0xBC9B2CC34ED04DA5, SAVE_TYPE_FLASHRAM, FEAT_NONE), // Starcraft 64 [Prototype 2000]
|
MATCH_CHECK_CODE(0xBC9B2CC34ED04DA5, SAVE_TYPE_FLASHRAM_1MBIT, FEAT_NONE), // Starcraft 64 [Prototype 2000]
|
||||||
MATCH_CHECK_CODE(0x5D40ED2C10D6ABCF, SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Viewpoint 2064
|
MATCH_CHECK_CODE(0x5D40ED2C10D6ABCF, SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Viewpoint 2064
|
||||||
MATCH_CHECK_CODE(0x7280E03F497689BA, SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Viewpoint 2064 [ENG patch]
|
MATCH_CHECK_CODE(0x7280E03F497689BA, SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Viewpoint 2064 [ENG patch]
|
||||||
|
|
||||||
MATCH_CHECK_CODE(0xCDB8B4D08832352D, SAVE_TYPE_SRAM, FEAT_RPAK), // Jet Force Gemini [USA CRACK]
|
MATCH_CHECK_CODE(0xCDB8B4D08832352D, SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Jet Force Gemini [USA CRACK]
|
||||||
MATCH_CHECK_CODE(0xB66E0F7C2709C22F, SAVE_TYPE_SRAM, FEAT_RPAK), // Jet Force Gemini [PAL CRACK]
|
MATCH_CHECK_CODE(0xB66E0F7C2709C22F, SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Jet Force Gemini [PAL CRACK]
|
||||||
|
|
||||||
MATCH_CHECK_CODE(0xCE84793D27ECC1AD, SAVE_TYPE_SRAM, FEAT_RPAK | FEAT_EXP_PAK_REQUIRED), // Donkey kong 64 [USA CRACK]
|
MATCH_CHECK_CODE(0xCE84793D27ECC1AD, SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK | FEAT_EXP_PAK_REQUIRED), // Donkey kong 64 [USA CRACK]
|
||||||
MATCH_CHECK_CODE(0x1F95CAAA047FC22A, SAVE_TYPE_SRAM, FEAT_RPAK | FEAT_EXP_PAK_REQUIRED), // Donkey kong 64 [PAL CRACK]
|
MATCH_CHECK_CODE(0x1F95CAAA047FC22A, SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK | FEAT_EXP_PAK_REQUIRED), // Donkey kong 64 [PAL CRACK]
|
||||||
|
|
||||||
MATCH_CHECK_CODE(0xE3FF09DFCAE4B0ED, SAVE_TYPE_SRAM, FEAT_RPAK), // Banjo tooie [USA CRACK]
|
MATCH_CHECK_CODE(0xE3FF09DFCAE4B0ED, SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Banjo tooie [USA CRACK]
|
||||||
|
|
||||||
MATCH_ID_REGION_VERSION("NK4J", 0, SAVE_TYPE_SRAM, FEAT_RPAK), // Kirby 64: The Crystal Shards [Hoshi no Kirby 64 (J)]
|
MATCH_ID_REGION_VERSION("NK4J", 0, SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Kirby 64: The Crystal Shards [Hoshi no Kirby 64 (J)]
|
||||||
MATCH_ID_REGION_VERSION("NK4J", 1, SAVE_TYPE_SRAM, FEAT_RPAK), // Kirby 64: The Crystal Shards [Hoshi no Kirby 64 (J)]
|
MATCH_ID_REGION_VERSION("NK4J", 1, SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Kirby 64: The Crystal Shards [Hoshi no Kirby 64 (J)]
|
||||||
MATCH_ID("NK4", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Kirby 64: The Crystal Shards [Hoshi no Kirby 64 (J)]
|
MATCH_ID("NK4", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Kirby 64: The Crystal Shards [Hoshi no Kirby 64 (J)]
|
||||||
|
|
||||||
MATCH_ID_REGION_VERSION("NSMJ", 3, SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Super Mario 64 Shindou Edition
|
MATCH_ID_REGION_VERSION("NSMJ", 3, SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Super Mario 64 Shindou Edition
|
||||||
MATCH_ID("NSM", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Super Mario 64
|
MATCH_ID("NSM", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Super Mario 64
|
||||||
|
|
||||||
MATCH_ID_REGION_VERSION("NWRJ", 2, SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Wave Race 64 Shindou Edition
|
MATCH_ID_REGION_VERSION("NWRJ", 2, SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Wave Race 64 Shindou Edition
|
||||||
MATCH_ID("NWR", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // Wave Race 64
|
MATCH_ID("NWR", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // Wave Race 64
|
||||||
|
|
||||||
MATCH_ID_REGION("N3HJ", SAVE_TYPE_SRAM, FEAT_NONE), // Ganbare! Nippon! Olympics 2000
|
MATCH_ID_REGION("N3HJ", SAVE_TYPE_SRAM_256KBIT, FEAT_NONE), // Ganbare! Nippon! Olympics 2000
|
||||||
MATCH_ID("N3H", SAVE_TYPE_NONE, FEAT_CPAK), // International Track & Field 2000
|
MATCH_ID("N3H", SAVE_TYPE_NONE, FEAT_CPAK), // International Track & Field 2000
|
||||||
|
|
||||||
MATCH_ID_REGION("ND3J", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Akumajou Dracula Mokushiroku (J)
|
MATCH_ID_REGION("ND3J", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Akumajou Dracula Mokushiroku (J)
|
||||||
MATCH_ID("ND3", SAVE_TYPE_NONE, FEAT_CPAK), // Castlevania
|
MATCH_ID("ND3", SAVE_TYPE_NONE, FEAT_CPAK), // Castlevania
|
||||||
|
|
||||||
MATCH_ID_REGION("ND4J", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Akumajou Dracula Mokushiroku Gaiden: Legend of Cornell (J)
|
MATCH_ID_REGION("ND4J", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Akumajou Dracula Mokushiroku Gaiden: Legend of Cornell (J)
|
||||||
MATCH_ID("ND4", SAVE_TYPE_NONE, FEAT_CPAK), // Castlevania - Legacy of Darkness
|
MATCH_ID("ND4", SAVE_TYPE_NONE, FEAT_CPAK), // Castlevania - Legacy of Darkness
|
||||||
|
|
||||||
MATCH_ID_REGION("NDKJ", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Dark Rift [Space Dynamites (J)]
|
MATCH_ID_REGION("NDKJ", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Dark Rift [Space Dynamites (J)]
|
||||||
|
|
||||||
MATCH_ID_REGION("NSVE", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Space Station Silicon Valley
|
MATCH_ID_REGION("NSVE", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Space Station Silicon Valley
|
||||||
MATCH_ID("NSV", SAVE_TYPE_EEPROM_4K, FEAT_RPAK | FEAT_EXP_PAK_BROKEN), // Space Station Silicon Valley
|
MATCH_ID("NSV", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK | FEAT_EXP_PAK_BROKEN), // Space Station Silicon Valley
|
||||||
|
|
||||||
MATCH_ID_REGION("NWTJ", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Wetrix
|
MATCH_ID_REGION("NWTJ", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Wetrix
|
||||||
MATCH_ID("NWT", SAVE_TYPE_NONE, FEAT_CPAK), // Wetrix
|
MATCH_ID("NWT", SAVE_TYPE_NONE, FEAT_CPAK), // Wetrix
|
||||||
|
|
||||||
// EEPROM 4K
|
// EEPROM 4K
|
||||||
MATCH_ID("CLB", SAVE_TYPE_EEPROM_4K, FEAT_RPAK | FEAT_64DD_ENHANCED), // Mario Party (NTSC)
|
MATCH_ID("CLB", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK | FEAT_64DD_ENHANCED), // Mario Party (NTSC)
|
||||||
MATCH_ID("NAB", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Air Boarder 64
|
MATCH_ID("NAB", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Air Boarder 64
|
||||||
MATCH_ID("NAD", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Worms Armageddon (U)
|
MATCH_ID("NAD", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Worms Armageddon (U)
|
||||||
MATCH_ID("NAG", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // AeroGauge
|
MATCH_ID("NAG", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // AeroGauge
|
||||||
MATCH_ID("NB6", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_TPAK), // Super B-Daman: Battle Phoenix 64
|
MATCH_ID("NB6", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_TPAK), // Super B-Daman: Battle Phoenix 64
|
||||||
MATCH_ID("NBC", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // Blast Corps
|
MATCH_ID("NBC", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // Blast Corps
|
||||||
MATCH_ID("NBD", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Bomberman Hero [Mirian Ojo o Sukue! (J)]
|
MATCH_ID("NBD", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Bomberman Hero [Mirian Ojo o Sukue! (J)]
|
||||||
MATCH_ID("NBH", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Body Harvest
|
MATCH_ID("NBH", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Body Harvest
|
||||||
MATCH_ID("NBK", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Banjo-Kazooie [Banjo to Kazooie no Daiboken (J)]
|
MATCH_ID("NBK", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Banjo-Kazooie [Banjo to Kazooie no Daiboken (J)]
|
||||||
MATCH_ID("NBM", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // Bomberman 64 [Baku Bomberman (J)]
|
MATCH_ID("NBM", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // Bomberman 64 [Baku Bomberman (J)]
|
||||||
MATCH_ID("NBN", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // Bakuretsu Muteki Bangaioh
|
MATCH_ID("NBN", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // Bakuretsu Muteki Bangaioh
|
||||||
MATCH_ID("NBV", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Bomberman 64: The Second Attack! [Baku Bomberman 2 (J)]
|
MATCH_ID("NBV", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Bomberman 64: The Second Attack! [Baku Bomberman 2 (J)]
|
||||||
MATCH_ID("NCG", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK | FEAT_TPAK), // Choro Q 64 II - Hacha Mecha Grand Prix Race (J)
|
MATCH_ID("NCG", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK | FEAT_TPAK), // Choro Q 64 II - Hacha Mecha Grand Prix Race (J)
|
||||||
MATCH_ID("NCH", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Chopper Attack
|
MATCH_ID("NCH", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Chopper Attack
|
||||||
MATCH_ID("NCR", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // Penny Racers [Choro Q 64 (J)]
|
MATCH_ID("NCR", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // Penny Racers [Choro Q 64 (J)]
|
||||||
MATCH_ID("NCT", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Chameleon Twist
|
MATCH_ID("NCT", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Chameleon Twist
|
||||||
MATCH_ID("NCU", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // Cruis'n USA
|
MATCH_ID("NCU", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // Cruis'n USA
|
||||||
MATCH_ID("NCX", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Custom Robo
|
MATCH_ID("NCX", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Custom Robo
|
||||||
MATCH_ID("NDQ", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // Disney's Donald Duck - Goin' Quackers [Quack Attack (E)]
|
MATCH_ID("NDQ", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // Disney's Donald Duck - Goin' Quackers [Quack Attack (E)]
|
||||||
MATCH_ID("NDR", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Doraemon: Nobita to 3tsu no Seireiseki
|
MATCH_ID("NDR", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Doraemon: Nobita to 3tsu no Seireiseki
|
||||||
MATCH_ID("NDU", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Duck Dodgers starring Daffy Duck
|
MATCH_ID("NDU", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Duck Dodgers starring Daffy Duck
|
||||||
MATCH_ID("NDY", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Diddy Kong Racing
|
MATCH_ID("NDY", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Diddy Kong Racing
|
||||||
MATCH_ID("NEA", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // PGA European Tour
|
MATCH_ID("NEA", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // PGA European Tour
|
||||||
MATCH_ID("NER", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Aero Fighters Assault [Sonic Wings Assault (J)]
|
MATCH_ID("NER", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Aero Fighters Assault [Sonic Wings Assault (J)]
|
||||||
MATCH_ID("NF2", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // F-1 World Grand Prix II
|
MATCH_ID("NF2", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // F-1 World Grand Prix II
|
||||||
MATCH_ID("NFG", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Fighter Destiny 2
|
MATCH_ID("NFG", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Fighter Destiny 2
|
||||||
MATCH_ID("NFH", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // In-Fisherman Bass Hunter 64
|
MATCH_ID("NFH", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // In-Fisherman Bass Hunter 64
|
||||||
MATCH_ID("NFW", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // F-1 World Grand Prix
|
MATCH_ID("NFW", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // F-1 World Grand Prix
|
||||||
MATCH_ID("NFX", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Star Fox 64 [Lylat Wars (E)]
|
MATCH_ID("NFX", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Star Fox 64 [Lylat Wars (E)]
|
||||||
MATCH_ID("NFY", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Kakutou Denshou: F-Cup Maniax
|
MATCH_ID("NFY", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Kakutou Denshou: F-Cup Maniax
|
||||||
MATCH_ID("NGE", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // GoldenEye 007
|
MATCH_ID("NGE", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // GoldenEye 007
|
||||||
MATCH_ID("NGL", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Getter Love!!
|
MATCH_ID("NGL", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Getter Love!!
|
||||||
MATCH_ID("NGU", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Tsumi to Batsu: Hoshi no Keishousha (Sin and Punishment)
|
MATCH_ID("NGU", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Tsumi to Batsu: Hoshi no Keishousha (Sin and Punishment)
|
||||||
MATCH_ID("NGV", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Glover
|
MATCH_ID("NGV", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Glover
|
||||||
MATCH_ID("NHA", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // Bomberman 64: Arcade Edition (J)
|
MATCH_ID("NHA", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // Bomberman 64: Arcade Edition (J)
|
||||||
MATCH_ID("NHF", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // 64 Hanafuda: Tenshi no Yakusoku
|
MATCH_ID("NHF", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // 64 Hanafuda: Tenshi no Yakusoku
|
||||||
MATCH_ID("NHP", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Heiwa Pachinko World 64
|
MATCH_ID("NHP", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Heiwa Pachinko World 64
|
||||||
MATCH_ID("NIC", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Indy Racing 2000
|
MATCH_ID("NIC", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Indy Racing 2000
|
||||||
MATCH_ID("NIJ", SAVE_TYPE_EEPROM_4K, FEAT_RPAK | FEAT_EXP_PAK_RECOMMENDED), // Indiana Jones and the Infernal Machine
|
MATCH_ID("NIJ", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK | FEAT_EXP_PAK_RECOMMENDED), // Indiana Jones and the Infernal Machine
|
||||||
MATCH_ID("NIR", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Utchan Nanchan no Hono no Challenger: Denryuu Ira Ira Bou
|
MATCH_ID("NIR", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Utchan Nanchan no Hono no Challenger: Denryuu Ira Ira Bou
|
||||||
MATCH_ID("NJM", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Earthworm Jim 3D
|
MATCH_ID("NJM", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Earthworm Jim 3D
|
||||||
MATCH_ID("NK2", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Snowboard Kids 2 [Chou Snobow Kids (J)]
|
MATCH_ID("NK2", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Snowboard Kids 2 [Chou Snobow Kids (J)]
|
||||||
MATCH_ID("NKA", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Fighters Destiny [Fighting Cup (J)]
|
MATCH_ID("NKA", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Fighters Destiny [Fighting Cup (J)]
|
||||||
MATCH_ID("NKI", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // Killer Instinct Gold
|
MATCH_ID("NKI", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // Killer Instinct Gold
|
||||||
MATCH_ID("NKT", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // Mario Kart 64
|
MATCH_ID("NKT", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // Mario Kart 64
|
||||||
MATCH_ID("NLB", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Mario Party (PAL)
|
MATCH_ID("NLB", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Mario Party (PAL)
|
||||||
MATCH_ID("NLL", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Last Legion UX
|
MATCH_ID("NLL", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Last Legion UX
|
||||||
MATCH_ID("NLR", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Lode Runner 3-D
|
MATCH_ID("NLR", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Lode Runner 3-D
|
||||||
MATCH_ID("NMG", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Monaco Grand Prix [Racing Simulation 2 (G)]
|
MATCH_ID("NMG", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Monaco Grand Prix [Racing Simulation 2 (G)]
|
||||||
MATCH_ID("NMI", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Mission: Impossible
|
MATCH_ID("NMI", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Mission: Impossible
|
||||||
MATCH_ID("NML", SAVE_TYPE_EEPROM_4K, FEAT_RPAK | FEAT_TPAK), // Mickey's Speedway USA [Mickey no Racing Challenge USA (J)]
|
MATCH_ID("NML", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK | FEAT_TPAK), // Mickey's Speedway USA [Mickey no Racing Challenge USA (J)]
|
||||||
MATCH_ID("NMO", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Monopoly
|
MATCH_ID("NMO", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Monopoly
|
||||||
MATCH_ID("NMR", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Multi-Racing Championship
|
MATCH_ID("NMR", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Multi-Racing Championship
|
||||||
MATCH_ID("NMS", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // Morita Shougi 64
|
MATCH_ID("NMS", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // Morita Shougi 64
|
||||||
MATCH_ID("NMU", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Big Mountain 2000
|
MATCH_ID("NMU", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Big Mountain 2000
|
||||||
MATCH_ID("NMW", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Mario Party 2
|
MATCH_ID("NMW", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Mario Party 2
|
||||||
MATCH_ID("NMZ", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Zool - Majou Tsukai Densetsu (J)
|
MATCH_ID("NMZ", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Zool - Majou Tsukai Densetsu (J)
|
||||||
MATCH_ID("NN6", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Dr. Mario 64
|
MATCH_ID("NN6", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Dr. Mario 64
|
||||||
MATCH_ID("NNA", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Star Wars Episode I: Battle for Naboo
|
MATCH_ID("NNA", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Star Wars Episode I: Battle for Naboo
|
||||||
MATCH_ID("NOS", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // 64 Oozumou
|
MATCH_ID("NOS", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // 64 Oozumou
|
||||||
MATCH_ID("NP2", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Chou Kuukan Night Pro Yakyuu King 2 (J)
|
MATCH_ID("NP2", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Chou Kuukan Night Pro Yakyuu King 2 (J)
|
||||||
MATCH_ID("NPG", SAVE_TYPE_EEPROM_4K, FEAT_RPAK | FEAT_VRU), // Hey You, Pikachu! [Pikachu Genki Dechu (J)]
|
MATCH_ID("NPG", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK | FEAT_VRU), // Hey You, Pikachu! [Pikachu Genki Dechu (J)]
|
||||||
MATCH_ID("NPT", SAVE_TYPE_EEPROM_4K, FEAT_RPAK | FEAT_TPAK), // Puyo Puyon Party
|
MATCH_ID("NPT", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK | FEAT_TPAK), // Puyo Puyon Party
|
||||||
MATCH_ID("NPW", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Pilotwings 64
|
MATCH_ID("NPW", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Pilotwings 64
|
||||||
MATCH_ID("NPY", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Puyo Puyo Sun 64
|
MATCH_ID("NPY", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Puyo Puyo Sun 64
|
||||||
MATCH_ID("NRA", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Rally '99 (J)
|
MATCH_ID("NRA", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Rally '99 (J)
|
||||||
MATCH_ID("NRC", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Top Gear Overdrive
|
MATCH_ID("NRC", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Top Gear Overdrive
|
||||||
MATCH_ID("NRS", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Star Wars: Rogue Squadron [Shutsugeki! Rogue Chuutai (J)]
|
MATCH_ID("NRS", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Star Wars: Rogue Squadron [Shutsugeki! Rogue Chuutai (J)]
|
||||||
MATCH_ID("NS3", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // AI Shougi 3
|
MATCH_ID("NS3", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // AI Shougi 3
|
||||||
MATCH_ID("NS6", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Star Soldier: Vanishing Earth
|
MATCH_ID("NS6", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Star Soldier: Vanishing Earth
|
||||||
MATCH_ID("NSA", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Sonic Wings Assault (J)
|
MATCH_ID("NSA", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Sonic Wings Assault (J)
|
||||||
MATCH_ID("NSC", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Starshot: Space Circus Fever
|
MATCH_ID("NSC", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Starshot: Space Circus Fever
|
||||||
MATCH_ID("NSN", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Snow Speeder (J)
|
MATCH_ID("NSN", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Snow Speeder (J)
|
||||||
MATCH_ID("NSS", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Super Robot Spirits
|
MATCH_ID("NSS", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Super Robot Spirits
|
||||||
MATCH_ID("NSU", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Rocket: Robot on Wheels
|
MATCH_ID("NSU", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Rocket: Robot on Wheels
|
||||||
MATCH_ID("NSW", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Star Wars: Shadows of the Empire [Teikoku no Kage (J)]
|
MATCH_ID("NSW", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Star Wars: Shadows of the Empire [Teikoku no Kage (J)]
|
||||||
MATCH_ID("NT6", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Tetris 64
|
MATCH_ID("NT6", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Tetris 64
|
||||||
MATCH_ID("NTB", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Transformers: Beast Wars Metals 64 (J)
|
MATCH_ID("NTB", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Transformers: Beast Wars Metals 64 (J)
|
||||||
MATCH_ID("NTC", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // 64 Trump Collection
|
MATCH_ID("NTC", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // 64 Trump Collection
|
||||||
MATCH_ID("NTJ", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Tom & Jerry in Fists of Fury
|
MATCH_ID("NTJ", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Tom & Jerry in Fists of Fury
|
||||||
MATCH_ID("NTM", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Mischief Makers [Yuke Yuke!! Trouble Makers (J)]
|
MATCH_ID("NTM", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Mischief Makers [Yuke Yuke!! Trouble Makers (J)]
|
||||||
MATCH_ID("NTN", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // All Star Tennis '99
|
MATCH_ID("NTN", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // All Star Tennis '99
|
||||||
MATCH_ID("NTP", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Tetrisphere
|
MATCH_ID("NTP", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Tetrisphere
|
||||||
MATCH_ID("NTR", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Top Gear Rally (J + E)
|
MATCH_ID("NTR", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Top Gear Rally (J + E)
|
||||||
MATCH_ID("NTW", SAVE_TYPE_EEPROM_4K, FEAT_CPAK), // 64 de Hakken!! Tamagotchi
|
MATCH_ID("NTW", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK), // 64 de Hakken!! Tamagotchi
|
||||||
MATCH_ID("NTX", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Taz Express
|
MATCH_ID("NTX", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Taz Express
|
||||||
MATCH_ID("NVL", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // V-Rally Edition '99
|
MATCH_ID("NVL", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // V-Rally Edition '99
|
||||||
MATCH_ID("NVY", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // V-Rally Edition '99 (J)
|
MATCH_ID("NVY", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // V-Rally Edition '99 (J)
|
||||||
MATCH_ID("NWC", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Wild Choppers
|
MATCH_ID("NWC", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Wild Choppers
|
||||||
MATCH_ID("NWQ", SAVE_TYPE_EEPROM_4K, FEAT_CPAK | FEAT_RPAK), // Rally Challenge 2000
|
MATCH_ID("NWQ", SAVE_TYPE_EEPROM_4KBIT, FEAT_CPAK | FEAT_RPAK), // Rally Challenge 2000
|
||||||
MATCH_ID("NWU", SAVE_TYPE_EEPROM_4K, FEAT_NONE), // Worms Armageddon (E)
|
MATCH_ID("NWU", SAVE_TYPE_EEPROM_4KBIT, FEAT_NONE), // Worms Armageddon (E)
|
||||||
MATCH_ID("NXO", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Cruis'n Exotica
|
MATCH_ID("NXO", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Cruis'n Exotica
|
||||||
MATCH_ID("NYK", SAVE_TYPE_EEPROM_4K, FEAT_RPAK), // Yakouchuu II: Satsujin Kouro
|
MATCH_ID("NYK", SAVE_TYPE_EEPROM_4KBIT, FEAT_RPAK), // Yakouchuu II: Satsujin Kouro
|
||||||
|
|
||||||
// EEPROM 16K
|
// EEPROM 16K
|
||||||
MATCH_ID("N3D", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Doraemon 3: Nobita no Machi SOS!
|
MATCH_ID("N3D", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Doraemon 3: Nobita no Machi SOS!
|
||||||
MATCH_ID("NB7", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Banjo-Tooie [Banjo to Kazooie no Daiboken 2 (J)]
|
MATCH_ID("NB7", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Banjo-Tooie [Banjo to Kazooie no Daiboken 2 (J)]
|
||||||
MATCH_ID("NCW", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Cruis'n World
|
MATCH_ID("NCW", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Cruis'n World
|
||||||
MATCH_ID("NCZ", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Custom Robo V2
|
MATCH_ID("NCZ", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Custom Robo V2
|
||||||
MATCH_ID("ND2", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Doraemon 2: Nobita to Hikari no Shinden
|
MATCH_ID("ND2", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Doraemon 2: Nobita to Hikari no Shinden
|
||||||
MATCH_ID("ND6", SAVE_TYPE_EEPROM_16K, FEAT_RPAK | FEAT_VRU), // Densha de Go! 64
|
MATCH_ID("ND6", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK | FEAT_VRU), // Densha de Go! 64
|
||||||
MATCH_ID("NDO", SAVE_TYPE_EEPROM_16K, FEAT_RPAK | FEAT_EXP_PAK_REQUIRED), // Donkey Kong 64
|
MATCH_ID("NDO", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK | FEAT_EXP_PAK_REQUIRED), // Donkey Kong 64
|
||||||
MATCH_ID("NEP", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Star Wars Episode I: Racer
|
MATCH_ID("NEP", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Star Wars Episode I: Racer
|
||||||
MATCH_ID("NEV", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Neon Genesis Evangelion
|
MATCH_ID("NEV", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Neon Genesis Evangelion
|
||||||
MATCH_ID("NFU", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Conker's Bad Fur Day
|
MATCH_ID("NFU", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Conker's Bad Fur Day
|
||||||
MATCH_ID("NGC", SAVE_TYPE_EEPROM_16K, FEAT_CPAK | FEAT_RPAK), // GT 64: Championship Edition
|
MATCH_ID("NGC", SAVE_TYPE_EEPROM_16KBIT, FEAT_CPAK | FEAT_RPAK), // GT 64: Championship Edition
|
||||||
MATCH_ID("NGT", SAVE_TYPE_EEPROM_16K, FEAT_CPAK | FEAT_RPAK), // City Tour GrandPrix - Zen Nihon GT Senshuken
|
MATCH_ID("NGT", SAVE_TYPE_EEPROM_16KBIT, FEAT_CPAK | FEAT_RPAK), // City Tour GrandPrix - Zen Nihon GT Senshuken
|
||||||
MATCH_ID("NIM", SAVE_TYPE_EEPROM_16K, FEAT_NONE), // Ide Yosuke no Mahjong Juku
|
MATCH_ID("NIM", SAVE_TYPE_EEPROM_16KBIT, FEAT_NONE), // Ide Yosuke no Mahjong Juku
|
||||||
MATCH_ID("NM8", SAVE_TYPE_EEPROM_16K, FEAT_RPAK | FEAT_TPAK), // Mario Tennis
|
MATCH_ID("NM8", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK | FEAT_TPAK), // Mario Tennis
|
||||||
MATCH_ID("NMV", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Mario Party 3
|
MATCH_ID("NMV", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Mario Party 3
|
||||||
MATCH_ID("NMX", SAVE_TYPE_EEPROM_16K, FEAT_CPAK | FEAT_RPAK), // Excitebike 64
|
MATCH_ID("NMX", SAVE_TYPE_EEPROM_16KBIT, FEAT_CPAK | FEAT_RPAK), // Excitebike 64
|
||||||
MATCH_ID("NNB", SAVE_TYPE_EEPROM_16K, FEAT_CPAK | FEAT_RPAK), // Kobe Bryant in NBA Courtside
|
MATCH_ID("NNB", SAVE_TYPE_EEPROM_16KBIT, FEAT_CPAK | FEAT_RPAK), // Kobe Bryant in NBA Courtside
|
||||||
MATCH_ID("NPD", SAVE_TYPE_EEPROM_16K, FEAT_CPAK | FEAT_RPAK | FEAT_TPAK | FEAT_EXP_PAK_RECOMMENDED), // Perfect Dark
|
MATCH_ID("NPD", SAVE_TYPE_EEPROM_16KBIT, FEAT_CPAK | FEAT_RPAK | FEAT_TPAK | FEAT_EXP_PAK_RECOMMENDED), // Perfect Dark
|
||||||
MATCH_ID("NPP", SAVE_TYPE_EEPROM_16K, FEAT_CPAK), // Parlor! Pro 64: Pachinko Jikki Simulation Game
|
MATCH_ID("NPP", SAVE_TYPE_EEPROM_16KBIT, FEAT_CPAK), // Parlor! Pro 64: Pachinko Jikki Simulation Game
|
||||||
MATCH_ID("NR7", SAVE_TYPE_EEPROM_16K, FEAT_TPAK), // Robot Poncots 64: 7tsu no Umi no Caramel
|
MATCH_ID("NR7", SAVE_TYPE_EEPROM_16KBIT, FEAT_TPAK), // Robot Poncots 64: 7tsu no Umi no Caramel
|
||||||
MATCH_ID("NRZ", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Ridge Racer 64
|
MATCH_ID("NRZ", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Ridge Racer 64
|
||||||
MATCH_ID("NUB", SAVE_TYPE_EEPROM_16K, FEAT_CPAK | FEAT_TPAK), // PD Ultraman Battle Collection 64
|
MATCH_ID("NUB", SAVE_TYPE_EEPROM_16KBIT, FEAT_CPAK | FEAT_TPAK), // PD Ultraman Battle Collection 64
|
||||||
MATCH_ID("NYS", SAVE_TYPE_EEPROM_16K, FEAT_RPAK), // Yoshi's Story
|
MATCH_ID("NYS", SAVE_TYPE_EEPROM_16KBIT, FEAT_RPAK), // Yoshi's Story
|
||||||
|
|
||||||
// SRAM 256K
|
// SRAM 256K
|
||||||
MATCH_ID("CFZ", SAVE_TYPE_SRAM, FEAT_RPAK | FEAT_64DD_ENHANCED), // F-Zero X (J)
|
MATCH_ID("CFZ", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK | FEAT_64DD_ENHANCED), // F-Zero X (J)
|
||||||
MATCH_ID("CPS", SAVE_TYPE_SRAM, FEAT_TPAK | FEAT_64DD_ENHANCED), // Pocket Monsters Stadium (J)
|
MATCH_ID("CPS", SAVE_TYPE_SRAM_256KBIT, FEAT_TPAK | FEAT_64DD_ENHANCED), // Pocket Monsters Stadium (J)
|
||||||
MATCH_ID("CZL", SAVE_TYPE_SRAM, FEAT_RPAK | FEAT_64DD_ENHANCED), // Legend of Zelda: Ocarina of Time [Zelda no Densetsu - Toki no Ocarina (J)]
|
MATCH_ID("CZL", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK | FEAT_64DD_ENHANCED), // Legend of Zelda: Ocarina of Time [Zelda no Densetsu - Toki no Ocarina (J)]
|
||||||
MATCH_ID("NA2", SAVE_TYPE_SRAM, FEAT_CPAK | FEAT_RPAK), // Virtual Pro Wrestling 2
|
MATCH_ID("NA2", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK | FEAT_RPAK), // Virtual Pro Wrestling 2
|
||||||
MATCH_ID("NAL", SAVE_TYPE_SRAM, FEAT_RPAK), // Super Smash Bros. [Nintendo All-Star! Dairantou Smash Brothers (J)]
|
MATCH_ID("NAL", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Super Smash Bros. [Nintendo All-Star! Dairantou Smash Brothers (J)]
|
||||||
MATCH_ID("NB5", SAVE_TYPE_SRAM, FEAT_RPAK), // Biohazard 2 (J)
|
MATCH_ID("NB5", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Biohazard 2 (J)
|
||||||
MATCH_ID("NDD", SAVE_TYPE_SRAM, FEAT_EXP_PAK_REQUIRED | FEAT_64DD_CONVERSION), // 64DD Conversion Rom
|
MATCH_ID("NDD", SAVE_TYPE_SRAM_256KBIT, FEAT_EXP_PAK_REQUIRED | FEAT_64DD_CONVERSION), // 64DD Conversion Rom
|
||||||
MATCH_ID("NFZ", SAVE_TYPE_SRAM, FEAT_RPAK), // F-Zero X (U + E)
|
MATCH_ID("NFZ", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // F-Zero X (U + E)
|
||||||
MATCH_ID("NG6", SAVE_TYPE_SRAM, FEAT_RPAK), // Ganmare Goemon: Dero Dero Douchuu Obake Tenkomori
|
MATCH_ID("NG6", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Ganmare Goemon: Dero Dero Douchuu Obake Tenkomori
|
||||||
MATCH_ID("NGP", SAVE_TYPE_SRAM, FEAT_CPAK), // Goemon: Mononoke Sugoroku
|
MATCH_ID("NGP", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK), // Goemon: Mononoke Sugoroku
|
||||||
MATCH_ID("NHY", SAVE_TYPE_SRAM, FEAT_CPAK | FEAT_RPAK), // Hybrid Heaven (J)
|
MATCH_ID("NHY", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK | FEAT_RPAK), // Hybrid Heaven (J)
|
||||||
MATCH_ID("NIB", SAVE_TYPE_SRAM, FEAT_RPAK), // Itoi Shigesato no Bass Tsuri No. 1 Kettei Ban!
|
MATCH_ID("NIB", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Itoi Shigesato no Bass Tsuri No. 1 Kettei Ban!
|
||||||
MATCH_ID("NJ5", SAVE_TYPE_SRAM, FEAT_CPAK), // Jikkyou Powerful Pro Yakyuu 5
|
MATCH_ID("NJ5", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK), // Jikkyou Powerful Pro Yakyuu 5
|
||||||
MATCH_ID("NJG", SAVE_TYPE_SRAM, FEAT_RPAK), // Jinsei Game 64
|
MATCH_ID("NJG", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Jinsei Game 64
|
||||||
MATCH_ID("NKG", SAVE_TYPE_SRAM, FEAT_CPAK | FEAT_RPAK), // Major League Baseball featuring Ken Griffey Jr.
|
MATCH_ID("NKG", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK | FEAT_RPAK), // Major League Baseball featuring Ken Griffey Jr.
|
||||||
MATCH_ID("NMF", SAVE_TYPE_SRAM, FEAT_RPAK | FEAT_TPAK), // Mario Golf 64
|
MATCH_ID("NMF", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK | FEAT_TPAK), // Mario Golf 64
|
||||||
MATCH_ID("NOB", SAVE_TYPE_SRAM, FEAT_NONE), // Ogre Battle 64: Person of Lordly Caliber
|
MATCH_ID("NOB", SAVE_TYPE_SRAM_256KBIT, FEAT_NONE), // Ogre Battle 64: Person of Lordly Caliber
|
||||||
MATCH_ID("NP4", SAVE_TYPE_SRAM, FEAT_CPAK), // Jikkyou Powerful Pro Yakyuu 4
|
MATCH_ID("NP4", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK), // Jikkyou Powerful Pro Yakyuu 4
|
||||||
MATCH_ID("NP6", SAVE_TYPE_SRAM, FEAT_CPAK | FEAT_TPAK), // Jikkyou Powerful Pro Yakyuu 6
|
MATCH_ID("NP6", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK | FEAT_TPAK), // Jikkyou Powerful Pro Yakyuu 6
|
||||||
MATCH_ID("NPA", SAVE_TYPE_SRAM, FEAT_CPAK | FEAT_TPAK), // Jikkyou Powerful Pro Yakyuu 2000
|
MATCH_ID("NPA", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK | FEAT_TPAK), // Jikkyou Powerful Pro Yakyuu 2000
|
||||||
MATCH_ID("NPE", SAVE_TYPE_SRAM, FEAT_CPAK), // Jikkyou Powerful Pro Yakyuu Basic Ban 2001
|
MATCH_ID("NPE", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK), // Jikkyou Powerful Pro Yakyuu Basic Ban 2001
|
||||||
MATCH_ID("NPM", SAVE_TYPE_SRAM, FEAT_CPAK), // Premier Manager 64
|
MATCH_ID("NPM", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK), // Premier Manager 64
|
||||||
MATCH_ID("NPS", SAVE_TYPE_SRAM, FEAT_CPAK | FEAT_RPAK), // Jikkyou J.League 1999: Perfect Striker 2
|
MATCH_ID("NPS", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK | FEAT_RPAK), // Jikkyou J.League 1999: Perfect Striker 2
|
||||||
MATCH_ID("NRE", SAVE_TYPE_SRAM, FEAT_RPAK), // Resident Evil 2
|
MATCH_ID("NRE", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Resident Evil 2
|
||||||
MATCH_ID("NRI", SAVE_TYPE_SRAM, FEAT_CPAK), // New Tetris, The
|
MATCH_ID("NRI", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK), // New Tetris, The
|
||||||
MATCH_ID("NS4", SAVE_TYPE_SRAM, FEAT_CPAK | FEAT_TPAK), // Super Robot Taisen 64
|
MATCH_ID("NS4", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK | FEAT_TPAK), // Super Robot Taisen 64
|
||||||
MATCH_ID("NSI", SAVE_TYPE_SRAM, FEAT_CPAK), // Fushigi no Dungeon: Fuurai no Shiren 2
|
MATCH_ID("NSI", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK), // Fushigi no Dungeon: Fuurai no Shiren 2
|
||||||
MATCH_ID("NT3", SAVE_TYPE_SRAM, FEAT_CPAK), // Shin Nihon Pro Wrestling - Toukon Road 2 - The Next Generation (J)
|
MATCH_ID("NT3", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK), // Shin Nihon Pro Wrestling - Toukon Road 2 - The Next Generation (J)
|
||||||
MATCH_ID("NTE", SAVE_TYPE_SRAM, FEAT_RPAK), // 1080 Snowboarding
|
MATCH_ID("NTE", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // 1080 Snowboarding
|
||||||
MATCH_ID("NUM", SAVE_TYPE_SRAM, FEAT_RPAK | FEAT_TPAK), // Nushi Zuri 64: Shiokaze ni Notte
|
MATCH_ID("NUM", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK | FEAT_TPAK), // Nushi Zuri 64: Shiokaze ni Notte
|
||||||
MATCH_ID("NUT", SAVE_TYPE_SRAM, FEAT_CPAK | FEAT_RPAK | FEAT_TPAK), // Nushi Zuri 64
|
MATCH_ID("NUT", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK | FEAT_RPAK | FEAT_TPAK), // Nushi Zuri 64
|
||||||
MATCH_ID("NVB", SAVE_TYPE_SRAM, FEAT_RPAK), // Bass Rush - ECOGEAR PowerWorm Championship (J)
|
MATCH_ID("NVB", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Bass Rush - ECOGEAR PowerWorm Championship (J)
|
||||||
MATCH_ID("NVP", SAVE_TYPE_SRAM, FEAT_CPAK | FEAT_RPAK), // Virtual Pro Wrestling 64
|
MATCH_ID("NVP", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK | FEAT_RPAK), // Virtual Pro Wrestling 64
|
||||||
MATCH_ID("NW2", SAVE_TYPE_SRAM, FEAT_RPAK), // WCW-nWo Revenge
|
MATCH_ID("NW2", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // WCW-nWo Revenge
|
||||||
MATCH_ID("NWL", SAVE_TYPE_SRAM, FEAT_RPAK), // Waialae Country Club: True Golf Classics
|
MATCH_ID("NWL", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Waialae Country Club: True Golf Classics
|
||||||
MATCH_ID("NWX", SAVE_TYPE_SRAM, FEAT_CPAK | FEAT_RPAK), // WWF WrestleMania 2000
|
MATCH_ID("NWX", SAVE_TYPE_SRAM_256KBIT, FEAT_CPAK | FEAT_RPAK), // WWF WrestleMania 2000
|
||||||
MATCH_ID("NYW", SAVE_TYPE_SRAM, FEAT_NONE), // Harvest Moon 64
|
MATCH_ID("NYW", SAVE_TYPE_SRAM_256KBIT, FEAT_NONE), // Harvest Moon 64
|
||||||
MATCH_ID("NZL", SAVE_TYPE_SRAM, FEAT_RPAK), // Legend of Zelda: Ocarina of Time (E)
|
MATCH_ID("NZL", SAVE_TYPE_SRAM_256KBIT, FEAT_RPAK), // Legend of Zelda: Ocarina of Time (E)
|
||||||
|
|
||||||
// SRAM 768K
|
// SRAM 768K
|
||||||
MATCH_ID("CDZ", SAVE_TYPE_SRAM_BANKED, FEAT_RPAK | FEAT_64DD_ENHANCED), // Dezaemon 3D
|
MATCH_ID("CDZ", SAVE_TYPE_SRAM_BANKED, FEAT_RPAK | FEAT_64DD_ENHANCED), // Dezaemon 3D
|
||||||
|
|
||||||
// FLASHRAM
|
// FLASHRAM
|
||||||
MATCH_ID("CP2", SAVE_TYPE_FLASHRAM, FEAT_TPAK | FEAT_64DD_ENHANCED), // Pocket Monsters Stadium 2 (J)
|
MATCH_ID("CP2", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_TPAK | FEAT_64DD_ENHANCED), // Pocket Monsters Stadium 2 (J)
|
||||||
MATCH_ID("NAF", SAVE_TYPE_FLASHRAM, FEAT_CPAK | FEAT_RTC), // Doubutsu no Mori
|
MATCH_ID("NAF", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_CPAK | FEAT_RTC), // Doubutsu no Mori
|
||||||
MATCH_ID("NCC", SAVE_TYPE_FLASHRAM, FEAT_RPAK), // Command & Conquer
|
MATCH_ID("NCC", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_RPAK), // Command & Conquer
|
||||||
MATCH_ID("NCV", SAVE_TYPE_FLASHRAM, FEAT_NONE), // Cubivore (Translation)
|
MATCH_ID("NCV", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_NONE), // Cubivore (Translation)
|
||||||
MATCH_ID("NCK", SAVE_TYPE_FLASHRAM, FEAT_RPAK), // NBA Courtside 2 featuring Kobe Bryant
|
MATCH_ID("NCK", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_RPAK), // NBA Courtside 2 featuring Kobe Bryant
|
||||||
MATCH_ID("NDA", SAVE_TYPE_FLASHRAM, FEAT_CPAK), // Derby Stallion 64
|
MATCH_ID("NDA", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_CPAK), // Derby Stallion 64
|
||||||
MATCH_ID("NDP", SAVE_TYPE_FLASHRAM, FEAT_EXP_PAK_REQUIRED), // Dinosaur Planet (Unlicensed)
|
MATCH_ID("NDP", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_EXP_PAK_REQUIRED), // Dinosaur Planet (Unlicensed)
|
||||||
MATCH_ID("NJF", SAVE_TYPE_FLASHRAM, FEAT_RPAK), // Jet Force Gemini [Star Twins (J)]
|
MATCH_ID("NJF", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_RPAK), // Jet Force Gemini [Star Twins (J)]
|
||||||
MATCH_ID("NKJ", SAVE_TYPE_FLASHRAM, FEAT_RPAK), // Ken Griffey Jr.'s Slugfest
|
MATCH_ID("NKJ", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_RPAK), // Ken Griffey Jr.'s Slugfest
|
||||||
MATCH_ID("NM6", SAVE_TYPE_FLASHRAM, FEAT_RPAK), // Mega Man 64
|
MATCH_ID("NM6", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_RPAK), // Mega Man 64
|
||||||
MATCH_ID("NMQ", SAVE_TYPE_FLASHRAM, FEAT_RPAK), // Paper Mario
|
MATCH_ID("NMQ", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_RPAK), // Paper Mario
|
||||||
MATCH_ID("NPF", SAVE_TYPE_FLASHRAM, FEAT_NONE), // Pokemon Snap [Pocket Monsters Snap (J)]
|
MATCH_ID("NPF", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_NONE), // Pokemon Snap [Pocket Monsters Snap (J)]
|
||||||
MATCH_ID("NPN", SAVE_TYPE_FLASHRAM, FEAT_NONE), // Pokemon Puzzle League
|
MATCH_ID("NPN", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_NONE), // Pokemon Puzzle League
|
||||||
MATCH_ID("NPO", SAVE_TYPE_FLASHRAM, FEAT_TPAK), // Pokemon Stadium
|
MATCH_ID("NPO", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_TPAK), // Pokemon Stadium
|
||||||
MATCH_ID("NRH", SAVE_TYPE_FLASHRAM, FEAT_RPAK), // Rockman Dash - Hagane no Boukenshin (J)
|
MATCH_ID("NRH", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_RPAK), // Rockman Dash - Hagane no Boukenshin (J)
|
||||||
MATCH_ID("NSQ", SAVE_TYPE_FLASHRAM, FEAT_RPAK | FEAT_EXP_PAK_RECOMMENDED), // StarCraft 64
|
MATCH_ID("NSQ", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_RPAK | FEAT_EXP_PAK_RECOMMENDED), // StarCraft 64
|
||||||
MATCH_ID("NT9", SAVE_TYPE_FLASHRAM, FEAT_NONE), // Tigger's Honey Hunt
|
MATCH_ID("NT9", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_NONE), // Tigger's Honey Hunt
|
||||||
MATCH_ID("NW4", SAVE_TYPE_FLASHRAM, FEAT_CPAK | FEAT_RPAK), // WWF No Mercy
|
MATCH_ID("NW4", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_CPAK | FEAT_RPAK), // WWF No Mercy
|
||||||
MATCH_ID("NZS", SAVE_TYPE_FLASHRAM, FEAT_RPAK | FEAT_EXP_PAK_REQUIRED), // Legend of Zelda: Majora's Mask [Zelda no Densetsu - Mujura no Kamen (J)]
|
MATCH_ID("NZS", SAVE_TYPE_FLASHRAM_1MBIT, FEAT_RPAK | FEAT_EXP_PAK_REQUIRED), // Legend of Zelda: Majora's Mask [Zelda no Densetsu - Mujura no Kamen (J)]
|
||||||
|
|
||||||
MATCH_ID("NP3", SAVE_TYPE_FLASHRAM_PKST2, FEAT_TPAK), // Pokemon Stadium 2 [Pocket Monsters Stadium - Kin Gin (J)]
|
MATCH_ID("NP3", SAVE_TYPE_FLASHRAM_PKST2, FEAT_TPAK), // Pokemon Stadium 2 [Pocket Monsters Stadium - Kin Gin (J)]
|
||||||
|
|
||||||
// CONTROLLER PAK / NONE
|
// CONTROLLER PAK / NONE
|
||||||
MATCH_ID("N22", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Ready 2 Rumble Boxing - Round 2
|
MATCH_ID("N22", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Ready 2 Rumble Boxing - Round 2
|
||||||
MATCH_ID("N2M", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Madden Football 2002
|
MATCH_ID("N2M", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Madden Football 2002
|
||||||
MATCH_ID("N32", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Army Men - Sarge's Heroes 2
|
MATCH_ID("N32", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Army Men - Sarge's Heroes 2
|
||||||
MATCH_ID("N3P", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Triple Play 2000
|
MATCH_ID("N3P", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Triple Play 2000
|
||||||
MATCH_ID("N64", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Kira to Kaiketsu! 64 Tanteidan
|
MATCH_ID("N64", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Kira to Kaiketsu! 64 Tanteidan
|
||||||
MATCH_ID("N7I", SAVE_TYPE_NONE, FEAT_CPAK), // FIFA Soccer 64 [FIFA 64 (E)]
|
MATCH_ID("N7I", SAVE_TYPE_NONE, FEAT_CPAK), // FIFA Soccer 64 [FIFA 64 (E)]
|
||||||
MATCH_ID("N8I", SAVE_TYPE_NONE, FEAT_CPAK), // FIFA - Road to World Cup 98 [World Cup e no Michi (J)]
|
MATCH_ID("N8I", SAVE_TYPE_NONE, FEAT_CPAK), // FIFA - Road to World Cup 98 [World Cup e no Michi (J)]
|
||||||
MATCH_ID("N8M", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Madden Football 64
|
MATCH_ID("N8M", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Madden Football 64
|
||||||
MATCH_ID("N8W", SAVE_TYPE_NONE, FEAT_CPAK), // World Cup '98
|
MATCH_ID("N8W", SAVE_TYPE_NONE, FEAT_CPAK), // World Cup '98
|
||||||
MATCH_ID("N9B", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NBA Live '99
|
MATCH_ID("N9B", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NBA Live '99
|
||||||
MATCH_ID("N9C", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Nascar '99
|
MATCH_ID("N9C", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Nascar '99
|
||||||
MATCH_ID("N9F", SAVE_TYPE_NONE, FEAT_CPAK), // FIFA 99
|
MATCH_ID("N9F", SAVE_TYPE_NONE, FEAT_CPAK), // FIFA 99
|
||||||
MATCH_ID("N9H", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NHL '99
|
MATCH_ID("N9H", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NHL '99
|
||||||
MATCH_ID("N9M", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Madden Football '99
|
MATCH_ID("N9M", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Madden Football '99
|
||||||
MATCH_ID("NAC", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Army Men - Air Combat
|
MATCH_ID("NAC", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Army Men - Air Combat
|
||||||
MATCH_ID("NAH", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Asteroids Hyper 64
|
MATCH_ID("NAH", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Asteroids Hyper 64
|
||||||
MATCH_ID("NAI", SAVE_TYPE_NONE, FEAT_CPAK), // Midway's Greatest Arcade Hits Volume 1
|
MATCH_ID("NAI", SAVE_TYPE_NONE, FEAT_CPAK), // Midway's Greatest Arcade Hits Volume 1
|
||||||
MATCH_ID("NAM", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Army Men - Sarge's Heroes
|
MATCH_ID("NAM", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Army Men - Sarge's Heroes
|
||||||
MATCH_ID("NAR", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Armorines - Project S.W.A.R.M.
|
MATCH_ID("NAR", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Armorines - Project S.W.A.R.M.
|
||||||
MATCH_ID("NAS", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // All-Star Baseball 2001
|
MATCH_ID("NAS", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // All-Star Baseball 2001
|
||||||
MATCH_ID("NAY", SAVE_TYPE_NONE, FEAT_CPAK), // Aidyn Chronicles - The First Mage
|
MATCH_ID("NAY", SAVE_TYPE_NONE, FEAT_CPAK), // Aidyn Chronicles - The First Mage
|
||||||
MATCH_ID("NB2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NBA In the Zone '99 [NBA Pro '99 (E)]
|
MATCH_ID("NB2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NBA In the Zone '99 [NBA Pro '99 (E)]
|
||||||
MATCH_ID("NB3", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Bust-A-Move '99 [Bust-A-Move 3 DX (E)]
|
MATCH_ID("NB3", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Bust-A-Move '99 [Bust-A-Move 3 DX (E)]
|
||||||
MATCH_ID("NB4", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Bass Masters 2000
|
MATCH_ID("NB4", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Bass Masters 2000
|
||||||
MATCH_ID("NB8", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Beetle Adventure Racing (J)
|
MATCH_ID("NB8", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Beetle Adventure Racing (J)
|
||||||
MATCH_ID("NB9", SAVE_TYPE_NONE, FEAT_CPAK), // NBA Jam '99
|
MATCH_ID("NB9", SAVE_TYPE_NONE, FEAT_CPAK), // NBA Jam '99
|
||||||
MATCH_ID("NBA", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NBA In the Zone '98 [NBA Pro '98 (E)]
|
MATCH_ID("NBA", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NBA In the Zone '98 [NBA Pro '98 (E)]
|
||||||
MATCH_ID("NBE", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // All-Star Baseball 2000
|
MATCH_ID("NBE", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // All-Star Baseball 2000
|
||||||
MATCH_ID("NBF", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Bio F.R.E.A.K.S.
|
MATCH_ID("NBF", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Bio F.R.E.A.K.S.
|
||||||
MATCH_ID("NBI", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Blitz 2000
|
MATCH_ID("NBI", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Blitz 2000
|
||||||
MATCH_ID("NBJ", SAVE_TYPE_NONE, FEAT_CPAK), // Bakushou Jinsei 64 - Mezase! Resort Ou
|
MATCH_ID("NBJ", SAVE_TYPE_NONE, FEAT_CPAK), // Bakushou Jinsei 64 - Mezase! Resort Ou
|
||||||
MATCH_ID("NBL", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Buck Bumble
|
MATCH_ID("NBL", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Buck Bumble
|
||||||
MATCH_ID("NBO", SAVE_TYPE_NONE, FEAT_CPAK), // Bottom of the 9th
|
MATCH_ID("NBO", SAVE_TYPE_NONE, FEAT_CPAK), // Bottom of the 9th
|
||||||
MATCH_ID("NBP", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Blues Brothers 2000
|
MATCH_ID("NBP", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Blues Brothers 2000
|
||||||
MATCH_ID("NBQ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Battletanx - Global Assault
|
MATCH_ID("NBQ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Battletanx - Global Assault
|
||||||
MATCH_ID("NBR", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Milo's Astro Lanes
|
MATCH_ID("NBR", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Milo's Astro Lanes
|
||||||
MATCH_ID("NBS", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // All-Star Baseball '99
|
MATCH_ID("NBS", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // All-Star Baseball '99
|
||||||
MATCH_ID("NBU", SAVE_TYPE_NONE, FEAT_CPAK), // Bust-A-Move 2 - Arcade Edition
|
MATCH_ID("NBU", SAVE_TYPE_NONE, FEAT_CPAK), // Bust-A-Move 2 - Arcade Edition
|
||||||
MATCH_ID("NBW", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Super Bowling
|
MATCH_ID("NBW", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Super Bowling
|
||||||
MATCH_ID("NBX", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Battletanx
|
MATCH_ID("NBX", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Battletanx
|
||||||
MATCH_ID("NBY", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Bug's Life, A
|
MATCH_ID("NBY", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Bug's Life, A
|
||||||
MATCH_ID("NBZ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Blitz
|
MATCH_ID("NBZ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Blitz
|
||||||
MATCH_ID("NCB", SAVE_TYPE_NONE, FEAT_RPAK), // Charlie Blast's Territory
|
MATCH_ID("NCB", SAVE_TYPE_NONE, FEAT_RPAK), // Charlie Blast's Territory
|
||||||
MATCH_ID("NCD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Carmageddon 64
|
MATCH_ID("NCD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Carmageddon 64
|
||||||
MATCH_ID("NCE", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Nuclear Strike 64
|
MATCH_ID("NCE", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Nuclear Strike 64
|
||||||
MATCH_ID("NCL", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // California Speed
|
MATCH_ID("NCL", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // California Speed
|
||||||
MATCH_ID("NCO", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Jeremy McGrath Supercross 2000
|
MATCH_ID("NCO", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Jeremy McGrath Supercross 2000
|
||||||
MATCH_ID("NCS", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // S.C.A.R.S.
|
MATCH_ID("NCS", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // S.C.A.R.S.
|
||||||
MATCH_ID("NDC", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // SD Hiryuu no Ken Densetsu (J)
|
MATCH_ID("NDC", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // SD Hiryuu no Ken Densetsu (J)
|
||||||
MATCH_ID("NDE", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Destruction Derby 64
|
MATCH_ID("NDE", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Destruction Derby 64
|
||||||
MATCH_ID("NDF", SAVE_TYPE_NONE, FEAT_RPAK), // Dance Dance Revolution - Disney Dancing Museum
|
MATCH_ID("NDF", SAVE_TYPE_NONE, FEAT_RPAK), // Dance Dance Revolution - Disney Dancing Museum
|
||||||
MATCH_ID("NDH", SAVE_TYPE_NONE, FEAT_CPAK), // Duel Heroes
|
MATCH_ID("NDH", SAVE_TYPE_NONE, FEAT_CPAK), // Duel Heroes
|
||||||
MATCH_ID("NDM", SAVE_TYPE_NONE, FEAT_CPAK), // Doom 64
|
MATCH_ID("NDM", SAVE_TYPE_NONE, FEAT_CPAK), // Doom 64
|
||||||
MATCH_ID("NDN", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Duke Nukem 64
|
MATCH_ID("NDN", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Duke Nukem 64
|
||||||
MATCH_ID("NDQ", SAVE_TYPE_NONE, FEAT_CPAK), // Disney's Donald Duck - Goin' Quackers [Quack Attack (E)]
|
MATCH_ID("NDQ", SAVE_TYPE_NONE, FEAT_CPAK), // Disney's Donald Duck - Goin' Quackers [Quack Attack (E)]
|
||||||
MATCH_ID("NDS", SAVE_TYPE_NONE, FEAT_CPAK), // J.League Dynamite Soccer 64
|
MATCH_ID("NDS", SAVE_TYPE_NONE, FEAT_CPAK), // J.League Dynamite Soccer 64
|
||||||
MATCH_ID("NDT", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // South Park
|
MATCH_ID("NDT", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // South Park
|
||||||
MATCH_ID("NDW", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Daikatana, John Romero's
|
MATCH_ID("NDW", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Daikatana, John Romero's
|
||||||
MATCH_ID("NDZ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Duke Nukem - Zero Hour
|
MATCH_ID("NDZ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Duke Nukem - Zero Hour
|
||||||
MATCH_ID("NEG", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Extreme-G
|
MATCH_ID("NEG", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Extreme-G
|
||||||
MATCH_ID("NET", SAVE_TYPE_NONE, FEAT_CPAK), // Quest 64 [Eltale Monsters (J) Holy Magic Century (E)]
|
MATCH_ID("NET", SAVE_TYPE_NONE, FEAT_CPAK), // Quest 64 [Eltale Monsters (J) Holy Magic Century (E)]
|
||||||
MATCH_ID("NF9", SAVE_TYPE_NONE, FEAT_CPAK), // Fox Sports College Hoops '99
|
MATCH_ID("NF9", SAVE_TYPE_NONE, FEAT_CPAK), // Fox Sports College Hoops '99
|
||||||
MATCH_ID("NFB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Blitz 2001
|
MATCH_ID("NFB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Blitz 2001
|
||||||
MATCH_ID("NFD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Flying Dragon
|
MATCH_ID("NFD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Flying Dragon
|
||||||
MATCH_ID("NFF", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Fighting Force 64
|
MATCH_ID("NFF", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Fighting Force 64
|
||||||
MATCH_ID("NFL", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Madden Football 2001
|
MATCH_ID("NFL", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Madden Football 2001
|
||||||
MATCH_ID("NFO", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Forsaken 64
|
MATCH_ID("NFO", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Forsaken 64
|
||||||
MATCH_ID("NFQ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Razor Freestyle Scooter
|
MATCH_ID("NFQ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Razor Freestyle Scooter
|
||||||
MATCH_ID("NFR", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // F-1 Racing Championship
|
MATCH_ID("NFR", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // F-1 Racing Championship
|
||||||
MATCH_ID("NFS", SAVE_TYPE_NONE, FEAT_CPAK), // Famista 64
|
MATCH_ID("NFS", SAVE_TYPE_NONE, FEAT_CPAK), // Famista 64
|
||||||
MATCH_ID("NG2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Extreme-G XG2
|
MATCH_ID("NG2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Extreme-G XG2
|
||||||
MATCH_ID("NG5", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Ganbare Goemon - Neo Momoyama Bakufu no Odori [Mystical Ninja Starring Goemon]
|
MATCH_ID("NG5", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Ganbare Goemon - Neo Momoyama Bakufu no Odori [Mystical Ninja Starring Goemon]
|
||||||
MATCH_ID("NGA", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Deadly Arts [G.A.S.P!! Fighter's NEXTream (E-J)]
|
MATCH_ID("NGA", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Deadly Arts [G.A.S.P!! Fighter's NEXTream (E-J)]
|
||||||
MATCH_ID("NGB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Top Gear Hyper Bike
|
MATCH_ID("NGB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Top Gear Hyper Bike
|
||||||
MATCH_ID("NGD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Gauntlet Legends (J)
|
MATCH_ID("NGD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Gauntlet Legends (J)
|
||||||
MATCH_ID("NGM", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Goemon's Great Adventure [Mystical Ninja 2 Starring Goemon]
|
MATCH_ID("NGM", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Goemon's Great Adventure [Mystical Ninja 2 Starring Goemon]
|
||||||
MATCH_ID("NGN", SAVE_TYPE_NONE, FEAT_CPAK), // Golden Nugget 64
|
MATCH_ID("NGN", SAVE_TYPE_NONE, FEAT_CPAK), // Golden Nugget 64
|
||||||
MATCH_ID("NGR", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Top Gear Rally (U)
|
MATCH_ID("NGR", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Top Gear Rally (U)
|
||||||
MATCH_ID("NGS", SAVE_TYPE_NONE, FEAT_CPAK), // Jikkyou G1 Stable
|
MATCH_ID("NGS", SAVE_TYPE_NONE, FEAT_CPAK), // Jikkyou G1 Stable
|
||||||
MATCH_ID("NGX", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Gauntlet Legends
|
MATCH_ID("NGX", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Gauntlet Legends
|
||||||
MATCH_ID("NH5", SAVE_TYPE_NONE, FEAT_CPAK), // Nagano Winter Olympics '98 [Hyper Olympics in Nagano (J)]
|
MATCH_ID("NH5", SAVE_TYPE_NONE, FEAT_CPAK), // Nagano Winter Olympics '98 [Hyper Olympics in Nagano (J)]
|
||||||
MATCH_ID("NH9", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NHL Breakaway '99
|
MATCH_ID("NH9", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NHL Breakaway '99
|
||||||
MATCH_ID("NHC", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Hercules - The Legendary Journeys
|
MATCH_ID("NHC", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Hercules - The Legendary Journeys
|
||||||
MATCH_ID("NHG", SAVE_TYPE_NONE, FEAT_CPAK), // F-1 Pole Position 64
|
MATCH_ID("NHG", SAVE_TYPE_NONE, FEAT_CPAK), // F-1 Pole Position 64
|
||||||
MATCH_ID("NHG", SAVE_TYPE_NONE, FEAT_CPAK), // Human Grand Prix - New Generation
|
MATCH_ID("NHG", SAVE_TYPE_NONE, FEAT_CPAK), // Human Grand Prix - New Generation
|
||||||
MATCH_ID("NHK", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Hiryuu no Ken Twin
|
MATCH_ID("NHK", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Hiryuu no Ken Twin
|
||||||
MATCH_ID("NHL", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NHL Breakaway '98
|
MATCH_ID("NHL", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NHL Breakaway '98
|
||||||
MATCH_ID("NHM", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Mia Hamm Soccer 64
|
MATCH_ID("NHM", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Mia Hamm Soccer 64
|
||||||
MATCH_ID("NHN", SAVE_TYPE_NONE, FEAT_CPAK), // Olympic Hockey Nagano '98
|
MATCH_ID("NHN", SAVE_TYPE_NONE, FEAT_CPAK), // Olympic Hockey Nagano '98
|
||||||
MATCH_ID("NHO", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NHL Blades of Steel '99 [NHL Pro '99 (E)]
|
MATCH_ID("NHO", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NHL Blades of Steel '99 [NHL Pro '99 (E)]
|
||||||
MATCH_ID("NHS", SAVE_TYPE_NONE, FEAT_CPAK), // Hamster Monogatari 64
|
MATCH_ID("NHS", SAVE_TYPE_NONE, FEAT_CPAK), // Hamster Monogatari 64
|
||||||
MATCH_ID("NHT", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Hydro Thunder
|
MATCH_ID("NHT", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Hydro Thunder
|
||||||
MATCH_ID("NHV", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Hybrid Heaven (U + E)
|
MATCH_ID("NHV", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Hybrid Heaven (U + E)
|
||||||
MATCH_ID("NHW", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Hot Wheels Turbo Racing
|
MATCH_ID("NHW", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Hot Wheels Turbo Racing
|
||||||
MATCH_ID("NHX", SAVE_TYPE_NONE, FEAT_CPAK), // Hexen
|
MATCH_ID("NHX", SAVE_TYPE_NONE, FEAT_CPAK), // Hexen
|
||||||
MATCH_ID("NIS", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // International Superstar Soccer 2000
|
MATCH_ID("NIS", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // International Superstar Soccer 2000
|
||||||
MATCH_ID("NIV", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Space Invaders
|
MATCH_ID("NIV", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Space Invaders
|
||||||
MATCH_ID("NJ2", SAVE_TYPE_NONE, FEAT_CPAK), // Wonder Project J2 - Koruro no Mori no Jozet (J)
|
MATCH_ID("NJ2", SAVE_TYPE_NONE, FEAT_CPAK), // Wonder Project J2 - Koruro no Mori no Jozet (J)
|
||||||
MATCH_ID("NJ3", SAVE_TYPE_NONE, FEAT_CPAK), // Jikkyou World Soccer 3
|
MATCH_ID("NJ3", SAVE_TYPE_NONE, FEAT_CPAK), // Jikkyou World Soccer 3
|
||||||
MATCH_ID("NJA", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NBA Jam 2000
|
MATCH_ID("NJA", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NBA Jam 2000
|
||||||
MATCH_ID("NJE", SAVE_TYPE_NONE, FEAT_CPAK), // J.League Eleven Beat 1997
|
MATCH_ID("NJE", SAVE_TYPE_NONE, FEAT_CPAK), // J.League Eleven Beat 1997
|
||||||
MATCH_ID("NJL", SAVE_TYPE_NONE, FEAT_CPAK), // J.League Live 64
|
MATCH_ID("NJL", SAVE_TYPE_NONE, FEAT_CPAK), // J.League Live 64
|
||||||
MATCH_ID("NJP", SAVE_TYPE_NONE, FEAT_CPAK), // International Superstar Soccer 64 [Jikkyo J-League Perfect Striker (J)]
|
MATCH_ID("NJP", SAVE_TYPE_NONE, FEAT_CPAK), // International Superstar Soccer 64 [Jikkyo J-League Perfect Striker (J)]
|
||||||
MATCH_ID("NJQ", SAVE_TYPE_NONE, FEAT_RPAK), // Batman Beyond - Return of the Joker [Batman of the Future - Return of the Joker (E)]
|
MATCH_ID("NJQ", SAVE_TYPE_NONE, FEAT_RPAK), // Batman Beyond - Return of the Joker [Batman of the Future - Return of the Joker (E)]
|
||||||
MATCH_ID("NKE", SAVE_TYPE_NONE, FEAT_RPAK), // Knife Edge - Nose Gunner
|
MATCH_ID("NKE", SAVE_TYPE_NONE, FEAT_RPAK), // Knife Edge - Nose Gunner
|
||||||
MATCH_ID("NKK", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Knockout Kings 2000
|
MATCH_ID("NKK", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Knockout Kings 2000
|
||||||
MATCH_ID("NKM", SAVE_TYPE_NONE, FEAT_CPAK), // Pro Mahjong Kiwame 64 (J)
|
MATCH_ID("NKM", SAVE_TYPE_NONE, FEAT_CPAK), // Pro Mahjong Kiwame 64 (J)
|
||||||
MATCH_ID("NKR", SAVE_TYPE_NONE, FEAT_CPAK), // Rakuga Kids (E)
|
MATCH_ID("NKR", SAVE_TYPE_NONE, FEAT_CPAK), // Rakuga Kids (E)
|
||||||
MATCH_ID("NL2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Top Gear Rally 2
|
MATCH_ID("NL2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Top Gear Rally 2
|
||||||
MATCH_ID("NLC", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Automobili Lamborghini [Super Speed Race 64 (J)]
|
MATCH_ID("NLC", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Automobili Lamborghini [Super Speed Race 64 (J)]
|
||||||
MATCH_ID("NLG", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // LEGO Racers
|
MATCH_ID("NLG", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // LEGO Racers
|
||||||
MATCH_ID("NM3", SAVE_TYPE_NONE, FEAT_RPAK), // Monster Truck Madness 64
|
MATCH_ID("NM3", SAVE_TYPE_NONE, FEAT_RPAK), // Monster Truck Madness 64
|
||||||
MATCH_ID("NM4", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Mortal Kombat 4
|
MATCH_ID("NM4", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Mortal Kombat 4
|
||||||
MATCH_ID("NM9", SAVE_TYPE_NONE, FEAT_CPAK), // Harukanaru Augusta Masters 98
|
MATCH_ID("NM9", SAVE_TYPE_NONE, FEAT_CPAK), // Harukanaru Augusta Masters 98
|
||||||
MATCH_ID("NMA", SAVE_TYPE_NONE, FEAT_CPAK), // Jangou Simulation Mahjong Do 64
|
MATCH_ID("NMA", SAVE_TYPE_NONE, FEAT_CPAK), // Jangou Simulation Mahjong Do 64
|
||||||
MATCH_ID("NMB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Mike Piazza's Strike Zone
|
MATCH_ID("NMB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Mike Piazza's Strike Zone
|
||||||
MATCH_ID("NMD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Madden Football 2000
|
MATCH_ID("NMD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Madden Football 2000
|
||||||
MATCH_ID("NMJ", SAVE_TYPE_NONE, FEAT_CPAK), // Mahjong 64
|
MATCH_ID("NMJ", SAVE_TYPE_NONE, FEAT_CPAK), // Mahjong 64
|
||||||
MATCH_ID("NMM", SAVE_TYPE_NONE, FEAT_CPAK), // Mahjong Master
|
MATCH_ID("NMM", SAVE_TYPE_NONE, FEAT_CPAK), // Mahjong Master
|
||||||
MATCH_ID("NMT", SAVE_TYPE_NONE, FEAT_RPAK), // Magical Tetris Challenge
|
MATCH_ID("NMT", SAVE_TYPE_NONE, FEAT_RPAK), // Magical Tetris Challenge
|
||||||
MATCH_ID("NMY", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Mortal Kombat Mythologies - Sub-Zero
|
MATCH_ID("NMY", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Mortal Kombat Mythologies - Sub-Zero
|
||||||
MATCH_ID("NN2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Nascar 2000
|
MATCH_ID("NN2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Nascar 2000
|
||||||
MATCH_ID("NNC", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Nightmare Creatures
|
MATCH_ID("NNC", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Nightmare Creatures
|
||||||
MATCH_ID("NNL", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NBA Live 2000
|
MATCH_ID("NNL", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NBA Live 2000
|
||||||
MATCH_ID("NNM", SAVE_TYPE_NONE, FEAT_CPAK), // Namco Museum 64
|
MATCH_ID("NNM", SAVE_TYPE_NONE, FEAT_CPAK), // Namco Museum 64
|
||||||
MATCH_ID("NNR", SAVE_TYPE_NONE, FEAT_CPAK), // Pro Mahjong Tsuwamono 64 - Jansou Battle ni Chousen (J)
|
MATCH_ID("NNR", SAVE_TYPE_NONE, FEAT_CPAK), // Pro Mahjong Tsuwamono 64 - Jansou Battle ni Chousen (J)
|
||||||
MATCH_ID("NNS", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Beetle Adventure Racing
|
MATCH_ID("NNS", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Beetle Adventure Racing
|
||||||
MATCH_ID("NO7", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // The World Is Not Enough
|
MATCH_ID("NO7", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // The World Is Not Enough
|
||||||
MATCH_ID("NOF", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Offroad Challenge
|
MATCH_ID("NOF", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Offroad Challenge
|
||||||
MATCH_ID("NOH", SAVE_TYPE_NONE, FEAT_RPAK | FEAT_TPAK), // Transformers Beast Wars - Transmetals
|
MATCH_ID("NOH", SAVE_TYPE_NONE, FEAT_RPAK | FEAT_TPAK), // Transformers Beast Wars - Transmetals
|
||||||
MATCH_ID("NOM", SAVE_TYPE_NONE, FEAT_CPAK), // Onegai Monsters
|
MATCH_ID("NOM", SAVE_TYPE_NONE, FEAT_CPAK), // Onegai Monsters
|
||||||
MATCH_ID("NOW", SAVE_TYPE_NONE, FEAT_CPAK), // Brunswick Circuit Pro Bowling
|
MATCH_ID("NOW", SAVE_TYPE_NONE, FEAT_CPAK), // Brunswick Circuit Pro Bowling
|
||||||
MATCH_ID("NP9", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Ms. Pac-Man - Maze Madness
|
MATCH_ID("NP9", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Ms. Pac-Man - Maze Madness
|
||||||
MATCH_ID("NPB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Puzzle Bobble 64 (J)
|
MATCH_ID("NPB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Puzzle Bobble 64 (J)
|
||||||
MATCH_ID("NPC", SAVE_TYPE_NONE, FEAT_CPAK), // Pachinko 365 Nichi (J)
|
MATCH_ID("NPC", SAVE_TYPE_NONE, FEAT_CPAK), // Pachinko 365 Nichi (J)
|
||||||
MATCH_ID("NPK", SAVE_TYPE_NONE, FEAT_CPAK), // Chou Kuukan Night Pro Yakyuu King (J)
|
MATCH_ID("NPK", SAVE_TYPE_NONE, FEAT_CPAK), // Chou Kuukan Night Pro Yakyuu King (J)
|
||||||
MATCH_ID("NPL", SAVE_TYPE_NONE, FEAT_CPAK), // Power League 64 (J)
|
MATCH_ID("NPL", SAVE_TYPE_NONE, FEAT_CPAK), // Power League 64 (J)
|
||||||
MATCH_ID("NPR", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // South Park Rally
|
MATCH_ID("NPR", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // South Park Rally
|
||||||
MATCH_ID("NPU", SAVE_TYPE_NONE, FEAT_CPAK), // Power Rangers - Lightspeed Rescue
|
MATCH_ID("NPU", SAVE_TYPE_NONE, FEAT_CPAK), // Power Rangers - Lightspeed Rescue
|
||||||
MATCH_ID("NPX", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Polaris SnoCross
|
MATCH_ID("NPX", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Polaris SnoCross
|
||||||
MATCH_ID("NPZ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Susume! Taisen Puzzle Dama Toukon! Marumata Chou (J)
|
MATCH_ID("NPZ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Susume! Taisen Puzzle Dama Toukon! Marumata Chou (J)
|
||||||
MATCH_ID("NQ2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Quake 2
|
MATCH_ID("NQ2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Quake 2
|
||||||
MATCH_ID("NQ8", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Quarterback Club '98
|
MATCH_ID("NQ8", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Quarterback Club '98
|
||||||
MATCH_ID("NQ9", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Quarterback Club '99
|
MATCH_ID("NQ9", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Quarterback Club '99
|
||||||
MATCH_ID("NQB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Quarterback Club 2000
|
MATCH_ID("NQB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Quarterback Club 2000
|
||||||
MATCH_ID("NQC", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Quarterback Club 2001
|
MATCH_ID("NQC", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Quarterback Club 2001
|
||||||
MATCH_ID("NQK", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Quake 64
|
MATCH_ID("NQK", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Quake 64
|
||||||
MATCH_ID("NR2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Rush 2 - Extreme Racing USA
|
MATCH_ID("NR2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Rush 2 - Extreme Racing USA
|
||||||
MATCH_ID("NR3", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Stunt Racer 64
|
MATCH_ID("NR3", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Stunt Racer 64
|
||||||
MATCH_ID("NR6", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Tom Clancy's Rainbow Six
|
MATCH_ID("NR6", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Tom Clancy's Rainbow Six
|
||||||
MATCH_ID("NRD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Ready 2 Rumble Boxing
|
MATCH_ID("NRD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Ready 2 Rumble Boxing
|
||||||
MATCH_ID("NRG", SAVE_TYPE_NONE, FEAT_RPAK), // Rugrats - Scavenger Hunt [Treasure Hunt (E)]
|
MATCH_ID("NRG", SAVE_TYPE_NONE, FEAT_RPAK), // Rugrats - Scavenger Hunt [Treasure Hunt (E)]
|
||||||
MATCH_ID("NRK", SAVE_TYPE_NONE, FEAT_CPAK), // Rugrats in Paris - The Movie
|
MATCH_ID("NRK", SAVE_TYPE_NONE, FEAT_CPAK), // Rugrats in Paris - The Movie
|
||||||
MATCH_ID("NRO", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Road Rash 64
|
MATCH_ID("NRO", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Road Rash 64
|
||||||
MATCH_ID("NRP", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Rampage - World Tour
|
MATCH_ID("NRP", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Rampage - World Tour
|
||||||
MATCH_ID("NRP", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Rampage 2 - Universal Tour
|
MATCH_ID("NRP", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Rampage 2 - Universal Tour
|
||||||
MATCH_ID("NRR", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Roadster's Trophy
|
MATCH_ID("NRR", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Roadster's Trophy
|
||||||
MATCH_ID("NRT", SAVE_TYPE_NONE, FEAT_CPAK), // Rat Attack
|
MATCH_ID("NRT", SAVE_TYPE_NONE, FEAT_CPAK), // Rat Attack
|
||||||
MATCH_ID("NRT", SAVE_TYPE_NONE, FEAT_CPAK), // Robotron 64
|
MATCH_ID("NRT", SAVE_TYPE_NONE, FEAT_CPAK), // Robotron 64
|
||||||
MATCH_ID("NRU", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // San Francisco Rush 2049
|
MATCH_ID("NRU", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // San Francisco Rush 2049
|
||||||
MATCH_ID("NRV", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Re-Volt
|
MATCH_ID("NRV", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Re-Volt
|
||||||
MATCH_ID("NRW", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Turok: Rage Wars
|
MATCH_ID("NRW", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Turok: Rage Wars
|
||||||
MATCH_ID("NS2", SAVE_TYPE_NONE, FEAT_CPAK), // Simcity 2000
|
MATCH_ID("NS2", SAVE_TYPE_NONE, FEAT_CPAK), // Simcity 2000
|
||||||
MATCH_ID("NSB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Twisted Edge - Extreme Snowboarding [King Hill 64 - Extreme Snowboarding (J)]
|
MATCH_ID("NSB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Twisted Edge - Extreme Snowboarding [King Hill 64 - Extreme Snowboarding (J)]
|
||||||
MATCH_ID("NSD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Shadow Man
|
MATCH_ID("NSD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Shadow Man
|
||||||
MATCH_ID("NSF", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // San Francisco Rush - Extreme Racing
|
MATCH_ID("NSF", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // San Francisco Rush - Extreme Racing
|
||||||
MATCH_ID("NSG", SAVE_TYPE_NONE, FEAT_CPAK), // Shadowgate 64 - Trials Of The Four Towers
|
MATCH_ID("NSG", SAVE_TYPE_NONE, FEAT_CPAK), // Shadowgate 64 - Trials Of The Four Towers
|
||||||
MATCH_ID("NSH", SAVE_TYPE_NONE, FEAT_CPAK), // Saikyou Habu Shougi (J)
|
MATCH_ID("NSH", SAVE_TYPE_NONE, FEAT_CPAK), // Saikyou Habu Shougi (J)
|
||||||
MATCH_ID("NSK", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Snowboard Kids [Snobow Kids (J)]
|
MATCH_ID("NSK", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Snowboard Kids [Snobow Kids (J)]
|
||||||
MATCH_ID("NSL", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Spider-Man
|
MATCH_ID("NSL", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Spider-Man
|
||||||
MATCH_ID("NSO", SAVE_TYPE_NONE, FEAT_CPAK), // NBA Showtime - NBA on NBC
|
MATCH_ID("NSO", SAVE_TYPE_NONE, FEAT_CPAK), // NBA Showtime - NBA on NBC
|
||||||
MATCH_ID("NSP", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Superman
|
MATCH_ID("NSP", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Superman
|
||||||
MATCH_ID("NST", SAVE_TYPE_NONE, FEAT_CPAK), // Eikou no Saint Andrews
|
MATCH_ID("NST", SAVE_TYPE_NONE, FEAT_CPAK), // Eikou no Saint Andrews
|
||||||
MATCH_ID("NSX", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Supercross 2000
|
MATCH_ID("NSX", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Supercross 2000
|
||||||
MATCH_ID("NSY", SAVE_TYPE_NONE, FEAT_CPAK), // Scooby-Doo! - Classic Creep Capers
|
MATCH_ID("NSY", SAVE_TYPE_NONE, FEAT_CPAK), // Scooby-Doo! - Classic Creep Capers
|
||||||
MATCH_ID("NSZ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Blitz - Special Edition
|
MATCH_ID("NSZ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NFL Blitz - Special Edition
|
||||||
MATCH_ID("NT2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Turok 2 - Seeds of Evil [Violence Killer - Turok New Generation (J)]
|
MATCH_ID("NT2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Turok 2 - Seeds of Evil [Violence Killer - Turok New Generation (J)]
|
||||||
MATCH_ID("NT3", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Tony Hawk's Pro Skater 3
|
MATCH_ID("NT3", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Tony Hawk's Pro Skater 3
|
||||||
MATCH_ID("NT4", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // CyberTiger
|
MATCH_ID("NT4", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // CyberTiger
|
||||||
MATCH_ID("NTA", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Disney's Tarzan
|
MATCH_ID("NTA", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Disney's Tarzan
|
||||||
MATCH_ID("NTF", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Tony Hawk's Pro Skater
|
MATCH_ID("NTF", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Tony Hawk's Pro Skater
|
||||||
MATCH_ID("NTH", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Toy Story 2 - Buzz Lightyear to the Rescue!
|
MATCH_ID("NTH", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Toy Story 2 - Buzz Lightyear to the Rescue!
|
||||||
MATCH_ID("NTI", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // WWF: Attitude
|
MATCH_ID("NTI", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // WWF: Attitude
|
||||||
MATCH_ID("NTK", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Turok 3 - Shadow of Oblivion
|
MATCH_ID("NTK", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Turok 3 - Shadow of Oblivion
|
||||||
MATCH_ID("NTO", SAVE_TYPE_NONE, FEAT_CPAK), // Shin Nihon Pro Wrestling - Toukon Road - Brave Spirits (J)
|
MATCH_ID("NTO", SAVE_TYPE_NONE, FEAT_CPAK), // Shin Nihon Pro Wrestling - Toukon Road - Brave Spirits (J)
|
||||||
MATCH_ID("NTQ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Tony Hawk's Pro Skater 2
|
MATCH_ID("NTQ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Tony Hawk's Pro Skater 2
|
||||||
MATCH_ID("NTS", SAVE_TYPE_NONE, FEAT_CPAK), // Centre Court Tennis [Let's Smash (J)]
|
MATCH_ID("NTS", SAVE_TYPE_NONE, FEAT_CPAK), // Centre Court Tennis [Let's Smash (J)]
|
||||||
MATCH_ID("NTT", SAVE_TYPE_NONE, FEAT_CPAK), // Tonic Trouble
|
MATCH_ID("NTT", SAVE_TYPE_NONE, FEAT_CPAK), // Tonic Trouble
|
||||||
MATCH_ID("NTU", SAVE_TYPE_NONE, FEAT_CPAK), // Turok: Dinosaur Hunter [Turok: Jikuu Senshi (J)]
|
MATCH_ID("NTU", SAVE_TYPE_NONE, FEAT_CPAK), // Turok: Dinosaur Hunter [Turok: Jikuu Senshi (J)]
|
||||||
MATCH_ID("NV2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Chameleon Twist 2
|
MATCH_ID("NV2", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Chameleon Twist 2
|
||||||
MATCH_ID("NV3", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Micro Machines 64 Turbo
|
MATCH_ID("NV3", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Micro Machines 64 Turbo
|
||||||
MATCH_ID("NV8", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Vigilante 8
|
MATCH_ID("NV8", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Vigilante 8
|
||||||
MATCH_ID("NVC", SAVE_TYPE_NONE, FEAT_CPAK), // Virtual Chess 64
|
MATCH_ID("NVC", SAVE_TYPE_NONE, FEAT_CPAK), // Virtual Chess 64
|
||||||
MATCH_ID("NVG", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Vigilante 8 - Second Offense
|
MATCH_ID("NVG", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Vigilante 8 - Second Offense
|
||||||
MATCH_ID("NVR", SAVE_TYPE_NONE, FEAT_CPAK), // Virtual Pool 64
|
MATCH_ID("NVR", SAVE_TYPE_NONE, FEAT_CPAK), // Virtual Pool 64
|
||||||
MATCH_ID("NW3", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // WCW: Nitro
|
MATCH_ID("NW3", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // WCW: Nitro
|
||||||
MATCH_ID("NW8", SAVE_TYPE_NONE, FEAT_CPAK), // Wayne Gretzky's 3D Hockey '98
|
MATCH_ID("NW8", SAVE_TYPE_NONE, FEAT_CPAK), // Wayne Gretzky's 3D Hockey '98
|
||||||
MATCH_ID("NWB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Iggy's Reckin' Balls [Iggy-kun no Bura Bura Poyon (J)]
|
MATCH_ID("NWB", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Iggy's Reckin' Balls [Iggy-kun no Bura Bura Poyon (J)]
|
||||||
MATCH_ID("NWD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Winback - Covert Operations
|
MATCH_ID("NWD", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Winback - Covert Operations
|
||||||
MATCH_ID("NWF", SAVE_TYPE_NONE, FEAT_RPAK), // Wheel of Fortune
|
MATCH_ID("NWF", SAVE_TYPE_NONE, FEAT_RPAK), // Wheel of Fortune
|
||||||
MATCH_ID("NWG", SAVE_TYPE_NONE, FEAT_CPAK), // Wayne Gretzky's 3D Hockey
|
MATCH_ID("NWG", SAVE_TYPE_NONE, FEAT_CPAK), // Wayne Gretzky's 3D Hockey
|
||||||
MATCH_ID("NWI", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // ECW Hardcore Revolution
|
MATCH_ID("NWI", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // ECW Hardcore Revolution
|
||||||
MATCH_ID("NWK", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Michael Owens WLS 2000 [World League Soccer 2000 (E) / Telefoot Soccer 2000 (F)]
|
MATCH_ID("NWK", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Michael Owens WLS 2000 [World League Soccer 2000 (E) / Telefoot Soccer 2000 (F)]
|
||||||
MATCH_ID("NWM", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // WCW: Mayhem
|
MATCH_ID("NWM", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // WCW: Mayhem
|
||||||
MATCH_ID("NWN", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // WCW vs. nWo - World Tour
|
MATCH_ID("NWN", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // WCW vs. nWo - World Tour
|
||||||
MATCH_ID("NWO", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // World Driver Championship
|
MATCH_ID("NWO", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // World Driver Championship
|
||||||
MATCH_ID("NWP", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Wipeout 64
|
MATCH_ID("NWP", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Wipeout 64
|
||||||
MATCH_ID("NWS", SAVE_TYPE_NONE, FEAT_CPAK), // International Superstar Soccer '98 [Jikkyo World Soccer - World Cup France '98 (J)]
|
MATCH_ID("NWS", SAVE_TYPE_NONE, FEAT_CPAK), // International Superstar Soccer '98 [Jikkyo World Soccer - World Cup France '98 (J)]
|
||||||
MATCH_ID("NWV", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // WCW: Backstage Assault
|
MATCH_ID("NWV", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // WCW: Backstage Assault
|
||||||
MATCH_ID("NWW", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // WWF: War Zone
|
MATCH_ID("NWW", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // WWF: War Zone
|
||||||
MATCH_ID("NWZ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NBA In the Zone 2000
|
MATCH_ID("NWZ", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // NBA In the Zone 2000
|
||||||
MATCH_ID("NX2", SAVE_TYPE_NONE, FEAT_CPAK), // Gex 64 - Enter the Gecko
|
MATCH_ID("NX2", SAVE_TYPE_NONE, FEAT_CPAK), // Gex 64 - Enter the Gecko
|
||||||
MATCH_ID("NX3", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Gex 3 - Deep Cover Gecko
|
MATCH_ID("NX3", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Gex 3 - Deep Cover Gecko
|
||||||
MATCH_ID("NXF", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Xena Warrior Princess - The Talisman of Fate
|
MATCH_ID("NXF", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Xena Warrior Princess - The Talisman of Fate
|
||||||
MATCH_ID("NXG", SAVE_TYPE_NONE, FEAT_CPAK), // NBA Hangtime
|
MATCH_ID("NXG", SAVE_TYPE_NONE, FEAT_CPAK), // NBA Hangtime
|
||||||
MATCH_ID("NY2", SAVE_TYPE_NONE, FEAT_CPAK), // Rayman 2 - The Great Escape
|
MATCH_ID("NY2", SAVE_TYPE_NONE, FEAT_CPAK), // Rayman 2 - The Great Escape
|
||||||
MATCH_ID("NYP", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Paperboy
|
MATCH_ID("NYP", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Paperboy
|
||||||
MATCH_ID("NYW", SAVE_TYPE_NONE, FEAT_CPAK), // Bokujou Monogatari 2
|
MATCH_ID("NYW", SAVE_TYPE_NONE, FEAT_CPAK), // Bokujou Monogatari 2
|
||||||
MATCH_ID("NZO", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Battlezone - Rise of the Black Dogs
|
MATCH_ID("NZO", SAVE_TYPE_NONE, FEAT_CPAK | FEAT_RPAK), // Battlezone - Rise of the Black Dogs
|
||||||
|
|
||||||
MATCH_END,
|
MATCH_END,
|
||||||
};
|
};
|
||||||
@ -749,12 +750,12 @@ static void extract_rom_info (match_t *match, rom_header_t *rom_header, rom_info
|
|||||||
}
|
}
|
||||||
switch ((rom_header->version & 0xF0) >> 4) {
|
switch ((rom_header->version & 0xF0) >> 4) {
|
||||||
case 0: match->data.save = SAVE_TYPE_NONE; break;
|
case 0: match->data.save = SAVE_TYPE_NONE; break;
|
||||||
case 1: match->data.save = SAVE_TYPE_EEPROM_4K; break;
|
case 1: match->data.save = SAVE_TYPE_EEPROM_4KBIT; break;
|
||||||
case 2: match->data.save = SAVE_TYPE_EEPROM_16K; break;
|
case 2: match->data.save = SAVE_TYPE_EEPROM_16KBIT; break;
|
||||||
case 3: match->data.save = SAVE_TYPE_SRAM; break;
|
case 3: match->data.save = SAVE_TYPE_SRAM_256KBIT; break;
|
||||||
case 4: match->data.save = SAVE_TYPE_SRAM_BANKED; break;
|
case 4: match->data.save = SAVE_TYPE_SRAM_BANKED; break;
|
||||||
case 5: match->data.save = SAVE_TYPE_FLASHRAM; break;
|
case 5: match->data.save = SAVE_TYPE_FLASHRAM_1MBIT; break;
|
||||||
case 6: match->data.save = SAVE_TYPE_SRAM_128K; break;
|
case 6: match->data.save = SAVE_TYPE_SRAM_1MBIT; break;
|
||||||
default: match->data.save = SAVE_TYPE_NONE; break;
|
default: match->data.save = SAVE_TYPE_NONE; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -832,13 +833,21 @@ static rom_err_t save_override (path_t *path, const char *id, int value, int def
|
|||||||
mini_t *ini = mini_try_load(path_get(overrides_path));
|
mini_t *ini = mini_try_load(path_get(overrides_path));
|
||||||
|
|
||||||
if (!ini) {
|
if (!ini) {
|
||||||
return ROM_ERR_IO;
|
return ROM_ERR_SAVE_IO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mini_err;
|
||||||
|
|
||||||
if (value == default_value) {
|
if (value == default_value) {
|
||||||
mini_delete_value(ini, NULL, id);
|
mini_err = mini_delete_value(ini, NULL, id);
|
||||||
} else {
|
} else {
|
||||||
mini_set_int(ini, NULL, id, value);
|
mini_err = mini_set_int(ini, NULL, id, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mini_err != MINI_OK) && (mini_err != MINI_VALUE_NOT_FOUND)) {
|
||||||
|
path_free(overrides_path);
|
||||||
|
mini_free(ini);
|
||||||
|
return ROM_ERR_SAVE_IO;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty = mini_empty(ini);
|
bool empty = mini_empty(ini);
|
||||||
@ -847,16 +856,16 @@ static rom_err_t save_override (path_t *path, const char *id, int value, int def
|
|||||||
if (mini_save(ini, MINI_FLAGS_NONE) != MINI_OK) {
|
if (mini_save(ini, MINI_FLAGS_NONE) != MINI_OK) {
|
||||||
path_free(overrides_path);
|
path_free(overrides_path);
|
||||||
mini_free(ini);
|
mini_free(ini);
|
||||||
return ROM_ERR_IO;
|
return ROM_ERR_SAVE_IO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mini_free(ini);
|
mini_free(ini);
|
||||||
|
|
||||||
if (empty) {
|
if (empty) {
|
||||||
if (remove(path_get(overrides_path))) {
|
if (remove(path_get(overrides_path)) && (errno != ENOENT)) {
|
||||||
path_free(overrides_path);
|
path_free(overrides_path);
|
||||||
return ROM_ERR_IO;
|
return ROM_ERR_SAVE_IO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -946,10 +955,10 @@ rom_err_t rom_info_load (path_t *path, rom_info_t *rom_info) {
|
|||||||
setbuf(f, NULL);
|
setbuf(f, NULL);
|
||||||
if (fread(&rom_header, sizeof(rom_header), 1, f) != 1) {
|
if (fread(&rom_header, sizeof(rom_header), 1, f) != 1) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return ROM_ERR_IO;
|
return ROM_ERR_LOAD_IO;
|
||||||
}
|
}
|
||||||
if (fclose(f)) {
|
if (fclose(f)) {
|
||||||
return ROM_ERR_IO;
|
return ROM_ERR_LOAD_IO;
|
||||||
}
|
}
|
||||||
|
|
||||||
fix_rom_header_endianness(&rom_header, rom_info);
|
fix_rom_header_endianness(&rom_header, rom_info);
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
/** @brief ROM error enumeration. */
|
/** @brief ROM error enumeration. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ROM_OK,
|
ROM_OK,
|
||||||
ROM_ERR_IO,
|
ROM_ERR_LOAD_IO,
|
||||||
|
ROM_ERR_SAVE_IO,
|
||||||
ROM_ERR_NO_FILE,
|
ROM_ERR_NO_FILE,
|
||||||
} rom_err_t;
|
} rom_err_t;
|
||||||
|
|
||||||
@ -113,12 +114,12 @@ typedef enum {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
/** @brief There is no expected save type. */
|
/** @brief There is no expected save type. */
|
||||||
SAVE_TYPE_NONE = 0,
|
SAVE_TYPE_NONE = 0,
|
||||||
SAVE_TYPE_EEPROM_4K = 1,
|
SAVE_TYPE_EEPROM_4KBIT = 1,
|
||||||
SAVE_TYPE_EEPROM_16K = 2,
|
SAVE_TYPE_EEPROM_16KBIT = 2,
|
||||||
SAVE_TYPE_SRAM = 3,
|
SAVE_TYPE_SRAM_256KBIT = 3,
|
||||||
SAVE_TYPE_SRAM_BANKED = 4,
|
SAVE_TYPE_SRAM_BANKED = 4,
|
||||||
SAVE_TYPE_SRAM_128K = 5,
|
SAVE_TYPE_SRAM_1MBIT = 5,
|
||||||
SAVE_TYPE_FLASHRAM = 6,
|
SAVE_TYPE_FLASHRAM_1MBIT = 6,
|
||||||
SAVE_TYPE_FLASHRAM_PKST2 = 7,
|
SAVE_TYPE_FLASHRAM_PKST2 = 7,
|
||||||
SAVE_TYPE_AUTOMATIC = -1,
|
SAVE_TYPE_AUTOMATIC = -1,
|
||||||
} rom_save_type_t;
|
} rom_save_type_t;
|
||||||
|
@ -13,10 +13,10 @@ static settings_t init = {
|
|||||||
.show_protected_entries = false,
|
.show_protected_entries = false,
|
||||||
.default_directory = "/",
|
.default_directory = "/",
|
||||||
.use_saves_folder = true,
|
.use_saves_folder = true,
|
||||||
|
.sound_enabled = true,
|
||||||
|
|
||||||
/* Beta feature flags (should always init to off) */
|
/* Beta feature flags (should always init to off) */
|
||||||
.bgm_enabled = false,
|
.bgm_enabled = false,
|
||||||
.sound_enabled = false,
|
|
||||||
.rumble_enabled = false,
|
.rumble_enabled = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -39,10 +39,10 @@ void settings_load (settings_t *settings) {
|
|||||||
settings->show_protected_entries = mini_get_bool(ini, "menu", "show_protected_entries", init.show_protected_entries);
|
settings->show_protected_entries = mini_get_bool(ini, "menu", "show_protected_entries", init.show_protected_entries);
|
||||||
settings->default_directory = strdup(mini_get_string(ini, "menu", "default_directory", init.default_directory));
|
settings->default_directory = strdup(mini_get_string(ini, "menu", "default_directory", init.default_directory));
|
||||||
settings->use_saves_folder = mini_get_bool(ini, "menu", "use_saves_folder", init.use_saves_folder);
|
settings->use_saves_folder = mini_get_bool(ini, "menu", "use_saves_folder", init.use_saves_folder);
|
||||||
|
settings->sound_enabled = mini_get_bool(ini, "menu", "sound_enabled", init.sound_enabled);
|
||||||
|
|
||||||
/* Beta feature flags, they might not be in the file */
|
/* Beta feature flags, they might not be in the file */
|
||||||
settings->bgm_enabled = mini_get_bool(ini, "menu_beta_flag", "bgm_enabled", init.bgm_enabled);
|
settings->bgm_enabled = mini_get_bool(ini, "menu_beta_flag", "bgm_enabled", init.bgm_enabled);
|
||||||
settings->sound_enabled = mini_get_bool(ini, "menu_beta_flag", "sound_enabled", init.sound_enabled);
|
|
||||||
settings->rumble_enabled = mini_get_bool(ini, "menu_beta_flag", "rumble_enabled", init.rumble_enabled);
|
settings->rumble_enabled = mini_get_bool(ini, "menu_beta_flag", "rumble_enabled", init.rumble_enabled);
|
||||||
|
|
||||||
mini_free(ini);
|
mini_free(ini);
|
||||||
@ -55,10 +55,10 @@ void settings_save (settings_t *settings) {
|
|||||||
mini_set_bool(ini, "menu", "show_protected_entries", settings->show_protected_entries);
|
mini_set_bool(ini, "menu", "show_protected_entries", settings->show_protected_entries);
|
||||||
mini_set_string(ini, "menu", "default_directory", settings->default_directory);
|
mini_set_string(ini, "menu", "default_directory", settings->default_directory);
|
||||||
mini_set_bool(ini, "menu", "use_saves_folder", settings->use_saves_folder);
|
mini_set_bool(ini, "menu", "use_saves_folder", settings->use_saves_folder);
|
||||||
|
mini_set_bool(ini, "menu", "sound_enabled", settings->sound_enabled);
|
||||||
|
|
||||||
/* Beta feature flags, they should not save until production ready! */
|
/* Beta feature flags, they should not save until production ready! */
|
||||||
// mini_set_bool(ini, "menu_beta_flag", "bgm_enabled", settings->bgm_enabled);
|
// mini_set_bool(ini, "menu_beta_flag", "bgm_enabled", settings->bgm_enabled);
|
||||||
// mini_set_bool(ini, "menu_beta_flag", "sound_enabled", settings->sound_enabled);
|
|
||||||
// mini_set_bool(ini, "menu_beta_flag", "rumble_enabled", settings->rumble_enabled);
|
// mini_set_bool(ini, "menu_beta_flag", "rumble_enabled", settings->rumble_enabled);
|
||||||
|
|
||||||
mini_save(ini, MINI_FLAGS_SKIP_EMPTY_GROUPS);
|
mini_save(ini, MINI_FLAGS_SKIP_EMPTY_GROUPS);
|
||||||
|
@ -3,14 +3,18 @@
|
|||||||
#include <libdragon.h>
|
#include <libdragon.h>
|
||||||
|
|
||||||
#include "mp3_player.h"
|
#include "mp3_player.h"
|
||||||
|
#include "sound.h"
|
||||||
|
|
||||||
|
|
||||||
#define DEFAULT_FREQUENCY (44100)
|
#define DEFAULT_FREQUENCY (44100)
|
||||||
#define NUM_BUFFERS (4)
|
#define NUM_BUFFERS (4)
|
||||||
#define NUM_CHANNELS (2)
|
#define NUM_CHANNELS (3)
|
||||||
|
|
||||||
|
static wav64_t sfx_cursor, sfx_error, sfx_enter, sfx_exit, sfx_setting;
|
||||||
|
|
||||||
|
|
||||||
static bool sound_initialized = false;
|
static bool sound_initialized = false;
|
||||||
|
static bool sfx_enabled = false;
|
||||||
|
|
||||||
|
|
||||||
static void sound_reconfigure (int frequency) {
|
static void sound_reconfigure (int frequency) {
|
||||||
@ -35,6 +39,51 @@ void sound_init_mp3_playback (void) {
|
|||||||
sound_reconfigure(mp3player_get_samplerate());
|
sound_reconfigure(mp3player_get_samplerate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sound_init_sfx (void) {
|
||||||
|
mixer_ch_set_vol(SOUND_SFX_CHANNEL, 0.5f, 0.5f);
|
||||||
|
wav64_open(&sfx_cursor, "rom:/cursorsound.wav64");
|
||||||
|
wav64_open(&sfx_exit, "rom:/back.wav64");
|
||||||
|
wav64_open(&sfx_setting, "rom:/settings.wav64");
|
||||||
|
wav64_open(&sfx_enter, "rom:/enter.wav64");
|
||||||
|
wav64_open(&sfx_error, "rom:/error.wav64");
|
||||||
|
sfx_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_use_sfx(bool state) {
|
||||||
|
if (state) {
|
||||||
|
sfx_enabled = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sfx_enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_play_effect(sound_effect_t sfx) {
|
||||||
|
if(sfx_enabled) {
|
||||||
|
switch (sfx) {
|
||||||
|
case SFX_CURSOR:
|
||||||
|
wav64_play(&sfx_cursor, SOUND_SFX_CHANNEL);
|
||||||
|
break;
|
||||||
|
case SFX_EXIT:
|
||||||
|
wav64_play(&sfx_exit, SOUND_SFX_CHANNEL);
|
||||||
|
break;
|
||||||
|
case SFX_SETTING:
|
||||||
|
wav64_play(&sfx_setting, SOUND_SFX_CHANNEL);
|
||||||
|
break;
|
||||||
|
case SFX_ENTER:
|
||||||
|
wav64_play(&sfx_enter, SOUND_SFX_CHANNEL);
|
||||||
|
break;
|
||||||
|
case SFX_ERROR:
|
||||||
|
wav64_play(&sfx_error, SOUND_SFX_CHANNEL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void sound_deinit (void) {
|
void sound_deinit (void) {
|
||||||
if (sound_initialized) {
|
if (sound_initialized) {
|
||||||
mixer_close();
|
mixer_close();
|
||||||
|
@ -7,14 +7,26 @@
|
|||||||
#ifndef SOUND_H__
|
#ifndef SOUND_H__
|
||||||
#define SOUND_H__
|
#define SOUND_H__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define SOUND_MP3_PLAYER_CHANNEL (0)
|
#define SOUND_MP3_PLAYER_CHANNEL (0)
|
||||||
|
#define SOUND_SFX_CHANNEL (2)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SFX_CURSOR,
|
||||||
|
SFX_ERROR,
|
||||||
|
SFX_ENTER,
|
||||||
|
SFX_EXIT,
|
||||||
|
SFX_SETTING,
|
||||||
|
} sound_effect_t;
|
||||||
|
|
||||||
|
|
||||||
void sound_init_default (void);
|
void sound_init_default (void);
|
||||||
void sound_init_mp3_playback (void);
|
void sound_init_mp3_playback (void);
|
||||||
|
void sound_init_sfx (void);
|
||||||
|
void sound_use_sfx(bool);
|
||||||
|
void sound_play_effect(sound_effect_t sfx);
|
||||||
void sound_deinit (void);
|
void sound_deinit (void);
|
||||||
void sound_poll (void);
|
void sound_poll (void);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/errno.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "../fonts.h"
|
#include "../fonts.h"
|
||||||
#include "utils/fs.h"
|
#include "utils/fs.h"
|
||||||
#include "views.h"
|
#include "views.h"
|
||||||
|
#include "../sound.h"
|
||||||
|
|
||||||
|
|
||||||
static const char *rom_extensions[] = { "z64", "n64", "v64", "rom", NULL };
|
static const char *rom_extensions[] = { "z64", "n64", "v64", "rom", NULL };
|
||||||
@ -22,10 +23,17 @@ static const char *hidden_paths[] = {
|
|||||||
"/menu.bin",
|
"/menu.bin",
|
||||||
"/menu",
|
"/menu",
|
||||||
"/N64FlashcartMenu.n64",
|
"/N64FlashcartMenu.n64",
|
||||||
"/OS64.v64",
|
"/ED64",
|
||||||
"/OS64P.v64",
|
"/ED64P",
|
||||||
"/sc64menu.n64",
|
"/sc64menu.n64",
|
||||||
|
// Windows garbage
|
||||||
"/System Volume Information",
|
"/System Volume Information",
|
||||||
|
// macOS garbage
|
||||||
|
"/.fseventsd",
|
||||||
|
"/.Spotlight-V100",
|
||||||
|
"/.Trashes",
|
||||||
|
"/.VolumeIcon.icns",
|
||||||
|
"/.metadata_never_index",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -303,16 +311,19 @@ static void process (menu_t *menu) {
|
|||||||
if (menu->browser.selected < 0) {
|
if (menu->browser.selected < 0) {
|
||||||
menu->browser.selected = 0;
|
menu->browser.selected = 0;
|
||||||
}
|
}
|
||||||
|
sound_play_effect(SFX_CURSOR);
|
||||||
} else if (menu->actions.go_down) {
|
} else if (menu->actions.go_down) {
|
||||||
menu->browser.selected += scroll_speed;
|
menu->browser.selected += scroll_speed;
|
||||||
if (menu->browser.selected >= menu->browser.entries) {
|
if (menu->browser.selected >= menu->browser.entries) {
|
||||||
menu->browser.selected = menu->browser.entries - 1;
|
menu->browser.selected = menu->browser.entries - 1;
|
||||||
}
|
}
|
||||||
|
sound_play_effect(SFX_CURSOR);
|
||||||
}
|
}
|
||||||
menu->browser.entry = &menu->browser.list[menu->browser.selected];
|
menu->browser.entry = &menu->browser.list[menu->browser.selected];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (menu->actions.enter && menu->browser.entry) {
|
if (menu->actions.enter && menu->browser.entry) {
|
||||||
|
sound_play_effect(SFX_ENTER);
|
||||||
switch (menu->browser.entry->type) {
|
switch (menu->browser.entry->type) {
|
||||||
case ENTRY_TYPE_DIR:
|
case ENTRY_TYPE_DIR:
|
||||||
if (push_directory(menu, menu->browser.entry->name)) {
|
if (push_directory(menu, menu->browser.entry->name)) {
|
||||||
@ -350,10 +361,13 @@ static void process (menu_t *menu) {
|
|||||||
menu->browser.valid = false;
|
menu->browser.valid = false;
|
||||||
menu_show_error(menu, "Couldn't open last directory");
|
menu_show_error(menu, "Couldn't open last directory");
|
||||||
}
|
}
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
} else if (menu->actions.options && menu->browser.entry) {
|
} else if (menu->actions.options && menu->browser.entry) {
|
||||||
component_context_menu_show(&entry_context_menu);
|
component_context_menu_show(&entry_context_menu);
|
||||||
|
sound_play_effect(SFX_SETTING);
|
||||||
} else if (menu->actions.settings) {
|
} else if (menu->actions.settings) {
|
||||||
component_context_menu_show(&settings_context_menu);
|
component_context_menu_show(&settings_context_menu);
|
||||||
|
sound_play_effect(SFX_SETTING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "views.h"
|
#include "views.h"
|
||||||
|
#include "../sound.h"
|
||||||
|
|
||||||
#ifndef MENU_VERSION
|
#ifndef MENU_VERSION
|
||||||
#define MENU_VERSION "Unknown"
|
#define MENU_VERSION "Unknown"
|
||||||
@ -13,6 +13,7 @@
|
|||||||
static void process (menu_t *menu) {
|
static void process (menu_t *menu) {
|
||||||
if (menu->actions.back) {
|
if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
#include "views.h"
|
#include "views.h"
|
||||||
|
#include "../sound.h"
|
||||||
|
|
||||||
|
|
||||||
static void process (menu_t *menu) {
|
static void process (menu_t *menu) {
|
||||||
if (menu->actions.back) {
|
if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +50,7 @@ void view_error_display (menu_t *menu, surface_t *display) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void menu_show_error (menu_t *menu, char *error_message) {
|
void menu_show_error (menu_t *menu, char *error_message) {
|
||||||
|
sound_play_effect(SFX_ERROR);
|
||||||
menu->next_mode = MENU_MODE_ERROR;
|
menu->next_mode = MENU_MODE_ERROR;
|
||||||
menu->error_message = error_message;
|
menu->error_message = error_message;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include "../sound.h"
|
||||||
|
|
||||||
#include "utils/fs.h"
|
#include "utils/fs.h"
|
||||||
#include "views.h"
|
#include "views.h"
|
||||||
@ -12,8 +13,8 @@ static const char *patch_extensions[] = { "aps", "bps", "ips", "pps", "ups", "xd
|
|||||||
static const char *archive_extensions[] = { "zip", "rar", "7z", "tar", "gz", NULL };
|
static const char *archive_extensions[] = { "zip", "rar", "7z", "tar", "gz", NULL };
|
||||||
static const char *image_extensions[] = { "png", "jpg", "gif", NULL };
|
static const char *image_extensions[] = { "png", "jpg", "gif", NULL };
|
||||||
static const char *music_extensions[] = { "mp3", "wav", "ogg", "wma", "flac", NULL };
|
static const char *music_extensions[] = { "mp3", "wav", "ogg", "wma", "flac", NULL };
|
||||||
static const char *dexdrive_extensions[] = { "mpk", NULL };
|
static const char *controller_pak_extensions[] = { "mpk", "pak", NULL };
|
||||||
static const char *emulator_extensions[] = { "emu", NULL };
|
static const char *emulator_extensions[] = { "nes", "smc", "gb", "gbc", "sms", "gg", NULL };
|
||||||
|
|
||||||
|
|
||||||
static struct stat st;
|
static struct stat st;
|
||||||
@ -38,10 +39,10 @@ static char *format_file_type (char *name, bool is_directory) {
|
|||||||
return " Type: Image file\n";
|
return " Type: Image file\n";
|
||||||
} else if (file_has_extensions(name, music_extensions)) {
|
} else if (file_has_extensions(name, music_extensions)) {
|
||||||
return " Type: Music file\n";
|
return " Type: Music file\n";
|
||||||
} else if (file_has_extensions(name, dexdrive_extensions)) {
|
} else if (file_has_extensions(name, controller_pak_extensions)) {
|
||||||
return " Type: DexDrive CPak backup file\n";
|
return " Type: Controller Pak file\n";
|
||||||
} else if (file_has_extensions(name, emulator_extensions)) {
|
} else if (file_has_extensions(name, emulator_extensions)) {
|
||||||
return " Type: Emulator file\n";
|
return " Type: Emulator ROM file\n";
|
||||||
}
|
}
|
||||||
return " Type: Unknown file\n";
|
return " Type: Unknown file\n";
|
||||||
}
|
}
|
||||||
@ -50,6 +51,7 @@ static char *format_file_type (char *name, bool is_directory) {
|
|||||||
static void process (menu_t *menu) {
|
static void process (menu_t *menu) {
|
||||||
if (menu->actions.back) {
|
if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
#include "views.h"
|
#include "views.h"
|
||||||
|
#include "../sound.h"
|
||||||
|
|
||||||
|
|
||||||
static void process (menu_t *menu) {
|
static void process (menu_t *menu) {
|
||||||
if (menu->actions.back) {
|
if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,8 +19,17 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
component_main_text_draw(
|
component_main_text_draw(
|
||||||
ALIGN_CENTER, VALIGN_TOP,
|
ALIGN_CENTER, VALIGN_TOP,
|
||||||
"FLASHCART INFORMATION\n"
|
"FLASHCART INFORMATION\n"
|
||||||
|
"\n"
|
||||||
|
"\n"
|
||||||
|
"This feature is not yet supported.\n\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// FIXME: Display:
|
||||||
|
// * cart_type
|
||||||
|
// * Firmware version
|
||||||
|
// * supported features (flashcart_features_t)
|
||||||
|
|
||||||
|
|
||||||
component_main_text_draw(
|
component_main_text_draw(
|
||||||
ALIGN_LEFT, VALIGN_TOP,
|
ALIGN_LEFT, VALIGN_TOP,
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "../sound.h"
|
||||||
|
|
||||||
#include "../png_decoder.h"
|
#include "../png_decoder.h"
|
||||||
#include "views.h"
|
#include "views.h"
|
||||||
@ -40,6 +41,7 @@ static void process (menu_t *menu) {
|
|||||||
} else {
|
} else {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
}
|
}
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
} else if (menu->actions.enter && image) {
|
} else if (menu->actions.enter && image) {
|
||||||
if (show_message) {
|
if (show_message) {
|
||||||
show_message = false;
|
show_message = false;
|
||||||
@ -48,6 +50,7 @@ static void process (menu_t *menu) {
|
|||||||
} else {
|
} else {
|
||||||
show_message = true;
|
show_message = true;
|
||||||
}
|
}
|
||||||
|
sound_play_effect(SFX_ENTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
#include "../cart_load.h"
|
#include "../cart_load.h"
|
||||||
#include "../disk_info.h"
|
#include "../disk_info.h"
|
||||||
#include "boot/boot.h"
|
#include "boot/boot.h"
|
||||||
|
#include "../sound.h"
|
||||||
#include "views.h"
|
#include "views.h"
|
||||||
|
|
||||||
|
|
||||||
static bool load_pending;
|
static bool load_pending;
|
||||||
static bool load_rom;
|
static bool load_rom;
|
||||||
|
static component_boxart_t *boxart;
|
||||||
|
|
||||||
|
|
||||||
static char *convert_error_message (disk_err_t err) {
|
static char *convert_error_message (disk_err_t err) {
|
||||||
@ -34,8 +36,10 @@ static void process (menu_t *menu) {
|
|||||||
} else if (menu->actions.options && menu->load.rom_path) {
|
} else if (menu->actions.options && menu->load.rom_path) {
|
||||||
load_pending = true;
|
load_pending = true;
|
||||||
load_rom = true;
|
load_rom = true;
|
||||||
|
sound_play_effect(SFX_SETTING);
|
||||||
} else if (menu->actions.back) {
|
} else if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +93,8 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
"R: Load with ROM"
|
"R: Load with ROM"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
component_boxart_draw(boxart);
|
||||||
}
|
}
|
||||||
|
|
||||||
rdpq_detach_show();
|
rdpq_detach_show();
|
||||||
@ -145,6 +151,9 @@ static void load (menu_t *menu) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void deinit (void) {
|
||||||
|
component_boxart_free(boxart);
|
||||||
|
}
|
||||||
|
|
||||||
void view_load_disk_init (menu_t *menu) {
|
void view_load_disk_init (menu_t *menu) {
|
||||||
if (menu->load.disk_path) {
|
if (menu->load.disk_path) {
|
||||||
@ -160,6 +169,8 @@ void view_load_disk_init (menu_t *menu) {
|
|||||||
if (err != DISK_OK) {
|
if (err != DISK_OK) {
|
||||||
menu_show_error(menu, convert_error_message(err));
|
menu_show_error(menu, convert_error_message(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boxart = component_boxart_init(menu->storage_prefix, menu->load.disk_info.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void view_load_disk_display (menu_t *menu, surface_t *display) {
|
void view_load_disk_display (menu_t *menu, surface_t *display) {
|
||||||
@ -171,4 +182,8 @@ void view_load_disk_display (menu_t *menu, surface_t *display) {
|
|||||||
load_pending = false;
|
load_pending = false;
|
||||||
load(menu);
|
load(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (menu->next_mode != MENU_MODE_LOAD_DISK) {
|
||||||
|
deinit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "../cart_load.h"
|
#include "../cart_load.h"
|
||||||
#include "boot/boot.h"
|
#include "boot/boot.h"
|
||||||
#include "utils/fs.h"
|
#include "utils/fs.h"
|
||||||
|
#include "../sound.h"
|
||||||
#include "views.h"
|
#include "views.h"
|
||||||
|
|
||||||
|
|
||||||
@ -36,6 +37,7 @@ static void process (menu_t *menu) {
|
|||||||
load_pending = true;
|
load_pending = true;
|
||||||
} else if (menu->actions.back) {
|
} else if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
#include "../cart_load.h"
|
#include "../cart_load.h"
|
||||||
#include "../rom_info.h"
|
#include "../rom_info.h"
|
||||||
#include "boot/boot.h"
|
#include "boot/boot.h"
|
||||||
|
#include "../sound.h"
|
||||||
#include "views.h"
|
#include "views.h"
|
||||||
|
|
||||||
|
static bool show_extra_info_message = false;
|
||||||
static bool load_pending;
|
static bool load_pending;
|
||||||
static component_boxart_t *boxart;
|
static component_boxart_t *boxart;
|
||||||
|
|
||||||
|
|
||||||
static char *convert_error_message (rom_err_t err) {
|
static char *convert_error_message (rom_err_t err) {
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case ROM_ERR_IO: return "I/O error during loading/storing ROM information";
|
case ROM_ERR_LOAD_IO: return "I/O error during loading ROM information and/or options";
|
||||||
|
case ROM_ERR_SAVE_IO: return "I/O error during storing ROM options";
|
||||||
case ROM_ERR_NO_FILE: return "Couldn't open ROM file";
|
case ROM_ERR_NO_FILE: return "Couldn't open ROM file";
|
||||||
default: return "Unknown ROM info load error";
|
default: return "Unknown ROM info load error";
|
||||||
}
|
}
|
||||||
@ -64,16 +66,16 @@ static const char *format_rom_destination_market (rom_destination_type_t market_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *format_rom_save_type (rom_save_type_t save_type) {
|
static const char *format_rom_save_type (rom_save_type_t save_type, bool supports_cpak) {
|
||||||
switch (save_type) {
|
switch (save_type) {
|
||||||
case SAVE_TYPE_NONE: return "None";
|
case SAVE_TYPE_NONE: return supports_cpak ? "Controller PAK" : "None";
|
||||||
case SAVE_TYPE_EEPROM_4K: return "EEPROM 4K";
|
case SAVE_TYPE_EEPROM_4KBIT: return supports_cpak ? "EEPROM 4kbit | Controller PAK" : "EEPROM 4kbit";
|
||||||
case SAVE_TYPE_EEPROM_16K: return "EEPROM 16K";
|
case SAVE_TYPE_EEPROM_16KBIT: return supports_cpak ? "EEPROM 16kbit | Controller PAK" : "EEPROM 16kbit";
|
||||||
case SAVE_TYPE_SRAM: return "SRAM";
|
case SAVE_TYPE_SRAM_256KBIT: return supports_cpak ? "SRAM 256kbit | Controller PAK" : "SRAM 256kbit";
|
||||||
case SAVE_TYPE_SRAM_BANKED: return "SRAM Banked";
|
case SAVE_TYPE_SRAM_BANKED: return supports_cpak ? "SRAM 768kbit / 3 banks | Controller PAK" : "SRAM 768kbit / 3 banks";
|
||||||
case SAVE_TYPE_SRAM_128K: return "SRAM 128K";
|
case SAVE_TYPE_SRAM_1MBIT: return supports_cpak ? "SRAM 1Mbit | Controller PAK" : "SRAM 1Mbit";
|
||||||
case SAVE_TYPE_FLASHRAM: return "FlashRAM";
|
case SAVE_TYPE_FLASHRAM_1MBIT: return supports_cpak ? "FlashRAM 1Mbit | Controller PAK" : "FlashRAM 1Mbit";
|
||||||
case SAVE_TYPE_FLASHRAM_PKST2: return "FlashRAM (Pokemon Stadium 2)";
|
case SAVE_TYPE_FLASHRAM_PKST2: return supports_cpak ? "FlashRAM (Pokemon Stadium 2) | Controller PAK" : "FlashRAM (Pokemon Stadium 2)";
|
||||||
default: return "Unknown";
|
default: return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,12 +166,12 @@ static component_context_menu_t set_cic_type_context_menu = { .list = {
|
|||||||
static component_context_menu_t set_save_type_context_menu = { .list = {
|
static component_context_menu_t set_save_type_context_menu = { .list = {
|
||||||
{ .text = "Automatic", .action = set_save_type, .arg = (void *) (SAVE_TYPE_AUTOMATIC) },
|
{ .text = "Automatic", .action = set_save_type, .arg = (void *) (SAVE_TYPE_AUTOMATIC) },
|
||||||
{ .text = "None", .action = set_save_type, .arg = (void *) (SAVE_TYPE_NONE) },
|
{ .text = "None", .action = set_save_type, .arg = (void *) (SAVE_TYPE_NONE) },
|
||||||
{ .text = "EEPROM 4kbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_EEPROM_4K) },
|
{ .text = "EEPROM 4kbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_EEPROM_4KBIT) },
|
||||||
{ .text = "EEPROM 16kbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_EEPROM_16K) },
|
{ .text = "EEPROM 16kbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_EEPROM_16KBIT) },
|
||||||
{ .text = "SRAM 256kbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_SRAM) },
|
{ .text = "SRAM 256kbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_SRAM_256KBIT) },
|
||||||
{ .text = "SRAM 768kbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_SRAM_BANKED) },
|
{ .text = "SRAM 768kbit / 3 banks", .action = set_save_type, .arg = (void *) (SAVE_TYPE_SRAM_BANKED) },
|
||||||
{ .text = "SRAM 1Mbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_SRAM_128K) },
|
{ .text = "SRAM 1Mbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_SRAM_1MBIT) },
|
||||||
{ .text = "FlashRAM 1Mbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_FLASHRAM) },
|
{ .text = "FlashRAM 1Mbit", .action = set_save_type, .arg = (void *) (SAVE_TYPE_FLASHRAM_1MBIT) },
|
||||||
COMPONENT_CONTEXT_MENU_LIST_END,
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@ -197,8 +199,17 @@ static void process (menu_t *menu) {
|
|||||||
load_pending = true;
|
load_pending = true;
|
||||||
} else if (menu->actions.back) {
|
} else if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
} else if (menu->actions.options) {
|
} else if (menu->actions.options) {
|
||||||
component_context_menu_show(&options_context_menu);
|
component_context_menu_show(&options_context_menu);
|
||||||
|
sound_play_effect(SFX_SETTING);
|
||||||
|
} else if (menu->actions.lz_context) {
|
||||||
|
if (show_extra_info_message) {
|
||||||
|
show_extra_info_message = false;
|
||||||
|
} else {
|
||||||
|
show_extra_info_message = true;
|
||||||
|
}
|
||||||
|
sound_play_effect(SFX_SETTING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,52 +237,61 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
"\n"
|
"\n"
|
||||||
"\n"
|
"\n"
|
||||||
"\n"
|
"\n"
|
||||||
" Endianness: %s\n"
|
"Description:\n None.\n\n\n\n\n\n\n\n"
|
||||||
" Title: %.20s\n"
|
"Expansion PAK: %s\n"
|
||||||
" Game code: %c%c%c%c\n"
|
"TV type: %s\n"
|
||||||
" Media type: %s\n"
|
"CIC: %s\n"
|
||||||
" Destination market: %s\n"
|
"GS/AR Cheats: Off\n"
|
||||||
" Version: %hhu\n"
|
"Patches: Off\n"
|
||||||
" Check code: 0x%016llX\n"
|
"Save type: %s\n",
|
||||||
" Save type: %s\n"
|
|
||||||
" TV type: %s\n"
|
|
||||||
" Expansion PAK: %s\n"
|
|
||||||
"\n"
|
|
||||||
" Extra information:\n"
|
|
||||||
" CIC: %s\n"
|
|
||||||
" Boot address: 0x%08lX\n"
|
|
||||||
" SDK version: %.1f%c\n"
|
|
||||||
" Clock Rate: %.2fMHz\n",
|
|
||||||
format_rom_endianness(menu->load.rom_info.endianness),
|
|
||||||
menu->load.rom_info.title,
|
|
||||||
menu->load.rom_info.game_code[0], menu->load.rom_info.game_code[1], menu->load.rom_info.game_code[2], menu->load.rom_info.game_code[3],
|
|
||||||
format_rom_media_type(menu->load.rom_info.category_code),
|
|
||||||
format_rom_destination_market(menu->load.rom_info.destination_code),
|
|
||||||
menu->load.rom_info.version,
|
|
||||||
menu->load.rom_info.check_code,
|
|
||||||
format_rom_save_type(rom_info_get_save_type(&menu->load.rom_info)),
|
|
||||||
format_rom_tv_type(rom_info_get_tv_type(&menu->load.rom_info)),
|
|
||||||
format_rom_expansion_pak_info(menu->load.rom_info.features.expansion_pak),
|
format_rom_expansion_pak_info(menu->load.rom_info.features.expansion_pak),
|
||||||
|
format_rom_tv_type(rom_info_get_tv_type(&menu->load.rom_info)),
|
||||||
format_cic_type(rom_info_get_cic_type(&menu->load.rom_info)),
|
format_cic_type(rom_info_get_cic_type(&menu->load.rom_info)),
|
||||||
menu->load.rom_info.boot_address,
|
format_rom_save_type(rom_info_get_save_type(&menu->load.rom_info), menu->load.rom_info.features.controller_pak)
|
||||||
(menu->load.rom_info.libultra.version / 10.0f), menu->load.rom_info.libultra.revision,
|
|
||||||
menu->load.rom_info.clock_rate
|
|
||||||
);
|
);
|
||||||
|
|
||||||
component_actions_bar_text_draw(
|
component_actions_bar_text_draw(
|
||||||
ALIGN_LEFT, VALIGN_TOP,
|
ALIGN_LEFT, VALIGN_TOP,
|
||||||
"A: Load and run ROM\n"
|
"A: Load and run ROM\n"
|
||||||
"B: Exit"
|
"B: Back"
|
||||||
);
|
);
|
||||||
|
|
||||||
component_actions_bar_text_draw(
|
component_actions_bar_text_draw(
|
||||||
ALIGN_RIGHT, VALIGN_TOP,
|
ALIGN_RIGHT, VALIGN_TOP,
|
||||||
"\n"
|
"L|Z: Extra Info\n"
|
||||||
"R: Options"
|
"R: Options"
|
||||||
);
|
);
|
||||||
|
|
||||||
component_boxart_draw(boxart);
|
component_boxart_draw(boxart);
|
||||||
|
|
||||||
|
if (show_extra_info_message) {
|
||||||
|
component_messagebox_draw(
|
||||||
|
"EXTRA ROM INFO\n"
|
||||||
|
"\n"
|
||||||
|
"Endianness: %s\n"
|
||||||
|
"Title: %.20s\n"
|
||||||
|
"Game code: %c%c%c%c\n"
|
||||||
|
"Media type: %s\n"
|
||||||
|
"Variant: %s\n"
|
||||||
|
"Version: %hhu\n"
|
||||||
|
"Check code: 0x%016llX\n"
|
||||||
|
"Boot address: 0x%08lX\n"
|
||||||
|
"SDK version: %.1f%c\n"
|
||||||
|
"Clock Rate: %.2fMHz\n\n\n"
|
||||||
|
"Press L|Z to return.\n",
|
||||||
|
format_rom_endianness(menu->load.rom_info.endianness),
|
||||||
|
menu->load.rom_info.title,
|
||||||
|
menu->load.rom_info.game_code[0], menu->load.rom_info.game_code[1], menu->load.rom_info.game_code[2], menu->load.rom_info.game_code[3],
|
||||||
|
format_rom_media_type(menu->load.rom_info.category_code),
|
||||||
|
format_rom_destination_market(menu->load.rom_info.destination_code),
|
||||||
|
menu->load.rom_info.version,
|
||||||
|
menu->load.rom_info.check_code,
|
||||||
|
menu->load.rom_info.boot_address,
|
||||||
|
(menu->load.rom_info.libultra.version / 10.0f), menu->load.rom_info.libultra.revision,
|
||||||
|
menu->load.rom_info.clock_rate
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
component_context_menu_draw(&options_context_menu);
|
component_context_menu_draw(&options_context_menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,11 +42,13 @@ static void process (menu_t *menu) {
|
|||||||
menu_show_error(menu, convert_error_message(err));
|
menu_show_error(menu, convert_error_message(err));
|
||||||
} else if (menu->actions.back) {
|
} else if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
} else if (menu->actions.enter) {
|
} else if (menu->actions.enter) {
|
||||||
err = mp3player_toggle();
|
err = mp3player_toggle();
|
||||||
if (err != MP3PLAYER_OK) {
|
if (err != MP3PLAYER_OK) {
|
||||||
menu_show_error(menu, convert_error_message(err));
|
menu_show_error(menu, convert_error_message(err));
|
||||||
}
|
}
|
||||||
|
sound_play_effect(SFX_ENTER);
|
||||||
} else if (menu->actions.go_left || menu->actions.go_right) {
|
} else if (menu->actions.go_left || menu->actions.go_right) {
|
||||||
int seconds = menu->actions.go_fast ? SEEK_SECONDS_FAST : SEEK_SECONDS;
|
int seconds = menu->actions.go_fast ? SEEK_SECONDS_FAST : SEEK_SECONDS;
|
||||||
err = mp3player_seek(menu->actions.go_left ? (-seconds) : seconds);
|
err = mp3player_seek(menu->actions.go_left ? (-seconds) : seconds);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "../sound.h"
|
||||||
#include "views.h"
|
#include "views.h"
|
||||||
|
|
||||||
// FIXME: add implementation!
|
// FIXME: add implementation!
|
||||||
@ -18,6 +19,7 @@
|
|||||||
static void process (menu_t *menu) {
|
static void process (menu_t *menu) {
|
||||||
if (menu->actions.back) {
|
if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,7 +36,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
"\n"
|
"\n"
|
||||||
"\n"
|
"\n"
|
||||||
"To set the date and time, please use the PC terminal\n"
|
"To set the date and time, please use the PC terminal\n"
|
||||||
"application and set via USB.\n\n"
|
"application and set via USB or a game that uses it.\n\n"
|
||||||
"Current date & time: %s\n",
|
"Current date & time: %s\n",
|
||||||
menu->current_time >= 0 ? ctime(&menu->current_time) : "Unknown\n"
|
menu->current_time >= 0 ? ctime(&menu->current_time) : "Unknown\n"
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
#include "../sound.h"
|
||||||
|
#include "../settings.h"
|
||||||
#include "views.h"
|
#include "views.h"
|
||||||
|
|
||||||
|
|
||||||
@ -8,10 +11,111 @@ static const char *format_switch (bool state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_pal60_type (menu_t *menu, void *arg) {
|
||||||
|
menu->settings.pal60_enabled = (bool) (arg);
|
||||||
|
settings_save(&menu->settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_protected_entries_type (menu_t *menu, void *arg) {
|
||||||
|
menu->settings.show_protected_entries = (bool) (arg);
|
||||||
|
settings_save(&menu->settings);
|
||||||
|
|
||||||
|
menu->browser.reload = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_use_saves_folder_type (menu_t *menu, void *arg) {
|
||||||
|
menu->settings.use_saves_folder = (bool) (arg);
|
||||||
|
settings_save(&menu->settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_sound_enabled_type (menu_t *menu, void *arg) {
|
||||||
|
menu->settings.sound_enabled = (bool) (arg);
|
||||||
|
sound_use_sfx(menu->settings.sound_enabled);
|
||||||
|
settings_save(&menu->settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BETA_SETTINGS
|
||||||
|
static void set_bgm_enabled_type (menu_t *menu, void *arg) {
|
||||||
|
menu->settings.bgm_enabled = (bool) (arg);
|
||||||
|
settings_save(&menu->settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_rumble_enabled_type (menu_t *menu, void *arg) {
|
||||||
|
menu->settings.rumble_enabled = (bool) (arg);
|
||||||
|
settings_save(&menu->settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static void set_use_default_settings (menu_t *menu, void *arg) {
|
||||||
|
// // FIXME: add implementation
|
||||||
|
// menu->browser.reload = true;
|
||||||
|
// }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static component_context_menu_t set_pal60_type_context_menu = { .list = {
|
||||||
|
{.text = "On", .action = set_pal60_type, .arg = (void *) (true) },
|
||||||
|
{.text = "Off", .action = set_pal60_type, .arg = (void *) (false) },
|
||||||
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static component_context_menu_t set_protected_entries_type_context_menu = { .list = {
|
||||||
|
{.text = "On", .action = set_protected_entries_type, .arg = (void *) (true) },
|
||||||
|
{.text = "Off", .action = set_protected_entries_type, .arg = (void *) (false) },
|
||||||
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static component_context_menu_t set_sound_enabled_type_context_menu = { .list = {
|
||||||
|
{.text = "On", .action = set_sound_enabled_type, .arg = (void *) (true) },
|
||||||
|
{.text = "Off", .action = set_sound_enabled_type, .arg = (void *) (false) },
|
||||||
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static component_context_menu_t set_use_saves_folder_type_context_menu = { .list = {
|
||||||
|
{.text = "On", .action = set_use_saves_folder_type, .arg = (void *) (true) },
|
||||||
|
{.text = "Off", .action = set_use_saves_folder_type, .arg = (void *) (false) },
|
||||||
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
|
}};
|
||||||
|
|
||||||
|
#ifdef BETA_SETTINGS
|
||||||
|
static component_context_menu_t set_bgm_enabled_type_context_menu = { .list = {
|
||||||
|
{.text = "On", .action = set_bgm_enabled_type, .arg = (void *) (true) },
|
||||||
|
{.text = "Off", .action = set_bgm_enabled_type, .arg = (void *) (false) },
|
||||||
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static component_context_menu_t set_rumble_enabled_type_context_menu = { .list = {
|
||||||
|
{.text = "On", .action = set_rumble_enabled_type, .arg = (void *) (true) },
|
||||||
|
{.text = "Off", .action = set_rumble_enabled_type, .arg = (void *) (false) },
|
||||||
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
|
}};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static component_context_menu_t options_context_menu = { .list = {
|
||||||
|
{ .text = "PAL60 Mode", .submenu = &set_pal60_type_context_menu },
|
||||||
|
{ .text = "Show Hidden Files", .submenu = &set_protected_entries_type_context_menu },
|
||||||
|
{ .text = "Sound Effects", .submenu = &set_sound_enabled_type_context_menu },
|
||||||
|
{ .text = "Use Saves Folder", .submenu = &set_use_saves_folder_type_context_menu },
|
||||||
|
#ifdef BETA_SETTINGS
|
||||||
|
{ .text = "Background Music", .submenu = &set_bgm_enabled_type_context_menu },
|
||||||
|
{ .text = "Rumble Feedback", .submenu = &set_rumble_enabled_type_context_menu },
|
||||||
|
// { .text = "Restore Defaults", .action = set_use_default_settings },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
COMPONENT_CONTEXT_MENU_LIST_END,
|
||||||
|
}};
|
||||||
|
|
||||||
|
|
||||||
static void process (menu_t *menu) {
|
static void process (menu_t *menu) {
|
||||||
if (menu->actions.back) {
|
if (component_context_menu_process(menu, &options_context_menu)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (menu->actions.enter) {
|
||||||
|
component_context_menu_show(&options_context_menu);
|
||||||
|
sound_play_effect(SFX_SETTING);
|
||||||
|
} else if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,44 +128,54 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
|
|
||||||
component_main_text_draw(
|
component_main_text_draw(
|
||||||
ALIGN_CENTER, VALIGN_TOP,
|
ALIGN_CENTER, VALIGN_TOP,
|
||||||
"SETTINGS EDITOR\n"
|
"MENU SETTINGS EDITOR\n"
|
||||||
"\n"
|
"\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
component_main_text_draw(
|
component_main_text_draw(
|
||||||
ALIGN_LEFT, VALIGN_TOP,
|
ALIGN_LEFT, VALIGN_TOP,
|
||||||
"\n"
|
"\n\n"
|
||||||
"\n"
|
" Default Directory : %s\n\n"
|
||||||
"To change the settings, please adjust them\n"
|
"To change the following menu settings, press 'A':\n"
|
||||||
"directly in the 'menu/config.ini' file.\n\n"
|
"* PAL60 Mode : %s\n"
|
||||||
"pal60_enabled: %s\n"
|
" Show Hidden Files : %s\n"
|
||||||
"show_protected_entries: %s\n"
|
" Use Saves folder : %s\n"
|
||||||
"default_directory: %s\n"
|
" Sound Effects : %s\n"
|
||||||
"use_saves_folder: %s\n"
|
#ifdef BETA_SETTINGS
|
||||||
"bgm_enabled: %s\n"
|
" Background Music : %s\n"
|
||||||
"sound_enabled: %s\n"
|
" Rumble Feedback : %s\n"
|
||||||
"rumble_enabled: %s\n",
|
#endif
|
||||||
|
"Note: Certain settings have the following caveats:\n\n"
|
||||||
|
"* Requires a flashcart reboot.\n",
|
||||||
|
menu->settings.default_directory,
|
||||||
format_switch(menu->settings.pal60_enabled),
|
format_switch(menu->settings.pal60_enabled),
|
||||||
format_switch(menu->settings.show_protected_entries),
|
format_switch(menu->settings.show_protected_entries),
|
||||||
menu->settings.default_directory,
|
|
||||||
format_switch(menu->settings.use_saves_folder),
|
format_switch(menu->settings.use_saves_folder),
|
||||||
|
format_switch(menu->settings.sound_enabled)
|
||||||
|
#ifdef BETA_SETTINGS
|
||||||
|
,
|
||||||
format_switch(menu->settings.bgm_enabled),
|
format_switch(menu->settings.bgm_enabled),
|
||||||
format_switch(menu->settings.sound_enabled),
|
|
||||||
format_switch(menu->settings.rumble_enabled)
|
format_switch(menu->settings.rumble_enabled)
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
component_actions_bar_text_draw(
|
component_actions_bar_text_draw(
|
||||||
ALIGN_LEFT, VALIGN_TOP,
|
ALIGN_LEFT, VALIGN_TOP,
|
||||||
"\n"
|
"A: Change\n"
|
||||||
"B: Back"
|
"B: Back"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
component_context_menu_draw(&options_context_menu);
|
||||||
|
|
||||||
rdpq_detach_show();
|
rdpq_detach_show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void view_settings_init (menu_t *menu) {
|
void view_settings_init (menu_t *menu) {
|
||||||
// Nothing to initialize (yet)
|
|
||||||
|
component_context_menu_init(&options_context_menu);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void view_settings_display (menu_t *menu, surface_t *display) {
|
void view_settings_display (menu_t *menu, surface_t *display) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "../sound.h"
|
||||||
#include "views.h"
|
#include "views.h"
|
||||||
|
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ static void process (menu_t *menu) {
|
|||||||
|
|
||||||
if (menu->actions.back) {
|
if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "../components/constants.h"
|
#include "../components/constants.h"
|
||||||
#include "../fonts.h"
|
#include "../fonts.h"
|
||||||
|
#include "../sound.h"
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
#include "views.h"
|
#include "views.h"
|
||||||
|
|
||||||
@ -55,6 +56,7 @@ static void perform_vertical_scroll (int lines) {
|
|||||||
static void process (menu_t *menu) {
|
static void process (menu_t *menu) {
|
||||||
if (menu->actions.back) {
|
if (menu->actions.back) {
|
||||||
menu->next_mode = MENU_MODE_BROWSER;
|
menu->next_mode = MENU_MODE_BROWSER;
|
||||||
|
sound_play_effect(SFX_EXIT);
|
||||||
} else if (text) {
|
} else if (text) {
|
||||||
if (menu->actions.go_up) {
|
if (menu->actions.go_up) {
|
||||||
perform_vertical_scroll(menu->actions.go_fast ? -10 : -1);
|
perform_vertical_scroll(menu->actions.go_fast ? -10 : -1);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/errno.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user