From 708dde5b6c873c428f3881b348047a079f06e2c8 Mon Sep 17 00:00:00 2001 From: CocoSimone Date: Sun, 18 Sep 2022 16:12:50 +0200 Subject: [PATCH] Introduce game db + fallback to stem of filename + volume control --- .github/workflows/build.yml | 7 +- .gitignore | 1 - resources/game_db.json | 3110 +++++++++++++++++++++++++++++ src/frontend/App.cpp | 4 +- src/frontend/App.hpp | 2 +- src/frontend/imgui/CMakeLists.txt | 3 +- src/frontend/imgui/Window.cpp | 64 +- src/frontend/imgui/Window.hpp | 5 + src/n64/Core.cpp | 21 +- src/n64/Core.hpp | 5 +- src/n64/core/Audio.cpp | 8 +- src/n64/core/Audio.hpp | 2 +- src/n64/core/Mem.cpp | 8 +- src/n64/core/Mem.hpp | 2 +- src/n64/core/RSP.cpp | 40 +- src/n64/core/RSP.hpp | 4 +- src/n64/core/mmio/AI.cpp | 4 +- src/n64/core/mmio/AI.hpp | 2 +- src/n64/core/rsp/instructions.cpp | 14 +- src/util.hpp | 62 +- 20 files changed, 3295 insertions(+), 73 deletions(-) create mode 100644 resources/game_db.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 94798c87..8f66f172 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: - name: Install dependencies run: | sudo apt-get update -qq - sudo apt-get install -y build-essential libgtk-3-dev libsdl2-dev libfmt-dev git ninja-build + sudo apt-get install -y build-essential libgtk-3-dev libsdl2-dev libfmt-dev git ninja-build nlohmann-json3-dev sudo apt-get install -y vulkan-tools libvulkan1 libvulkan-dev vulkan-validationlayers-dev spirv-tools - name: Build natsukashii run: | @@ -44,7 +44,10 @@ jobs: submodules: recursive - uses: msys2/setup-msys2@v2 with: - install: make git mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-vulkan-devel mingw-w64-x86_64-fmt mingw-w64-x86_64-ninja + install: + make git mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 + mingw-w64-x86_64-vulkan-devel mingw-w64-x86_64-fmt mingw-w64-x86_64-ninja + mingw-w64-x86_64-nlohmann-json - name: Build natsukashii run: | cmake \ diff --git a/.gitignore b/.gitignore index 810f048f..095860ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ *.toml *.ini -*.json *build*/ .idea/ roms/ diff --git a/resources/game_db.json b/resources/game_db.json new file mode 100644 index 00000000..079be31b --- /dev/null +++ b/resources/game_db.json @@ -0,0 +1,3110 @@ +{ + "6c180fef":{ + "name": "007 - The World Is Not Enough (USA) (v2) (Beta)" + }, + "002c3b2a":{ + "name": "007 - The World Is Not Enough (Europe) (En,Fr,De)" + }, + "26360987":{ + "name": "007 - The World Is Not Enough (USA)" + }, + "f0b6bf59":{ + "name": "007 - The World Is Not Enough (USA) (v21) (Beta)" + }, + "75a21679":{ + "name": "1080 Snowboarding (Europe) (En,Ja,Fr,De)" + }, + "08fe81c7":{ + "name": "1080 Snowboarding (Japan, USA) (En,Ja)" + }, + "3504dbd5":{ + "name": "3D Model RGB Test Program (USA) (Test Program)" + }, + "3a674026":{ + "name": "40 Winks (USA) (Proto) (2000-01-10)" + }, + "31c19633":{ + "name": "40 Winks (USA) (Aftermarket) (Unl)" + }, + "7e718143":{ + "name": "40 Winks (Europe) (En,Es,It) (Proto) (1999-10-07)" + }, + "67a789e5":{ + "name": "64 de Hakken!! Tamagotchi - Minna de Tamagotchi World (Japan)" + }, + "60a680e7":{ + "name": "64 Hanafuda - Tenshi no Yakusoku (Japan)" + }, + "742e31fb":{ + "name": "64 Oozumou (Japan)" + }, + "c1bc6fd8":{ + "name": "64 Oozumou 2 (Japan)" + }, + "dca7f4eb":{ + "name": "64 Trump Collection - Alice no Wakuwaku Trump World (Japan)" + }, + "c992dfb4":{ + "name": "Action Replay Pro 64 (Europe) (v3.0) (Unl)" + }, + "9fbabfda":{ + "name": "Action Replay Pro 64 (Europe) (v3.3) (Unl)" + }, + "6a2b08da":{ + "name": "AeroFighters Assault (Europe) (En,Fr,De)" + }, + "4370d7e3":{ + "name": "AeroFighters Assault (USA)" + }, + "040b0046":{ + "name": "AeroGauge (Europe) (En,Fr,De)" + }, + "6ee3b932":{ + "name": "AeroGauge (Japan) (Demo) (Kiosk)" + }, + "f322b641":{ + "name": "AeroGauge (Japan) (Rev 1)" + }, + "198b9e0e":{ + "name": "AeroGauge (USA)" + }, + "86df90e6":{ + "name": "AI Shougi 3 (Japan)" + }, + "be7e230d":{ + "name": "Aidyn Chronicles - The First Mage (Europe)" + }, + "b1f18186":{ + "name": "Aidyn Chronicles - The First Mage (USA)" + }, + "d5051096":{ + "name": "Aidyn Chronicles - The First Mage (USA) (Rev 1)" + }, + "c46d84a0":{ + "name": "Aidyn Chronicles - The First Mage (USA) (Beta) (2000-02-10)" + }, + "abd43f3f":{ + "name": "Aidyn Chronicles - The First Mage (USA) (Beta) (2000-05-09)" + }, + "58fcb771":{ + "name": "Air Boarder 64 (Japan)" + }, + "c14d45ac":{ + "name": "Airboarder 64 (Europe)" + }, + "e349cfec":{ + "name": "Akumajou Dracula Mokushiroku - Real Action Adventure (Japan)" + }, + "ff009c21":{ + "name": "Akumajou Dracula Mokushiroku Gaiden - Legend of Cornell (Japan)" + }, + "996e845f":{ + "name": "All Star Tennis '99 (Europe) (En,Fr,De,Es,It)" + }, + "a7dcf638":{ + "name": "All Star Tennis 99 (USA)" + }, + "d3c29aa4":{ + "name": "All-Star Baseball 2000 (Europe)" + }, + "69e88471":{ + "name": "All-Star Baseball 2000 (USA)" + }, + "4d659e85":{ + "name": "All-Star Baseball 2001 (USA)" + }, + "d0de3584":{ + "name": "All-Star Baseball 99 (Europe)" + }, + "6d25b36f":{ + "name": "All-Star Baseball 99 (USA)" + }, + "600bc49e":{ + "name": "Armorines - Project S.W.A.R.M. (Europe)" + }, + "5bab9100":{ + "name": "Armorines - Project S.W.A.R.M. (Germany)" + }, + "630a19e2":{ + "name": "Armorines - Project S.W.A.R.M. (USA)" + }, + "1952cc87":{ + "name": "Army Men - Air Combat (USA)" + }, + "e79048e2":{ + "name": "Army Men - Sarge's Heroes (Europe) (En,Fr,De)" + }, + "2fe786f6":{ + "name": "Army Men - Sarge's Heroes (USA)" + }, + "79a71608":{ + "name": "Army Men - Sarge's Heroes 2 (USA)" + }, + "f5ce3d91":{ + "name": "Asteroids Hyper 64 (USA)" + }, + "3baf58d5":{ + "name": "Automobili Lamborghini (Europe)" + }, + "a4374eac":{ + "name": "Automobili Lamborghini (USA)" + }, + "22f54a52":{ + "name": "Baku Bomberman (Japan)" + }, + "86bbc278":{ + "name": "Baku Bomberman 2 (Japan)" + }, + "6ab7fec6":{ + "name": "Bakuretsu Muteki Bangaioh (Japan)" + }, + "ef8c2f34":{ + "name": "Bakushou Jinsei 64 - Mezase! Resort Ou (Japan)" + }, + "8f7c9324":{ + "name": "Banjo to Kazooie no Daibouken (Japan)" + }, + "258c58d0":{ + "name": "Banjo to Kazooie no Daibouken 2 (Japan)" + }, + "525899c9":{ + "name": "Banjo-Kazooie (Europe) (En,Fr,De)" + }, + "ad429961":{ + "name": "Banjo-Kazooie (USA)" + }, + "fb7ffb10":{ + "name": "Banjo-Kazooie (USA) (Rev 1)" + }, + "2736266a":{ + "name": "Banjo-Tooie (Australia)" + }, + "1ec12f5a":{ + "name": "Banjo-Tooie (Europe) (En,Fr,De,Es)" + }, + "bab803ef":{ + "name": "Banjo-Tooie (USA)" + }, + "383b86ef":{ + "name": "Bass Rush - ECOGEAR PowerWorm Championship (Japan)" + }, + "6b09092e":{ + "name": "Bassmasters 2000 (USA)" + }, + "86f8e439":{ + "name": "Bassmasters 2000 (USA) (Beta)" + }, + "35299f9c":{ + "name": "Batman Beyond - Return of the Joker (USA)" + }, + "82a4bb8a":{ + "name": "Batman of the Future - Return of the Joker (Europe) (En,Fr,De)" + }, + "6c230765":{ + "name": "BattleTanx (USA)" + }, + "c99c6030":{ + "name": "BattleTanx - Global Assault (Europe) (En,Fr,De)" + }, + "31beb053":{ + "name": "BattleTanx - Global Assault (USA)" + }, + "736f9d5c":{ + "name": "Battlezone - Rise of the Black Dogs (USA)" + }, + "5b6c6e4c":{ + "name": "Beetle Adventure Racing! (Europe) (En,Fr,De)" + }, + "49e75825":{ + "name": "Beetle Adventure Racing! (Japan)" + }, + "f4a97c73":{ + "name": "Beetle Adventure Racing! (USA) (En,Fr,De)" + }, + "3ac924bc":{ + "name": "Big Mountain 2000 (USA)" + }, + "2c4eb906":{ + "name": "Bio F.R.E.A.K.S. (Europe)" + }, + "dfbf448c":{ + "name": "Bio F.R.E.A.K.S. (USA)" + }, + "4f9d569f":{ + "name": "Biohazard 2 (Japan)" + }, + "4c820695":{ + "name": "Blast Corps (Europe) (En,De)" + }, + "767a95e7":{ + "name": "Blast Corps (USA)" + }, + "9cbbccf1":{ + "name": "Blast Corps (USA) (Rev 1)" + }, + "081a3641":{ + "name": "Blastdozer (Japan)" + }, + "8fb41658":{ + "name": "Blues Brothers 2000 (Europe) (En,Fr,De,Es,It,Nl)" + }, + "c6f49764":{ + "name": "Blues Brothers 2000 (USA)" + }, + "1ac60460":{ + "name": "Blues Brothers 2000 (Europe) (En,Fr,De,Es,It,Nl) (Beta) (2000-01-15) (#20)" + }, + "bb1ca04d":{ + "name": "Blues Brothers 2000 (Europe) (En,Fr,De,Es,It,Nl) (Beta) (2000-01-15) (#53)" + }, + "6a04cdae":{ + "name": "Body Harvest (Europe) (En,Fr,De)" + }, + "fabbdf02":{ + "name": "Body Harvest (USA)" + }, + "f97237c7":{ + "name": "Bokujou Monogatari 2 (Japan)" + }, + "20fd2939":{ + "name": "Bokujou Monogatari 2 (Japan) (Rev 1)" + }, + "9181c1b7":{ + "name": "Bokujou Monogatari 2 (Japan) (Rev 2)" + }, + "525339c5":{ + "name": "Bomberman 64 (Europe)" + }, + "cb9bd3f5":{ + "name": "Bomberman 64 (Japan)" + }, + "3ed0e0dc":{ + "name": "Bomberman 64 (USA)" + }, + "57550007":{ + "name": "Bomberman 64 - The Second Attack! (USA)" + }, + "59e39947":{ + "name": "Bomberman Hero (Europe)" + }, + "2cc2e634":{ + "name": "Bomberman Hero (USA)" + }, + "69ceabcc":{ + "name": "Bomberman Hero - Mirian Oujo o Sukue! (Japan)" + }, + "1844c8ca":{ + "name": "Bottom of the 9th (USA)" + }, + "80d70173":{ + "name": "Brunswick Circuit Pro Bowling (USA)" + }, + "e26192ab":{ + "name": "Buck Bumble (Europe) (En,Fr,De,Es,It)" + }, + "2ed81a65":{ + "name": "Buck Bumble (Japan)" + }, + "8ec937db":{ + "name": "Buck Bumble (USA)" + }, + "791881d4":{ + "name": "Bug's Life, A (Europe)" + }, + "e5429094":{ + "name": "Bug's Life, A (France)" + }, + "15a32836":{ + "name": "Bug's Life, A (Germany)" + }, + "2d118764":{ + "name": "Bug's Life, A (Italy)" + }, + "cf2ea0b6":{ + "name": "Bug's Life, A (USA)" + }, + "c285fc69":{ + "name": "Bust-A-Move '99 (USA)" + }, + "04731bab":{ + "name": "Bust-A-Move 2 - Arcade Edition (Europe)" + }, + "9f54cd2d":{ + "name": "Bust-A-Move 2 - Arcade Edition (USA)" + }, + "95595889":{ + "name": "Bust-A-Move 3 DX (Europe)" + }, + "6f6262cb":{ + "name": "California Speed (USA)" + }, + "d913b95f":{ + "name": "California Speed (Europe) (Proto)" + }, + "8569f1a0":{ + "name": "Carmageddon 64 (Europe) (En,Fr,De,Es)" + }, + "8036f999":{ + "name": "Carmageddon 64 (Europe) (En,Fr,Es,It)" + }, + "10c6a0a1":{ + "name": "Carmageddon 64 (USA)" + }, + "3d9f8d32":{ + "name": "Carnivale - Cenzo's Adventure (USA) (Proto)" + }, + "d9d76235":{ + "name": "Castlevania (Europe) (En,Fr,De)" + }, + "8b0d3c00":{ + "name": "Castlevania (USA)" + }, + "83032d97":{ + "name": "Castlevania (USA) (Rev 2)" + }, + "274d3493":{ + "name": "Castlevania (USA) (Rev 1)" + }, + "12ab9b45":{ + "name": "Castlevania - Legacy of Darkness (Europe) (En,Fr,De)" + }, + "ab13028c":{ + "name": "Castlevania - Legacy of Darkness (USA)" + }, + "b1d26f39":{ + "name": "Centre Court Tennis (Europe)" + }, + "587dd983":{ + "name": "Chameleon Twist (Europe)" + }, + "6395c475":{ + "name": "Chameleon Twist (Japan)" + }, + "7fe024c9":{ + "name": "Chameleon Twist (USA)" + }, + "7ff42fd0":{ + "name": "Chameleon Twist (USA) (Rev 1)" + }, + "3b53519f":{ + "name": "Chameleon Twist 2 (Europe)" + }, + "08287cc8":{ + "name": "Chameleon Twist 2 (Japan)" + }, + "cdf26d67":{ + "name": "Chameleon Twist 2 (USA)" + }, + "82c1d9e1":{ + "name": "Charlie Blast's Territory (Europe)" + }, + "531f98b5":{ + "name": "Charlie Blast's Territory (USA)" + }, + "c1dcd7ab":{ + "name": "Chopper Attack (Europe)" + }, + "aa5d76a9":{ + "name": "Chopper Attack (USA)" + }, + "231f9284":{ + "name": "Choro Q 64 (Japan)" + }, + "5c565ad6":{ + "name": "Choro Q 64 2 - Hacha Mecha Grand Prix Race (Japan)" + }, + "5f75634e":{ + "name": "Chou Kuukan Nighter Pro Yakyuu King (Japan)" + }, + "479643e2":{ + "name": "Chou Kuukan Nighter Pro Yakyuu King 2 (Japan)" + }, + "dd4e84e4":{ + "name": "Chou Snobo Kids (Japan)" + }, + "e272bdf6":{ + "name": "City-Tour GP - Zen-Nihon GT Senshuken (Japan)" + }, + "434de656":{ + "name": "Clay Fighter - Sculptor's Cut (USA)" + }, + "82263e5d":{ + "name": "Clay Fighter 63 1-3 (Europe)" + }, + "3fa647dd":{ + "name": "Clay Fighter 63 1-3 (USA)" + }, + "18f4166a":{ + "name": "Clay Fighter 63 1-3 (USA) (Beta) (1997-08-21)" + }, + "f3da8a26":{ + "name": "Command & Conquer (Europe) (En,Fr)" + }, + "6cd0fc99":{ + "name": "Command & Conquer (Germany)" + }, + "3e9069ef":{ + "name": "Command & Conquer (USA)" + }, + "4667cfe9":{ + "name": "Conker's Bad Fur Day (Europe)" + }, + "ce8cc172":{ + "name": "Conker's Bad Fur Day (USA)" + }, + "e1cda95a":{ + "name": "Conker's Bad Fur Day (USA) (Beta) (ECTS 2000) (2000-08-26)" + }, + "4f73408c":{ + "name": "Conker's Bad Fur Day (USA) (Beta) (2000-10-25)" + }, + "e5828a7f":{ + "name": "Controller Kensa-ki NUS-yo N Cassette (Japan) (Test Program)" + }, + "867a2ced":{ + "name": "Cruis'n Exotica (USA)" + }, + "8935a8d9":{ + "name": "Cruis'n USA (Europe)" + }, + "5238b727":{ + "name": "Cruis'n USA (USA)" + }, + "4655ba2d":{ + "name": "Cruis'n USA (USA) (Rev 1)" + }, + "c3b52701":{ + "name": "Cruis'n USA (USA) (Rev 2)" + }, + "8fc564f9":{ + "name": "Cruis'n USA (USA) (Wii Virtual Console)" + }, + "e46ce079":{ + "name": "Cruis'n World (Europe)" + }, + "a123769f":{ + "name": "Cruis'n World (USA)" + }, + "ebaed1f9":{ + "name": "Cruis'n World (Europe) (Rev 1)" + }, + "f2fae693":{ + "name": "Custom Robo (Japan)" + }, + "c8201454":{ + "name": "Custom Robo V2 (Japan)" + }, + "7319d9af":{ + "name": "CyberTiger (Europe)" + }, + "10cc5f15":{ + "name": "CyberTiger (USA)" + }, + "c61f6bb9":{ + "name": "Daffy Duck Starring as Duck Dodgers (Europe) (En,Fr,De,Es,It,Nl)" + }, + "43ee0117":{ + "name": "Dance Dance Revolution - Disney Dancing Museum (Japan)" + }, + "d2a19c71":{ + "name": "Dark Rift (Europe)" + }, + "83fd222f":{ + "name": "Dark Rift (USA)" + }, + "3db8130e":{ + "name": "Deadly Arts (USA)" + }, + "e7ef60e8":{ + "name": "Defi au Tetris Magique (France)" + }, + "7bfc71e0":{ + "name": "Densha de Go! 64 (Japan)" + }, + "a9417994":{ + "name": "Derby Stallion 64 (Japan)" + }, + "8ec950a9":{ + "name": "Derby Stallion 64 (Japan) (Beta) [b]" + }, + "7ad9e429":{ + "name": "Destruction Derby 64 (Europe) (En,Fr,De)" + }, + "38f1b5d9":{ + "name": "Destruction Derby 64 (USA)" + }, + "9e978488":{ + "name": "Dezaemon 3D (Japan)" + }, + "4a13323c":{ + "name": "Diddy Kong Racing (Europe) (En,Fr,De)" + }, + "b1e87639":{ + "name": "Diddy Kong Racing (Europe) (En,Fr,De) (Rev 1)" + }, + "b566fb94":{ + "name": "Diddy Kong Racing (Japan)" + }, + "eb759206":{ + "name": "Diddy Kong Racing (USA) (En,Fr)" + }, + "5acca298":{ + "name": "Diddy Kong Racing (USA) (En,Fr) (Rev 1)" + }, + "5e826037":{ + "name": "Die Hard 64 (USA) (Proto) (Level 1)" + }, + "d1d593cf":{ + "name": "Die Hard 64 (USA) (Proto) (Level 2)" + }, + "70943925":{ + "name": "Die Hard 64 (USA) (Proto) (Level 3)" + }, + "a7daf9fa":{ + "name": "Dinosaur Planet (USA) (Proto) (2000-12-01)" + }, + "0075d32b":{ + "name": "Donald Duck - Goin' Quackers (USA) (En,Fr,De,Es,It)" + }, + "e6220482":{ + "name": "Donald Duck - Quack Attack (Europe) (En,Fr,De,Es,It)" + }, + "a28c71c6":{ + "name": "Donkey Kong 64 (Europe) (En,Fr,De,Es)" + }, + "919f7e74":{ + "name": "Donkey Kong 64 (Japan)" + }, + "d44b4fc6":{ + "name": "Donkey Kong 64 (USA)" + }, + "c83dfa15":{ + "name": "Donkey Kong 64 (USA) (Demo) (Kiosk)" + }, + "d985c356":{ + "name": "Doom 64 (Europe)" + }, + "c8f3af5b":{ + "name": "Doom 64 (Japan)" + }, + "5cc1ade6":{ + "name": "Doom 64 (USA)" + }, + "1d3a17b5":{ + "name": "Doom 64 (USA) (Rev 1)" + }, + "154e8b33":{ + "name": "Doraemon - Nobita to 3tsu no Seireiseki (Japan)" + }, + "0c1a0c38":{ + "name": "Doraemon 2 - Nobita to Hikari no Shinden (Japan)" + }, + "d3b68be4":{ + "name": "Doraemon 3 - Nobita no Machi SOS! (Japan)" + }, + "6f8e3e71":{ + "name": "Doubutsu Banchou (Japan) (Proto)" + }, + "9503e3f1":{ + "name": "Doubutsu no Mori (Japan)" + }, + "a4701927":{ + "name": "Dr. Mario 64 (USA)" + }, + "55ded416":{ + "name": "Dragon Sword 64 (Europe) (Proto)" + }, + "2296b50d":{ + "name": "Dragon Sword 64 (USA) (Proto) (1999-08-25)" + }, + "5a7e226b":{ + "name": "Dual Heroes (Europe)" + }, + "20f23dde":{ + "name": "Dual Heroes (Japan)" + }, + "d09f4da8":{ + "name": "Dual Heroes (USA)" + }, + "3177a905":{ + "name": "Duck Dodgers Starring Daffy Duck (USA) (En,Fr,Es)" + }, + "1e48d155":{ + "name": "Duck Dodgers Starring Daffy Duck (USA) (En,Fr,Es) (Beta) (2000-03-07)" + }, + "ea82f037":{ + "name": "Duke Nukem - Zero Hour (Europe)" + }, + "7ecdfb28":{ + "name": "Duke Nukem - Zero Hour (France)" + }, + "9a3258d7":{ + "name": "Duke Nukem - Zero Hour (USA)" + }, + "3275adb0":{ + "name": "Duke Nukem 64 (Europe)" + }, + "b9c9f07a":{ + "name": "Duke Nukem 64 (France)" + }, + "dbfd5a53":{ + "name": "Duke Nukem 64 (USA)" + }, + "4a82d036":{ + "name": "Duke Nukem 64 (Europe) (Beta)" + }, + "61a56330":{ + "name": "Earthworm Jim 3D (Europe) (En,Fr,De,Es,It)" + }, + "9e6579c5":{ + "name": "Earthworm Jim 3D (USA)" + }, + "be8feead":{ + "name": "ECW Hardcore Revolution (Europe)" + }, + "36d368ef":{ + "name": "ECW Hardcore Revolution (USA)" + }, + "e9cf3d9f":{ + "name": "ECW Hardcore Revolution (Germany)" + }, + "0a239818":{ + "name": "ECW Hardcore Revolution (USA) (Beta)" + }, + "1699d2d6":{ + "name": "Eikou no Saint Andrews (Japan)" + }, + "24d937bf":{ + "name": "Eltale Monsters (Japan)" + }, + "0b881e60":{ + "name": "Excitebike 64 (Europe)" + }, + "03bfd065":{ + "name": "Excitebike 64 (Japan)" + }, + "fc459192":{ + "name": "Excitebike 64 (USA)" + }, + "be6298b0":{ + "name": "Excitebike 64 (USA) (Demo) (Kiosk)" + }, + "143926ce":{ + "name": "Excitebike 64 (USA) (Rev 1)" + }, + "0b71b1ea":{ + "name": "Extreme-G (Europe) (En,Fr,De,Es,It)" + }, + "750dc9a7":{ + "name": "Extreme-G (Japan)" + }, + "04cb74ec":{ + "name": "Extreme-G (USA)" + }, + "1a57f416":{ + "name": "Extreme-G XG2 (Europe) (En,Fr,De,Es,It)" + }, + "7c8a36da":{ + "name": "Extreme-G XG2 (Japan)" + }, + "81a4c28b":{ + "name": "Extreme-G XG2 (USA)" + }, + "1f4e651a":{ + "name": "F-1 World Grand Prix (Europe)" + }, + "57cd299d":{ + "name": "F-1 World Grand Prix (France)" + }, + "0f1984dc":{ + "name": "F-1 World Grand Prix (Germany)" + }, + "f7bacbc3":{ + "name": "F-1 World Grand Prix (Japan)" + }, + "7dc9ef2c":{ + "name": "F-1 World Grand Prix (USA)" + }, + "bebbc6c8":{ + "name": "F-1 World Grand Prix (Europe) (Beta)" + }, + "803d33df":{ + "name": "F-1 World Grand Prix II (Europe) (En,Fr,De,Es)" + }, + "2d6f7e8b":{ + "name": "F-Zero X (Europe)" + }, + "6b1cef83":{ + "name": "F-Zero X (Japan)" + }, + "0b561fba":{ + "name": "F-Zero X (USA)" + }, + "68fe1cec":{ + "name": "F-Zero X (USA) (Beta) (The Legend of Zelda Ocarina of Time Overdump)" + }, + "ed750623":{ + "name": "F1 Pole Position 64 (Europe) (En,Fr,De)" + }, + "30a24d89":{ + "name": "F1 Pole Position 64 (USA) (En,Fr,De)" + }, + "2da744f5":{ + "name": "F1 Racing Championship (Europe) (En,Fr,De,Es,It)" + }, + "c05b9184":{ + "name": "F1 Racing Championship (Brazil) (En,Fr)" + }, + "5a55b4c2":{ + "name": "F1 Racing Championship (USA) (Beta)" + }, + "9fb0e6c9":{ + "name": "Famista 64 (Japan)" + }, + "137cb3cc":{ + "name": "FIFA - Road to World Cup 98 (Europe) (En,Fr,De,Es,It,Nl,Sv)" + }, + "28b1221c":{ + "name": "FIFA - Road to World Cup 98 (USA) (En,Fr,De,Es,It,Nl,Sv)" + }, + "ae346df6":{ + "name": "FIFA - Road to World Cup 98 - World Cup e no Michi (Japan)" + }, + "ae2583fb":{ + "name": "FIFA 64 (Europe) (En,Fr,De)" + }, + "6eae1e6e":{ + "name": "FIFA 99 (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv)" + }, + "6b2473a9":{ + "name": "FIFA 99 (USA) (En,Fr,De,Es,It,Nl,Pt,Sv)" + }, + "57de7cab":{ + "name": "FIFA Soccer 64 (USA) (En,Fr,De)" + }, + "bb2563c6":{ + "name": "Fighter Destiny 2 (USA)" + }, + "c9225511":{ + "name": "Fighters Destiny (Europe)" + }, + "b3a034d6":{ + "name": "Fighters Destiny (France)" + }, + "5052168c":{ + "name": "Fighters Destiny (Germany)" + }, + "f45ea789":{ + "name": "Fighters Destiny (USA)" + }, + "8a1c261e":{ + "name": "Fighting Cup (Japan)" + }, + "4052c176":{ + "name": "Fighting Force 64 (Europe)" + }, + "8456841e":{ + "name": "Fighting Force 64 (USA)" + }, + "c3066e59":{ + "name": "Flying Dragon (Europe)" + }, + "91bc9aeb":{ + "name": "Flying Dragon (USA)" + }, + "5ed736d9":{ + "name": "Forsaken (Europe) (En,Fr,Es,It)" + }, + "9793abc2":{ + "name": "Forsaken (Germany)" + }, + "76c4333d":{ + "name": "Forsaken 64 (USA)" + }, + "67eaf0f3":{ + "name": "Fox Sports College Hoops '99 (USA)" + }, + "40632bec":{ + "name": "Freak Boy (Unknown) (Proto)" + }, + "a8f81f39":{ + "name": "Frogger 2 (USA) (Proto 2)" + }, + "8d62268e":{ + "name": "Frogger 2 (USA) (Proto 1)" + }, + "2aa6d2a1":{ + "name": "Fushigi no Dungeon - Fuurai no Shiren 2 - Oni Shuurai! Shiren Jou! (Japan)" + }, + "5aa63b04":{ + "name": "G.A.S.P!! Fighters' NEXTream (Europe)" + }, + "6ead2d89":{ + "name": "G.A.S.P!! Fighters' NEXTream (Japan)" + }, + "35b99bd9":{ + "name": "GameBooster 64 (Europe) (v1.1) (Unl)" + }, + "e0b8edae":{ + "name": "GameBooster 64 (USA) (v1.1) (Unl)" + }, + "ef9edf87":{ + "name": "GameShark Pro (USA) (v2.0) (Unl)" + }, + "7cc07bbc":{ + "name": "GameShark Pro (USA) (v3.3) (Unl)" + }, + "08c41e0e":{ + "name": "Ganbare Goemon - Dero Dero Douchuu Obake Tenkomori (Japan)" + }, + "2e91efc9":{ + "name": "Ganbare Goemon - Neo Momoyama Bakufu no Odori (Japan)" + }, + "73133cd2":{ + "name": "Ganbare! Nippon! Olympics 2000 (Japan)" + }, + "b7b3a489":{ + "name": "Gauntlet Legends (Europe)" + }, + "8d133db0":{ + "name": "Gauntlet Legends (Japan)" + }, + "64765e82":{ + "name": "Gauntlet Legends (USA)" + }, + "724ecae7":{ + "name": "Getter Love!! - Cho Renai Party Game Tanjou (Japan)" + }, + "6bc4a056":{ + "name": "Gex 3 - Deep Cover Gecko (Europe) (En,Es,It)" + }, + "a43cb8e4":{ + "name": "Gex 3 - Deep Cover Gecko (Europe) (Fr,De)" + }, + "87a7d099":{ + "name": "Gex 3 - Deep Cover Gecko (USA)" + }, + "a7c92bea":{ + "name": "Gex 64 - Enter the Gecko (Europe)" + }, + "c545ce80":{ + "name": "Gex 64 - Enter the Gecko (USA)" + }, + "90eceb4a":{ + "name": "Glover (Europe) (En,Fr,De)" + }, + "f874571c":{ + "name": "Glover (USA)" + }, + "7a866221":{ + "name": "Glover (USA) (Beta) (1998-07-16) [b]" + }, + "5e091e8f":{ + "name": "Glover (USA) (Proto) (1998-09-04)" + }, + "29966555":{ + "name": "Glover 2 (USA) (Proto 2)" + }, + "1a526dcd":{ + "name": "Glover 2 (USA) (Proto 1)" + }, + "965c4575":{ + "name": "Goemon - Mononoke Sugoroku (Japan)" + }, + "52d418e1":{ + "name": "Goemon's Great Adventure (USA)" + }, + "70594d3c":{ + "name": "Golden Nugget 64 (USA)" + }, + "9ec14aeb":{ + "name": "GoldenEye 007 (Europe)" + }, + "a6be19dd":{ + "name": "GoldenEye 007 (Japan)" + }, + "b6330846":{ + "name": "GoldenEye 007 (USA)" + }, + "6dfb4747":{ + "name": "GT 64 - Championship Edition (Europe) (En,Fr,De)" + }, + "bc627da7":{ + "name": "GT 64 - Championship Edition (USA)" + }, + "191bf504":{ + "name": "GT 64 - Championship Edition (USA) (Beta) (1998-05-25)" + }, + "c1d98b78":{ + "name": "Hamster Monogatari 64 (Japan)" + }, + "51228f0c":{ + "name": "Harukanaru Augusta - Masters '98 (Japan)" + }, + "decdc0ad":{ + "name": "Harvest Moon 64 (USA)" + }, + "99a427fa":{ + "name": "Heiwa Pachinko World 64 (Japan)" + }, + "b1954b08":{ + "name": "Hercules - The Legendary Journeys (Europe) (En,Fr,De,Es,It,Nl)" + }, + "4948892b":{ + "name": "Hercules - The Legendary Journeys (USA)" + }, + "a7759499":{ + "name": "Hercules - The Legendary Journeys (Unknown) (Beta)" + }, + "5369efb4":{ + "name": "Hexen (Europe)" + }, + "e373fa31":{ + "name": "Hexen (France)" + }, + "e4821c4b":{ + "name": "Hexen (Germany)" + }, + "571da09a":{ + "name": "Hexen (Japan)" + }, + "1d35e110":{ + "name": "Hexen (USA)" + }, + "b18b2734":{ + "name": "Hey You, Pikachu! (USA)" + }, + "ba6a687e":{ + "name": "Hiryuu no Ken Twin (Japan)" + }, + "84ff9890":{ + "name": "Holy Magic Century (Europe)" + }, + "284170ed":{ + "name": "Holy Magic Century (France)" + }, + "d1934cf6":{ + "name": "Holy Magic Century (Germany)" + }, + "ae7cb69d":{ + "name": "Hoshi no Kirby 64 (Japan)" + }, + "a263c1b9":{ + "name": "Hoshi no Kirby 64 (Japan) (Rev 1)" + }, + "f4589aa8":{ + "name": "Hoshi no Kirby 64 (Japan) (Rev 2)" + }, + "6d5e1332":{ + "name": "Hoshi no Kirby 64 (Japan) (Rev 3)" + }, + "850633a7":{ + "name": "Hot Wheels - Turbo Racing (Europe) (En,Fr,De)" + }, + "a5c92148":{ + "name": "Hot Wheels - Turbo Racing (USA)" + }, + "c0ba9440":{ + "name": "HSV Adventure Racing! (Australia)" + }, + "31e102e3":{ + "name": "Human Grand Prix - The New Generation (Japan)" + }, + "e76627ff":{ + "name": "Hybrid Heaven (Europe) (En,Fr,De)" + }, + "e769de96":{ + "name": "Hybrid Heaven (Japan)" + }, + "15b57ef8":{ + "name": "Hybrid Heaven (USA)" + }, + "863ab8f3":{ + "name": "Hydro Thunder (Europe)" + }, + "010f6242":{ + "name": "Hydro Thunder (France)" + }, + "e744456f":{ + "name": "Hydro Thunder (USA)" + }, + "c1ea5d33":{ + "name": "Hyper Olympics in Nagano 64 (Japan)" + }, + "dbd96deb":{ + "name": "Ide Yosuke no Mahjong Juku (Japan)" + }, + "26cc1266":{ + "name": "Iggy-kun no Bura Bura Poyon (Japan)" + }, + "9bf26065":{ + "name": "Iggy's Reckin' Balls (Europe)" + }, + "6a6fbd5d":{ + "name": "Iggy's Reckin' Balls (USA)" + }, + "00da3704":{ + "name": "In-Fisherman - Bass Hunter 64 (Europe)" + }, + "d8eb5e6e":{ + "name": "In-Fisherman - Bass Hunter 64 (USA)" + }, + "4978eb57":{ + "name": "Indiana Jones and the Infernal Machine (USA)" + }, + "337219be":{ + "name": "Indiana Jones and the Infernal Machine (Australia) (Proto)" + }, + "a5163f29":{ + "name": "Indy Racing 2000 (USA)" + }, + "bf23945d":{ + "name": "International Superstar Soccer '98 (Europe)" + }, + "b85fa721":{ + "name": "International Superstar Soccer '98 (USA)" + }, + "a63dcb66":{ + "name": "International Superstar Soccer '98 (Europe) (Beta) (1998-03-02)" + }, + "69572558":{ + "name": "International Superstar Soccer 2000 (Europe) (En,De)" + }, + "8a16a6a9":{ + "name": "International Superstar Soccer 2000 (Europe) (Fr,It)" + }, + "dcd0538f":{ + "name": "International Superstar Soccer 2000 (USA) (En,Es)" + }, + "4c433fdd":{ + "name": "International Superstar Soccer 2000 (USA) (En,Es) (Rev 1)" + }, + "8c839268":{ + "name": "International Superstar Soccer 64 (Europe)" + }, + "0ea249b9":{ + "name": "International Superstar Soccer 64 (USA)" + }, + "b3181ee0":{ + "name": "International Track & Field - Summer Games (Europe) (En,Fr,De)" + }, + "da443f0b":{ + "name": "International Track & Field 2000 (USA)" + }, + "576915d4":{ + "name": "Itoi Shigesato no Bass Tsuri No. 1 Kettei Ban! (Japan)" + }, + "dc0b2c8f":{ + "name": "J.League Dynamite Soccer 64 (Japan)" + }, + "7d0eed6a":{ + "name": "J.League Eleven Beat 1997 (Japan)" + }, + "4c536dd7":{ + "name": "J.League Live 64 (Japan)" + }, + "976a2d12":{ + "name": "J.League Tactics Soccer (Japan)" + }, + "156e705e":{ + "name": "J.League Tactics Soccer (Japan) (Rev 1)" + }, + "d1c1681e":{ + "name": "Jangou Simulation Mahjong Dou 64 (Japan)" + }, + "e739947c":{ + "name": "Jeopardy! (USA)" + }, + "5bf42ec4":{ + "name": "Jeremy McGrath Supercross 2000 (Europe)" + }, + "2a5c9a06":{ + "name": "Jeremy McGrath Supercross 2000 (USA)" + }, + "cfbed88c":{ + "name": "Jet Force Gemini (Europe) (En,Fr,De,Es)" + }, + "6753d5a3":{ + "name": "Jet Force Gemini (USA)" + }, + "fa061b96":{ + "name": "Jet Force Gemini (USA) (Demo) (Kiosk)" + }, + "0a796c3e":{ + "name": "Jikkyou G1 Stable (Japan)" + }, + "6fc0a31b":{ + "name": "Jikkyou G1 Stable (Japan) (Rev 1)" + }, + "2ef647d3":{ + "name": "Jikkyou J.League 1999 - Perfect Striker 2 (Japan)" + }, + "f96c2be1":{ + "name": "Jikkyou J.League 1999 - Perfect Striker 2 (Japan) (Rev 1)" + }, + "8ed60dea":{ + "name": "Jikkyou J.League Perfect Striker (Japan)" + }, + "6a9e24d7":{ + "name": "Jikkyou Powerful Pro Yakyuu - Basic Ban 2001 (Japan)" + }, + "bc7ef5c1":{ + "name": "Jikkyou Powerful Pro Yakyuu - Basic Ban 2001 (Japan) (Rev 1)" + }, + "351cde48":{ + "name": "Jikkyou Powerful Pro Yakyuu 2000 (Japan)" + }, + "753706ef":{ + "name": "Jikkyou Powerful Pro Yakyuu 2000 (Japan) (Rev 1)" + }, + "480b953e":{ + "name": "Jikkyou Powerful Pro Yakyuu 4 (Japan)" + }, + "40e3ac61":{ + "name": "Jikkyou Powerful Pro Yakyuu 4 (Japan) (Rev 1)" + }, + "1b8b9a68":{ + "name": "Jikkyou Powerful Pro Yakyuu 4 (Japan) (Beta) (1996-11-30)" + }, + "feec34f6":{ + "name": "Jikkyou Powerful Pro Yakyuu 5 (Japan)" + }, + "c02fd9be":{ + "name": "Jikkyou Powerful Pro Yakyuu 5 (Japan) (Rev 2)" + }, + "7994c2fe":{ + "name": "Jikkyou Powerful Pro Yakyuu 5 (Japan) (Rev 1)" + }, + "1e53a7ba":{ + "name": "Jikkyou Powerful Pro Yakyuu 6 (Japan)" + }, + "7ab7ebf4":{ + "name": "Jikkyou Powerful Pro Yakyuu 6 (Japan) (Rev 1)" + }, + "fcc10356":{ + "name": "Jikkyou Powerful Pro Yakyuu 6 (Japan) (Rev 2)" + }, + "5c721850":{ + "name": "Jikkyou World Soccer - World Cup France '98 (Japan)" + }, + "68dbcc04":{ + "name": "Jikkyou World Soccer - World Cup France '98 (Japan) (Rev 1)" + }, + "f63f9a5e":{ + "name": "Jikkyou World Soccer - World Cup France '98 (Japan) (Rev 2)" + }, + "3ba9e644":{ + "name": "Jikkyou World Soccer 3 (Japan)" + }, + "e6bd65d5":{ + "name": "Jikuu Senshi Turok (Japan)" + }, + "67a1a22c":{ + "name": "Jinsei Game 64 (Japan)" + }, + "f88ac3ce":{ + "name": "John Romero's Daikatana (Europe) (En,Fr,De)" + }, + "44b80fd7":{ + "name": "John Romero's Daikatana (Japan)" + }, + "494950c6":{ + "name": "John Romero's Daikatana (USA)" + }, + "db40a155":{ + "name": "Kakutou Denshou - F-Cup Maniax (Japan)" + }, + "12d8f3e9":{ + "name": "Ken Griffey Jr.'s Slugfest (USA)" + }, + "5d0ee5d2":{ + "name": "Killer Instinct Gold (Europe)" + }, + "31c76be7":{ + "name": "Killer Instinct Gold (USA)" + }, + "49ef8f2b":{ + "name": "Killer Instinct Gold (USA) (Rev 1)" + }, + "0b5b5df8":{ + "name": "Killer Instinct Gold (USA) (Rev 2)" + }, + "f120cc52":{ + "name": "King Hill 64 - Extreme Snowboarding (Japan)" + }, + "7fdc3784":{ + "name": "Kiratto Kaiketsu! 64 Tanteidan (Japan)" + }, + "5b8b89ef":{ + "name": "Kirby 64 - The Crystal Shards (Europe)" + }, + "20a1c120":{ + "name": "Kirby 64 - The Crystal Shards (USA)" + }, + "b77783be":{ + "name": "Knife Edge - Nose Gunner (Europe)" + }, + "3bc93017":{ + "name": "Knife Edge - Nose Gunner (Japan)" + }, + "255ee1dd":{ + "name": "Knife Edge - Nose Gunner (USA)" + }, + "58ce7d80":{ + "name": "Knockout Kings 2000 (Europe)" + }, + "074690d6":{ + "name": "Knockout Kings 2000 (USA)" + }, + "1355a826":{ + "name": "Kobe Bryant in NBA Courtside (Europe)" + }, + "86360bfb":{ + "name": "Kobe Bryant in NBA Courtside (USA)" + }, + "9db99881":{ + "name": "Last Legion UX (Japan)" + }, + "9ead1608":{ + "name": "Legend of Zelda, The - Majora's Mask (Europe) (En,Fr,De,Es)" + }, + "e2e6823d":{ + "name": "Legend of Zelda, The - Majora's Mask (Europe) (En,Fr,De,Es) (Rev 1)" + }, + "b428d8a7":{ + "name": "Legend of Zelda, The - Majora's Mask (USA)" + }, + "dcc110a0":{ + "name": "Legend of Zelda, The - Majora's Mask (USA) (Demo) (Kiosk)" + }, + "04ea55ea":{ + "name": "Legend of Zelda, The - Majora's Mask (Europe) (En,Fr,De,Es) (Rev 1) (Debug)" + }, + "b008458f":{ + "name": "Legend of Zelda, The - Majora's Mask (USA) (GameCube)" + }, + "12836e19":{ + "name": "Legend of Zelda, The - Majora's Mask (Europe) (GameCube)" + }, + "a83abf72":{ + "name": "Legend of Zelda, The - Majora's Mask (Europe) (En,Fr,De,Es) (Rev 1) (Wii Virtual Console)" + }, + "946fd0f7":{ + "name": "Legend of Zelda, The - Ocarina of Time (Europe) (En,Fr,De)" + }, + "a108f6e3":{ + "name": "Legend of Zelda, The - Ocarina of Time (Europe) (En,Fr,De) (Rev 1)" + }, + "cd16c529":{ + "name": "Legend of Zelda, The - Ocarina of Time (USA)" + }, + "3fd2151e":{ + "name": "Legend of Zelda, The - Ocarina of Time (USA) (Rev 1)" + }, + "32120c23":{ + "name": "Legend of Zelda, The - Ocarina of Time (USA) (Rev 2)" + }, + "346de3ae":{ + "name": "Legend of Zelda, The - Ocarina of Time (USA) (GameCube)" + }, + "3fbd519f":{ + "name": "Legend of Zelda, The - Ocarina of Time (Europe) (GameCube)" + }, + "5d1b2996":{ + "name": "Legend of Zelda, The - Ocarina of Time (Europe) (Debug) (GameCube)" + }, + "c188acda":{ + "name": "Legend of Zelda, The - Ocarina of Time (Europe) (Beta) (2003-02-13) (GameCube)" + }, + "6c348aa8":{ + "name": "Legend of Zelda, The - Ocarina of Time (USA) (Beta)" + }, + "a1d34e08":{ + "name": "Legend of Zelda, The - Ocarina of Time - Master Quest (Europe) (Debug) (GameCube)" + }, + "c744c4db":{ + "name": "Legend of Zelda, The - Ocarina of Time - Master Quest (USA) (GameCube)" + }, + "832d6449":{ + "name": "Legend of Zelda, The - Ocarina of Time - Master Quest (Europe) (GameCube)" + }, + "c7d9b21c":{ + "name": "LEGO Racers (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi)" + }, + "4d1e1897":{ + "name": "LEGO Racers (USA) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi)" + }, + "455a1770":{ + "name": "Let's Smash (Japan)" + }, + "7148251d":{ + "name": "Lode Runner 3-D (Europe) (En,Fr,De,Es,It)" + }, + "1d4fb466":{ + "name": "Lode Runner 3-D (Japan)" + }, + "4ea07453":{ + "name": "Lode Runner 3-D (USA)" + }, + "9a3425da":{ + "name": "Lylat Wars (Australia) (En,Fr,De)" + }, + "50a9c0b1":{ + "name": "Lylatwars (Europe) (En,Fr,De)" + }, + "57ddede1":{ + "name": "Mace - The Dark Age (Europe)" + }, + "d2a363a6":{ + "name": "Mace - The Dark Age (USA)" + }, + "2b23212f":{ + "name": "Mace - The Dark Age (USA) (Beta)" + }, + "fab3e50d":{ + "name": "Madden Football 64 (Europe)" + }, + "42e5fafa":{ + "name": "Madden Football 64 (USA)" + }, + "ef5f997b":{ + "name": "Madden NFL 2000 (USA)" + }, + "245eaee8":{ + "name": "Madden NFL 2001 (USA)" + }, + "f573f107":{ + "name": "Madden NFL 2002 (USA)" + }, + "d0929942":{ + "name": "Madden NFL 99 (Europe)" + }, + "2eb64fc2":{ + "name": "Madden NFL 99 (USA)" + }, + "033a2ca6":{ + "name": "Madden NFL 99 (USA) (Beta) (1998-08-05)" + }, + "56769a44":{ + "name": "Madden NFL 99 (USA) (Rev 1)" + }, + "af3b099e":{ + "name": "Magical Tetris Challenge (Europe)" + }, + "377f18e9":{ + "name": "Magical Tetris Challenge (Germany)" + }, + "22fe979c":{ + "name": "Magical Tetris Challenge (USA)" + }, + "7efb2f1e":{ + "name": "Magical Tetris Challenge featuring Mickey (Japan)" + }, + "dbe7d51a":{ + "name": "Mahjong 64 (Japan)" + }, + "990a8e54":{ + "name": "Mahjong Hourouki Classic (Japan)" + }, + "b68d596f":{ + "name": "Mahjong Master (Japan)" + }, + "e08f7578":{ + "name": "Major League Baseball Featuring Ken Griffey Jr. (Australia)" + }, + "2ef1ea20":{ + "name": "Major League Baseball Featuring Ken Griffey Jr. (USA)" + }, + "a5071a77":{ + "name": "Mario Golf (Europe)" + }, + "2fc4c216":{ + "name": "Mario Golf (USA)" + }, + "bb03a1a6":{ + "name": "Mario Golf 64 (Japan)" + }, + "ad1758ac":{ + "name": "Mario Golf 64 (Japan) (Rev 1)" + }, + "faa6b083":{ + "name": "Mario Kart 64 (Europe)" + }, + "0248f6c3":{ + "name": "Mario Kart 64 (Europe) (Rev 1)" + }, + "5d9696df":{ + "name": "Mario Kart 64 (Japan)" + }, + "6ced6472":{ + "name": "Mario Kart 64 (Japan) (Rev 1)" + }, + "434389c1":{ + "name": "Mario Kart 64 (USA)" + }, + "176b3683":{ + "name": "Mario no Photopie (Japan)" + }, + "da98a5d3":{ + "name": "Mario Party (Europe) (En,Fr,De)" + }, + "4f1adc7b":{ + "name": "Mario Party (Japan)" + }, + "4d60abe5":{ + "name": "Mario Party (USA)" + }, + "dc00357a":{ + "name": "Mario Party 2 (Europe) (En,Fr,De,Es,It)" + }, + "7457b081":{ + "name": "Mario Party 2 (Japan)" + }, + "e58a1955":{ + "name": "Mario Party 2 (USA)" + }, + "dca66040":{ + "name": "Mario Party 2 (Europe) (En,Fr,De,Es,It) (Wii Virtual Console)" + }, + "fdc89220":{ + "name": "Mario Party 2 (Japan) (Wii Virtual Console)" + }, + "6f45853e":{ + "name": "Mario Party 2 (USA) (Wii Virtual Console)" + }, + "813b13f2":{ + "name": "Mario Party 3 (Europe) (En,Fr,De,Es)" + }, + "3fc04053":{ + "name": "Mario Party 3 (Japan)" + }, + "b7445ddc":{ + "name": "Mario Party 3 (USA)" + }, + "697c1777":{ + "name": "Mario Party 3 (USA) (Beta)" + }, + "bd60ca66":{ + "name": "Mario Story (Japan)" + }, + "29aa5df4":{ + "name": "Mario Tennis (Europe)" + }, + "4e9560f6":{ + "name": "Mario Tennis (USA)" + }, + "e9ba8e6b":{ + "name": "Mario Tennis (Europe) (Wii Virtual Console)" + }, + "8e85b369":{ + "name": "Mario Tennis (USA) (Wii Virtual Console)" + }, + "c665301d":{ + "name": "Mario Tennis 64 (Japan)" + }, + "32c58af3":{ + "name": "Mario Tennis 64 (Japan) (Wii Virtual Console)" + }, + "1bfc71f0":{ + "name": "Mega Man 64 (USA)" + }, + "d3562b57":{ + "name": "Mega Man 64 (USA) (Beta)" + }, + "2db3d3d6":{ + "name": "Mia Hamm Soccer 64 (USA) (En,Es)" + }, + "bb680cbe":{ + "name": "Michael Owen's WLS 2000 (Europe)" + }, + "1aecfc56":{ + "name": "Mickey no Racing Challenge USA (Japan)" + }, + "0ae51ea5":{ + "name": "Mickey's Speedway USA (Europe) (En,Fr,De,Es,It)" + }, + "2d4f8f1b":{ + "name": "Mickey's Speedway USA (USA)" + }, + "10b9ff1f":{ + "name": "Micro Machines 64 Turbo (Europe) (En,Fr,De,Es,It)" + }, + "a62a2763":{ + "name": "Micro Machines 64 Turbo (USA)" + }, + "e5c1fedc":{ + "name": "Midway's Greatest Arcade Hits - Volume 1 (USA)" + }, + "cc253cab":{ + "name": "Mike Piazza's Strike Zone (USA)" + }, + "c08ce624":{ + "name": "Milo's Astro Lanes (Europe)" + }, + "172fca97":{ + "name": "Milo's Astro Lanes (USA)" + }, + "f59f881b":{ + "name": "Mini Racers (USA) (Ja) (Proto)" + }, + "68a4f072":{ + "name": "Mischief Makers (Europe)" + }, + "7d222d3f":{ + "name": "Mischief Makers (USA)" + }, + "c3300cef":{ + "name": "Mischief Makers (USA) (Rev 1)" + }, + "2c7131d6":{ + "name": "Mission - Impossible (Europe)" + }, + "282a350d":{ + "name": "Mission - Impossible (France)" + }, + "67c30a2d":{ + "name": "Mission - Impossible (Germany)" + }, + "2d789d98":{ + "name": "Mission - Impossible (Italy)" + }, + "ebb060dc":{ + "name": "Mission - Impossible (Spain)" + }, + "3677a8b8":{ + "name": "Mission - Impossible (USA)" + }, + "e1c470fd":{ + "name": "Mission - Impossible (Spain) (Rev 1)" + }, + "e2bbeac1":{ + "name": "Monaco Grand Prix (USA)" + }, + "3f5e5830":{ + "name": "Monaco Grand Prix - Racing Simulation 2 (Europe) (En,Fr,Es,It)" + }, + "c8cad8f6":{ + "name": "Monopoly (USA)" + }, + "4731df5c":{ + "name": "Monster Truck Madness 64 (Europe) (En,Fr,De,Es,It)" + }, + "3fd0604d":{ + "name": "Monster Truck Madness 64 (USA)" + }, + "88c83511":{ + "name": "Morita Shougi 64 (Japan)" + }, + "635adeca":{ + "name": "Mortal Kombat 4 (Europe)" + }, + "b7f46516":{ + "name": "Mortal Kombat 4 (USA)" + }, + "ea21015a":{ + "name": "Mortal Kombat Mythologies - Sub-Zero (Europe)" + }, + "51a07fd9":{ + "name": "Mortal Kombat Mythologies - Sub-Zero (USA)" + }, + "bc04c62f":{ + "name": "Mortal Kombat Trilogy (Europe)" + }, + "50a99d60":{ + "name": "Mortal Kombat Trilogy (USA)" + }, + "0f323d00":{ + "name": "Mortal Kombat Trilogy (USA) (Rev 2)" + }, + "ba64f824":{ + "name": "Mortal Kombat Trilogy (USA) (Rev 1)" + }, + "eab22c06":{ + "name": "Mortal Kombat Trilogy (USA) (Beta) (1996-05-13)" + }, + "bc966b10":{ + "name": "MRC - Multi-Racing Championship (Europe) (En,Fr,De)" + }, + "bea43300":{ + "name": "MRC - Multi-Racing Championship (Japan)" + }, + "1dc1c812":{ + "name": "MRC - Multi-Racing Championship (USA)" + }, + "e34c7060":{ + "name": "Ms. Pac-Man - Maze Madness (USA)" + }, + "3502dbbe":{ + "name": "Mystical Ninja 2 Starring Goemon (Europe) (En,Fr,De)" + }, + "3bd9059a":{ + "name": "Mystical Ninja Starring Goemon (Europe)" + }, + "4180c296":{ + "name": "Mystical Ninja Starring Goemon (USA)" + }, + "c44de11c":{ + "name": "Nagano Winter Olympics '98 (Europe)" + }, + "ee8288d4":{ + "name": "Nagano Winter Olympics '98 (USA)" + }, + "ce361f92":{ + "name": "Namco Museum 64 (USA)" + }, + "02bf7c2d":{ + "name": "NASCAR 2000 (USA)" + }, + "76e79cea":{ + "name": "NASCAR 99 (Europe) (En,Fr,De)" + }, + "3d8eb950":{ + "name": "NASCAR 99 (USA)" + }, + "a7cc4ce2":{ + "name": "NBA Courtside 2 featuring Kobe Bryant (USA)" + }, + "7e6d00ae":{ + "name": "NBA Hangtime (Europe)" + }, + "714cf532":{ + "name": "NBA Hangtime (USA)" + }, + "aed2700a":{ + "name": "NBA in the Zone '98 (Japan)" + }, + "a245d737":{ + "name": "NBA in the Zone '98 (USA)" + }, + "eab083b8":{ + "name": "NBA in the Zone '99 (USA)" + }, + "41093b73":{ + "name": "NBA in the Zone 2 (Japan)" + }, + "a4973197":{ + "name": "NBA in the Zone 2000 (Europe)" + }, + "cbb4b730":{ + "name": "NBA in the Zone 2000 (USA)" + }, + "9f95485e":{ + "name": "NBA Jam 2000 (Europe)" + }, + "163dadf9":{ + "name": "NBA Jam 2000 (USA)" + }, + "90e4275b":{ + "name": "NBA Jam 99 (Europe)" + }, + "559cd6b1":{ + "name": "NBA Jam 99 (USA)" + }, + "0e4b944c":{ + "name": "NBA Live 2000 (Europe) (En,Fr,De,Es)" + }, + "7c3bc95e":{ + "name": "NBA Live 2000 (USA) (En,Fr,De,Es)" + }, + "a316df37":{ + "name": "NBA Live 99 (Europe) (En,Fr,De,Es,It)" + }, + "9be0a7ac":{ + "name": "NBA Live 99 (USA) (En,Fr,De,Es,It)" + }, + "04b75ccc":{ + "name": "NBA Pro 98 (Europe)" + }, + "588e60e8":{ + "name": "NBA Pro 99 (Europe)" + }, + "a4e378f4":{ + "name": "NBA Showtime - NBA on NBC (USA)" + }, + "a10a86af":{ + "name": "Neon Genesis Evangelion (Japan)" + }, + "983263d7":{ + "name": "New Tetris, The (Europe)" + }, + "528a07fa":{ + "name": "New Tetris, The (USA)" + }, + "9bcd670f":{ + "name": "NFL Blitz (USA)" + }, + "5d1907f7":{ + "name": "NFL Blitz - Special Edition (USA)" + }, + "7f471773":{ + "name": "NFL Blitz 2000 (USA)" + }, + "b591cfea":{ + "name": "NFL Blitz 2000 (USA) (Rev 1)" + }, + "18eeb41b":{ + "name": "NFL Blitz 2001 (USA)" + }, + "6d849e17":{ + "name": "NFL QB Club 2001 (USA)" + }, + "ceef5c29":{ + "name": "NFL Quarterback Club 2000 (Europe)" + }, + "8f54f999":{ + "name": "NFL Quarterback Club 2000 (USA)" + }, + "34a21417":{ + "name": "NFL Quarterback Club 98 (Europe)" + }, + "abf0e8f2":{ + "name": "NFL Quarterback Club 98 (USA)" + }, + "f688bdf3":{ + "name": "NFL Quarterback Club 99 (Europe)" + }, + "44496b26":{ + "name": "NFL Quarterback Club 99 (USA)" + }, + "f3b2aa4d":{ + "name": "NHL 99 (Europe) (En,De,Sv,Fi)" + }, + "e5df2afe":{ + "name": "NHL 99 (USA)" + }, + "1ee678fe":{ + "name": "NHL Blades of Steel '99 (USA)" + }, + "8c0c9669":{ + "name": "NHL Breakaway 98 (Europe)" + }, + "49d86c00":{ + "name": "NHL Breakaway 98 (USA)" + }, + "572060e0":{ + "name": "NHL Breakaway 99 (Europe)" + }, + "75f75b9d":{ + "name": "NHL Breakaway 99 (USA)" + }, + "e272867e":{ + "name": "NHL Pro 99 (Europe)" + }, + "6a1eb795":{ + "name": "Nightmare Creatures (USA)" + }, + "8c7c2dca":{ + "name": "Nintama Rantarou 64 Game Gallery (Japan)" + }, + "77d7b7e3":{ + "name": "Nintendo 64 Modem (Japan) (Add-on)" + }, + "04c9d3b1":{ + "name": "Nintendo All-Star! Dairantou Smash Brothers (Japan)" + }, + "9afbfcaf":{ + "name": "Nuclear Strike 64 (Europe) (En,Fr)" + }, + "d175397b":{ + "name": "Nuclear Strike 64 (Germany)" + }, + "d7467294":{ + "name": "Nuclear Strike 64 (USA)" + }, + "020b6443":{ + "name": "Nuclear Strike 64 (Germany) (Beta) (1999-11-17)" + }, + "a6800ec0":{ + "name": "Nushi Zuri 64 (Japan)" + }, + "16414ae4":{ + "name": "Nushi Zuri 64 (Japan) (Rev 1)" + }, + "f0bcd1ce":{ + "name": "Nushi Zuri 64 - Shiokaze ni Notte (Japan)" + }, + "7b870026":{ + "name": "O.D.T. (Europe) (En,Fr,De,Es,It) (Proto)" + }, + "1d4a8659":{ + "name": "O.D.T. (USA) (En,Fr,Es) (Proto)" + }, + "d9fe9ee7":{ + "name": "Off Road Challenge (Europe)" + }, + "1a45c5ab":{ + "name": "Off Road Challenge (USA)" + }, + "845b8711":{ + "name": "Ogre Battle 64 - Person of Lordly Caliber (Japan) (Rev 1)" + }, + "a05aea85":{ + "name": "Ogre Battle 64 - Person of Lordly Caliber (USA)" + }, + "410f6510":{ + "name": "Ogre Battle 64 - Person of Lordly Caliber (USA) (Rev 1)" + }, + "19337b04":{ + "name": "Ogre Battle 64 - Person of Lordly Caliber (USA, Europe) (Rev 1) (Wii Virtual Console)" + }, + "991f569c":{ + "name": "Ogre Battle 64 - Person of Lordly Caliber (Japan) (Rev 1) (Wii Virtual Console)" + }, + "5a805c2e":{ + "name": "Olympic Hockey 98 (Europe) (En,Fr,De,Es)" + }, + "9e98fce8":{ + "name": "Olympic Hockey 98 (Japan)" + }, + "2d777652":{ + "name": "Olympic Hockey 98 (USA)" + }, + "ac72a1c7":{ + "name": "Onegai Monsters (Japan)" + }, + "fb96f166":{ + "name": "Operation WinBack (Europe) (En,Fr,De,Es,It)" + }, + "42d06e32":{ + "name": "Pachinko 365 Nichi (Japan)" + }, + "9fc00ce3":{ + "name": "Paper Mario (Europe) (En,Fr,De,Es)" + }, + "a7f5cd7e":{ + "name": "Paper Mario (USA)" + }, + "f00c5053":{ + "name": "Paperboy (Europe)" + }, + "f27114e6":{ + "name": "Paperboy (USA)" + }, + "c5dc4795":{ + "name": "Parlor! Pro 64 - Pachinko Jikki Simulation Game (Japan)" + }, + "86cc80b5":{ + "name": "PD Ultraman Battle Collection 64 (Japan)" + }, + "a1d6eb5b":{ + "name": "Penny Racers (Europe)" + }, + "c1e57337":{ + "name": "Penny Racers (USA)" + }, + "7718a714":{ + "name": "Perfect Dark (Europe) (En,Fr,De,Es,It)" + }, + "639c0da9":{ + "name": "Perfect Dark (Japan)" + }, + "68446ad4":{ + "name": "Perfect Dark (USA)" + }, + "4c1677f7":{ + "name": "Perfect Dark (USA) (Rev 1)" + }, + "b33c4a54":{ + "name": "Perfect Dark (Europe) (Debug Version) (2000-04-26)" + }, + "b568a9fe":{ + "name": "Perfect Dark (USA) (Debug Version) (2000-03-22)" + }, + "7cdfcdaa":{ + "name": "PGA European Tour (USA)" + }, + "6b5ff959":{ + "name": "PGA European Tour Golf (Europe) (En,Fr,De,Es,It)" + }, + "3f6245ae":{ + "name": "Pikachuu Genki de Chuu (Japan)" + }, + "c902e57c":{ + "name": "Pilotwings 64 (Europe) (En,Fr,De)" + }, + "3d3a84a9":{ + "name": "Pilotwings 64 (Japan)" + }, + "728807e7":{ + "name": "Pilotwings 64 (USA)" + }, + "75839254":{ + "name": "Pokemon Puzzle League (Europe)" + }, + "c3aa0074":{ + "name": "Pokemon Puzzle League (France)" + }, + "ac543150":{ + "name": "Pokemon Puzzle League (Germany)" + }, + "8b9c598f":{ + "name": "Pokemon Puzzle League (USA)" + }, + "13f996b2":{ + "name": "Pokemon Puzzle League (Europe) (Wii Virtual Console)" + }, + "8671137d":{ + "name": "Pokemon Puzzle League (France) (Wii Virtual Console)" + }, + "00e73008":{ + "name": "Pokemon Puzzle League (Germany) (Wii Virtual Console)" + }, + "91623130":{ + "name": "Pokemon Puzzle League (USA) (Wii Virtual Console)" + }, + "a091bd56":{ + "name": "Pokemon Snap (Japan)" + }, + "cdea6d4c":{ + "name": "Pokemon Snap (Australia)" + }, + "f824a057":{ + "name": "Pokemon Snap (Europe)" + }, + "ec843586":{ + "name": "Pokemon Snap (France)" + }, + "10c27b3c":{ + "name": "Pokemon Snap (Germany)" + }, + "df56e922":{ + "name": "Pokemon Snap (Italy)" + }, + "371b787f":{ + "name": "Pokemon Snap (Spain)" + }, + "86a69756":{ + "name": "Pokemon Snap (USA)" + }, + "a761daef":{ + "name": "Pokemon Snap (Japan) (Rev 1) (Wii Virtual Console)" + }, + "e22a00d0":{ + "name": "Pokemon Snap Station (USA) (Demo) (Kiosk)" + }, + "3139189c":{ + "name": "Pokemon Stadium (Japan)" + }, + "dc57508d":{ + "name": "Pokemon Stadium (Europe)" + }, + "da889668":{ + "name": "Pokemon Stadium (Europe) (Rev 1)" + }, + "5dd92d4c":{ + "name": "Pokemon Stadium (France)" + }, + "9f22a945":{ + "name": "Pokemon Stadium (Germany)" + }, + "f155c465":{ + "name": "Pokemon Stadium (Italy)" + }, + "f02cd5eb":{ + "name": "Pokemon Stadium (Spain)" + }, + "72f66f05":{ + "name": "Pokemon Stadium (USA)" + }, + "4b1bc2ac":{ + "name": "Pokemon Stadium (USA) (Rev 1)" + }, + "235b1842":{ + "name": "Pokemon Stadium (USA) (Rev 2)" + }, + "40aa4874":{ + "name": "Pokemon Stadium 2 (Japan)" + }, + "6b3096c4":{ + "name": "Pokemon Stadium 2 (Europe)" + }, + "e2a78066":{ + "name": "Pokemon Stadium 2 (France)" + }, + "1146a43a":{ + "name": "Pokemon Stadium 2 (Germany)" + }, + "9fa5c095":{ + "name": "Pokemon Stadium 2 (Italy)" + }, + "283e7641":{ + "name": "Pokemon Stadium 2 (Spain)" + }, + "a9998e09":{ + "name": "Pokemon Stadium 2 (USA)" + }, + "cbc3b935":{ + "name": "Pokemon Stadium Kin Gin (Japan)" + }, + "8dd735ef":{ + "name": "Polaris SnoCross (USA)" + }, + "aec21c28":{ + "name": "Power League 64 (Japan)" + }, + "36ee5ca8":{ + "name": "Power Rangers - Lightspeed Rescue (Europe)" + }, + "a5033311":{ + "name": "Power Rangers - Lightspeed Rescue (USA)" + }, + "9514da0a":{ + "name": "Powerpuff Girls, The - Chemical X-Traction (USA)" + }, + "81cda888":{ + "name": "Premier Manager 64 (Europe)" + }, + "1f5907f9":{ + "name": "Pro Mahjong Kiwame 64 (Japan)" + }, + "b9be7b90":{ + "name": "Pro Mahjong Kiwame 64 (Japan) (Rev 1)" + }, + "35461699":{ + "name": "Pro Mahjong Tsuwamono 64 - Jansou Battle ni Chousen (Japan)" + }, + "355ff9de":{ + "name": "Puyo Puyo Sun 64 (Japan)" + }, + "d59d2794":{ + "name": "Puyo Puyoon Party (Japan)" + }, + "ea837423":{ + "name": "Puzzle Bobble 64 (Japan)" + }, + "b7ebddc6":{ + "name": "Pyoro 64 (USA) (Aftermarket) (Homebrew)" + }, + "1ee17b37":{ + "name": "Pyoro 64 (Italy) (Aftermarket) (Homebrew)" + }, + "b8874c09":{ + "name": "Pyoro 64 (Unknown) (Aftermarket) (Homebrew)" + }, + "28c10844":{ + "name": "Quake (Europe)" + }, + "761f39d1":{ + "name": "Quake (USA)" + }, + "82beca21":{ + "name": "Quake II (Europe)" + }, + "e6b34387":{ + "name": "Quake II (USA)" + }, + "d75b45c6":{ + "name": "Quest 64 (USA)" + }, + "9b30252e":{ + "name": "R64 (World) (Aftermarket) (Homebrew)" + }, + "ba73a7e4":{ + "name": "Racing Simulation 2 (Germany)" + }, + "483129aa":{ + "name": "Rakugakids (Europe)" + }, + "b9e53b06":{ + "name": "Rakugakids (Japan)" + }, + "99f25365":{ + "name": "Rally '99 (Japan)" + }, + "3edec7b0":{ + "name": "Rally Challenge 2000 (USA)" + }, + "cdc458ec":{ + "name": "Rampage - World Tour (Europe)" + }, + "211119dd":{ + "name": "Rampage - World Tour (USA)" + }, + "fa6e097b":{ + "name": "Rampage 2 - Universal Tour (Europe)" + }, + "7614ee0d":{ + "name": "Rampage 2 - Universal Tour (USA)" + }, + "dd4fa798":{ + "name": "Rat Attack (Europe) (En,Fr,De,Es,It,Nl)" + }, + "2315fea7":{ + "name": "Rat Attack! (USA) (En,Fr,De,Es,It,Nl)" + }, + "169a5037":{ + "name": "Rayman 2 - The Great Escape (Europe) (En,Fr,De,Es,It)" + }, + "02bb4409":{ + "name": "Rayman 2 - The Great Escape (USA) (En,Fr,De,Es,It)" + }, + "66766469":{ + "name": "Razmoket, Les - La Chasse aux Tresors (France)" + }, + "927ce621":{ + "name": "Razor Freestyle Scooter (USA)" + }, + "81d13a11":{ + "name": "Re-Volt (Europe) (En,Fr,De,Es)" + }, + "fc0c86d0":{ + "name": "Re-Volt (USA)" + }, + "a69df7b3":{ + "name": "Ready 2 Rumble Boxing (Europe) (En,Fr,De)" + }, + "2a554048":{ + "name": "Ready 2 Rumble Boxing (USA)" + }, + "052a0e04":{ + "name": "Ready 2 Rumble Boxing - Round 2 (USA)" + }, + "7c8ee011":{ + "name": "Resident Evil 2 (Europe) (En,Fr)" + }, + "848fbc0d":{ + "name": "Resident Evil 2 (USA) (Rev 1)" + }, + "832ea1da":{ + "name": "Resident Evil 2 (USA)" + }, + "3c664a7b":{ + "name": "Road Rash 64 (Europe)" + }, + "600b3988":{ + "name": "Road Rash 64 (USA)" + }, + "4fb98385":{ + "name": "Road Rash 64 (Europe) (Beta) (1999-10-12)" + }, + "997ed5af":{ + "name": "Roadsters (Europe) (En,Fr,De,Es,It,Nl)" + }, + "e4337b92":{ + "name": "Roadsters (USA) (En,Fr,Es)" + }, + "3b0f8061":{ + "name": "Robot Poncots 64 - 7tsu no Umi no Caramel (Japan)" + }, + "f9a7904e":{ + "name": "Robotech - Crystal Dreams (USA) (Proto 2)" + }, + "baa8646d":{ + "name": "Robotech - Crystal Dreams (USA) (Proto 1)" + }, + "23bf4956":{ + "name": "Robotron 64 (Europe)" + }, + "3c95e84c":{ + "name": "Robotron 64 (USA)" + }, + "7de5d20d":{ + "name": "Rocket - Robot on Wheels (Europe) (En,Fr,De)" + }, + "e0399f23":{ + "name": "Rocket - Robot on Wheels (USA)" + }, + "7d766772":{ + "name": "Rocket - Robot on Wheels (Europe) (Beta) (1999-09-29)" + }, + "61eaee83":{ + "name": "Rockman Dash - Hagane no Boukenshin (Japan)" + }, + "c296eca1":{ + "name": "Ronaldinho's Soccer 64 (Brazil) (Pirate)" + }, + "dd9ae3a8":{ + "name": "RR64 - Ridge Racer 64 (Europe)" + }, + "3c2c2d1c":{ + "name": "RR64 - Ridge Racer 64 (USA)" + }, + "0a17da7b":{ + "name": "RTL World League Soccer 2000 (Germany)" + }, + "23aed3a2":{ + "name": "Rugrats - Die grosse Schatzsuche (Germany)" + }, + "a87faf82":{ + "name": "Rugrats - Scavenger Hunt (USA)" + }, + "3338b7c8":{ + "name": "Rugrats - Treasure Hunt (Europe)" + }, + "cd74b07e":{ + "name": "Rugrats in Paris - The Movie (Europe)" + }, + "a9cc2419":{ + "name": "Rugrats in Paris - The Movie (USA)" + }, + "30f21f89":{ + "name": "Rush 2 - Extreme Racing USA (Europe) (En,Fr,De,Es,It,Nl)" + }, + "9eb14ea8":{ + "name": "Rush 2 - Extreme Racing USA (USA)" + }, + "4e37b6f2":{ + "name": "S.C.A.R.S. (Europe) (En,Fr,De)" + }, + "22916735":{ + "name": "S.C.A.R.S. (USA)" + }, + "01794d62":{ + "name": "Saikyou Habu Shougi (Japan)" + }, + "e064962a":{ + "name": "San Francisco Rush - Extreme Racing (Europe) (En,Fr,De)" + }, + "3e20070b":{ + "name": "San Francisco Rush - Extreme Racing (USA) (En,Fr,De)" + }, + "886c5753":{ + "name": "San Francisco Rush - Extreme Racing (USA) (En,Fr,De) (Rev 1)" + }, + "e63b86c5":{ + "name": "San Francisco Rush 2049 (Europe) (En,Fr,De,Es,It,Nl)" + }, + "10941439":{ + "name": "San Francisco Rush 2049 (USA)" + }, + "0d737e6f":{ + "name": "Scooby-Doo! - Classic Creep Capers (Europe)" + }, + "39068228":{ + "name": "Scooby-Doo! - Classic Creep Capers (USA)" + }, + "cdf86f5e":{ + "name": "Scooby-Doo! - Classic Creep Capers (USA) (Rev 1)" + }, + "cc083e34":{ + "name": "SD Hiryuu no Ken Densetsu (Japan)" + }, + "92c3ba6f":{ + "name": "Sesame Street - Elmo's Letter Adventure (USA)" + }, + "ea3b92d8":{ + "name": "Sesame Street - Elmo's Number Journey (USA)" + }, + "8d230306":{ + "name": "Shadow Man (Europe) (En,Es,It)" + }, + "6812d3a7":{ + "name": "Shadow Man (France)" + }, + "eaf6add1":{ + "name": "Shadow Man (Germany)" + }, + "5e20cc63":{ + "name": "Shadow Man (USA)" + }, + "61e6642c":{ + "name": "Shadow Man (Brazil)" + }, + "ff7d7df0":{ + "name": "Shadowgate 64 - Trials of the Four Towers (Europe)" + }, + "87f00472":{ + "name": "Shadowgate 64 - Trials of the Four Towers (Europe) (Es,It)" + }, + "eedc0bea":{ + "name": "Shadowgate 64 - Trials of the Four Towers (Europe) (Fr,De,Nl)" + }, + "9f74a58c":{ + "name": "Shadowgate 64 - Trials of the Four Towers (Japan)" + }, + "69983cc3":{ + "name": "Shadowgate 64 - Trials of the Four Towers (USA) (En,Es)" + }, + "e892ed43":{ + "name": "Shin Nihon Pro Wrestling Toukon Road - Brave Spirits (Japan)" + }, + "deac787f":{ + "name": "Shin Nihon Pro Wrestling Toukon Road 2 - The Next Generation (Japan)" + }, + "57767e45":{ + "name": "SimCity 2000 (Japan)" + }, + "213bf381":{ + "name": "Snobo Kids (Japan)" + }, + "30ea3fd7":{ + "name": "Snow Speeder (Japan)" + }, + "5619a70d":{ + "name": "Snowboard Kids (Europe, Australia)" + }, + "020fb906":{ + "name": "Snowboard Kids (USA)" + }, + "3a0b6214":{ + "name": "Snowboard Kids 2 (Australia)" + }, + "d0dc8a8e":{ + "name": "Snowboard Kids 2 (USA)" + }, + "fc73fb79":{ + "name": "Sonic Wings Assault (Japan)" + }, + "b2c3e123":{ + "name": "South Park (Europe) (En,Fr,Es)" + }, + "5711e197":{ + "name": "South Park (Germany)" + }, + "7d666b9e":{ + "name": "South Park (USA)" + }, + "235caec6":{ + "name": "South Park (Brazil)" + }, + "ac1628eb":{ + "name": "South Park - Chef's Luv Shack (Europe)" + }, + "6b6b1d09":{ + "name": "South Park - Chef's Luv Shack (USA)" + }, + "296e3525":{ + "name": "South Park Rally (Europe)" + }, + "ccdd322a":{ + "name": "South Park Rally (USA)" + }, + "1c535592":{ + "name": "South Park Rally (Europe) (Beta)" + }, + "8cb4b948":{ + "name": "Space Dynamites (Japan)" + }, + "60f7ff8e":{ + "name": "Space Invaders (USA)" + }, + "63042e36":{ + "name": "SpaceStation Silicon Valley (Europe) (En,Fr,De,Es,It,Nl,Pt)" + }, + "dcec9f8a":{ + "name": "SpaceStation Silicon Valley (Japan) (Proto)" + }, + "a606e8ae":{ + "name": "SpaceStation Silicon Valley (USA)" + }, + "e32d9e7b":{ + "name": "SpaceStation Silicon Valley (USA) (Rev 1)" + }, + "696cc2a4":{ + "name": "Spider-Man (USA)" + }, + "411142a7":{ + "name": "Star Fox 64 (Japan)" + }, + "b1fcaa9c":{ + "name": "Star Fox 64 (USA)" + }, + "b1b5fc46":{ + "name": "Star Fox 64 (USA) (Rev 1)" + }, + "6508d4ad":{ + "name": "Star Fox 64 (Japan) (Rev 1) (Wii Virtual Console)" + }, + "7ee5f51d":{ + "name": "Star Soldier - Vanishing Earth (Japan)" + }, + "ea650def":{ + "name": "Star Soldier - Vanishing Earth (USA)" + }, + "964506ce":{ + "name": "Star Twins (Japan)" + }, + "6289645f":{ + "name": "Star Wars - Rogue Squadron (Europe) (En,Fr,De)" + }, + "c88e5638":{ + "name": "Star Wars - Rogue Squadron (Europe) (En,Fr,De) (Rev 1)" + }, + "83c225cc":{ + "name": "Star Wars - Rogue Squadron (USA)" + }, + "65a8fba0":{ + "name": "Star Wars - Rogue Squadron (USA) (Rev 1)" + }, + "f0a191bf":{ + "name": "Star Wars - Shadows of the Empire (Europe)" + }, + "3c0837b3":{ + "name": "Star Wars - Shadows of the Empire (USA)" + }, + "b0540688":{ + "name": "Star Wars - Shadows of the Empire (USA) (Rev 1)" + }, + "e8727549":{ + "name": "Star Wars - Shadows of the Empire (USA) (Rev 2)" + }, + "28368603":{ + "name": "Star Wars - Shadows of the Empire (USA) (Beta) (1996-10-15)" + }, + "776a069b":{ + "name": "Star Wars - Shadows of the Empire (USA) (Aftermarket) (Unl)" + }, + "ee7643b6":{ + "name": "Star Wars - Shutsugeki! Rogue Chuutai (Japan)" + }, + "7ce71426":{ + "name": "Star Wars - Teikoku no Kage (Japan)" + }, + "029104fd":{ + "name": "Star Wars Episode I - Battle for Naboo (Europe)" + }, + "99dee3c0":{ + "name": "Star Wars Episode I - Battle for Naboo (USA)" + }, + "e0f46629":{ + "name": "Star Wars Episode I - Racer (Europe) (En,Fr,De)" + }, + "97c155c5":{ + "name": "Star Wars Episode I - Racer (Japan)" + }, + "c53c1035":{ + "name": "Star Wars Episode I - Racer (USA)" + }, + "fb401a2a":{ + "name": "Star Wars Episode I - Racer (USA) (Aftermarket) (Unl)" + }, + "2639dae2":{ + "name": "StarCraft 64 (Australia)" + }, + "4e4c7ec9":{ + "name": "StarCraft 64 (USA)" + }, + "b0e1654f":{ + "name": "StarCraft 64 (USA) (Beta)" + }, + "2b1c9fe4":{ + "name": "StarCraft 64 (Germany) (Proto)" + }, + "056d2218":{ + "name": "Starshot - Space Circus Fever (Europe) (En,Fr,De)" + }, + "7720e5f3":{ + "name": "Starshot - Space Circus Fever (USA) (En,Fr,Es)" + }, + "3438b1af":{ + "name": "Stunt Racer 64 (USA)" + }, + "5006dc88":{ + "name": "Super B-Daman - Battle Phoenix 64 (Japan)" + }, + "ba2d8b2e":{ + "name": "Super Bowling (Japan)" + }, + "f6ccd04a":{ + "name": "Super Bowling (USA)" + }, + "03048de6":{ + "name": "Super Mario 64 (Europe) (En,Fr,De)" + }, + "dd801954":{ + "name": "Super Mario 64 (Japan)" + }, + "a1e15117":{ + "name": "Super Mario 64 (Japan) (Rev 3) (Shindou Edition)" + }, + "3ce60709":{ + "name": "Super Mario 64 (USA)" + }, + "8c9216c1":{ + "name": "Super Robot Spirits (Japan)" + }, + "85df2771":{ + "name": "Super Robot Taisen 64 (Japan)" + }, + "e96779fa":{ + "name": "Super Smash Bros. (Australia)" + }, + "45a91cb1":{ + "name": "Super Smash Bros. (Europe) (En,Fr,De)" + }, + "eb97929e":{ + "name": "Super Smash Bros. (USA)" + }, + "0f879a70":{ + "name": "Super Speed Race 64 (Japan)" + }, + "cb5482ec":{ + "name": "Supercross 2000 (Europe) (En,Fr,De)" + }, + "094e2a48":{ + "name": "Supercross 2000 (USA)" + }, + "bca4ff8c":{ + "name": "Superman (Europe) (En,Fr,De,Es,It,Nl)" + }, + "a0897826":{ + "name": "Superman (USA) (Beta) (1998-09-06)" + }, + "437e3677":{ + "name": "Superman - The New Superman Aventures (USA) (En,Fr,Es)" + }, + "4cd21372":{ + "name": "Susume! Taisen Puzzle Dama - Toukon! Marutama Chou (Japan)" + }, + "db7b31b9":{ + "name": "Sydney 2000 (Europe) (Proto)" + }, + "5b6673aa":{ + "name": "Sydney 2000 (USA) (Proto)" + }, + "1b4c53fa":{ + "name": "Tamiya Racing 64 (USA) (Proto)" + }, + "7737ed9e":{ + "name": "Tarzan (Europe)" + }, + "99c7649d":{ + "name": "Tarzan (France)" + }, + "0b0954c5":{ + "name": "Tarzan (Germany)" + }, + "c38ca641":{ + "name": "Tarzan (USA)" + }, + "0712c306":{ + "name": "Taz Express (Europe) (En,Fr,De,Es,It,Nl)" + }, + "dde7cfbd":{ + "name": "Taz Express (USA) (Proto) (2000-05-15)" + }, + "7bd20931":{ + "name": "Telefoot Soccer 2000 (France)" + }, + "f128cd17":{ + "name": "Tetris 64 (Japan) (En)" + }, + "7cb31b0f":{ + "name": "Tetrisphere (Europe)" + }, + "70a3a5ce":{ + "name": "Tetrisphere (USA)" + }, + "135c8eb0":{ + "name": "TG Rally 2 (Europe)" + }, + "d82d5736":{ + "name": "Tigger's Honey Hunt (Europe) (En,Fr,De,Es,It,Nl,Da)" + }, + "68c2ac8f":{ + "name": "Tigger's Honey Hunt (USA)" + }, + "9ea8a3b8":{ + "name": "Tom and Jerry in Fists of Furry (Europe) (En,Fr,De,Es,It,Nl)" + }, + "6d685b83":{ + "name": "Tom and Jerry in Fists of Furry (USA)" + }, + "4b71e083":{ + "name": "Tom Clancy's Rainbow Six (Europe)" + }, + "bbf7b6a8":{ + "name": "Tom Clancy's Rainbow Six (France)" + }, + "5d73e788":{ + "name": "Tom Clancy's Rainbow Six (Germany)" + }, + "53b0cc13":{ + "name": "Tom Clancy's Rainbow Six (USA)" + }, + "66734854":{ + "name": "Tommy Thunder (USA) (Proto) (1997-10-01)" + }, + "b4322403":{ + "name": "Tonic Trouble (Europe) (En,Fr,De,Es,It)" + }, + "1c04ba12":{ + "name": "Tonic Trouble (USA) (Rev 1)" + }, + "f5c1b64f":{ + "name": "Tony Hawk's Pro Skater (USA)" + }, + "6182a092":{ + "name": "Tony Hawk's Pro Skater (USA) (Rev 1)" + }, + "f50204da":{ + "name": "Tony Hawk's Pro Skater (USA) (Beta)" + }, + "bcf178c5":{ + "name": "Tony Hawk's Pro Skater 2 (USA) (v012) (Beta) (2001-06-04)" + }, + "98d0d335":{ + "name": "Tony Hawk's Pro Skater 2 (USA) (Beta) (2001-04-20)" + }, + "a1207132":{ + "name": "Tony Hawk's Pro Skater 2 (Europe)" + }, + "80aa83f3":{ + "name": "Tony Hawk's Pro Skater 2 (USA)" + }, + "62a8ce7d":{ + "name": "Tony Hawk's Pro Skater 3 (USA)" + }, + "39e4f766":{ + "name": "Tony Hawk's Skateboarding (Europe)" + }, + "cf396c4e":{ + "name": "Toon Panic (Japan) (Proto)" + }, + "bae57ea7":{ + "name": "Top Gear Hyper Bike (Europe)" + }, + "09b2cda1":{ + "name": "Top Gear Hyper Bike (Japan)" + }, + "6eebc26a":{ + "name": "Top Gear Hyper-Bike (USA)" + }, + "00c0278a":{ + "name": "Top Gear Hyper-Bike (USA) (Beta)" + }, + "0cc70580":{ + "name": "Top Gear Overdrive (Europe)" + }, + "81aafc2b":{ + "name": "Top Gear Overdrive (Japan)" + }, + "f3e0ff21":{ + "name": "Top Gear Overdrive (USA)" + }, + "40b3bb21":{ + "name": "Top Gear Rally (Europe)" + }, + "c6707cd6":{ + "name": "Top Gear Rally (Japan)" + }, + "137287f5":{ + "name": "Top Gear Rally (USA)" + }, + "c4bc4df8":{ + "name": "Top Gear Rally (Asia) (En)" + }, + "cb294d39":{ + "name": "Top Gear Rally 2 (Europe)" + }, + "aa136e07":{ + "name": "Top Gear Rally 2 (Japan)" + }, + "914cf9c4":{ + "name": "Top Gear Rally 2 (USA)" + }, + "3c77c5d6":{ + "name": "Top Gear Rally 2 (Europe) (Beta) (1999-08-31)" + }, + "fb4bea9a":{ + "name": "Toy Story 2 - Buzz l'Eclair a la Rescousse! (France)" + }, + "59574cb9":{ + "name": "Toy Story 2 - Buzz Lightyear to the Rescue! (Europe)" + }, + "b9570841":{ + "name": "Toy Story 2 - Buzz Lightyear to the Rescue! (USA)" + }, + "c81f3321":{ + "name": "Toy Story 2 - Buzz Lightyear to the Rescue! (USA) (Rev 1)" + }, + "c5e4c89f":{ + "name": "Toy Story 2 - Captain Buzz Lightyear auf Rettungsmission! (Germany)" + }, + "d1906de4":{ + "name": "Toy Story 2 - Captain Buzz Lightyear auf Rettungsmission! (Germany) (Rev 1)" + }, + "338f1d45":{ + "name": "Transformers - Beast Wars Metals 64 (Japan)" + }, + "85138b5a":{ + "name": "Transformers - Beast Wars Transmetals (USA)" + }, + "785dd0f8":{ + "name": "Triple Play 2000 (USA)" + }, + "ca2e5e49":{ + "name": "Tsumi to Batsu - Hoshi no Keishousha (Japan)" + }, + "e8525687":{ + "name": "Turok - Dinosaur Hunter (Europe)" + }, + "c2353283":{ + "name": "Turok - Dinosaur Hunter (Europe) (Rev 1)" + }, + "312af877":{ + "name": "Turok - Dinosaur Hunter (Europe) (Rev 2)" + }, + "64631ff9":{ + "name": "Turok - Dinosaur Hunter (Germany)" + }, + "26c4f597":{ + "name": "Turok - Dinosaur Hunter (USA)" + }, + "7f2476f4":{ + "name": "Turok - Dinosaur Hunter (USA) (Rev 1)" + }, + "8c3bbc00":{ + "name": "Turok - Dinosaur Hunter (USA) (Rev 2)" + }, + "2765dd8f":{ + "name": "Turok - Dinosaur Hunter (Germany) (Rev 1)" + }, + "72ca307a":{ + "name": "Turok - Dinosaur Hunter (Germany) (Rev 2)" + }, + "b937874f":{ + "name": "Turok - Legenden des Verlorenen Landes (Germany)" + }, + "82b1e116":{ + "name": "Turok - Rage Wars (Europe)" + }, + "f4a2862b":{ + "name": "Turok - Rage Wars (Europe) (En,Fr,It)" + }, + "422872a2":{ + "name": "Turok - Rage Wars (USA)" + }, + "e28756f4":{ + "name": "Turok - Rage Wars (USA) (Rev 1)" + }, + "e2d34bfe":{ + "name": "Turok 2 - Seeds of Evil (Europe)" + }, + "1febde32":{ + "name": "Turok 2 - Seeds of Evil (Europe) (En,Fr,Es,It)" + }, + "4e29b234":{ + "name": "Turok 2 - Seeds of Evil (Europe) (Demo) (Kiosk)" + }, + "c07877b6":{ + "name": "Turok 2 - Seeds of Evil (Germany)" + }, + "ff5e7636":{ + "name": "Turok 2 - Seeds of Evil (USA)" + }, + "8d5b9bd0":{ + "name": "Turok 2 - Seeds of Evil (USA) (Demo) (Kiosk)" + }, + "57f1fbf5":{ + "name": "Turok 2 - Seeds of Evil (USA) (Rev 1)" + }, + "58c4c0ab":{ + "name": "Turok 3 - Shadow of Oblivion (USA) (Beta) (2000-06-26)" + }, + "9a01a5f4":{ + "name": "Turok 3 - Shadow of Oblivion (Europe) (Beta) (2000-07-16)" + }, + "98d3114c":{ + "name": "Turok 3 - Shadow of Oblivion (Europe)" + }, + "cb297224":{ + "name": "Turok 3 - Shadow of Oblivion (USA)" + }, + "3cd1f9af":{ + "name": "Turok 3 - Shadow of Oblivion (Europe) (Beta) (2000-07-10) [b]" + }, + "66e63bbc":{ + "name": "Turok 3 - Shadow of Oblivion (Europe) (Beta) (2000-05-31)" + }, + "7946b05a":{ + "name": "Turok 3 - Shadow of Oblivion (Europe) (Beta) (2000-06-06) [b]" + }, + "667b553d":{ + "name": "Turok 3 - Shadow of Oblivion (USA) (Beta) (2000-07-21)" + }, + "bfbcc038":{ + "name": "Twisted Edge - Extreme Snowboarding (USA)" + }, + "bf0c1291":{ + "name": "Twisted Edge - Snowboarding (Europe)" + }, + "50cbe8a6":{ + "name": "Utchan Nanchan no Hono no Challenger - Denryuu Ira Ira Bou (Japan)" + }, + "0735d7a2":{ + "name": "V-Rally Edition 99 (Europe) (En,Fr,De)" + }, + "02475a01":{ + "name": "V-Rally Edition 99 (Japan)" + }, + "4803075e":{ + "name": "V-Rally Edition 99 (USA)" + }, + "93a630cb":{ + "name": "Viewpoint 2064 (Japan) (Proto)" + }, + "0e9bb6d6":{ + "name": "Vigilante 8 (Europe)" + }, + "11d23ab3":{ + "name": "Vigilante 8 (France)" + }, + "17f63c3f":{ + "name": "Vigilante 8 (Germany)" + }, + "330b73e6":{ + "name": "Vigilante 8 (USA)" + }, + "691aa971":{ + "name": "Vigilante 8 - 2nd Offense (Europe)" + }, + "0293203f":{ + "name": "Vigilante 8 - 2nd Offense (USA)" + }, + "097f139f":{ + "name": "Violence Killer - Turok New Generation (Japan)" + }, + "aae15243":{ + "name": "Virtual Chess 64 (Europe) (En,Fr,De,Es,It,Nl)" + }, + "620de0b7":{ + "name": "Virtual Chess 64 (USA) (En,Fr,Es)" + }, + "9a6fb0bc":{ + "name": "Virtual Pool 64 (Europe)" + }, + "ad628ded":{ + "name": "Virtual Pool 64 (USA)" + }, + "f620835d":{ + "name": "Virtual Pro Wrestling 2 - Oudou Keishou (Japan)" + }, + "e6651803":{ + "name": "Virtual Pro Wrestling 64 (Japan)" + }, + "6858759a":{ + "name": "Waialae Country Club - True Golf Classics (Europe)" + }, + "6cb097b3":{ + "name": "Waialae Country Club - True Golf Classics (Europe) (Rev 1)" + }, + "ccab08d7":{ + "name": "Waialae Country Club - True Golf Classics (USA)" + }, + "c65ee122":{ + "name": "Waialae Country Club - True Golf Classics (USA) (Rev 1)" + }, + "c73010c8":{ + "name": "War Gods (Europe)" + }, + "ffacf993":{ + "name": "War Gods (USA)" + }, + "fb289893":{ + "name": "Wave Race 64 - Kawasaki Jet Ski (Europe) (En,De)" + }, + "6c93ff83":{ + "name": "Wave Race 64 - Kawasaki Jet Ski (Japan)" + }, + "90044c4b":{ + "name": "Wave Race 64 - Kawasaki Jet Ski (Japan) (Rev 2) (Shindou Edition)" + }, + "74a7b725":{ + "name": "Wave Race 64 - Kawasaki Jet Ski (USA)" + }, + "394948c4":{ + "name": "Wave Race 64 - Kawasaki Jet Ski (USA) (Rev 1)" + }, + "54d190a8":{ + "name": "Wave Race 64 - Kawasaki Jet Ski (Japan) (Rev 1)" + }, + "442a4f5f":{ + "name": "Wayne Gretzky's 3D Hockey (Europe) (En,Fr,De,Es)" + }, + "485275ed":{ + "name": "Wayne Gretzky's 3D Hockey (Japan)" + }, + "9781f88d":{ + "name": "Wayne Gretzky's 3D Hockey (USA)" + }, + "c2678971":{ + "name": "Wayne Gretzky's 3D Hockey (USA) (Rev 1)" + }, + "6f6dc53d":{ + "name": "Wayne Gretzky's 3D Hockey '98 (Europe) (En,Fr,De,Es)" + }, + "355fb089":{ + "name": "Wayne Gretzky's 3D Hockey '98 (USA)" + }, + "5dcc2e4e":{ + "name": "WCW Backstage Assault (USA)" + }, + "864e066e":{ + "name": "WCW Mayhem (Europe)" + }, + "f1f9b6eb":{ + "name": "WCW Mayhem (USA)" + }, + "455b0830":{ + "name": "WCW Nitro (USA)" + }, + "37f358eb":{ + "name": "WCW vs. nWo - World Tour (Europe)" + }, + "dfbfc61f":{ + "name": "WCW vs. nWo - World Tour (USA)" + }, + "a74da07a":{ + "name": "WCW vs. nWo - World Tour (USA) (Rev 1)" + }, + "8af0f964":{ + "name": "WCW-nWo Revenge (Europe)" + }, + "54cbaaa8":{ + "name": "WCW-nWo Revenge (USA)" + }, + "eddc5b06":{ + "name": "Wetrix (Europe) (En,Fr,De,Es,It,Nl)" + }, + "bad08218":{ + "name": "Wetrix (Japan)" + }, + "50cd1f71":{ + "name": "Wetrix (USA) (En,Fr,De,Es,It,Nl)" + }, + "74df67bb":{ + "name": "Whack 'n' Roll (USA) (Beta) (1998-02-05)" + }, + "8d3efa8d":{ + "name": "Wheel of Fortune (USA)" + }, + "d6136dc5":{ + "name": "Wild Choppers (Japan)" + }, + "40443c67":{ + "name": "Wildwaters (USA) (Proto) (1999-06-15)" + }, + "d35360b0":{ + "name": "WinBack (Japan)" + }, + "927383bb":{ + "name": "WinBack (Japan) (Rev 1)" + }, + "64c817c5":{ + "name": "WinBack - Covert Operations (USA)" + }, + "38111048":{ + "name": "Wipeout 64 (Europe)" + }, + "4888d0fe":{ + "name": "Wipeout 64 (USA)" + }, + "944b258f":{ + "name": "Wipeout 64 (Europe) (Beta)" + }, + "5e8fc436":{ + "name": "Wonder Project J2 - Koruro no Mori no Jozet (Japan)" + }, + "79f483f7":{ + "name": "World Cup 98 (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" + }, + "13930c26":{ + "name": "World Cup 98 (USA) (En,Fr,De,Es,It,Nl,Sv,Da)" + }, + "76151df6":{ + "name": "World Driver Championship (Europe) (En,Fr,De,Es,It)" + }, + "5e4acbfa":{ + "name": "World Driver Championship (USA)" + }, + "6bfff27b":{ + "name": "Worms Armageddon (Europe) (En,Fr,De,Es,It,Nl)" + }, + "5471ae3b":{ + "name": "Worms Armageddon (USA) (En,Fr,Es)" + }, + "804fe494":{ + "name": "WWF Attitude (Europe)" + }, + "ea5d8359":{ + "name": "WWF Attitude (Germany)" + }, + "7a4b3686":{ + "name": "WWF Attitude (USA)" + }, + "e88d7e16":{ + "name": "WWF No Mercy (Europe)" + }, + "43ba9e7e":{ + "name": "WWF No Mercy (Europe) (Rev 1)" + }, + "b33f44f0":{ + "name": "WWF No Mercy (USA)" + }, + "baceea13":{ + "name": "WWF No Mercy (USA) (Rev 1)" + }, + "90a0b609":{ + "name": "WWF War Zone (Europe)" + }, + "2fbb5507":{ + "name": "WWF War Zone (USA)" + }, + "09d710c7":{ + "name": "WWF WrestleMania 2000 (Europe)" + }, + "c2034d24":{ + "name": "WWF WrestleMania 2000 (Japan)" + }, + "0b50b4c6":{ + "name": "WWF WrestleMania 2000 (USA)" + }, + "fce6875f":{ + "name": "X'treme Roller (USA) (Proto)" + }, + "d3932f88":{ + "name": "Xena - Warrior Princess - The Talisman of Fate (Europe)" + }, + "7da93999":{ + "name": "Xena - Warrior Princess - The Talisman of Fate (USA)" + }, + "656acdf5":{ + "name": "Xplorer 64 (Germany) (v1.067) (Unl)" + }, + "4538c41a":{ + "name": "Yakouchuu II - Satsujin Kouro (Japan)" + }, + "4f44a9ef":{ + "name": "Yoshi Story (Japan)" + }, + "f9ffc760":{ + "name": "Yoshi's Story (Europe) (En,Fr,De)" + }, + "a1453e0d":{ + "name": "Yoshi's Story (USA) (En,Ja)" + }, + "b69d3068":{ + "name": "Yuke Yuke!! Trouble Makers (Japan)" + }, + "0d33e1db":{ + "name": "Zelda no Densetsu - Mujura no Kamen (Japan)" + }, + "356c2e19":{ + "name": "Zelda no Densetsu - Mujura no Kamen (Japan) (Rev 1)" + }, + "b9bf76df":{ + "name": "Zelda no Densetsu - Mujura no Kamen (Japan) (GameCube)" + }, + "d423e8b0":{ + "name": "Zelda no Densetsu - Toki no Ocarina (Japan)" + }, + "26e73887":{ + "name": "Zelda no Densetsu - Toki no Ocarina (Japan) (Rev 1)" + }, + "2b2721ba":{ + "name": "Zelda no Densetsu - Toki no Ocarina (Japan) (Rev 2)" + }, + "8c5b90c1":{ + "name": "Zelda no Densetsu - Toki no Ocarina (Japan) (GameCube, Zelda Collection)" + }, + "1c6ce8cb":{ + "name": "Zelda no Densetsu - Toki no Ocarina GC (Japan) (GameCube)" + }, + "122ff261":{ + "name": "Zelda no Densetsu - Toki no Ocarina GC Ura (Japan) (GameCube)" + }, + "756ba26d": { + "name": "Zool - Majuu Tsukai Densetsu (Japan)" + } +} \ No newline at end of file diff --git a/src/frontend/App.cpp b/src/frontend/App.cpp index 9fda13fc..a7829746 100644 --- a/src/frontend/App.cpp +++ b/src/frontend/App.cpp @@ -6,7 +6,7 @@ void App::Run() { // Main loop const u8* state = SDL_GetKeyboardState(nullptr); while (!core.done) { - core.Run(window); + core.Run(window, window.volumeL, window.volumeR); core.UpdateController(state); SDL_Event event; @@ -33,7 +33,7 @@ void App::Run() { const nfdu8filteritem_t filter {"Nintendo 64 roms", "n64,z64,v64,N64,Z64,V64"}; nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr); if(result == NFD_OKAY) { - core.LoadROM(outpath); + LoadROM(outpath); NFD_FreePath(outpath); } } break; diff --git a/src/frontend/App.hpp b/src/frontend/App.hpp index bd05d841..5b773224 100644 --- a/src/frontend/App.hpp +++ b/src/frontend/App.hpp @@ -6,7 +6,7 @@ struct App { ~App() = default; void Run(); inline void LoadROM(const std::string& path) { - core.LoadROM(path); + window.LoadROM(core, path); } private: n64::Core core; diff --git a/src/frontend/imgui/CMakeLists.txt b/src/frontend/imgui/CMakeLists.txt index 09505835..9657192e 100644 --- a/src/frontend/imgui/CMakeLists.txt +++ b/src/frontend/imgui/CMakeLists.txt @@ -7,6 +7,7 @@ SET(NFD_PORTAL ON CACHE BOOL "Use dbus for native file dialog instead of gtk") find_package(SDL2 REQUIRED) find_package(fmt REQUIRED) +find_package(nlohmann_json REQUIRED) add_library(frontend-imgui STATIC Window.cpp @@ -34,4 +35,4 @@ else() set(LIBRARIES ) endif() -target_link_libraries(frontend-imgui PUBLIC SDL2main SDL2 ${LIBRARIES} imgui nfd fmt) \ No newline at end of file +target_link_libraries(frontend-imgui PUBLIC nlohmann_json::nlohmann_json SDL2main SDL2 ${LIBRARIES} imgui nfd fmt) \ No newline at end of file diff --git a/src/frontend/imgui/Window.cpp b/src/frontend/imgui/Window.cpp index c131e7bc..d2bf76e1 100644 --- a/src/frontend/imgui/Window.cpp +++ b/src/frontend/imgui/Window.cpp @@ -4,8 +4,11 @@ #include #include #include +#include +#include VkInstance instance{}; +using json = nlohmann::json; Window::Window(n64::Core& core) { InitSDL(); @@ -142,9 +145,30 @@ ImDrawData* Window::Present(n64::Core& core) { return ImGui::GetDrawData(); } +void Window::LoadROM(n64::Core& core, const std::string &path) { + if(!path.empty()) { + u32 crc = core.LoadROM(path); + std::ifstream gameDbFile("resources/game_db.json"); + json gameDb = json::parse(gameDbFile); + auto entry = gameDb[fmt::format("{:08x}", crc)]["name"]; + std::string name{}; + if(!entry.empty()) { + name = entry.get(); + } else { + name = std::filesystem::path(path).stem().string(); + } + + windowTitle = "natsukashii - " + name; + + SDL_SetWindowTitle(window, windowTitle.c_str()); + } +} + void Window::Render(n64::Core& core) { ImGui::PushFont(uiFont); - if(windowID == SDL_GetWindowID(SDL_GetMouseFocus())) { + static bool showSettings = false; + bool showMainMenuBar = windowID == SDL_GetWindowID(SDL_GetMouseFocus()); + if(showMainMenuBar) { ImGui::BeginMainMenuBar(); if (ImGui::BeginMenu("File")) { if (ImGui::MenuItem("Open", "O")) { @@ -152,7 +176,7 @@ void Window::Render(n64::Core& core) { const nfdu8filteritem_t filter{"Nintendo 64 roms", "n64,z64,v64,N64,Z64,V64"}; nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr); if (result == NFD_OKAY) { - core.LoadROM(outpath); + LoadROM(core, outpath); NFD_FreePath(outpath); } } @@ -163,17 +187,51 @@ void Window::Render(n64::Core& core) { } if (ImGui::BeginMenu("Emulation")) { if (ImGui::MenuItem("Reset")) { - core.Reset(); + LoadROM(core, core.rom); } if (ImGui::MenuItem("Stop")) { + windowTitle = "natsukashii"; + SDL_SetWindowTitle(window, windowTitle.c_str()); core.Stop(); } if (ImGui::MenuItem(core.pause ? "Resume" : "Pause", nullptr, false, core.romLoaded)) { core.TogglePause(); + std::string paused = "| Paused"; + if(core.pause) { + windowTitle += paused; + } else { + auto pausedPos = windowTitle.find_first_of(paused); + if(pausedPos != std::string::npos) { + windowTitle.erase(pausedPos, paused.length()); + } + } + SDL_SetWindowTitle(window, windowTitle.c_str()); + } + if (ImGui::MenuItem("Settings")) { + showSettings = true; } ImGui::EndMenu(); } ImGui::EndMainMenuBar(); } + + if(showSettings) { + ImGui::OpenPopup("Settings"); + if(ImGui::BeginPopupModal("Settings", &showSettings)) { + ImGui::Checkbox("Lock channels", &lockVolume); + ImGui::SliderFloat("Volume L", &volumeL, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); + if (!lockVolume) { + ImGui::SliderFloat("Volume R", &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); + } else { + ImGui::PushStyleColor(ImGuiCol_SliderGrabActive, 0x11111111); + ImGui::BeginDisabled(); + ImGui::SliderFloat("Volume R", &volumeR, 0, 1, "%.2f", ImGuiSliderFlags_NoInput); + ImGui::EndDisabled(); + ImGui::PopStyleColor(); + volumeR = volumeL; + } + ImGui::EndPopup(); + } + } ImGui::PopFont(); } diff --git a/src/frontend/imgui/Window.hpp b/src/frontend/imgui/Window.hpp index 1c644e8f..8223c9f5 100644 --- a/src/frontend/imgui/Window.hpp +++ b/src/frontend/imgui/Window.hpp @@ -15,8 +15,13 @@ struct Window { [[nodiscard]] bool gotClosed(SDL_Event event); ImFont *uiFont, *codeFont; u32 windowID; + float volumeL = 0.5, volumeR = 0.5; + void LoadROM(n64::Core& core, const std::string& path); private: + bool lockVolume = true; + bool showSettings = false; SDL_Window* window; + std::string windowTitle; void InitSDL(); void InitImgui(); void Render(n64::Core& core); diff --git a/src/n64/Core.cpp b/src/n64/Core.cpp index a866314e..9e0be83d 100644 --- a/src/n64/Core.cpp +++ b/src/n64/Core.cpp @@ -14,29 +14,18 @@ void Core::Stop() { mem.Reset(); pause = true; romLoaded = false; - rom.clear(); } -void Core::Reset() { - cpu.Reset(); - mem.Reset(); - pause = true; - romLoaded = false; - if(!rom.empty()) { - LoadROM(rom); - } -} - -void Core::LoadROM(const std::string& rom_) { +u32 Core::LoadROM(const std::string& rom_) { rom = rom_; cpu.Reset(); mem.Reset(); - mem.LoadROM(rom); pause = false; romLoaded = true; + return mem.LoadROM(rom); } -void Core::Run(Window& window) { +void Core::Run(Window& window, float volumeL, float volumeR) { MMIO& mmio = mem.mmio; Controller& controller = mmio.si.controller; int cycles = 0; @@ -54,7 +43,7 @@ void Core::Run(Window& window) { cpu.Step(mem); mmio.rsp.Step(mmio.mi, cpu.regs, mmio.rdp); - mmio.ai.Step(mem, cpu.regs, 1); + mmio.ai.Step(mem, cpu.regs, 1, volumeL, volumeR); } cycles -= mmio.vi.cyclesPerHalfline; @@ -67,7 +56,7 @@ void Core::Run(Window& window) { UpdateScreenParallelRdp(*this, window, GetVI()); int missedCycles = N64_CYCLES_PER_FRAME - frameCycles; - mmio.ai.Step(mem, cpu.regs, missedCycles); + mmio.ai.Step(mem, cpu.regs, missedCycles, volumeL, volumeR); } else if(pause && romLoaded) { UpdateScreenParallelRdp(*this, window, GetVI()); } else if(pause && !romLoaded) { diff --git a/src/n64/Core.hpp b/src/n64/Core.hpp index 1e5be72a..c123cfd9 100644 --- a/src/n64/Core.hpp +++ b/src/n64/Core.hpp @@ -10,9 +10,8 @@ struct Core { ~Core() { Stop(); } Core(); void Stop(); - void Reset(); - void LoadROM(const std::string&); - void Run(Window&); + u32 LoadROM(const std::string&); + void Run(Window&, float volumeL, float volumeR); void UpdateController(const u8*); void TogglePause() { pause = !pause; } VI& GetVI() { return mem.mmio.vi; } diff --git a/src/n64/core/Audio.cpp b/src/n64/core/Audio.cpp index d5d88895..1e914809 100644 --- a/src/n64/core/Audio.cpp +++ b/src/n64/core/Audio.cpp @@ -65,12 +65,12 @@ void InitAudio() { } } -void PushSample(s16 left, s16 right) { - s16 samples[2]{ left, right }; +void PushSample(float left, float volumeL, float volumeR, float right) { + float samples[2]{ left * volumeL, right * volumeR }; int availableBytes = SDL_AudioStreamAvailable(audioStream); if(availableBytes < BYTES_PER_HALF_SECOND) { - SDL_AudioStreamPut(audioStream, samples, 2 * sizeof(16)); + SDL_AudioStreamPut(audioStream, samples, 2 * sizeof(float)); } } @@ -78,7 +78,7 @@ void AdjustSampleRate(int sampleRate) { LockAudioMutex(); if(audioStream) SDL_FreeAudioStream(audioStream); - audioStream = SDL_NewAudioStream(AUDIO_S16SYS, 2, sampleRate, SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE); + audioStream = SDL_NewAudioStream(AUDIO_F32SYS, 2, sampleRate, SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE); UnlockAudioMutex(); } diff --git a/src/n64/core/Audio.hpp b/src/n64/core/Audio.hpp index e3878ec0..42d39f7d 100644 --- a/src/n64/core/Audio.hpp +++ b/src/n64/core/Audio.hpp @@ -2,7 +2,7 @@ #include "common.hpp" namespace n64 { -void PushSample(s16, s16); +void PushSample(float, float, float, float); void InitAudio(); void AdjustSampleRate(int); } \ No newline at end of file diff --git a/src/n64/core/Mem.cpp b/src/n64/core/Mem.cpp index 170f64ff..23cebb23 100644 --- a/src/n64/core/Mem.cpp +++ b/src/n64/core/Mem.cpp @@ -16,7 +16,7 @@ void Mem::Reset() { mmio.Reset(); } -void Mem::LoadROM(const std::string& filename) { +u32 Mem::LoadROM(const std::string& filename) { std::ifstream file(filename, std::ios::binary); file.unsetf(std::ios::skipws); @@ -35,8 +35,12 @@ void Mem::LoadROM(const std::string& filename) { cart.insert(cart.begin(), std::istream_iterator(file), std::istream_iterator()); file.close(); - util::SwapN64Rom(sizeAdjusted, cart.data()); + + u32 crc = 0; + util::SwapN64Rom(crc, sizeAdjusted, cart.data()); memcpy(mmio.rsp.dmem, cart.data(), 0x1000); + + return crc; } template diff --git a/src/n64/core/Mem.hpp b/src/n64/core/Mem.hpp index 2e628f8a..aed0fdbd 100644 --- a/src/n64/core/Mem.hpp +++ b/src/n64/core/Mem.hpp @@ -11,7 +11,7 @@ struct Mem { ~Mem() = default; Mem(); void Reset(); - void LoadROM(const std::string&); + u32 LoadROM(const std::string&); [[nodiscard]] auto GetRDRAM() -> u8* { return mmio.rdp.dram.data(); } diff --git a/src/n64/core/RSP.cpp b/src/n64/core/RSP.cpp index 22643c89..145a600e 100644 --- a/src/n64/core/RSP.cpp +++ b/src/n64/core/RSP.cpp @@ -16,8 +16,7 @@ void RSP::Reset() { nextPC = 0; spDMASPAddr.raw = 0; spDMADRAMAddr.raw = 0; - spDMARDLen.raw = 0; - spDMAWRLen.raw = 0; + spDMALen.raw = 0; memset(dmem, 0, DMEM_SIZE); memset(imem, 0, IMEM_SIZE); memset(vpr, 0, 32 * sizeof(VPR)); @@ -44,8 +43,8 @@ auto RSP::Read(u32 addr) -> u32{ switch (addr) { case 0x04040000: return spDMASPAddr.raw & 0xFFFFF8; case 0x04040004: return spDMADRAMAddr.raw & 0x1FF8; - case 0x04040008: return spDMARDLen.raw; - case 0x0404000C: return spDMAWRLen.raw; + case 0x04040008: + case 0x0404000C: return spDMALen.raw; case 0x04040010: return spStatus.raw; case 0x04040018: return 0; case 0x0404001C: return AcquireSemaphore(); @@ -61,20 +60,22 @@ inline void DMA(SPDMALen len, RSP& rsp, u8* dst, u8* src) { length = (length + 0x7) & ~0x7; - u32 last_addr = rsp.spDMASPAddr.address + length; - if (last_addr > 0x1000) { - u32 overshoot = last_addr - 0x1000; - length -= overshoot; - } - u32 dram_address = rsp.spDMADRAMAddr.address & 0xFFFFF8; - u32 mem_address = rsp.spDMASPAddr.address & 0x1FF8; + u32 mem_address = rsp.spDMASPAddr.address & 0xFF8; for (int i = 0; i < len.count + 1; i++) { - if(isDRAMdest) { + /*if(isDRAMdest) { memcpy(&dst[dram_address], &src[mem_address], length); } else { memcpy(&dst[mem_address], &src[dram_address], length); + }*/ + + for(int j = 0; j < length; j++) { + if constexpr (isDRAMdest) { + dst[dram_address + j] = src[(mem_address + j) & 0xFFF]; + } else { + dst[(mem_address + j) & 0xFFF] = src[dram_address + j]; + } } int skip = i == len.count ? 0 : len.skip; @@ -82,6 +83,9 @@ inline void DMA(SPDMALen len, RSP& rsp, u8* dst, u8* src) { dram_address += (length + skip) & 0xFFFFF8; mem_address += length; } + + rsp.spDMADRAMAddr.address = dram_address; + rsp.spDMASPAddr.address = mem_address; } void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) { @@ -90,14 +94,14 @@ void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) { case 0x04040000: spDMASPAddr.raw = value & 0x1FF8; break; case 0x04040004: spDMADRAMAddr.raw = value & 0xFFFFF8; break; case 0x04040008: { - spDMARDLen.raw = value; - DMA(spDMARDLen, *this, spDMASPAddr.bank ? imem : dmem, mem.GetRDRAM()); - spDMARDLen.raw = 0xFF8 | (spDMARDLen.skip << 20); + spDMALen.raw = value; + DMA(spDMALen, *this, spDMASPAddr.bank ? imem : dmem, mem.GetRDRAM()); + spDMALen.raw = 0xFF8 | (spDMALen.skip << 20); } break; case 0x0404000C: { - spDMAWRLen.raw = value; - DMA(spDMAWRLen, *this, mem.GetRDRAM(), spDMASPAddr.bank ? imem : dmem); - spDMAWRLen.raw = 0xFF8 | (spDMAWRLen.skip << 20); + spDMALen.raw = value; + DMA(spDMALen, *this, mem.GetRDRAM(), spDMASPAddr.bank ? imem : dmem); + spDMALen.raw = 0xFF8 | (spDMALen.skip << 20); } break; case 0x04040010: { auto write = SPStatusWrite{.raw = value}; diff --git a/src/n64/core/RSP.hpp b/src/n64/core/RSP.hpp index 52a9ad77..48dfff99 100644 --- a/src/n64/core/RSP.hpp +++ b/src/n64/core/RSP.hpp @@ -3,7 +3,7 @@ #include #include -#define RSP_BYTE(addr) (dmem[BYTE_ADDRESS(addr) & 0xfff]) +#define RSP_BYTE(addr) (dmem[BYTE_ADDRESS(addr) & 0xFFF]) #define GET_RSP_HALF(addr) ((RSP_BYTE(addr) << 8) | RSP_BYTE((addr) + 1)) #define SET_RSP_HALF(addr, value) do { RSP_BYTE(addr) = ((value) >> 8) & 0xFF; RSP_BYTE((addr) + 1) = (value) & 0xFF;} while(0) #define GET_RSP_WORD(addr) ((GET_RSP_HALF(addr) << 16) | GET_RSP_HALF((addr) + 2)) @@ -117,7 +117,7 @@ struct RSP { u16 oldPC{}, pc{}, nextPC{}; SPDMASPAddr spDMASPAddr{}; SPDMADRAMAddr spDMADRAMAddr{}; - SPDMALen spDMARDLen{}, spDMAWRLen{}; + SPDMALen spDMALen{}; u8 dmem[DMEM_SIZE]{}, imem[IMEM_SIZE]{}; VPR vpr[32]{}; s32 gpr[32]{}; diff --git a/src/n64/core/mmio/AI.cpp b/src/n64/core/mmio/AI.cpp index fe6d3cc6..b7d59b1b 100644 --- a/src/n64/core/mmio/AI.cpp +++ b/src/n64/core/mmio/AI.cpp @@ -72,7 +72,7 @@ void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { } } -void AI::Step(Mem& mem, Registers& regs, int cpuCycles) { +void AI::Step(Mem& mem, Registers& regs, int cpuCycles, float volumeL, float volumeR) { cycles += cpuCycles; while(cycles > dac.period) { if (dmaCount == 0) { @@ -85,7 +85,7 @@ void AI::Step(Mem& mem, Registers& regs, int cpuCycles) { s16 left = (s16)(data >> 16); s16 right = (s16)data; - PushSample(left, right); + PushSample((float)left / INT16_MAX, volumeL, volumeR, (float)right / INT16_MAX); u32 address_lo = (dmaAddr[0] + 4) & 0x1fff; dmaAddr[0] = (dmaAddr[0] & ~0x1fff) | address_lo; diff --git a/src/n64/core/mmio/AI.hpp b/src/n64/core/mmio/AI.hpp index 88389cba..bec1ade8 100644 --- a/src/n64/core/mmio/AI.hpp +++ b/src/n64/core/mmio/AI.hpp @@ -11,7 +11,7 @@ struct AI { void Reset(); auto Read(u32) const -> u32; void Write(Mem&, Registers&, u32, u32); - void Step(Mem&, Registers&, int); + void Step(Mem&, Registers&, int, float, float); bool dmaEnable{}; u16 dacRate{}; u8 bitrate{}; diff --git a/src/n64/core/rsp/instructions.cpp b/src/n64/core/rsp/instructions.cpp index efe75899..68ca8e7d 100644 --- a/src/n64/core/rsp/instructions.cpp +++ b/src/n64/core/rsp/instructions.cpp @@ -20,8 +20,8 @@ inline auto GetCop0Reg(RSP& rsp, RDP& rdp, u8 index) -> u32{ switch(index) { case 0: return rsp.spDMASPAddr.raw; case 1: return rsp.spDMADRAMAddr.raw; - case 2: return rsp.spDMARDLen.raw; - case 3: return rsp.spDMAWRLen.raw; + case 2: + case 3: return rsp.spDMALen.raw; case 4: return rsp.spStatus.raw; case 5: return rsp.spStatus.dmaFull; case 6: return 0; @@ -36,8 +36,8 @@ inline void SetCop0Reg(MI& mi, Registers& regs, RSP& rsp, RDP& rdp, u8 index, u3 switch(index) { case 0: rsp.spDMASPAddr.raw = val; break; case 1: rsp.spDMADRAMAddr.raw = val; break; - case 2: rsp.spDMARDLen.raw = val; break; - case 3: rsp.spDMAWRLen.raw = val; break; + case 2: + case 3: rsp.spDMALen.raw = val; break; case 4: rsp.spStatus.raw = val; break; case 7: if(val == 0) { @@ -227,12 +227,14 @@ void RSP::sqv(u32 instr) { void RSP::sllv(u32 instr) { u8 sa = gpr[RS(instr)] & 0x1F; - gpr[RD(instr)] = gpr[RT(instr)] << sa; + s32 rt = gpr[RT(instr)]; + gpr[RD(instr)] = rt << sa; } void RSP::srlv(u32 instr) { u8 sa = gpr[RS(instr)] & 0x1F; - gpr[RD(instr)] = (u32)gpr[RT(instr)] >> sa; + u32 rt = gpr[RT(instr)]; + gpr[RD(instr)] = rt >> sa; } void RSP::srav(u32 instr) { diff --git a/src/util.hpp b/src/util.hpp index c3a385d3..c88ac093 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -131,23 +131,71 @@ inline void SwapBuffer16(size_t size, u8* data) { } } +inline u32 crc32(u32 crc, const u8 *buf, size_t len) { + static u32 table[256]; + static int have_table = 0; + u32 rem; + u8 octet; + int i, j; + const u8 *p, *q; + + if (have_table == 0) { + for (i = 0; i < 256; i++) { + rem = i; + for (j = 0; j < 8; j++) { + if (rem & 1) { + rem >>= 1; + rem ^= 0xedb88320; + } else + rem >>= 1; + } + table[i] = rem; + } + have_table = 1; + } + + crc = ~crc; + q = buf + len; + for (p = buf; p < q; p++) { + octet = *p; /* Cast to unsigned octet. */ + crc = (crc >> 8) ^ table[(crc & 0xff) ^ octet]; + } + return ~crc; +} + enum RomTypes { Z64 = 0x80371240, N64 = 0x40123780, V64 = 0x37804012 }; -inline void SwapN64Rom(size_t size, u8* data) { +inline void SwapN64Rom(u32& crc, size_t size, u8* rom) { RomTypes endianness; - memcpy(&endianness, data, 4); + memcpy(&endianness, rom, 4); endianness = static_cast(be32toh(endianness)); + switch(endianness) { - case V64: - SwapBuffer32(size, data); - SwapBuffer16(size, data); + case RomTypes::V64: { + u8* temp = (u8*)calloc(size, 1); + memcpy(temp, rom, size); + SwapBuffer16(size, temp); + crc = crc32(0, temp, size); + free(temp); + + SwapBuffer32(size, rom); + SwapBuffer16(size, rom); + } break; + case RomTypes::N64: { + u8* temp = (u8*)calloc(size, 1); + memcpy(temp, rom, size); + SwapBuffer32(size, temp); + crc = crc32(0, temp, size); + free(temp); + } break; + case RomTypes::Z64: + crc = crc32(0, rom, size); + SwapBuffer32(size, rom); break; - case N64: break; - case Z64: SwapBuffer32(size, data); break; default: panic("Unrecognized rom format! Make sure this is a valid Nintendo 64 ROM dump!\n"); }