Showing preview only (2,679K chars total). Download the full file or copy to clipboard to get everything.
Repository: euan-forrester/save-file-converter
Branch: main
Commit: 5935b41fc1fd
Files: 936
Total size: 2.4 MB
Directory structure:
gitextract_5fpwvxle/
├── .gitattributes
├── .gitignore
├── .vscode/
│ └── settings.json
├── LICENSE
├── README.md
├── frontend/
│ ├── .editorconfig
│ ├── .eslintignore
│ ├── .gitignore
│ ├── .nvmrc
│ ├── README.md
│ ├── babel.config.js
│ ├── buildspec.yml
│ ├── lib/
│ │ └── minlzo-js/
│ │ └── lzo1x.js
│ ├── package.json
│ ├── public/
│ │ ├── browserconfig.xml
│ │ ├── index.html
│ │ ├── robots.txt
│ │ ├── site.webmanifest
│ │ └── sitemap.txt
│ ├── src/
│ │ ├── App.vue
│ │ ├── components/
│ │ │ ├── AdvancedUtils.vue
│ │ │ ├── ByteExpandContract.vue
│ │ │ ├── CompressionDecompression.vue
│ │ │ ├── CompressionType.vue
│ │ │ ├── ConversionDirection.vue
│ │ │ ├── ConvertDreamcast.vue
│ │ │ ├── ConvertFlashCarts.vue
│ │ │ ├── ConvertGameCube.vue
│ │ │ ├── ConvertGbaActionReplay.vue
│ │ │ ├── ConvertGbaGameShark.vue
│ │ │ ├── ConvertGbaGameSharkSP.vue
│ │ │ ├── ConvertMister.vue
│ │ │ ├── ConvertN64DexDrive.vue
│ │ │ ├── ConvertN64Mempack.vue
│ │ │ ├── ConvertNintendoSwitchOnline.vue
│ │ │ ├── ConvertOnlineEmulators.vue
│ │ │ ├── ConvertPs1DexDrive.vue
│ │ │ ├── ConvertPs1Emulator.vue
│ │ │ ├── ConvertPs1Ps3.vue
│ │ │ ├── ConvertPs1Psp.vue
│ │ │ ├── ConvertRetron5.vue
│ │ │ ├── ConvertSegaCd.vue
│ │ │ ├── ConvertSegaSaturnEmulator.vue
│ │ │ ├── ConvertSegaSaturnSaroo.vue
│ │ │ ├── ConvertSrmSav.vue
│ │ │ ├── ConvertWii.vue
│ │ │ ├── DecryptPsp.vue
│ │ │ ├── DreamcastIndividualSaveTypeSelector.vue
│ │ │ ├── EndiannessWordSize.vue
│ │ │ ├── EraseSave.vue
│ │ │ ├── FileInfo.vue
│ │ │ ├── FileList.vue
│ │ │ ├── FileReader.vue
│ │ │ ├── FileSize.vue
│ │ │ ├── FlashCartType.vue
│ │ │ ├── GameCubeEncodingSelector.vue
│ │ │ ├── HeaderFooter.vue
│ │ │ ├── HelpButton.vue
│ │ │ ├── IndividualSavesOrMemoryCardSelector.vue
│ │ │ ├── InputFile.vue
│ │ │ ├── InputNumber.vue
│ │ │ ├── MemoryCardSelector.vue
│ │ │ ├── MisterPlatform.vue
│ │ │ ├── NintendoSwitchOnlinePlatform.vue
│ │ │ ├── OnlineEmulatorPlatform.vue
│ │ │ ├── OutputFilename.vue
│ │ │ ├── OutputFilesize.vue
│ │ │ ├── PadFillByte.vue
│ │ │ ├── RegionViewer.vue
│ │ │ ├── Retron5EraseSave.vue
│ │ │ ├── SegaCdSaveTypeSelector.vue
│ │ │ ├── TabAddHeaderFooter.vue
│ │ │ ├── TabByteExpansion.vue
│ │ │ ├── TabCompression.vue
│ │ │ ├── TabEndianSwap.vue
│ │ │ ├── TabFileCompare.vue
│ │ │ ├── TabRemoveHeaderFooter.vue
│ │ │ ├── TabResize.vue
│ │ │ ├── TabSlice.vue
│ │ │ ├── TroubleshootingUtils.vue
│ │ │ └── WiiVcPlatform.vue
│ │ ├── main.js
│ │ ├── plugins/
│ │ │ ├── bootstrap-vue.js
│ │ │ ├── fontawesome-vue.js
│ │ │ ├── google-tag-manager-vue.js
│ │ │ ├── mediaquery-vue.js
│ │ │ └── vue-async-computed.js
│ │ ├── rom-formats/
│ │ │ ├── PspIso.js
│ │ │ ├── SegaSaturnCueBin.js
│ │ │ ├── gb.js
│ │ │ ├── gba.js
│ │ │ ├── nes.js
│ │ │ └── sms.js
│ │ ├── router/
│ │ │ └── index.js
│ │ ├── save-formats/
│ │ │ ├── Dreamcast/
│ │ │ │ ├── Components/
│ │ │ │ │ ├── Basics.js
│ │ │ │ │ ├── Directory.js
│ │ │ │ │ ├── DirectoryEntry.js
│ │ │ │ │ ├── FileAllocationTable.js
│ │ │ │ │ └── SystemInfo.js
│ │ │ │ ├── Dreamcast.js
│ │ │ │ ├── IndividualSaves/
│ │ │ │ │ ├── Dci.js
│ │ │ │ │ └── VmiVms.js
│ │ │ │ └── Util.js
│ │ │ ├── FlashCarts/
│ │ │ │ ├── GB.js
│ │ │ │ ├── GBA/
│ │ │ │ │ ├── EmulatorBase.js
│ │ │ │ │ ├── GBA.js
│ │ │ │ │ ├── GoombaEmulator.js
│ │ │ │ │ ├── PocketNesEmulator.js
│ │ │ │ │ └── SmsAdvanceEmulator.js
│ │ │ │ ├── GameGear.js
│ │ │ │ ├── Genesis/
│ │ │ │ │ ├── MegaEverdrivePro/
│ │ │ │ │ │ ├── 32X.js
│ │ │ │ │ │ ├── Genesis.js
│ │ │ │ │ │ ├── NES.js
│ │ │ │ │ │ ├── SMS.js
│ │ │ │ │ │ └── SegaCd.js
│ │ │ │ │ └── MegaSD/
│ │ │ │ │ ├── 32X.js
│ │ │ │ │ ├── Genesis.js
│ │ │ │ │ ├── GenesisBase.js
│ │ │ │ │ ├── SMS.js
│ │ │ │ │ └── SegaCd.js
│ │ │ │ ├── N64/
│ │ │ │ │ ├── GB64Emulator.js
│ │ │ │ │ ├── N64.js
│ │ │ │ │ ├── NES.js
│ │ │ │ │ └── Neon64Emulator.js
│ │ │ │ ├── NES.js
│ │ │ │ ├── PcEngine.js
│ │ │ │ ├── SMS.js
│ │ │ │ └── SNES/
│ │ │ │ ├── GB.js
│ │ │ │ └── SNES.js
│ │ │ ├── GBA/
│ │ │ │ ├── ActionReplay.js
│ │ │ │ ├── GameShark.js
│ │ │ │ └── GameSharkSP.js
│ │ │ ├── GameCube/
│ │ │ │ ├── Components/
│ │ │ │ │ ├── Basics.js
│ │ │ │ │ ├── BlockAllocationTable.js
│ │ │ │ │ ├── Directory.js
│ │ │ │ │ ├── DirectoryEntry.js
│ │ │ │ │ └── Header.js
│ │ │ │ ├── GameCube.js
│ │ │ │ ├── GameSpecificFixups/
│ │ │ │ │ ├── FZeroGx.js
│ │ │ │ │ ├── GameSpecificFixups.js
│ │ │ │ │ └── PhantasyStarOnline.js
│ │ │ │ ├── IndividualSaves/
│ │ │ │ │ ├── GameShark.js
│ │ │ │ │ ├── Gci.js
│ │ │ │ │ ├── IndividualSaves.js
│ │ │ │ │ └── MaxDrive.js
│ │ │ │ └── Util.js
│ │ │ ├── Mister/
│ │ │ │ ├── GameGear.js
│ │ │ │ ├── Gameboy.js
│ │ │ │ ├── GameboyAdvance.js
│ │ │ │ ├── Genesis.js
│ │ │ │ ├── N64Cart.js
│ │ │ │ ├── N64Mempack.js
│ │ │ │ ├── Nes.js
│ │ │ │ ├── PcEngine.js
│ │ │ │ ├── Ps1.js
│ │ │ │ ├── SegaCd.js
│ │ │ │ ├── SegaSaturn.js
│ │ │ │ ├── Sms.js
│ │ │ │ ├── Snes.js
│ │ │ │ └── WonderSwan.js
│ │ │ ├── N64/
│ │ │ │ ├── Components/
│ │ │ │ │ ├── Basics.js
│ │ │ │ │ ├── GameSerialCodeUtil.js
│ │ │ │ │ ├── IdArea.js
│ │ │ │ │ ├── InodeTable.js
│ │ │ │ │ ├── NoteTable.js
│ │ │ │ │ └── TextDecoder.js
│ │ │ │ ├── DexDrive.js
│ │ │ │ ├── IndividualSaveFilename.js
│ │ │ │ └── Mempack.js
│ │ │ ├── NintendoSwitchOnline/
│ │ │ │ ├── Gameboy.js
│ │ │ │ ├── GameboyAdvance.js
│ │ │ │ ├── Genesis.js
│ │ │ │ ├── N64.js
│ │ │ │ ├── Nes.js
│ │ │ │ └── Snes.js
│ │ │ ├── OnlineEmulators/
│ │ │ │ ├── Emulators/
│ │ │ │ │ ├── EmulatorBase.js
│ │ │ │ │ ├── Gambatte.js
│ │ │ │ │ ├── Gb.js
│ │ │ │ │ ├── Snes9x.js
│ │ │ │ │ ├── VBA-Next.js
│ │ │ │ │ └── mGba.js
│ │ │ │ └── OnlineEmulatorWrapper.js
│ │ │ ├── PS1/
│ │ │ │ ├── Components/
│ │ │ │ │ ├── Basics.js
│ │ │ │ │ ├── DirectoryBlock.js
│ │ │ │ │ ├── SaveBlocks.js
│ │ │ │ │ └── SonyUtil.js
│ │ │ │ ├── DexDrive.js
│ │ │ │ ├── Memcard.js
│ │ │ │ ├── Ps3.js
│ │ │ │ └── Psp.js
│ │ │ ├── PSP/
│ │ │ │ ├── Executable.js
│ │ │ │ ├── ParamSfo.js
│ │ │ │ ├── PspEncryptionUtil.js
│ │ │ │ ├── Savefile.js
│ │ │ │ └── psp-encryption/
│ │ │ │ ├── psp-encryption.js
│ │ │ │ └── psp-encryption.wasm
│ │ │ ├── PlatformSaveSizes.js
│ │ │ ├── Retron5/
│ │ │ │ └── Retron5.js
│ │ │ ├── SegaCd/
│ │ │ │ ├── Crc16.js
│ │ │ │ ├── ReedSolomon.js
│ │ │ │ └── SegaCd.js
│ │ │ ├── SegaError.js
│ │ │ ├── SegaSaturn/
│ │ │ │ ├── Emulators/
│ │ │ │ │ ├── Emulators.js
│ │ │ │ │ ├── mednafen.js
│ │ │ │ │ ├── yabasanshiro.js
│ │ │ │ │ └── yabause.js
│ │ │ │ ├── IndividualSaves/
│ │ │ │ │ └── Bup.js
│ │ │ │ ├── Saroo/
│ │ │ │ │ ├── Cart.js
│ │ │ │ │ ├── Internal.js
│ │ │ │ │ ├── System.js
│ │ │ │ │ └── Util.js
│ │ │ │ ├── SegaSaturn.js
│ │ │ │ └── Util.js
│ │ │ └── Wii/
│ │ │ ├── ConvertFrom/
│ │ │ │ ├── ConvertFromN64.js
│ │ │ │ ├── ConvertFromPcEngine.js
│ │ │ │ ├── ConvertFromPlatform.js
│ │ │ │ └── ConvertFromSega.js
│ │ │ ├── GetPlatform/
│ │ │ │ ├── GetPlatform.js
│ │ │ │ └── HttpClient.js
│ │ │ └── Wii.js
│ │ ├── store/
│ │ │ └── index.js
│ │ ├── util/
│ │ │ ├── Array.js
│ │ │ ├── CompressionGzip.js
│ │ │ ├── CompressionLzo.js
│ │ │ ├── CompressionRzip.js
│ │ │ ├── CompressionZlib.js
│ │ │ ├── Endian.js
│ │ │ ├── Genesis.js
│ │ │ ├── Hash.js
│ │ │ ├── Math.js
│ │ │ ├── N64.js
│ │ │ ├── Padding.js
│ │ │ ├── PcEngine.js
│ │ │ ├── SaveFiles.js
│ │ │ ├── SegaCd.js
│ │ │ ├── crypto-aes.js
│ │ │ ├── crypto-des.js
│ │ │ └── util.js
│ │ └── views/
│ │ ├── About.vue
│ │ ├── AdvancedView.vue
│ │ ├── DownloadSaves.vue
│ │ ├── Dreamcast.vue
│ │ ├── EraseSaveView.vue
│ │ ├── FlashCarts.vue
│ │ ├── GameCube.vue
│ │ ├── GbaActionReplay.vue
│ │ ├── GbaGameShark.vue
│ │ ├── GbaGameSharkSP.vue
│ │ ├── Mister.vue
│ │ ├── N64DexDrive.vue
│ │ ├── N64Mempack.vue
│ │ ├── NintendoSwitchOnline.vue
│ │ ├── OnlineEmulators.vue
│ │ ├── OriginalHardware.vue
│ │ ├── OtherConverters.vue
│ │ ├── Ps1DexDrive.vue
│ │ ├── Ps1Emulator.vue
│ │ ├── Ps1Ps3.vue
│ │ ├── Ps1Psp.vue
│ │ ├── PspDecrypt.vue
│ │ ├── Retron5.vue
│ │ ├── Retron5EraseSaveView.vue
│ │ ├── SegaCd.vue
│ │ ├── SegaSaturnEmulator.vue
│ │ ├── SegaSaturnSaroo.vue
│ │ ├── SrmSav.vue
│ │ ├── Troubleshooting.vue
│ │ └── Wii.vue
│ ├── tests/
│ │ ├── config.js
│ │ ├── config.local.js.example
│ │ ├── data/
│ │ │ ├── rom-formats/
│ │ │ │ ├── gb/
│ │ │ │ │ ├── Wario Land 3 header.gbc
│ │ │ │ │ └── Zelda - Link's Awakening header.gb
│ │ │ │ ├── gba/
│ │ │ │ │ └── Zelda - Minish Cap header.gba
│ │ │ │ ├── nes/
│ │ │ │ │ └── Zelda II - header.nes
│ │ │ │ └── psp/
│ │ │ │ ├── encrypted-executable-alternative-boot - EBOOT.DNR
│ │ │ │ ├── encrypted-executable-alternative-boot.iso
│ │ │ │ ├── encrypted-executable-incorrect-magic.iso
│ │ │ │ ├── encrypted-executable-magic0.iso
│ │ │ │ ├── encrypted-executable-magic1.iso
│ │ │ │ ├── encrypted-executable-other-alternative-boot - GBL
│ │ │ │ ├── encrypted-executable-other-alternative-boot-wrong-game-id.iso
│ │ │ │ ├── encrypted-executable-other-alternative-boot.iso
│ │ │ │ └── unencrypted-executable.iso
│ │ │ ├── save-formats/
│ │ │ │ ├── dreamcast/
│ │ │ │ │ ├── individualsaves/
│ │ │ │ │ │ ├── FLPPYBRD-recreated.VMI
│ │ │ │ │ │ ├── FLPPYBRD.VMI
│ │ │ │ │ │ ├── FLPPYBRD.vms
│ │ │ │ │ │ ├── IKARUGA-recreated.VMI
│ │ │ │ │ │ ├── IKARUGA.VMI
│ │ │ │ │ │ ├── IKARUGA.VMS
│ │ │ │ │ │ ├── KISSPC-recreated.VMI
│ │ │ │ │ │ ├── KISSPC.VMI
│ │ │ │ │ │ ├── KISSPC.VMS
│ │ │ │ │ │ ├── kiss-psycho-circus-the-nightmare-child.29341-recreated.dci
│ │ │ │ │ │ ├── kiss-psycho-circus-the-nightmare-child.29341.dci
│ │ │ │ │ │ ├── project-justice.882-recreated.dci
│ │ │ │ │ │ ├── project-justice.882.dci
│ │ │ │ │ │ ├── tetr-recreated.dci
│ │ │ │ │ │ ├── tetr.dci
│ │ │ │ │ │ ├── v4596-recreated.vmi
│ │ │ │ │ │ ├── v4596.VMS
│ │ │ │ │ │ ├── v4596.vmi
│ │ │ │ │ │ ├── v93102-recreated.vmi
│ │ │ │ │ │ ├── v93102.VMS
│ │ │ │ │ │ └── v93102.vmi
│ │ │ │ │ ├── vmoooo.bin-0
│ │ │ │ │ └── vmu5_FUCKED.vmu
│ │ │ │ ├── flashcarts/
│ │ │ │ │ ├── gamegear/
│ │ │ │ │ │ └── Crystalis.sav
│ │ │ │ │ ├── gb/
│ │ │ │ │ │ └── Final Fantasy Legend II.srm
│ │ │ │ │ ├── gba/
│ │ │ │ │ │ ├── Metroid - Zero Mission (USA).sav
│ │ │ │ │ │ ├── goombaemulator/
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe) (32k - compressed save data).sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe) (32k - compressed save data).srm
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-from-cart.esv
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-from-cart.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-from-goomba.esv
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-from-goomba.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia) (32kB - uncompressed save data).sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia) (32kB - uncompressed save data).srm
│ │ │ │ │ │ │ ├── Wario Land 3.sav
│ │ │ │ │ │ │ └── Wario Land 3.srm
│ │ │ │ │ │ ├── pocketnesemulator/
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-from-cart.esv
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-from-cart.sav
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-from-pocketnes.esv
│ │ │ │ │ │ │ └── Zelda II - The Adventure of Link (USA)-from-pocketnes.sav
│ │ │ │ │ │ └── smsadvanceemulator/
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev 1)-from-coury-raw.srm
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev 1)-from-coury.srm
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev A)-from-emulator-to-smsadvance.sav
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev A)-from-emulator.sav
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (v1.3)-from-reddit-raw.srm
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (v1.3)-from-reddit.srm
│ │ │ │ │ │ ├── Phantasy Star-from-smsadvance-bundled-raw.sav
│ │ │ │ │ │ └── Phantasy Star-from-smsadvance-bundled.sav
│ │ │ │ │ ├── genesis/
│ │ │ │ │ │ ├── megaeverdrivepro/
│ │ │ │ │ │ │ ├── 36 Great Holes Starring Fred Couples (Japan, USA).srm
│ │ │ │ │ │ │ ├── Dark Wizard (USA) cd-bram.brm
│ │ │ │ │ │ │ ├── Knuckles' Chaotix (Japan, USA) (En).srm
│ │ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev A).srm
│ │ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A).srm
│ │ │ │ │ │ │ ├── Phantasy_Star_USA_Europe_Rev_A-byte-collapsed.srm
│ │ │ │ │ │ │ ├── Phantasy_Star_USA_Europe_Rev_A-byte-expanded.srm
│ │ │ │ │ │ │ ├── Popful Mail (USA) (RE) cd-cart-raw.srm
│ │ │ │ │ │ │ ├── Popful Mail (USA) (RE) cd-cart.srm
│ │ │ │ │ │ │ ├── Popful Mail (USA) (RE)-from-emulator cart.brm
│ │ │ │ │ │ │ ├── Popful Mail (USA) (RE)-from-emulator-to-med cd-cart.srm
│ │ │ │ │ │ │ ├── Sonic The Hedgehog 3 (USA).srm
│ │ │ │ │ │ │ ├── Wonder Boy in Monster World (USA, Europe).srm
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA).srm
│ │ │ │ │ │ │ └── emulator/
│ │ │ │ │ │ │ └── Sonic The Hedgehog 3 (USA).sav
│ │ │ │ │ │ └── megasd/
│ │ │ │ │ │ ├── 36 Great Holes Starring Fred Couples (Japan, USA)-raw.sav
│ │ │ │ │ │ ├── 36 Great Holes Starring Fred Couples (Japan, USA).SRM
│ │ │ │ │ │ ├── Knuckles' Chaotix (Japan, USA) (En)-raw.sav
│ │ │ │ │ │ ├── Knuckles' Chaotix (Japan, USA) (En).SRM
│ │ │ │ │ │ ├── Lunar_The_Silver_Star-internal-memory.brm
│ │ │ │ │ │ ├── Lunar_The_Silver_Star-ram-cart.brm
│ │ │ │ │ │ ├── Lunar_The_Silver_Star.SRM
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev 1)-raw.sav
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev 1).SRM
│ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A)-new-style-raw.sav
│ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A)-new-style.SRM
│ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A)-old-style-raw.sav
│ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A)-old-style.srm
│ │ │ │ │ │ ├── Phantasy Star IV (USA)-new-style-converted-back.SRM
│ │ │ │ │ │ ├── Phantasy Star IV (USA)-new-style-raw.sav
│ │ │ │ │ │ ├── Phantasy Star IV (USA)-new-style.SRM
│ │ │ │ │ │ ├── Popful Mail (U)-converted-back-internal-memory.SRM
│ │ │ │ │ │ ├── Popful Mail (U)-converted-back-ram-cart.SRM
│ │ │ │ │ │ ├── Popful Mail (U)-internal-memory-only.SRM
│ │ │ │ │ │ ├── Popful Mail (U)-internal-memory.brm
│ │ │ │ │ │ ├── Popful Mail (U)-ram-cart.brm
│ │ │ │ │ │ ├── Popful Mail (U).SRM
│ │ │ │ │ │ ├── Sonic the Hedgehog 3 (USA)-new-style-raw.sav
│ │ │ │ │ │ ├── Sonic the Hedgehog 3 (USA)-new-style.SRM
│ │ │ │ │ │ ├── Sword of Vermilion (USA, Europe)-new-style-raw.sav
│ │ │ │ │ │ ├── Sword of Vermilion (USA, Europe)-new-style.SRM
│ │ │ │ │ │ ├── Wonder Boy in Monster World (USA, Europe)-new-style-raw.sav
│ │ │ │ │ │ ├── Wonder Boy in Monster World (USA, Europe)-new-style.SRM
│ │ │ │ │ │ ├── Wonder Boy in Monster World (USA, Europe)-old-style.srm
│ │ │ │ │ │ └── emulator/
│ │ │ │ │ │ └── Sonic The Hedgehog 3 (USA).sav
│ │ │ │ │ ├── n64/
│ │ │ │ │ │ ├── Pokemon Snap-flashcart.fla
│ │ │ │ │ │ ├── Pokemon Snap.fla
│ │ │ │ │ │ ├── Star Fox 64.eep
│ │ │ │ │ │ ├── f-zero-x.15165-flashcart.sra
│ │ │ │ │ │ ├── f-zero-x.15165.sra
│ │ │ │ │ │ ├── gb64emulator/
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-emulator-to-everdrive.fla
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-emulator.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-everdrive-to-raw.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-everdrive-uncompressed-data.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-everdrive.fla
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia)-emulator-to-everdrive.fla
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia)-emulator.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia)-everdrive-to-raw.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia)-everdrive-uncompressed-data.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia)-everdrive.fla
│ │ │ │ │ │ │ ├── Wario Land 3 (World) (En,Ja)-emulator-to-everdrive.fla
│ │ │ │ │ │ │ ├── Wario Land 3 (World) (En,Ja)-emulator.sav
│ │ │ │ │ │ │ ├── Wario Land 3 (World) (En,Ja)-everdrive-to-raw.sav
│ │ │ │ │ │ │ ├── Wario Land 3 (World) (En,Ja)-everdrive-uncompressed-data.sav
│ │ │ │ │ │ │ └── Wario Land 3 (World) (En,Ja)-everdrive.fla
│ │ │ │ │ │ ├── neon64emulator/
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-neon.srm
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-to-raw.sav
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link-cart-to-neon.srm
│ │ │ │ │ │ │ └── Zelda II - The Adventure of Link-cart.sav
│ │ │ │ │ │ ├── nes/
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-from-cart-to-everdrive.sav
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-from-cart.sav
│ │ │ │ │ │ │ └── Zelda II - The Adventure of Link (USA)-from-everdrive.srm
│ │ │ │ │ │ └── yoshis-story.17238.eep
│ │ │ │ │ ├── nes/
│ │ │ │ │ │ └── Crystalis.sav
│ │ │ │ │ ├── pcengine/
│ │ │ │ │ │ └── Castlevania - Rondo of Blood (my save) - raw.sav
│ │ │ │ │ ├── sms/
│ │ │ │ │ │ └── Phantasy Star (USA, Europe) (Rev A).srm
│ │ │ │ │ └── snes/
│ │ │ │ │ ├── Donkey Kong Country 2 - Diddy's Kong Quest.srm
│ │ │ │ │ └── Legend of Zelda, The - Link's Awakening (USA, Europe).srm
│ │ │ │ ├── gamecube/
│ │ │ │ │ ├── GameShark/
│ │ │ │ │ │ ├── soulcalibur-ii.20763.gcs
│ │ │ │ │ │ └── soulcalibur-ii.20766.gcs
│ │ │ │ │ ├── GameSpecificFixups/
│ │ │ │ │ │ ├── f_zero_gx_usa.gci
│ │ │ │ │ │ └── phantasy-star-online-SNUGGLES-WEAPONS.gcp
│ │ │ │ │ ├── MaxDrive/
│ │ │ │ │ │ ├── soulcalibur-ii.20764.sav
│ │ │ │ │ │ └── soulcalibur-ii.8736.sav
│ │ │ │ │ ├── gci/
│ │ │ │ │ │ ├── bleach_gc_tasogare_ni_mamieru_shinigami_jp.gci
│ │ │ │ │ │ ├── dokapon_dx_wataru_sekai_wa_oni_darake_jp_1.gci
│ │ │ │ │ │ ├── hikaru_no_go_3_jp.gci
│ │ │ │ │ │ ├── konjiki_no_gashbell__yuujou_no_tag_battle_jp.gci
│ │ │ │ │ │ ├── need_for_speed_underground_2_usa-recreated.gci
│ │ │ │ │ │ └── need_for_speed_underground_2_usa.gci
│ │ │ │ │ ├── jpn-empty-0251b-16mb.raw
│ │ │ │ │ ├── memcard-image-empty-no-serial.raw
│ │ │ │ │ ├── memcard-image-japan-nintendont.raw
│ │ │ │ │ ├── memcard-image-recreated-fzero-no-serial.raw
│ │ │ │ │ ├── memcard-image-recreated-fzero.raw
│ │ │ │ │ ├── memcard-image-recreated-resized.raw
│ │ │ │ │ ├── memcard-image-recreated.raw
│ │ │ │ │ ├── memcard-image.raw
│ │ │ │ │ ├── mine-different-flash-id-different-date.raw
│ │ │ │ │ ├── mine-different-flash-id.raw
│ │ │ │ │ ├── mine-same-flash-id-different-date.raw
│ │ │ │ │ ├── mine-same-flash-id.raw
│ │ │ │ │ └── usa-empty-0251b-16mb.raw
│ │ │ │ ├── gba/
│ │ │ │ │ ├── action-replay/
│ │ │ │ │ │ ├── the-legend-of-zelda-the-minish-cap.11439.srm
│ │ │ │ │ │ └── the-legend-of-zelda-the-minish-cap.11439.xps
│ │ │ │ │ ├── gameshark/
│ │ │ │ │ │ ├── mario-and-luigi-superstar-saga.25949.sps
│ │ │ │ │ │ ├── the-legend-of-zelda-the-minish-cap.6650.sps
│ │ │ │ │ │ ├── the-legend-of-zelda-the-minish-cap.6650.sps-2
│ │ │ │ │ │ └── the-legend-of-zelda-the-minish-cap.6650.srm
│ │ │ │ │ └── gameshark-sp/
│ │ │ │ │ ├── final-fantasy-tactics-advance.22864.gsv
│ │ │ │ │ └── final-fantasy-tactics-advance.22864.srm
│ │ │ │ ├── mister/
│ │ │ │ │ ├── gba/
│ │ │ │ │ │ ├── Final_Fight_One_Japan-mister.sav
│ │ │ │ │ │ ├── Final_Fight_One_Japan-raw-converted-back.srm
│ │ │ │ │ │ ├── Final_Fight_One_Japan-raw.srm
│ │ │ │ │ │ ├── pokemon-sapphire-mister-fake-rtc.sav
│ │ │ │ │ │ ├── pokemon-sapphire-mister-no-rtc.sav
│ │ │ │ │ │ ├── pokemon-sapphire-raw.srm
│ │ │ │ │ │ ├── the-legend-of-zelda-the-minish-cap.sav
│ │ │ │ │ │ └── the-legend-of-zelda-the-minish-cap.srm
│ │ │ │ │ ├── genesis/
│ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A)-from-mega-sd.sav
│ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A)-from-mega-sd.srm
│ │ │ │ │ │ ├── Phantasy_Star_IV_USA-from-mister-zero-padded-to-raw.srm
│ │ │ │ │ │ ├── Phantasy_Star_IV_USA-from-mister-zero-padded.sav
│ │ │ │ │ │ ├── Phantasy_Star_IV_USA-from-retrode-to-mister.sav
│ │ │ │ │ │ ├── Phantasy_Star_IV_USA-from-retrode.srm
│ │ │ │ │ │ ├── Wonder Boy in Monster World mister.sav
│ │ │ │ │ │ ├── Wonder Boy in Monster World raw.srm
│ │ │ │ │ │ ├── phantasy-star-ii.18168-mister.sav
│ │ │ │ │ │ └── phantasy-star-ii.18168-raw.srm
│ │ │ │ │ ├── n64/
│ │ │ │ │ │ ├── 007 - The World Is Not Enough (USA)_1.cpk
│ │ │ │ │ │ ├── Banjo-Kazooie (USA).eep
│ │ │ │ │ │ ├── Donkey Kong 64 (USA).eep
│ │ │ │ │ │ ├── Legend of Zelda, The - Majora's Mask (USA).fla
│ │ │ │ │ │ └── Legend of Zelda, The - Ocarina of Time (USA).sra
│ │ │ │ │ ├── segacd/
│ │ │ │ │ │ ├── Empty-mister-save.sav
│ │ │ │ │ │ ├── Popful Mail (USA) (RE)-internal-plus-raw-cart-to-mister.sav
│ │ │ │ │ │ ├── Popful Mail (USA) (RE)-mister-internal-only.sav
│ │ │ │ │ │ ├── Popful Mail (USA) (RE)-ram-cart-only.brm
│ │ │ │ │ │ ├── Popful Mail (USA) (RE)-raw-cart-only-to-mister.sav
│ │ │ │ │ │ ├── Popful Mail (USA) (RE)-raw-internal.brm
│ │ │ │ │ │ ├── Popful Mail (USA) Internal plus Cart to-emulator-internal.brm
│ │ │ │ │ │ ├── Popful Mail (USA) Internal plus Cart to-emulator-ram-cart.brm
│ │ │ │ │ │ ├── Popful Mail (USA) Internal plus Cart-mister.sav
│ │ │ │ │ │ ├── Shining Force CD (USA) (3R)-mister-internal-only-padded.sav
│ │ │ │ │ │ └── Shining Force CD (USA) (3R)-to-emulator-internal.brm
│ │ │ │ │ └── segasaturn/
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA)-recreated.sav
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA).bkr
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA).sav
│ │ │ │ │ ├── Empty-mister-save.sav
│ │ │ │ │ ├── Pretend-mister-save-only-cart.sav
│ │ │ │ │ ├── Rayman (USA) (R2)-cart-uncompressed.bcr
│ │ │ │ │ ├── Rayman (USA) (R2)-cart.bcr
│ │ │ │ │ ├── Rayman (USA) (R2)-internal.bkr
│ │ │ │ │ ├── Rayman (USA) (R2).sav
│ │ │ │ │ ├── Sega Rally Championship Plus (Japan).bkr
│ │ │ │ │ └── Sega Rally Championship Plus (Japan).sav
│ │ │ │ ├── n64/
│ │ │ │ │ ├── dexdrive/
│ │ │ │ │ │ ├── Ready 2 Rumble Boxing (U) [!]-fixed-1
│ │ │ │ │ │ ├── Ready 2 Rumble Boxing (U) [!]-fixed-2
│ │ │ │ │ │ ├── Ready 2 Rumble Boxing (U) [!]-fixed.mpk
│ │ │ │ │ │ ├── Ready 2 Rumble Boxing (U) [!].n64
│ │ │ │ │ │ ├── banjo-kazooie.1141-1
│ │ │ │ │ │ ├── banjo-kazooie.1141-2
│ │ │ │ │ │ ├── banjo-kazooie.1141-3
│ │ │ │ │ │ ├── banjo-kazooie.1141-4
│ │ │ │ │ │ ├── banjo-kazooie.1141.mpk
│ │ │ │ │ │ ├── banjo-kazooie.1141.n64
│ │ │ │ │ │ ├── banjokaz-1
│ │ │ │ │ │ ├── banjokaz-2
│ │ │ │ │ │ ├── banjokaz.mpk
│ │ │ │ │ │ ├── banjokaz.n64
│ │ │ │ │ │ ├── donkey-kong-64.1156-1
│ │ │ │ │ │ ├── donkey-kong-64.1156.mpk
│ │ │ │ │ │ ├── donkey-kong-64.1156.n64
│ │ │ │ │ │ ├── ecw-hardcore-revolution-empty-header.1000.n64
│ │ │ │ │ │ ├── ecw-hardcore-revolution-no-header.1000.n64
│ │ │ │ │ │ ├── ecw-hardcore-revolution.1000-1
│ │ │ │ │ │ ├── ecw-hardcore-revolution.1000.mpk
│ │ │ │ │ │ ├── ecw-hardcore-revolution.1000.n64
│ │ │ │ │ │ ├── mario-kart-64.1102.eep
│ │ │ │ │ │ ├── mario-kart-64.1102.n64
│ │ │ │ │ │ ├── mario-kart-64.1116-1
│ │ │ │ │ │ ├── mario-kart-64.1116.mpk
│ │ │ │ │ │ ├── mario-kart-64.1116.n64
│ │ │ │ │ │ ├── perfect-dark.1043.1116-1
│ │ │ │ │ │ ├── perfect-dark.1043.mpk
│ │ │ │ │ │ ├── perfect-dark.1043.n64
│ │ │ │ │ │ ├── san-francisco-rush-extreme-racing.1103-1
│ │ │ │ │ │ ├── san-francisco-rush-extreme-racing.1103.mpk
│ │ │ │ │ │ ├── san-francisco-rush-extreme-racing.1103.n64
│ │ │ │ │ │ ├── super-mario-64.1091-1
│ │ │ │ │ │ ├── super-mario-64.1091.mpk
│ │ │ │ │ │ ├── super-mario-64.1091.n64
│ │ │ │ │ │ ├── tony-hawks-pro-skater-2.1077-1
│ │ │ │ │ │ ├── tony-hawks-pro-skater-2.1077-2
│ │ │ │ │ │ ├── tony-hawks-pro-skater-2.1077-output.n64
│ │ │ │ │ │ ├── tony-hawks-pro-skater-2.1077.mpk
│ │ │ │ │ │ └── tony-hawks-pro-skater-2.1077.n64
│ │ │ │ │ └── mempack/
│ │ │ │ │ ├── banjokaz-1
│ │ │ │ │ ├── mario-kart-64.1116-1
│ │ │ │ │ ├── mario-kart-64.1116.mpk
│ │ │ │ │ ├── san-francisco-rush-extreme-racing.1103-1
│ │ │ │ │ ├── super-mario-64.1091-1
│ │ │ │ │ ├── tony-hawks-pro-skater-2.1077-1
│ │ │ │ │ ├── tony-hawks-pro-skater-2.1077-2
│ │ │ │ │ └── tony-hawks-pro-skater-2.1077.mpk
│ │ │ │ ├── nintendoswitchonline/
│ │ │ │ │ ├── gb/
│ │ │ │ │ │ ├── Kirbys_Dreamland_2.sav
│ │ │ │ │ │ ├── Kirbys_Dreamland_2.sram
│ │ │ │ │ │ ├── Links_Awakening_DX.sav
│ │ │ │ │ │ ├── Links_Awakening_DX.sram
│ │ │ │ │ │ ├── Metroid_II_Return_of_Samus.sav
│ │ │ │ │ │ ├── Metroid_II_Return_of_Samus.sram
│ │ │ │ │ │ ├── Pokemon Cristal.sav
│ │ │ │ │ │ ├── Pokemon Cristal.sram
│ │ │ │ │ │ ├── Pokemon_-_Crystal_Version.sav
│ │ │ │ │ │ ├── Pokemon_-_Crystal_Version.sram
│ │ │ │ │ │ ├── Pokemon_TCG.sav
│ │ │ │ │ │ ├── Pokemon_TCG.sram
│ │ │ │ │ │ ├── Pokemon_TCG_Europe.sav
│ │ │ │ │ │ ├── Pokemon_TCG_Europe.sram
│ │ │ │ │ │ ├── Wario_Land_3.sav
│ │ │ │ │ │ └── Wario_Land_3.sram
│ │ │ │ │ ├── gba/
│ │ │ │ │ │ └── The_Legend_of_Zelda_The_Minish_Cap.sram
│ │ │ │ │ ├── genesis/
│ │ │ │ │ │ ├── MegaMan Wily Wars SEGA GENESIS.sav
│ │ │ │ │ │ ├── MegaMan Wily Wars SEGA GENESIS.sram
│ │ │ │ │ │ ├── Phantasy Star 4 SEGA GENESIS.sav
│ │ │ │ │ │ └── Phantasy Star 4 SEGA GENESIS.sram
│ │ │ │ │ ├── n64/
│ │ │ │ │ │ ├── F-Zero N64.sra
│ │ │ │ │ │ ├── F-Zero N64.sram
│ │ │ │ │ │ ├── Majoras Mask N64.fla
│ │ │ │ │ │ ├── Majoras Mask N64.sram
│ │ │ │ │ │ ├── Mario 64 N64.sram
│ │ │ │ │ │ ├── Mario Tennis N64.sram
│ │ │ │ │ │ └── Operation Winback N64.sram
│ │ │ │ │ ├── nes/
│ │ │ │ │ │ ├── Legend_of_Zelda_The_USA_Rev_1.sram
│ │ │ │ │ │ └── Zelda-converted.srm
│ │ │ │ │ └── snes/
│ │ │ │ │ └── Super Mario World SNES.sram
│ │ │ │ ├── online-emulators/
│ │ │ │ │ ├── arcadespot.com/
│ │ │ │ │ │ ├── gb/
│ │ │ │ │ │ │ ├── final-fantasy-legend.sav
│ │ │ │ │ │ │ ├── final-fantasy-legend.save
│ │ │ │ │ │ │ ├── invalid-save-state.save
│ │ │ │ │ │ │ ├── legend-of-zelda-the-links-awakening.sav
│ │ │ │ │ │ │ ├── legend-of-zelda-the-links-awakening.save
│ │ │ │ │ │ │ ├── pokemon-crystal.sav
│ │ │ │ │ │ │ ├── pokemon-crystal.save
│ │ │ │ │ │ │ ├── pokemon-yellow.sav
│ │ │ │ │ │ │ ├── pokemon-yellow.save
│ │ │ │ │ │ │ ├── the-legend-of-zelda-links-awakening-dx.sav
│ │ │ │ │ │ │ ├── the-legend-of-zelda-links-awakening-dx.save
│ │ │ │ │ │ │ ├── the-legend-of-zelda-oracle-of-seasons.sav
│ │ │ │ │ │ │ ├── the-legend-of-zelda-oracle-of-seasons.save
│ │ │ │ │ │ │ ├── wario-land-2.sav
│ │ │ │ │ │ │ └── wario-land-2.save
│ │ │ │ │ │ ├── gba/
│ │ │ │ │ │ │ ├── advance-wars.sav
│ │ │ │ │ │ │ ├── advance-wars.save
│ │ │ │ │ │ │ ├── donkey-kong-country-3.sav
│ │ │ │ │ │ │ ├── donkey-kong-country-3.save
│ │ │ │ │ │ │ ├── golden-sun.sav
│ │ │ │ │ │ │ ├── golden-sun.save
│ │ │ │ │ │ │ ├── invalid-save-state.save
│ │ │ │ │ │ │ ├── metroid-fusion.sav
│ │ │ │ │ │ │ ├── metroid-fusion.save
│ │ │ │ │ │ │ ├── metroid-zero-mission.sav
│ │ │ │ │ │ │ ├── metroid-zero-mission.save
│ │ │ │ │ │ │ ├── pokemon-sapphire.sav
│ │ │ │ │ │ │ ├── pokemon-sapphire.save
│ │ │ │ │ │ │ ├── super-mario-advance-4.sav
│ │ │ │ │ │ │ ├── super-mario-advance-4.save
│ │ │ │ │ │ │ ├── the-legend-of-zelda-the-minish-cap.sav
│ │ │ │ │ │ │ └── the-legend-of-zelda-the-minish-cap.save
│ │ │ │ │ │ ├── genesis/
│ │ │ │ │ │ │ ├── phantasy-star-ii.save
│ │ │ │ │ │ │ └── readme
│ │ │ │ │ │ └── snes/
│ │ │ │ │ │ ├── Legend-of-Zelda-The-A-Link-to-the-Past-U-.sav
│ │ │ │ │ │ └── Legend-of-Zelda-The-A-Link-to-the-Past-U-.save
│ │ │ │ │ ├── myemulator.online/
│ │ │ │ │ │ ├── gba/
│ │ │ │ │ │ │ ├── gbazelda-0.sav
│ │ │ │ │ │ │ ├── gbazelda-1.sav
│ │ │ │ │ │ │ ├── gbazelda-2.sav
│ │ │ │ │ │ │ ├── gbazelda-3.sav
│ │ │ │ │ │ │ └── gbazelda.ggz
│ │ │ │ │ │ ├── genesis/
│ │ │ │ │ │ │ ├── genesisphantasystar4.ggz
│ │ │ │ │ │ │ └── readme
│ │ │ │ │ │ └── snes/
│ │ │ │ │ │ ├── sneszelda1.ggz
│ │ │ │ │ │ └── sneszelda1.sav
│ │ │ │ │ └── retrogames.onl/
│ │ │ │ │ ├── gb/
│ │ │ │ │ │ ├── final-fantasy-legend-gboy.sav
│ │ │ │ │ │ ├── final-fantasy-legend-gboy.state
│ │ │ │ │ │ ├── invalid-file.state
│ │ │ │ │ │ ├── legend-zelda-link-awakening-dx.sav
│ │ │ │ │ │ ├── legend-zelda-link-awakening-dx.state
│ │ │ │ │ │ ├── pokemon-crystal.sav
│ │ │ │ │ │ ├── pokemon-crystal.state
│ │ │ │ │ │ ├── pokemon-yellow.sav
│ │ │ │ │ │ ├── pokemon-yellow.state
│ │ │ │ │ │ ├── wario-land-2-gbcolor.sav
│ │ │ │ │ │ ├── wario-land-2-gbcolor.state
│ │ │ │ │ │ ├── wrong-size.state
│ │ │ │ │ │ ├── zelda-oracle-sesion.sav
│ │ │ │ │ │ └── zelda-oracle-sesion.state
│ │ │ │ │ └── gba/
│ │ │ │ │ ├── advance-wars-gmba.sav
│ │ │ │ │ ├── advance-wars-gmba.state
│ │ │ │ │ ├── baldurs-gate.sav
│ │ │ │ │ ├── baldurs-gate.state
│ │ │ │ │ ├── golden-sun-gmba.sav
│ │ │ │ │ ├── golden-sun-gmba.state
│ │ │ │ │ ├── invalid-file.state
│ │ │ │ │ ├── metroid-fusion.sav
│ │ │ │ │ ├── metroid-fusion.state
│ │ │ │ │ ├── metroid-zero-mission.sav
│ │ │ │ │ ├── metroid-zero-mission.state
│ │ │ │ │ ├── pokemon-sapphire.sav
│ │ │ │ │ ├── pokemon-sapphire.state
│ │ │ │ │ ├── super-mario-advance-4.sav
│ │ │ │ │ ├── super-mario-advance-4.state
│ │ │ │ │ ├── wrong-size.state
│ │ │ │ │ ├── zelda-minish-cap.sav
│ │ │ │ │ └── zelda-minish-cap.state
│ │ │ │ ├── ps1/
│ │ │ │ │ ├── dexdrive/
│ │ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.BASLUS-00067DRAX00.srm
│ │ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.gme
│ │ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.mcr
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1368-BASLUS-00067DRAX01.srm
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1368.gme
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1782-BASLUS-00067DRAX00.srm
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1782-BASLUS-00067DRAX01.srm
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1782.gme
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.3172.gme
│ │ │ │ │ │ ├── digimon-world.21133-BASLUS-01032DMR0.srm
│ │ │ │ │ │ ├── digimon-world.21133.gme
│ │ │ │ │ │ ├── gran-turismo.26535-BASCUS-94194GT.srm
│ │ │ │ │ │ ├── gran-turismo.26535.gme
│ │ │ │ │ │ ├── gran-turismo.26537-BASCUS-94194GT.srm
│ │ │ │ │ │ ├── gran-turismo.26537-BASCUS-94194RT.srm
│ │ │ │ │ │ ├── gran-turismo.26537-output.gme
│ │ │ │ │ │ ├── gran-turismo.26537.gme
│ │ │ │ │ │ ├── tony-hawks-pro-skater-4.24197-BASLUS-01485PNMOG01.srm
│ │ │ │ │ │ └── tony-hawks-pro-skater-4.24197.gme
│ │ │ │ │ ├── memcard/
│ │ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.BASLUS-00067DRAX00.srm
│ │ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.mcr
│ │ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).1.mcr
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1782-BASLUS-00067DRAX00.srm
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1782-BASLUS-00067DRAX01.srm
│ │ │ │ │ │ ├── gran-turismo.26537-BASCUS-94194GT.srm
│ │ │ │ │ │ └── gran-turismo.26537-BASCUS-94194RT.srm
│ │ │ │ │ ├── ps3/
│ │ │ │ │ │ ├── Street Fighter EX2 Plus-BASLUS-0110553595354454D.PSV
│ │ │ │ │ │ ├── Suikoden 2-BASLUS-009584753322D37.PSV
│ │ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-7.srm
│ │ │ │ │ │ └── street-fighter-ex2-plus.17782.mcr
│ │ │ │ │ └── psp/
│ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.BASLUS-00067DRAX00.srm
│ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.VMP
│ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.mcr
│ │ │ │ │ ├── Suikoden 1-save-editor-signature.VMP
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-1.srm
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-2.srm
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-3.srm
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-4.srm
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-5.srm
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-6.srm
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-7.srm
│ │ │ │ │ ├── Suikoden 2-no-signature.VMP
│ │ │ │ │ ├── Suikoden 2-psp-signature.VMP
│ │ │ │ │ ├── Suikoden 2-vita-mcr2vmp-signature.VMP
│ │ │ │ │ ├── Suikoden 2.VMP
│ │ │ │ │ ├── gran-turismo.26537-BASCUS-94194GT.srm
│ │ │ │ │ ├── gran-turismo.26537-BASCUS-94194RT.srm
│ │ │ │ │ └── gran-turismo.26537-output.vmp
│ │ │ │ ├── psp/
│ │ │ │ │ ├── DRACULA-PARAM-reencrypted-debug.SFO
│ │ │ │ │ ├── DRACULA-PARAM-reencrypted-release.SFO
│ │ │ │ │ ├── DRACULA-PARAM.SFO
│ │ │ │ │ └── PARAM.SFO
│ │ │ │ ├── retron5/
│ │ │ │ │ ├── Final Fantasy III (USA).sav
│ │ │ │ │ ├── Final Fantasy III (USA).srm
│ │ │ │ │ ├── Tomato Adventure (Japan)-truncated.srm
│ │ │ │ │ └── Tomato Adventure (Japan).sav
│ │ │ │ ├── segacd/
│ │ │ │ │ ├── Multiple titles - corrupted.brm
│ │ │ │ │ ├── Multiple titles - created by program.brm
│ │ │ │ │ ├── Multiple titles-1.srm
│ │ │ │ │ ├── Multiple titles-2.srm
│ │ │ │ │ ├── Multiple titles-3.srm
│ │ │ │ │ ├── Multiple titles-4.srm
│ │ │ │ │ ├── Multiple titles-5.srm
│ │ │ │ │ ├── Multiple titles-6.srm
│ │ │ │ │ ├── Multiple titles-7.srm
│ │ │ │ │ ├── Multiple titles.brm
│ │ │ │ │ ├── Popful Mail (U)-internal-memory-1.srm
│ │ │ │ │ ├── Popful Mail (U)-internal-memory.brm
│ │ │ │ │ ├── SHINING FORCE CD-0.srm
│ │ │ │ │ ├── SHINING FORCE CD-1.srm
│ │ │ │ │ ├── SHINING FORCE CD-2.srm
│ │ │ │ │ ├── SHINING FORCE CD-3.srm
│ │ │ │ │ ├── SHINING FORCE CD-4.srm
│ │ │ │ │ └── SHINING FORCE CD.brm
│ │ │ │ ├── segasaturn/
│ │ │ │ │ ├── DRACULAX-recreated.BUP
│ │ │ │ │ ├── DRACULAX.BUP
│ │ │ │ │ ├── DRACULAX.raw
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA)-1.raw
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA)-2.raw
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA)-uncompressed-recreated.bcr
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA)-uncompressed.bcr
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA).bcr
│ │ │ │ │ ├── Dezaemon 2 (Japan)-1.raw
│ │ │ │ │ ├── Dezaemon 2 (Japan).bkr
│ │ │ │ │ ├── Empty save.bkr
│ │ │ │ │ ├── Hyper Duel (Japan)-1.raw
│ │ │ │ │ ├── Hyper Duel (Japan).bkr
│ │ │ │ │ ├── SFORCE31-recreated.BUP
│ │ │ │ │ ├── SFORCE31.BUP
│ │ │ │ │ ├── SFORCE31.raw
│ │ │ │ │ ├── Shining Force III Scenario 3 (English v25.1)-1.raw
│ │ │ │ │ ├── Shining Force III Scenario 3 (English v25.1)-cart-1.raw
│ │ │ │ │ ├── Shining Force III Scenario 3 (English v25.1)-recreated.bcr
│ │ │ │ │ ├── Shining Force III Scenario 3 (English v25.1)-uncompressed.bcr
│ │ │ │ │ ├── Shining Force III Scenario 3 (English v25.1).bcr
│ │ │ │ │ ├── Shining Force III Scenario 3 (English v25.1).bkr
│ │ │ │ │ ├── saroo/
│ │ │ │ │ │ ├── Blast Wind (Japan).raw
│ │ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA) 1-1.raw
│ │ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA) 1-2.raw
│ │ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA) 2-1.raw
│ │ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA) 2-2.raw
│ │ │ │ │ │ ├── Dungeons and Dragons Collection (Japan) (Disc 2) (Shadows over Mystara).raw
│ │ │ │ │ │ ├── Hyper Duel (Japan).raw
│ │ │ │ │ │ ├── Shining Force III Scenario 1 (English v25.1)-1.raw
│ │ │ │ │ │ └── Shining Force III Scenario 1 (English v25.1)-2.raw
│ │ │ │ │ └── yabause/
│ │ │ │ │ ├── Akumajou Dracula X - Gekka no Yasoukyoku (Japan) (2M).srm
│ │ │ │ │ └── Akumajou Dracula X - Gekka no Yasoukyoku (Japan) (2M).srm-1.raw
│ │ │ │ └── wii/
│ │ │ │ ├── gametdb/
│ │ │ │ │ ├── C97E.html
│ │ │ │ │ ├── D40A.html
│ │ │ │ │ ├── DAXE01.html
│ │ │ │ │ ├── E6ZJ.html
│ │ │ │ │ ├── EAEP.html
│ │ │ │ │ ├── FBNE.html
│ │ │ │ │ ├── JECE.html
│ │ │ │ │ ├── LADE.html
│ │ │ │ │ ├── MC4E.html
│ │ │ │ │ ├── NADJ.html
│ │ │ │ │ ├── NAJE.html
│ │ │ │ │ ├── QAPN.html
│ │ │ │ │ ├── R3OP01.html
│ │ │ │ │ └── WKTE.html
│ │ │ │ ├── n64/
│ │ │ │ │ ├── f-zero-x.15165-raw.sra
│ │ │ │ │ ├── mario-golf.23681-raw.sra
│ │ │ │ │ ├── mario-kart-64.14534-raw.eep
│ │ │ │ │ ├── paper-mario.17225-raw.fla
│ │ │ │ │ ├── super-mario-64.14546-raw.eep
│ │ │ │ │ ├── the-legend-of-zelda-majoras-mask.19354-raw.fla
│ │ │ │ │ └── yoshis-story.17238-raw.eep
│ │ │ │ └── pcengine/
│ │ │ │ ├── Castlevania - Rondo of Blood (my save) - extracted.bup
│ │ │ │ ├── Castlevania - Rondo of Blood (my save) - raw.sav
│ │ │ │ ├── Castlevania - Rondo of Blood (test save) - extracted.bup
│ │ │ │ ├── Castlevania - Rondo of Blood (test save) - raw.sav
│ │ │ │ ├── battle-lode-runner.16193 - extracted.bup
│ │ │ │ ├── battle-lode-runner.16193 - raw.sav
│ │ │ │ ├── bomberman-93.20114 - extracted.bup
│ │ │ │ ├── bomberman-93.20114 - raw.sav
│ │ │ │ ├── neutopia-ii.21439 - extracted.bup
│ │ │ │ └── neutopia-ii.21439 - raw.sav
│ │ │ └── util/
│ │ │ ├── Multiple titles-to-ram-cart.brm
│ │ │ ├── Multiple titles.brm
│ │ │ ├── Popful Mail (USA) (RE)-internal-to-ram-cart.brm
│ │ │ ├── Popful Mail (USA) (RE)-internal.sav
│ │ │ ├── Tomato Adventure (Japan) extra padding at end.srm
│ │ │ ├── Tomato Adventure (Japan) fixed extra padding at end.srm
│ │ │ ├── Tomato Adventure (Japan) fixed extra padding at start.srm
│ │ │ ├── Tomato Adventure (Japan) fixed.srm
│ │ │ ├── Tomato Adventure (Japan) test save all padding.srm
│ │ │ ├── Tomato Adventure (Japan).srm
│ │ │ ├── Xenogears (USA) (Disc 1)-compressed.srm
│ │ │ ├── Xenogears (USA) (Disc 1)-uncompressed.srm
│ │ │ └── endian/
│ │ │ ├── 2ByteWord-input.sav
│ │ │ ├── 2ByteWord-output.sav
│ │ │ ├── 4ByteWord-input.sav
│ │ │ ├── 4ByteWord-output.sav
│ │ │ ├── 8ByteWord-input.sav
│ │ │ └── 8ByteWord-output.sav
│ │ ├── unit/
│ │ │ ├── rom-formats/
│ │ │ │ ├── GB/
│ │ │ │ │ └── gb.spec.js
│ │ │ │ ├── GBA/
│ │ │ │ │ └── gba.spec.js
│ │ │ │ ├── NES/
│ │ │ │ │ └── nes.spec.js
│ │ │ │ ├── PSP/
│ │ │ │ │ └── PspIso.spec.js
│ │ │ │ ├── SMS/
│ │ │ │ │ └── sms.spec.js
│ │ │ │ └── SegaSaturn/
│ │ │ │ └── SegaSaturnCueBin.spec.js
│ │ │ ├── save-formats/
│ │ │ │ ├── Dreamcast/
│ │ │ │ │ ├── Dreamcast.spec.js
│ │ │ │ │ └── IndividualSaves/
│ │ │ │ │ ├── Dci.spec.js
│ │ │ │ │ └── VmiVms.spec.js
│ │ │ │ ├── FlashCarts/
│ │ │ │ │ ├── GB.spec.js
│ │ │ │ │ ├── GBA/
│ │ │ │ │ │ ├── GBA.spec.js
│ │ │ │ │ │ ├── GoombaEmulator.spec.js
│ │ │ │ │ │ ├── PocketNesEmulator.spec.js
│ │ │ │ │ │ └── SmsAdvanceEmulator.spec.js
│ │ │ │ │ ├── GameGear.spec.js
│ │ │ │ │ ├── Genesis/
│ │ │ │ │ │ ├── MegaEverdrivePro/
│ │ │ │ │ │ │ ├── 32X.spec.js
│ │ │ │ │ │ │ ├── Genesis.spec.js
│ │ │ │ │ │ │ ├── NES.spec.js
│ │ │ │ │ │ │ ├── SMS.spec.js
│ │ │ │ │ │ │ └── SegaCd.spec.js
│ │ │ │ │ │ └── MegaSD/
│ │ │ │ │ │ ├── 32X.spec.js
│ │ │ │ │ │ ├── Genesis.spec.js
│ │ │ │ │ │ ├── SMS.spec.js
│ │ │ │ │ │ └── SegaCd.spec.js
│ │ │ │ │ ├── N64/
│ │ │ │ │ │ ├── GB64.spec.js
│ │ │ │ │ │ ├── N64.spec.js
│ │ │ │ │ │ ├── NES.spec.js
│ │ │ │ │ │ └── Neon64Emulator.spec.js
│ │ │ │ │ ├── NES.spec.js
│ │ │ │ │ ├── PcEngine.spec.js
│ │ │ │ │ ├── SMS.spec.js
│ │ │ │ │ └── SNES/
│ │ │ │ │ ├── GB.spec.js
│ │ │ │ │ └── SNES.spec.js
│ │ │ │ ├── GBA/
│ │ │ │ │ ├── ActionReplay.spec.js
│ │ │ │ │ ├── GameShark.spec.js
│ │ │ │ │ └── GameSharkSP.spec.js
│ │ │ │ ├── GameCube/
│ │ │ │ │ ├── GameCube.spec.js
│ │ │ │ │ ├── GameSpecificFixups/
│ │ │ │ │ │ ├── FZeroGx.spec.js
│ │ │ │ │ │ └── PhantasyStarOnline.spec.js
│ │ │ │ │ └── IndividualSaves/
│ │ │ │ │ ├── GameShark.spec.js
│ │ │ │ │ ├── Gci.spec.js
│ │ │ │ │ └── MaxDrive.spec.js
│ │ │ │ ├── Mister/
│ │ │ │ │ ├── GameboyAdvance.spec.js
│ │ │ │ │ ├── Genesis.spec.js
│ │ │ │ │ ├── N64Cart.spec.js
│ │ │ │ │ ├── N64Mempack.spec.js
│ │ │ │ │ ├── SegaCd.spec.js
│ │ │ │ │ └── SegaSaturn.spec.js
│ │ │ │ ├── N64/
│ │ │ │ │ ├── DexDrive.spec.js
│ │ │ │ │ ├── IndividualSaveFilename.spec.js
│ │ │ │ │ └── Mempack.spec.js
│ │ │ │ ├── NintendoSwitchOnline/
│ │ │ │ │ ├── Gameboy.spec.js
│ │ │ │ │ ├── GameboyAdvance.spec.js
│ │ │ │ │ ├── Genesis.spec.js
│ │ │ │ │ ├── N64.spec.js
│ │ │ │ │ ├── Nes.spec.js
│ │ │ │ │ └── Snes.spec.js
│ │ │ │ ├── OnlineEmulators/
│ │ │ │ │ ├── Emulators/
│ │ │ │ │ │ ├── Gambatte.spec.js
│ │ │ │ │ │ ├── Gb.spec.js
│ │ │ │ │ │ ├── Snes9x.spec.js
│ │ │ │ │ │ ├── VBA-Next.spec.js
│ │ │ │ │ │ └── mGba.spec.js
│ │ │ │ │ └── OnlineEmulatorWrapper.spec.js
│ │ │ │ ├── PS1/
│ │ │ │ │ ├── DexDrive.spec.js
│ │ │ │ │ ├── Memcard.spec.js
│ │ │ │ │ ├── Ps3.spec.js
│ │ │ │ │ └── Psp.spec.js
│ │ │ │ ├── PSP/
│ │ │ │ │ ├── Executable.spec.js
│ │ │ │ │ ├── ParamSfo.spec.js
│ │ │ │ │ └── Savefile.spec.js
│ │ │ │ ├── Retron5/
│ │ │ │ │ └── Retron5.spec.js
│ │ │ │ ├── SegaCd/
│ │ │ │ │ └── SegaCd.spec.js
│ │ │ │ ├── SegaSaturn/
│ │ │ │ │ ├── Emulators/
│ │ │ │ │ │ ├── mednafen.spec.js
│ │ │ │ │ │ ├── yabasanshiro.spec.js
│ │ │ │ │ │ └── yabause.spec.js
│ │ │ │ │ ├── IndividualSaves/
│ │ │ │ │ │ └── Bup.spec.js
│ │ │ │ │ ├── Saroo/
│ │ │ │ │ │ ├── Cart.spec.js
│ │ │ │ │ │ ├── Internal.spec.js
│ │ │ │ │ │ └── System.spec.js
│ │ │ │ │ └── SegaSaturn.spec.js
│ │ │ │ └── Wii/
│ │ │ │ ├── ConvertFrom/
│ │ │ │ │ ├── ConvertFromN64.spec.js
│ │ │ │ │ ├── ConvertFromPcEngine.spec.js
│ │ │ │ │ └── ConvertFromSega.spec.js
│ │ │ │ ├── GetPlatform/
│ │ │ │ │ ├── GetPlatform.spec.js
│ │ │ │ │ └── MockHttpClient.js
│ │ │ │ └── Wii.spec.js
│ │ │ └── util/
│ │ │ ├── CompressionGzip.spec.js
│ │ │ ├── CompressionLzo.spec.js
│ │ │ ├── CompressionRzip.spec.js
│ │ │ ├── CompressionZlib.spec.js
│ │ │ ├── Endian.spec.js
│ │ │ ├── Math.spec.js
│ │ │ ├── Padding.spec.js
│ │ │ ├── SaveFiles.spec.js
│ │ │ ├── SegaCdUtil.spec.js
│ │ │ ├── Troubleshooting test files.spec.js
│ │ │ ├── crypto-aes.spec.js
│ │ │ ├── crypto-des.spec.js
│ │ │ └── util.spec.js
│ │ └── util/
│ │ ├── ArrayBuffer.js
│ │ └── Crypto.js
│ └── vue.config.js
└── terraform/
├── .gitignore
├── aws_credentials.example
├── dev/
│ ├── main.tf
│ ├── provider.tf
│ ├── variables.tf
│ └── versions.tf
├── modules/
│ ├── alarms/
│ │ ├── outputs.tf
│ │ ├── sns-topic.tf
│ │ ├── variables.tf
│ │ └── versions.tf
│ ├── build-common-infrastructure/
│ │ ├── logs-bucket.tf
│ │ ├── outputs.tf
│ │ ├── role.tf
│ │ ├── variables.tf
│ │ └── versions.tf
│ ├── build-pipeline-frontend/
│ │ ├── alarms.tf
│ │ ├── code-build.tf
│ │ ├── email-logs.tf
│ │ ├── eventbridge.tf
│ │ ├── python/
│ │ │ └── email-logs.py
│ │ ├── variables.tf
│ │ └── versions.tf
│ └── frontend/
│ ├── build.tf
│ ├── cloudfront.tf
│ ├── dns.tf
│ ├── outputs.tf
│ ├── s3.tf
│ ├── variables.tf
│ └── versions.tf
├── prod/
│ ├── main.tf
│ ├── provider.tf
│ ├── variables.tf
│ └── versions.tf
└── terraform.tfvars.example
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
terraform/* linguist-detectable=false
================================================
FILE: .gitignore
================================================
.DS_Store
/test
/frontend/stats.json
/frontend/tests/data/rom-formats/psp/retail/*
/frontend/tests/data/rom-formats/psp/make-iso/*
/frontend/tests/data/rom-formats/sms/retail/*
/frontend/tests/data/save-formats/flashcarts/gba/goombaemulator/retail/*
/frontend/tests/data/save-formats/flashcarts/gba/pocketnesemulator/retail/*
/frontend/tests/data/save-formats/flashcarts/gba/smsadvanceemulator/retail/*
/frontend/tests/data/save-formats/flashcarts/n64/gb64emulator/retail/*
/frontend/tests/config.local.js
================================================
FILE: .vscode/settings.json
================================================
{
"vue.server.path": "node_modules/@vue/language-server",
}
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: README.md
================================================
# Save File Converter
Web-based tool to convert save files from retro game consoles to different formats

Available at https://savefileconverter.com
## Upcoming features
- PS2 formats (check out https://gamefaqs.gamespot.com/ps2/536777-suikoden-iii/saves for a potential list)
## Contact
If you have questions, need help, or have comments or suggestions, please hop on Discord: https://discord.gg/wtJ7xUKKTR
Or email savefileconverter (at) gmail (dot) com
## Donations
Everything on this site is free and open source with no advertising. If you find the site helpful and want to donate you can here:
[](https://www.paypal.com/donate/?hosted_button_id=DHDERHCQVLGPJ)
## Emulators with incompatible save formats
- (GBA) Pizza Boy files incompatible with mGBA (believe mGBA uses raw files)
- (PS1) Beetle HW incompatible with DuckStation
- (Saturn) SSF incompatible with Mednafen/Beetle Saturn
- (N64) Mupen64Plus Next files incompatible with Wii64
- (32X) Picodrive has its own save format (somewhere around here? https://github.com/notaz/picodrive/blob/1d366b1ad9362fd463c42979c8a687dfc7f46c46/platform/common/emu.c#L873)
## Save file formats
- Retron5
- https://www.retro5.net/viewtopic.php?f=5&t=67&start=10
- GameShark (GBA)
- (partial): https://gbatemp.net/threads/converting-gsv-or-sps-files-to-sav.51838/#post-664786
- (reading): https://github.com/visualboyadvance-m/visualboyadvance-m/blob/master/src/gba/GBA.cpp#L1025
- (writing): https://github.com/visualboyadvance-m/visualboyadvance-m/blob/master/src/gba/GBA.cpp#L1146
- (partial): https://github.com/mgba-emu/mgba/blob/master/src/gba/sharkport.c
- GameShark SP (GBA)
- (reading): https://github.com/visualboyadvance-m/visualboyadvance-m/blob/master/src/gba/GBA.cpp#L1078
- GameShark (PS2)
- (partial): https://www.ps2savetools.com/documents/xps-format/
- PS2
- Tool to parse images, contains links to docs describing various parts of the filesystem: https://github.com/sevonj/eightmb
- Description of PS2 save data: https://babyno.top/en/posts/2023/09/parsing-ps2-memcard-file-system/
- Parsing PS2 save data: https://babyno.top/en/posts/2023/09/exporting-file-from-ps2-memcard/
- Parser with 3D icon viewer: https://github.com/caol64/ps2mc-browser
- Save Tools: https://www.ps2savetools.com/
- mymc save tool:
- http://www.csclub.uwaterloo.ca:11068/mymc/
- https://github.com/ps2dev/mymc
- https://git.sr.ht/~thestr4ng3r/mymcplus (port of mymc with some enhancements)
- Memory card format:
- http://www.csclub.uwaterloo.ca:11068/mymc/ps2mcfs.html
- https://www.ps2savetools.com/ps2memcardformat.html (same info as link above, and that one appears to be newer/more cleaned up)
- Use PS2 files on PS3: https://github.com/bucanero/apollo-ps3
- Convert PS2 formats: https://github.com/bucanero/psv-save-converter
- Manage PS2 memory cards: https://github.com/bucanero/ps2vmc-tool
- Wii Virtual Console save game format (note that the files are encrypted)
- https://wiibrew.org/wiki/Wii_Savegame_Parser
- https://wiibrew.org/wiki/Savegame_Files
- https://wiibrew.org/wiki/FE100
- https://hackmii.com/2008/04/keys-keys-keys/
- https://github.com/Plombo/segher-wii-tools
- (writing) https://github.com/Plombo/segher-wii-tools/blob/master/twintig.c
- https://github.com/Plombo/vcromclaim
- https://github.com/JanErikGunnar/vcromclaim
- Wii U Virtual Console:
- https://github.com/mstan/SaveAIO
- PSP save file decryption/encryption (note that some files require a per-game key):
- KIRK engine reverse-engineering: https://github.com/ProximaV/kirk-engine-full/tree/master
- https://www.psdevwiki.com/ps3/PSP_Savedata
- https://github.com/BrianBTB/SED-PC (PC application that decrypts/encrypts saves)
- https://github.com/cielavenir/psp-savedata-endecrypter (improvement to SED-PC that works with "mode 4" (whatever that is???))
- https://wololo.net/talk/viewtopic.php?t=37556 (PSP plugin that dumps a game's key)
- https://github.com/TheHellcat/psp-hb/blob/master/SavegameDeemer_620TN/deemer_hooker/main.c#L204 Code for a plugin that does this. It intercepts the call to save the game, and writes out a copy of the save in plaintext, plus the key
- https://wololo.net/talk/viewtopic.php?p=137153&sid=37bd385d91e7c2d89cf1ff8d70e8c640#p137153 Discussion saying that you need to either use a plugin, or parse the executable for look for code around a certain system call to figure out what value is being passed to it
- I can't seem to find an online list of game keys, and requiring users to install a plugin on their PSP then type a gamekey into the interface seems like too much to ask.
- https://github.com/hrydgard/ppsspp PSP emulator
- https://github.com/hrydgard/ppsspp/blob/master/Tools/SaveTool/decrypt.c This decrypts a savegame file
- https://github.com/hrydgard/ppsspp/blob/81b5e080ff885e98b5761632158457ce3e5d1fb5/Core/HLE/sceKernelModule.cpp#L1251 The code before here decrypts the executable
- https://github.com/euan-forrester/psp-encryption-webassembly Copy of the relevant code in PPSSPP, compiled into webassembly
- For Gran Turismo the game key is device-specific. Must be generated somehow from a device ID. So can't find it in the executable.
- So we still need a box to enter the game key instead of just ISO/eboot
- Maybe detect this ISO and warn the user?
- NES/SNES Classic save game format
- https://github.com/TeamShinkansen/Hakchi2-CE (tool used to write games onto the devices)
- https://github.com/JanErikGunnar/ClassicEditionTools (scripts to convert raw saves to/from NES Classic format)
- http://darkakuma.z-net.us/p/sfromtool.html (convert SNES ROMs and/or saves to the SNES Classic ROM and/or save format)
- I'm not sure there's enough demand for a web-based tool that does this. The devices aren't available for sale anymore and you already have to run a Windows program to transfer the games. Also the Windows tool for the SNES Classic has the ability to convert saves already.
- PS1:
- https://www.psdevwiki.com/ps3/PS1_Savedata
- MemcardRex format: https://github.com/ShendoXT/memcardrex/blob/master/MemcardRex/ps1card.cs
- DexDrive format: https://github.com/ShendoXT/memcardrex/blob/master/MemcardRex/ps1card.cs
- Signing a PSP .VMP file: https://github.com/dots-tb/vita-mcr2vmp
- PS3 format: https://psdevwiki.com/ps3/PS1_Savedata#PS1_Single_Save_.3F_.28.PSV.29
- Command line tool for PS1 memcards: https://github.com/G4Vi/psx_mc_cli
- N64:
- https://github.com/bryc/mempak
- https://bryc.github.io/mempak/ (online preview)
- https://github.com/bryc/mempak/wiki/DexDrive-.N64-format
- https://github.com/bryc/mempak/wiki/MemPak-structure
- https://github.com/DragonMinded/libdragon/wiki/Cpaktool
- https://github.com/heuripedes/pj64tosrm (convert raw save to emulator format)
- http://micro-64.com/database/gamesave.shtml (list of games which use each save type)
- https://www.reddit.com/r/n64/comments/ezhleg/guide_how_to_backup_your_n64_saves_to_your_pc/
- https://www.youtube.com/watch?v=PpolokImIeU (convert individual note to .eep format)
- https://github.com/ssokolow/saveswap Swap endianness of N64 saves to move between Everdrive/emulators/etc
- https://github.com/Ninjiteu/N64SaveConverter Does endian swaps, padding/trimming of files, and parses retroarch files that store n64 cart saves at various offsets
- https://github.com/drehren/ra_mp64_srm_convert Combines/splits retroarch saves. Also has GUI version: https://github.com/drehren/ramp64-convert-gui and web version: https://github.com/drehren/ramp64-convert-web
- Game serial codes:
- https://niwanetwork.org/wiki/List_of_Nintendo_64_games_by_serial_code
- https://meanwhileblog.wordpress.com/n64-game-code-list/
- 3DS Virtual Console
- SNES games: https://github.com/manuGMG/3ds-snes-sc
- This tool above apparently works on some WiiU VC games as well: https://gbatemp.net/threads/release-3ds-snes-save-converter.574927/
- Pokemon saves: https://sav2vc.fm1337.com/
- https://github.com/mstan/SaveAIO
- List of emulators on the 3DS: https://wiki.gbatemp.net/wiki/List_of_3DS_homebrew_emulators
- open_agb_firm: https://github.com/profi200/open_agb_firm allows usage of the build-in GBA hardware
- Save files from here need to be 64-bit endian-swapped to work in a regular emulator: https://github.com/exelotl/gba-eeprom-save-fix
- Sega Saturn
- https://github.com/hitomi2500/ss-save-parser
- https://github.com/slinga-homebrew/Save-Game-BUP-Scripts (description of the `.BUP` save format)
- https://github.com/slinga-homebrew/Save-Game-Copier
- https://segaxtreme.net/resources/saturn-save-converter.74/
- https://github.com/slinga-homebrew/Save-Game-Extractor (cool, but hopefully not the main method of getting files off of an actual Saturn)
- http://ppcenter.free.fr/satdocs/ST-162-R1-092994.html (official documentation)
- https://segaxtreme.net/threads/backup-memory-structure.16803/
- Saroo:
- https://github.com/tpunix/SAROO/tree/master/tools/savetool (SAROO save file converter)
- https://github.com/tpunix/SAROO/issues/131 (description of how the saroo deals with save files, also watch this for potential changes)
- https://github.com/tpunix/SAROO/issues/117 (description of current process of copying save files to saroo)
- https://www.reddit.com/r/SegaSaturn/comments/1acty0v/saroo_save_file_format/ (information on the saroo file format, tools, and example files)
- Potential save formats (based on what Saturn Save Converter does):
- These ones to initially support:
- BUP (is this the standardized format? Used by Psuedo Saturn Kai -> this is the tool used by ODEs as well?)
- https://github.com/slinga-homebrew/Save-Game-BUP-Scripts/blob/main/bup_header.h#L94
- SaroSave (Saroo flash cart)
- https://github.com/tpunix/SAROO/blob/master/tools/savetool/sr_bup.c#L135
- https://github.com/tpunix/SAROO/blob/6f6e18289bbdc9b23b4c91b9da343a1362ed921c/doc/SAROO%E6%8A%80%E6%9C%AF%E7%82%B9%E6%BB%B4.txt#L448 (translation posted at https://www.reddit.com/r/SegaSaturn/comments/1acty0v/comment/kjz73ft/)
- Mednafen - generates 3 files:
- `.bkr`: Internal save memory? Appears to be described here: https://www.reddit.com/r/SegaSaturn/comments/1acty0v/comment/kjz73ft/
- `.bcr`: Cartridge save memory? Compressed with gzip, then as described in link above but with bigger block size: https://www.reddit.com/r/RetroArch/comments/wke28j/comment/ijmw25t/
- `.smpc`: System management data, including clock information: https://docs.exodusemulator.com/Archives/SSDDV25/segahtml/index.html?page=hard/smpc/index.htm
- These ones to maybe support based on feedback:
- SSF (SSF emulator: https://segaretro.org/SSF)
- Yabause (https://yabause.org/ -- seems old, Kronos is a newer fork: https://github.com/FCare/Kronos)
- Giri Giri
- Nova
- Action Replay (https://github.com/hitomi2500/ss-save-parser/blob/master/config.cpp#L26)
- Druid II (https://github.com/hitomi2500/ss-save-parser/blob/master/config.cpp#L59)
- TG-16/PCE:
- https://github.com/Widdiful/PCE_BRAM_Manager
- Gamecube
- Memory card image
- https://www.gc-forever.com/yagcd/chap12.html#sec12
- https://github.com/bodgit/gc
- https://github.com/bodgit/memcardpro
- https://github.com/suloku/gcmm
- .GCI individual save file
- http://www.surugi.com/projects/gcifaq.html
- https://github.com/suloku/gcmm/blob/master/source/gci.h#L12
- Recovery tool
- https://github.com/GerbilSoft/mcrecover
- Flash carts:
- Goomba emulator (for GB/C games on GBA flash cart)
- https://github.com/libertyernie/goombasav (save converter)
- https://github.com/masterhou/goombacolor/blob/master/src/sram.c
- https://www.reddit.com/r/everdrive/comments/qcgus7/using_a_gba_x5_goomba_sram_save_file_on_a_gbc_x7/****
- It seems that uncompressed save data may be available at `0x6000` rather than `0xe000`? Was there a bug in Goomba Save Converter?
- https://www.reddit.com/r/everdrive/comments/1368o8d/converting_goomba_gbc_saves_for_use_on_other/
- N64 Everdrive
- https://github.com/ssokolow/saveswap
- GB/C emulator: https://github.com/lambertjamesd/gb64/blob/master/src/save.c
- NES emulator:
- https://github.com/hcs64/neon64v2/issues/20
- http://themanbehindcurtain.blogspot.com/
- Sega CD:
- https://github.com/superctr/buram/
- Sega operating manuals
- Standards that games were to use when interfacing with backup RAM: https://segaretro.org/images/6/6e/Sega-CD_Software_Standards.pdf
- BIOS calls that games were to use to access backup RAM: https://segaretro.org/images/4/44/MCDBios.pdf
- https://segaretro.org/CD_BackUp_RAM_Cart
- https://github.com/ekeeke/Genesis-Plus-GX/issues/449
- savesplitter tool here: https://krikzz.com/pub/support/mega-everdrive/pro-series/
- Dreamcast
- https://vmu.falcogirgis.net/filesystem.html
- https://github.com/likeagfeld/VM2_TO_VMUPRO_CONVERTER
- https://github.com/DerekPascarella/VMU-Disc-Builder (just packs up save files and doesn't do much parsing, so not much info about their format)
- https://bswirl.kitsunet.org/dci_converter/ (old and unmaintained, only parts of it worK: https://www.dreamcast-talk.com/forum/viewtopic.php?t=17425)
- https://segaretro.org/VMU_Explorer (Old Windows-only tool without source code)
- https://github.com/sizious/vmu-tool-pc
- https://github.com/bucanero/dc-save-converter
- Official docs: https://segaxtreme.net/resources/maple-bus-1-0-function-type-specifications-ft1-storage-function.195/ (these were apparently leaked, apparently have been translated back and forth, and do not appear to be final as they contain multiple descrepancies vs the actual files)
- Analogue Pocket:
- List of available cores: https://openfpga-cores-inventory.github.io/analogue-pocket/
- Note that there are sometimes multiple cores for a particular platform (e.g. Genesis)
- Visual Boy Advance emulator
- Explanation of its format: https://emulation.gametechwiki.com/index.php/Game_Boy_Advance_emulators#Save_formats
- Code that does the conversion:
- https://github.com/Thysbelon/gbaconv-web
- https://github.com/libretro/vbam-libretro/blob/25fefc1b3dcdc6362c44845687bea70dd350c33a/src/libretro/gbaconv/gbaconv.c
- Online converter: https://thysbelon.github.io/gbaconv-web/
- Info on some ports of this emulator: https://thysbelon.github.io/2023/03/07/How-to-Convert-4GS-and-DSZ-save-files-to-SAV
- Online emulators
- `.ggz` files when unzipped apparently contain one or more pairs of `.gba`/`.snes`/etc and `.png` file: a save state and a thumbnail
- There's a port of Retroarch available online here: https://binbashbanana.github.io/webretro/ with code here: https://github.com/BinBashBanana/webretro . Its save file compatibility is the same as regular Retroarch and the emulators therein
- Retroarch
- Some save files are compressed with ZLIB compression. I'm not sure the circumstances under which this happens: https://github.com/libretro/RetroArch/issues/14031#issuecomment-1159400581
- iOS
- The Delta emulator uses .svs for save states. Instructions for creating a raw save instead: https://www.reddit.com/r/Delta_Emulator/comments/1helbo1/svs_to_sav/
- Gameboy
- Games using the MBC2 mapper can have their save files represented differently
- Either as half-bytes with the top nybble set to `0x0000` or as packed bytes
- Half bytes are more common; mGBA uses packed bytes but can convert
- See discussion here: https://github.com/Gronis/gb-save-manager/issues/5#issuecomment-4101338096
- See more details here: https://github.com/Gronis/gb-save-manager?tab=readme-ov-file#games-to-watch-out-for---mbc2-cartridges
- Game affected:
- F-1 Race
- Golf
- Kirby's Pinball Land
- Top Rank Tennis
## Cart reader notes
- Retrode2
- Genesis: SRAM/FRAM saves are byte expanded by doubling: "HELLO" becomes "HHEELLLLOO" rather than " H E L L O" like in many emulators/flash carts
- Retroblaster
- Same as Retrode2
## GBA save file size difficulty
- https://zork.net/~st/jottings/GBA_saves.html
- https://dillonbeliveau.com/2020/06/05/GBA-FLASH.html
## Real-Time Clock save format
- https://bgb.bircd.org/rtcsave.html
Some platforms (e.g. some MiSTer cores) append RTC data to the end of a save file. The above link describes a common format for RTC data.
## PSP decompiling
- Use ghidra:
- Download from: https://github.com/NationalSecurityAgency/ghidra/releases
- Add this extension: https://github.com/kotcrab/ghidra-allegrex
- Add these scripts: https://github.com/pspdev/psp-ghidra-scripts
- Libraries documentation: https://github.com/mathieulh/PSP-PRX-Libraries-Documentation-Project
## Offline use
Occassionally there's a need to use the tool offline, such as when you'll be without an Internet connection for an extended period. There's 2 methods to achieve this:
### Method 1: Use a website saving tool
You can't just right click on the page and select Save As... because the site is divided internally into many different files, and that will only download some of them.
Google `website saving tool` or something similar to find an up-to-date list of such tools.
### Method 2: Build it locally (for people comfortable with the command line and development tools)
You may need to modify some of these steps depending on your development environment, but this should give you the general idea.
#### MacOS/Linux
Install `homebrew`: https://brew.sh/
```
brew install yarn
brew install git
```
Then proceed to the [Common](https://github.com/euan-forrester/save-file-converter#common) section
#### Windows
Find an equivalent package manager to `homebrew`, and use it to install `git` and `yarn` (or install them and their dependencies manually: `git`: https://github.com/git-guides/install-git, `yarn`: https://yarnpkg.com/getting-started/install)
Then proceed to the [Common](https://github.com/euan-forrester/save-file-converter#common) section
#### Common
```
git clone git@github.com:euan-forrester/save-file-converter.git
cd save-file-converter/frontend
yarn install
yarn serve
```
Then open http://localhost:8080/ in your browser.
Note that you'll have to keep the command line window open with `yarn serve` running for as long as you want to access the site.
## Internet archive
If you need to, you can also access the site via the Internet archive here: https://web.archive.org/web/https://savefileconverter.com/
================================================
FILE: frontend/.editorconfig
================================================
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100
================================================
FILE: frontend/.eslintignore
================================================
src/save-formats/PSP/psp-encryption/*
lib/*
================================================
FILE: frontend/.gitignore
================================================
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
================================================
FILE: frontend/.nvmrc
================================================
16.19.1
================================================
FILE: frontend/README.md
================================================
# Vue 3 upgrade notes
Need to undo these changes made for vscode: https://github.com/vuejs/language-tools/wiki/Vue-2-Compat-Guides
Described here: https://github.com/vuejs/language-tools/discussions/5455
================================================
FILE: frontend/babel.config.js
================================================
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
],
};
================================================
FILE: frontend/buildspec.yml
================================================
version: 0.2
phases:
install:
runtime-versions:
nodejs: 16
commands:
- apt-get update -y
- apt-get install -y yarn
- cd frontend
- yarn install
pre_build:
commands:
- yarn test:unit
build:
commands:
- yarn build --mode=$ENVIRONMENT
post_build:
commands:
- yarn deploy --mode=$ENVIRONMENT && yarn deploy:cleanup --mode=$ENVIRONMENT
================================================
FILE: frontend/lib/minlzo-js/lzo1x.js
================================================
// This file is copied from https://github.com/euan-forrester/minilzo-js
// Which was forked from https://github.com/abraidwood/minilzo-js
/*
* minilzo-js
* JavaScript port of minilzo by Alistair Braidwood
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* You should have received a copy of the GNU General Public License
* along with the minilzo-js library; see the file COPYING.
* If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
* original minilzo.c by:
*
* Markus F.X.J. Oberhumer
* <markus@oberhumer.com>
* http://www.oberhumer.com/opensource/lzo/
*/
/*
* NOTE:
* the full LZO package can be found at
* http://www.oberhumer.com/opensource/lzo/
*/
function _lzo1x() {
this.blockSize = 128 * 1024;
this.minNewSize = this.blockSize;
this.maxSize = 0;
this.OK = 0;
this.INPUT_OVERRUN = -4;
this.OUTPUT_OVERRUN = -5;
this.LOOKBEHIND_OVERRUN = -6;
this.EOF_FOUND = -999;
this.ret = 0;
this.buf = null;
this.buf32 = null;
this.out = new Uint8Array(256 * 1024);
this.cbl = 0;
this.ip_end = 0;
this.op_end = 0;
this.t = 0;
this.ip = 0;
this.op = 0;
this.m_pos = 0;
this.m_len = 0;
this.m_off = 0;
this.dv_hi = 0;
this.dv_lo = 0;
this.dindex = 0;
this.ii = 0;
this.jj = 0;
this.tt = 0;
this.v = 0;
this.dict = new Uint32Array(16384);
this.emptyDict = new Uint32Array(16384);
this.skipToFirstLiteralFun = false;
this.returnNewBuffers = true;
this.setBlockSize = function(blockSize) {
if(typeof blockSize === 'number' && !isNaN(blockSize) && parseInt(blockSize) > 0) {
this.blockSize = parseInt(blockSize);
return true;
} else {
return false;
}
};
this.setOutputSize = function(outputSize) {
if(typeof outputSize === 'number' && !isNaN(outputSize) && parseInt(outputSize) > 0) {
this.out = new Uint8Array(parseInt(outputSize));
return true;
} else {
return false;
}
};
this.setReturnNewBuffers = function(b) {
this.returnNewBuffers = !!b;
};
this.applyConfig = function(cfg) {
if(cfg !== undefined) {
if(cfg.outputSize !== undefined) {
instance.setOutputSize(cfg.outputSize);
}
if(cfg.blockSize !== undefined) {
instance.setBlockSize(cfg.blockSize);
}
}
};
this.ctzl = function(v) {
// this might be needed for _compressCore (it isn't in my current test files)
/*
* https://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightBinSearch
* Matt Whitlock suggested this on January 25, 2006. Andrew Shapira shaved a couple operations off on Sept. 5, 2007 (by setting c=1 and unconditionally subtracting at the end).
*/
var c; // c will be the number of zero bits on the right,
// so if v is 1101000 (base 2), then c will be 3
// NOTE: if 0 == v, then c = 31.
if (v & 0x1) {
// special case for odd v (assumed to happen half of the time)
c = 0;
} else {
c = 1;
if ((v & 0xffff) === 0) {
v >>= 16;
c += 16;
}
if ((v & 0xff) === 0) {
v >>= 8;
c += 8;
}
if ((v & 0xf) === 0) {
v >>= 4;
c += 4;
}
if ((v & 0x3) === 0) {
v >>= 2;
c += 2;
}
c -= v & 0x1;
}
return c;
};
// It might be faster to copy 4 bytes at a time, but
// the allocation seems to kill performance.
// this._get4ByteAlignedBuf = function(buf) {
// if(buf.length % 4 === 0) {
// return new Uint32Array(buf.buffer);
// } else {
// var buf_4b = new Uint8Array(buf.length + (4 - buf.length % 4));
// buf_4b.set(buf);
// return new Uint32Array(buf_4b.buffer);
// }
// };
this.extendBuffer = function() {
var newBuffer = new Uint8Array(this.minNewSize + (this.blockSize - this.minNewSize % this.blockSize));
newBuffer.set(this.out);
this.out = newBuffer;
this.cbl = this.out.length;
};
this.match_next = function() {
// if (op_end - op < t) return OUTPUT_OVERRUN;
// if (this.ip_end - ip < t+3) return INPUT_OVERRUN;
this.minNewSize = this.op + 3;
if(this.minNewSize > this.cbl) {this.extendBuffer();}
this.out[this.op++] = this.buf[this.ip++];
if(this.t > 1) {
this.out[this.op++] = this.buf[this.ip++];
if(this.t > 2) {
this.out[this.op++] = this.buf[this.ip++];
}
}
this.t = this.buf[this.ip++];
};
this.match_done = function() {
this.t = this.buf[this.ip-2] & 3;
return this.t;
};
this.copy_match = function() {
this.t += 2;
this.minNewSize = this.op + this.t;
if(this.minNewSize > this.cbl) {this.extendBuffer();}
do {
this.out[this.op++] = this.out[this.m_pos++];
} while(--this.t > 0);
};
this.copy_from_buf = function() {
this.minNewSize = this.op + this.t;
if(this.minNewSize > this.cbl) {this.extendBuffer();}
do {
this.out[this.op++] = this.buf[this.ip++];
} while (--this.t > 0);
};
this.match = function() {
for (;;) {
if (this.t >= 64) {
this.m_pos = (this.op - 1) - ((this.t >> 2) & 7) - (this.buf[this.ip++] << 3);
this.t = (this.t >> 5) - 1;
// if ( m_pos < out || m_pos >= op) return LOOKBEHIND_OVERRUN;
// if (op_end - op < t+3-1) return OUTPUT_OVERRUN;
this.copy_match();
} else if (this.t >= 32) {
this.t &= 31;
if (this.t === 0) {
while (this.buf[this.ip] === 0) {
this.t += 255;
this.ip++;
// if (t > -511) return OUTPUT_OVERRUN;
// if (this.ip_end - ip < 1) return INPUT_OVERRUN;
}
this.t += 31 + this.buf[this.ip++];
// if (this.ip_end - ip < 2) return INPUT_OVERRUN;
}
this.m_pos = (this.op - 1) - (this.buf[this.ip] >> 2) - (this.buf[this.ip + 1] << 6);
this.ip += 2;
this.copy_match();
} else if (this.t >= 16) {
this.m_pos = this.op - ((this.t & 8) << 11);
this.t &= 7;
if (this.t === 0) {
while (this.buf[this.ip] === 0) {
this.t += 255;
this.ip++;
// if (t > -511) return OUTPUT_OVERRUN;
// if (this.ip_end - ip < 1) return INPUT_OVERRUN;
}
this.t += 7 + this.buf[this.ip++];
// if (this.ip_end - ip < 2) return INPUT_OVERRUN;
}
this.m_pos -= (this.buf[this.ip] >> 2) + (this.buf[this.ip + 1] << 6);
this.ip += 2;
if (this.m_pos === this.op) {
this.state.outputBuffer = this.returnNewBuffers === true ?
new Uint8Array(this.out.subarray(0, this.op)) :
this.out.subarray(0, this.op);
return this.EOF_FOUND;
} else {
this.m_pos -= 0x4000;
this.copy_match();
}
} else {
this.m_pos = (this.op - 1) - (this.t >> 2) - (this.buf[this.ip++] << 2);
// if (m_pos < out || m_pos >= op) return LOOKBEHIND_OVERRUN;
// if (op_end - op < 2) return OUTPUT_OVERRUN;
this.minNewSize = this.op + 2;
if(this.minNewSize > this.cbl) {this.extendBuffer();}
this.out[this.op++] = this.out[this.m_pos++];
this.out[this.op++] = this.out[this.m_pos];
}
// if (m_pos < out || m_pos >= op) return LOOKBEHIND_OVERRUN;
// if (op_end - op < t+3-1) return OUTPUT_OVERRUN;
if(this.match_done() === 0) {
return this.OK;
}
this.match_next();
}
};
this.decompress = function(state) {
this.state = state;
this.buf = this.state.inputBuffer;
this.cbl = this.out.length;
this.ip_end = this.buf.length;
// this.op_end = this.out.length;
this.t = 0;
this.ip = 0;
this.op = 0;
this.m_pos = 0;
this.skipToFirstLiteralFun = false;
// if (this.ip_end - ip < 1) return INPUT_OVERRUN;
if (this.buf[this.ip] > 17) {
this.t = this.buf[this.ip++] - 17;
if (this.t < 4) {
this.match_next();
this.ret = this.match();
if(this.ret !== this.OK) {
return this.ret === this.EOF_FOUND ? this.OK : this.ret;
}
} else {
// if (op_end - op < t) return OUTPUT_OVERRUN;
// if (this.ip_end - ip < t+3) return INPUT_OVERRUN;
this.copy_from_buf();
this.skipToFirstLiteralFun = true;
}
}
for (;;) {
if(!this.skipToFirstLiteralFun) {
// EDIT EUAN: I re-enabled the line below because otherwise the function enters an infinite loop when presented with
// unexpected data. this.ip gets incremented forever, and this.t gets set to undefined as it tries to read past the end of the array
if (this.ip_end - this.ip < 3) return this.INPUT_OVERRUN;
this.t = this.buf[this.ip++];
if (this.t >= 16) {
this.ret = this.match();
if(this.ret !== this.OK) {
return this.ret === this.EOF_FOUND ? this.OK : this.ret;
}
continue;
} else if (this.t === 0) {
while (this.buf[this.ip] === 0) {
this.t += 255;
this.ip++;
// if (t > 511) return INPUT_OVERRUN;
// if (this.ip_end - ip < 1) return INPUT_OVERRUN;
}
this.t += 15 + this.buf[this.ip++];
}
// if (op_end - op < t+3) return OUTPUT_OVERRUN;
// if (this.ip_end - ip < t+6) return INPUT_OVERRUN;
this.t += 3;
this.copy_from_buf();
} else {
this.skipToFirstLiteralFun = false;
}
this.t = this.buf[this.ip++];
if (this.t < 16) {
this.m_pos = this.op - (1 + 0x0800);
this.m_pos -= this.t >> 2;
this.m_pos -= this.buf[this.ip++] << 2;
// if ( m_pos < out || m_pos >= op) return LOOKBEHIND_OVERRUN;
// if (op_end - op < 3) return OUTPUT_OVERRUN;
this.minNewSize = this.op + 3;
if(this.minNewSize > this.cbl) {this.extendBuffer();}
this.out[this.op++] = this.out[this.m_pos++];
this.out[this.op++] = this.out[this.m_pos++];
this.out[this.op++] = this.out[this.m_pos];
if(this.match_done() === 0) {
continue;
} else {
this.match_next();
}
}
this.ret = this.match();
if(this.ret !== this.OK) {
return this.ret === this.EOF_FOUND ? this.OK : this.ret;
}
}
return this.OK;
};
this._compressCore = function() {
this.ip_start = this.ip;
this.ip_end = this.ip + this.ll - 20;
this.jj = this.ip;
this.ti = this.t;
this.ip += this.ti < 4 ? 4 - this.ti : 0;
this.ip += 1 + ((this.ip - this.jj) >> 5);
for (;;) {
if(this.ip >= this.ip_end) {
break;
}
// dv = this.buf[this.ip] | (this.buf[this.ip + 1] << 8) | (this.buf[this.ip + 2] << 16) | (this.buf[this.ip + 3] << 24);
// this.dindex = ((0x1824429d * dv) >> 18) & 16383;
// The above code doesn't work in JavaScript due to a lack of 64 bit bitwise operations
// Instead, use (optimised two's complement integer arithmetic)
// Optimization is based on us only needing the high 16 bits of the lower 32 bit integer.
this.dv_lo = this.buf[this.ip] | (this.buf[this.ip + 1] << 8);
this.dv_hi = this.buf[this.ip + 2] | (this.buf[this.ip + 3] << 8);
this.dindex = (((this.dv_lo * 0x429d) >>> 16) + (this.dv_hi * 0x429d) + (this.dv_lo * 0x1824) & 0xFFFF) >>> 2;
this.m_pos = this.ip_start + this.dict[this.dindex];
this.dict[this.dindex] = this.ip - this.ip_start;
if ((this.dv_hi<<16) + this.dv_lo != (this.buf[this.m_pos] | (this.buf[this.m_pos + 1] << 8) | (this.buf[this.m_pos + 2] << 16) | (this.buf[this.m_pos + 3] << 24))) {
this.ip += 1 + ((this.ip - this.jj) >> 5);
continue;
}
this.jj -= this.ti;
this.ti = 0;
this.v = this.ip - this.jj;
if (this.v !== 0) {
if (this.v <= 3) {
this.out[this.op - 2] |= this.v;
do {
this.out[this.op++] = this.buf[this.jj++];
} while (--this.v > 0);
} else {
if (this.v <= 18) {
this.out[this.op++] = this.v - 3;
} else {
this.tt = this.v - 18;
this.out[this.op++] = 0;
while (this.tt > 255) {
this.tt -= 255;
this.out[this.op++] = 0;
}
this.out[this.op++] = this.tt;
}
do {
this.out[this.op++] = this.buf[this.jj++];
} while (--this.v > 0);
}
}
this.m_len = 4;
// var skipTo_this.m_len_done = false;
if (this.buf[this.ip + this.m_len] === this.buf[this.m_pos + this.m_len]) {
do {
this.m_len += 1; if(this.buf[this.ip + this.m_len] !== this.buf[this.m_pos + this.m_len]) {break;}
this.m_len += 1; if(this.buf[this.ip + this.m_len] !== this.buf[this.m_pos + this.m_len]) {break;}
this.m_len += 1; if(this.buf[this.ip + this.m_len] !== this.buf[this.m_pos + this.m_len]) {break;}
this.m_len += 1; if(this.buf[this.ip + this.m_len] !== this.buf[this.m_pos + this.m_len]) {break;}
this.m_len += 1; if(this.buf[this.ip + this.m_len] !== this.buf[this.m_pos + this.m_len]) {break;}
this.m_len += 1; if(this.buf[this.ip + this.m_len] !== this.buf[this.m_pos + this.m_len]) {break;}
this.m_len += 1; if(this.buf[this.ip + this.m_len] !== this.buf[this.m_pos + this.m_len]) {break;}
this.m_len += 1; if(this.buf[this.ip + this.m_len] !== this.buf[this.m_pos + this.m_len]) {break;}
if(this.ip + this.m_len >= this.ip_end) {
// skipTo_this.m_len_done = true;
break;
}
} while (this.buf[this.ip + this.m_len] === this.buf[this.m_pos + this.m_len]);
}
// if (!skipTo_this.m_len_done) {
// var inc = this.ctzl(this.buf[this.ip + this.m_len] ^ this.buf[this.m_pos + this.m_len]) >> 3;
// this.m_len += inc;
// }
this.m_off = this.ip - this.m_pos;
this.ip += this.m_len;
this.jj = this.ip;
if (this.m_len <= 8 && this.m_off <= 0x0800) {
this.m_off -= 1;
this.out[this.op++] = ((this.m_len - 1) << 5) | ((this.m_off & 7) << 2);
this.out[this.op++] = this.m_off >> 3;
} else if (this.m_off <= 0x4000) {
this.m_off -= 1;
if (this.m_len <= 33) {
this.out[this.op++] = 32 | (this.m_len - 2);
} else {
this.m_len -= 33;
this.out[this.op++] = 32;
while (this.m_len > 255) {
this.m_len -= 255;
this.out[this.op++] = 0;
}
this.out[this.op++] = this.m_len;
}
this.out[this.op++] = this.m_off << 2;
this.out[this.op++] = this.m_off >> 6;
} else {
this.m_off -= 0x4000;
if (this.m_len <= 9) {
this.out[this.op++] = 16 | ((this.m_off >> 11) & 8) | (this.m_len - 2);
} else {
this.m_len -= 9;
this.out[this.op++] = 16 | ((this.m_off >> 11) & 8);
while (this.m_len > 255) {
this.m_len -= 255;
this.out[this.op++] = 0;
}
this.out[this.op++] = this.m_len;
}
this.out[this.op++] = this.m_off << 2;
this.out[this.op++] = this.m_off >> 6;
}
}
this.t = this.ll - ((this.jj - this.ip_start) - this.ti);
};
this.compress = function (state) {
this.state = state;
this.ip = 0;
this.buf = this.state.inputBuffer;
this.maxSize = this.buf.length + Math.ceil(this.buf.length / 16) + 64 + 3;
if(this.maxSize > this.out.length) {
this.out = new Uint8Array(this.maxSize);
}
// this.state.outputBuffer = new Uint8Array(this.buf.length + Math.ceil(this.buf.length / 16) + 64 + 3);
// this.out = this.state.outputBuffer;
this.op = 0;
this.l = this.buf.length;
this.t = 0;
while (this.l > 20) {
this.ll = (this.l <= 49152) ? this.l : 49152;
if ((this.t + this.ll) >> 5 <= 0) {
break;
}
this.dict.set(this.emptyDict);
this.prev_ip = this.ip;
this._compressCore();
this.ip = this.prev_ip + this.ll;
this.l -= this.ll;
}
this.t += this.l;
if (this.t > 0) {
this.ii = this.buf.length - this.t;
if (this.op === 0 && this.t <= 238) {
this.out[this.op++] = 17 + this.t;
} else if (this.t <= 3) {
this.out[this.op-2] |= this.t;
} else if (this.t <= 18) {
this.out[this.op++] = this.t - 3;
} else {
this.tt = this.t - 18;
this.out[this.op++] = 0;
while (this.tt > 255) {
this.tt -= 255;
this.out[this.op++] = 0;
}
this.out[this.op++] = this.tt;
}
do {
this.out[this.op++] = this.buf[this.ii++];
} while (--this.t > 0);
}
this.out[this.op++] = 17;
this.out[this.op++] = 0;
this.out[this.op++] = 0;
this.state.outputBuffer = this.returnNewBuffers === true ?
new Uint8Array(this.out.subarray(0, this.op)) :
this.out.subarray(0, this.op);
return this.OK;
}
};
var instance = new _lzo1x();
export default {
OK: instance.OK,
INPUT_OVERRUN: instance.INPUT_OVERRUN,
OUTPUT_OVERRUN: instance.OUTPUT_OVERRUN,
LOOKBEHIND_OVERRUN: instance.LOOKBEHIND_OVERRUN,
EOF_FOUND: instance.EOF_FOUND,
setBlockSize: function(blockSize) {
return instance.setBlockSize(blockSize);
},
setOutputEstimate: function(outputSize) {
return instance.setOutputSize(outputSize);
},
setReturnNewBuffers: function(b) {
instance.setReturnNewBuffers(b);
},
compress: function(state, cfg) {
if(cfg !== undefined) {
instance.applyConfig(cfg);
}
return instance.compress(state);
},
decompress: function(state, cfg) {
if(cfg !== undefined) {
instance.applyConfig(cfg);
}
return instance.decompress(state);
}
};
================================================
FILE: frontend/package.json
================================================
{
"name": "save-file-converter",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"lint": "vue-cli-service lint",
"deploy": "vue-cli-service s3-deploy",
"deploy:cleanup": "vue-cli-service s3-deploy-cleanup"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.34",
"@fortawesome/free-solid-svg-icons": "^6.5.0",
"@fortawesome/vue-fontawesome": "^2.0.2",
"@gtm-support/vue2-gtm": "^1.2.0",
"axios": "^0.21.2",
"axios-retry": "^3.1.9",
"bootstrap": "^4.5.3",
"bootstrap-vue": "^2.22.0",
"browserfs": "^1.4.3",
"browserify-aes": "^1.2.0",
"browserify-des": "^1.0.2",
"core-js": "^3.6.5",
"crc-32": "^1.2.0",
"create-hash": "^1.2.0",
"dayjs": "^1.10.4",
"encoding-japanese": "^2.2.0",
"file-saver": "^2.0.5",
"jszip": "^3.10.1",
"lodash-es": "^4.17.21",
"node-html-parser": "^4.0.0",
"pako": "^2.0.3",
"path": "^0.12.7",
"process": "^0.11.10",
"rzipjs": "^1.0.0",
"stream-browserify": "^3.0.0",
"vue": "^2.6.12",
"vue-async-computed": "^4.0.1",
"vue-mq": "^1.0.1",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.4",
"@vue/cli-plugin-eslint": "~5.0.4",
"@vue/cli-plugin-router": "~5.0.4",
"@vue/cli-plugin-unit-mocha": "~5.0.4",
"@vue/cli-plugin-vuex": "~5.0.4",
"@vue/cli-service": "~5.0.4",
"@vue/eslint-config-airbnb": "^6.0.0",
"@vue/language-server": "~3.0.0",
"@vue/test-utils": "^1.0.3",
"chai": "^4.1.2",
"eslint": "^7.32.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-vue": "^8.0.3",
"eslint-plugin-vuejs-accessibility": "^1.1.0",
"file-loader": "^6.2.0",
"pkcs7": "^1.0.4",
"seedrandom": "^3.0.5",
"vue-cli-plugin-s3-deploy": "~4.0.0-rc3",
"vue-cli-plugin-s3-deploy-cleanup": "^1.1.0",
"vue-cli-plugin-webpack-bundle-analyzer": "~4.0.0",
"vue-template-compiler": "^2.6.12",
"webpack-bundle-analyzer": "^4.5.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"@vue/airbnb"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {
"max-len": [
"error",
{
"code": 200,
"tabWidth": 2,
"ignoreComments": true,
"ignoreTrailingComments": true,
"ignoreUrls": true
}
]
},
"overrides": [
{
"files": [
"**/__tests__/*.{j,t}s?(x)",
"**/tests/unit/**/*.spec.{j,t}s?(x)"
],
"env": {
"mocha": true
}
}
]
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
================================================
FILE: frontend/public/browserconfig.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/mstile-150x150.png"/>
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
</browserconfig>
================================================
FILE: frontend/public/index.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="robots" content="max-image-preview:none">
<meta name="description" content="Converts save files for retro consoles: MiSTer, srm to sav, sav to srm, GameShark (sps and gsv), PS1, GameCube, N64, DexDrive, Action Replay, Dreamcast, Sega Saturn, Saroo, Sega CD, Nintendo Switch Online, Retron 5, Wii Virtual Console, emulators, various flash cartridge formats, and save states from online emulation websites. Decrypts PSP saves. Provides help for downloading save files, erasing cartridge saves, and copying saves to and from original hardware." />
<link rel="apple-touch-icon" sizes="180x180" href="<%= BASE_URL %>apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="<%= BASE_URL %>favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="<%= BASE_URL %>favicon-16x16.png">
<link rel="manifest" href="<%= BASE_URL %>site.webmanifest">
<link rel="mask-icon" href="<%= BASE_URL %>safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<title>Save File Converter</title>
</head>
<body>
<!-- Google Tag Manager (noscript) -->
<noscript>
<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-MFQ82X4" height="0" width="0" style="display:none;visibility:hidden"></iframe>
</noscript>
<!-- End Google Tag Manager (noscript) -->
<noscript>
<strong>We're sorry but Save File Converter doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
================================================
FILE: frontend/public/robots.txt
================================================
Sitemap: http://savefileconverter.com/sitemap.txt
================================================
FILE: frontend/public/site.webmanifest
================================================
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
================================================
FILE: frontend/public/sitemap.txt
================================================
https://savefileconverter.com/#/retron-5
https://savefileconverter.com/#/retron-5/erase-save
https://savefileconverter.com/#/wii
https://savefileconverter.com/#/nintendo-switch-online
https://savefileconverter.com/#/gba/gameshark
https://savefileconverter.com/#/gba/gameshark-sp
https://savefileconverter.com/#/gba/action-replay
https://savefileconverter.com/#/ps1/dexdrive
https://savefileconverter.com/#/ps1/psp
https://savefileconverter.com/#/ps1/ps3
https://savefileconverter.com/#/ps1/emulator
https://savefileconverter.com/#/psp
https://savefileconverter.com/#/sega-cd
https://savefileconverter.com/#/sega-saturn/emulator
https://savefileconverter.com/#/sega-saturn/saroo
https://savefileconverter.com/#/dreamcast
https://savefileconverter.com/#/gamecube
https://savefileconverter.com/#/n64/dexdrive
https://savefileconverter.com/#/n64/controller-pak
https://savefileconverter.com/#/mister
https://savefileconverter.com/#/flash-carts
https://savefileconverter.com/#/online-emulators
https://savefileconverter.com/#/srm-sav
https://savefileconverter.com/#/utilities/erase-save
https://savefileconverter.com/#/utilities/advanced
https://savefileconverter.com/#/other-converters
https://savefileconverter.com/#/download-saves
https://savefileconverter.com/#/original-hardware
https://savefileconverter.com/#/about
================================================
FILE: frontend/src/App.vue
================================================
<template>
<div id="app">
<div id="nav">
<b-row>
<b-col class="nav-row">
<router-link to="/mister">MiSTer</router-link>
</b-col>
</b-row>
<b-row>
<b-col class="nav-row">
<router-link to="/srm-sav">
.srm{{'\xa0'}}
<span class="arrow-spacing"><i class="fa fa-arrow-right-arrow-left"></i></span>
{{'\xa0'}}.sav{{'\xa0'}}
</router-link>
</b-col>
</b-row>
<b-row>
<b-col class="nav-row">
<router-link to="/flash-carts">Flash{{'\xa0'}}cartridges{{'\xa0'}}/ original{{'\xa0'}}cartridges</router-link>
</b-col>
</b-row>
<b-row>
<b-col class="nav-row">
<router-link to="/nintendo-switch-online">Nintendo{{'\xa0'}}Switch{{'\xa0'}}Online</router-link> |
<router-link to="/wii">Wii{{'\xa0'}}Virtual{{'\xa0'}}Console</router-link>
</b-col>
</b-row>
<b-row>
<b-col class="nav-row">
<router-link to="/online-emulators">Online{{'\xa0'}}emulators{{'\xa0'}}</router-link> |
<router-link to="/retron-5">Retron{{'\xa0'}}5 / RetroFreak</router-link>
</b-col>
</b-row>
<b-row>
<b-col class="nav-row">
<router-link to="/n64/dexdrive">N64{{'\xa0'}}-{{'\xa0'}}DexDrive</router-link> |
<router-link to="/n64/controller-pak">N64{{'\xa0'}}-{{'\xa0'}}Controller{{'\xa0'}}Pak{{'\xa0'}}/{{'\xa0'}}emulator</router-link>
</b-col>
</b-row>
<b-row>
<b-col class="nav-row">
<router-link to="/gba/gameshark">GBA{{'\xa0'}}-{{'\xa0'}}GameShark</router-link> |
<router-link to="/gba/gameshark-sp">GBA{{'\xa0'}}-{{'\xa0'}}GameShark{{'\xa0'}}SP</router-link> |
<router-link to="/gba/action-replay">GBA{{'\xa0'}}-{{'\xa0'}}Action{{'\xa0'}}Replay</router-link>
</b-col>
</b-row>
<b-row>
<b-col class="nav-row">
<router-link to="/ps1/dexdrive">PS1{{'\xa0'}}-{{'\xa0'}}DexDrive</router-link> |
<router-link to="/ps1/psp">PS1{{'\xa0'}}-{{'\xa0'}}PSP</router-link> |
<router-link to="/ps1/ps3">PS1{{'\xa0'}}-{{'\xa0'}}PS3</router-link> |
<router-link to="/ps1/emulator">PS1{{'\xa0'}}-{{'\xa0'}}emulator</router-link>
</b-col>
</b-row>
<b-row>
<b-col class="nav-row">
<router-link to="/dreamcast">Dreamcast{{'\xa0'}}<span class="new-text">(New)</span></router-link> |
<router-link to="/sega-saturn/saroo">Sega{{'\xa0'}}Saturn{{'\xa0'}}-{{'\xa0'}}Saroo</router-link> |
<router-link to="/sega-saturn/emulator">Sega{{'\xa0'}}Saturn{{'\xa0'}}-{{'\xa0'}}Emulator</router-link> |
<router-link to="/sega-cd">Sega{{'\xa0'}}CD</router-link>
</b-col>
</b-row>
<b-row>
<b-col class="nav-row">
<router-link to="/gamecube">GameCube{{'\xa0'}}<span class="new-text">(New)</span></router-link> |
<router-link to="/psp">PSP{{'\xa0'}}-{{'\xa0'}}Save{{'\xa0'}}decryption</router-link>
</b-col>
</b-row>
<b-row>
<b-col class="nav-row">
<router-link to="/download-saves">Download{{'\xa0'}}saves</router-link> |
<router-link to="/original-hardware">Copy{{'\xa0'}}saves{{'\xa0'}}to/from{{'\xa0'}}original{{'\xa0'}}hardware</router-link> |
<router-link to="/utilities/erase-save">Erase{{'\xa0'}}save from cartridge</router-link>
</b-col>
</b-row>
<b-row class="nav-row">
<b-col>
<router-link to="/other-converters">Other{{'\xa0'}}converters</router-link> |
<router-link to="/utilities/advanced">Advanced</router-link>
</b-col>
</b-row>
<b-row>
<b-col>
<router-link to="/about">Discord{{'\xa0'}}/{{'\xa0'}}Contact{{'\xa0'}}/{{'\xa0'}}Donate</router-link>
</b-col>
</b-row>
<hr/>
</div>
<router-view/>
<div class="footer"/> <!-- Add some blank space at the bottom to look better -->
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 2em;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
.arrow-spacing {
padding-left: 0.1em;
padding-right: 0.1em;
}
.nav-row {
padding-bottom: 1em;
}
.footer {
min-height: 6em;
}
.new-text {
color: indianred;
}
.beta-text {
color: indianred;
}
</style>
================================================
FILE: frontend/src/components/AdvancedUtils.vue
================================================
<template>
<div>
<b-container>
<b-tabs v-model="tabIndex" content-class="mt-3" justified>
<b-tab title="Resize">
<tab-resize ref="tabResize"/>
</b-tab>
<b-tab :title="'Endian\xa0swap'">
<tab-endian-swap ref="tabEndianSwap"/>
</b-tab>
<b-tab title="Slice">
<tab-slice ref="tabSlice"/>
</b-tab>
<b-tab :title="'File\xa0compare'">
<tab-file-compare ref="tabFileCompare"/>
</b-tab>
<b-tab title="Remove header/footer">
<tab-remove-header-footer ref="tabRemoveHeaderFooter"/>
</b-tab>
<b-tab title="Add header/footer">
<tab-add-header-footer ref="tabAddHeaderFooter"/>
</b-tab>
<b-tab title="Compression">
<tab-compression ref="tabCompression"/>
</b-tab>
<b-tab :title="'Byte\xa0expansion'">
<tab-byte-expansion ref="tabByteExpansion"/>
</b-tab>
</b-tabs>
</b-container>
</div>
</template>
<style scoped>
</style>
<script>
import TabResize from './TabResize.vue';
import TabEndianSwap from './TabEndianSwap.vue';
import TabSlice from './TabSlice.vue';
import TabFileCompare from './TabFileCompare.vue';
import TabRemoveHeaderFooter from './TabRemoveHeaderFooter.vue';
import TabAddHeaderFooter from './TabAddHeaderFooter.vue';
import TabCompression from './TabCompression.vue';
import TabByteExpansion from './TabByteExpansion.vue';
export default {
name: 'AdvancedUtils',
components: {
TabResize,
TabEndianSwap,
TabSlice,
TabFileCompare,
TabRemoveHeaderFooter,
TabAddHeaderFooter,
TabCompression,
TabByteExpansion,
},
props: {
initialTab: {
type: String,
default: 'resize',
},
},
data() {
return {
tabIndex: 0,
};
},
beforeMount() {
// Need to keep these in sync with the template above. Is there a way to get these programmatically?
const possibleTabNames = [
'resize',
'endian-swap',
'slice',
'file-compare',
'remove-header-footer',
'add-header-footer',
'compression',
'byte-expansion',
];
const initialTabIndex = possibleTabNames.indexOf(this.initialTab);
this.tabIndex = (initialTabIndex >= 0) ? initialTabIndex : 0;
},
watch: {
tabIndex() {
this.$refs.tabResize.reset();
this.$refs.tabEndianSwap.reset();
this.$refs.tabSlice.reset();
this.$refs.tabFileCompare.reset();
this.$refs.tabRemoveHeaderFooter.reset();
this.$refs.tabAddHeaderFooter.reset();
this.$refs.tabCompression.reset();
this.$refs.tabByteExpansion.reset();
},
},
};
</script>
================================================
FILE: frontend/src/components/ByteExpandContract.vue
================================================
<template>
<div>
<b-row no-gutters align-h="start" align-v="center">
<b-col cols=11 sm=12>
<div>
<b-form-select
v-bind:value="value"
v-on:input="$emit('input', $event)"
:options="options"
:disabled="disabled"
/>
<help-button
popover-text="Different emulators, cores, flash carts, and cart readers store Sega Genesis/Mega Drive save files in different ways.
Some store each 8-bit byte as a 16-bit word with 0x00 as the high byte, some use 0xFF as the high byte,
some duplicate each byte into a 16-bit word, and some store the individual bytes as-is with no expansion."
:id="this.id"
class="help-button"
/>
</div>
</b-col>
</b-row>
</div>
</template>
<style scoped>
.help-button {
position: absolute;
right: -1.2em;
top: 0em;
}
</style>
<script>
import HelpButton from './HelpButton.vue';
export default {
name: 'ByteExpandContract',
props: {
value: {
type: String,
default: null,
},
id: String,
disabled: {
type: Boolean,
default: false,
},
},
components: {
HelpButton,
},
data() {
return {
options: [
{ value: null, text: 'Choose byte expansion style or contraction', disabled: true },
{ value: 'byte-expand-00', text: 'Byte expansion with 0x00 ("HELLO" -> " H E L L O")' },
{ value: 'byte-expand-ff', text: 'Byte expansion with 0xFF ("HELLO" -> " H E L L O")' },
{ value: 'byte-expand-duplicate', text: 'Byte expansion with duplication ("HELLO" -> "HHEELLLLOO")' },
{ value: 'byte-contract', text: 'Byte contraction (" H E L L O"/"HHEELLLLOO" -> "HELLO")' },
],
};
},
};
</script>
================================================
FILE: frontend/src/components/CompressionDecompression.vue
================================================
<template>
<div>
<b-row no-gutters align-h="start" align-v="center">
<b-col cols=11 sm=12>
<div>
<b-form-select
v-bind:value="value"
v-on:input="$emit('input', $event)"
:options="options"
:disabled="disabled"
/>
<help-button
popover-text="Whether to decompress or compress the save file"
:id="this.id"
class="help-button"
/>
</div>
</b-col>
</b-row>
</div>
</template>
<style scoped>
.help-button {
position: absolute;
right: -1.2em;
top: 0em;
}
</style>
<script>
import HelpButton from './HelpButton.vue';
export default {
name: 'CompressionDecompression',
props: {
value: {
type: String,
default: null,
},
id: String,
disabled: {
type: Boolean,
default: false,
},
},
components: {
HelpButton,
},
data() {
return {
options: [
{ value: 'decompress', text: 'Decompress file' }, // I think the most common use of this tool will be to decompress retroarch save files, so making decompress the default here makes sense
{ value: 'compress', text: 'Compress file' },
],
};
},
};
</script>
================================================
FILE: frontend/src/components/CompressionType.vue
================================================
<template>
<div>
<b-row no-gutters align-h="start" align-v="center">
<b-col cols=11 sm=12>
<div>
<b-form-select
v-bind:value="value"
v-on:input="$emit('input', $event)"
:options="options"
:disabled="disabled"
/>
<help-button
popover-text="The algorithm to use to compress or decompress the save file"
:id="this.id"
class="help-button"
/>
</div>
</b-col>
</b-row>
</div>
</template>
<style scoped>
.help-button {
position: absolute;
right: -1.2em;
top: 0em;
}
</style>
<script>
import HelpButton from './HelpButton.vue';
export default {
name: 'CompressionType',
props: {
value: {
type: String,
default: null,
},
id: String,
disabled: {
type: Boolean,
default: false,
},
},
components: {
HelpButton,
},
data() {
return {
options: [
{ value: 'zlib', text: 'zlib algorithm' }, // Used by retroarch (also used internally in Retron 5 files). I think this is by far the most common compression type users will run into, so I think it makes sense to make this the default
{ value: 'gzip', text: 'gzip algorithm' }, // Used by mednafen to compress Saturn saves (to cartridge memory)
{ value: 'rzip', text: 'rzip algorithm' }, // Proprietary format for retroarch, which can be turned on optionally
{ value: 'lzo', text: 'LZO algorithm' }, // This is used internally in goomba etc files, so it was easy to include here
// We could potentially add .zip compression here as well, since we handle it elsewhere for online emulators
// But that's the only use case I've found for it so far, and it has a dedicated page in the app and we can always ask users
// to just use their operating system's zip program. Also, zip supports multiple files inside one .zip file, which would increase
// the complexity of our Advanced tab, and without a use case for that it doesn't seem like the right thing to do at the moment.
],
};
},
};
</script>
================================================
FILE: frontend/src/components/ConversionDirection.vue
================================================
<template>
<div>
<mq-layout :mq="this.horizontalLayout">
<b-form-group class="horizontal-arrangement" v-slot="{ ariaDescribedby }">
<b-form-radio-group
v-model="conversionDirectionInternal"
:options="optionsHorizontal"
:aria-describedby="ariaDescribedby"
button-variant="outline-info"
@change="onChange($event)"
stacked
buttons
/>
</b-form-group>
</mq-layout>
<mq-layout :mq="this.verticalLayout">
<b-form-group class="vertical-arrangement" v-slot="{ ariaDescribedby }">
<b-form-radio-group
v-model="conversionDirectionInternal"
:options="optionsVertical"
:aria-describedby="ariaDescribedby"
button-variant="outline-info"
@change="onChange($event)"
buttons
/>
</b-form-group>
</mq-layout>
</div>
</template>
<style scoped>
.horizontal-arrangement {
margin-top: 2.5em;
margin-left: 0.5em;
margin-right: 0.5em;
}
.vertical-arrangement {
margin-top: 1em;
}
</style>
<script>
export default {
props: {
horizontalLayout: Array,
verticalLayout: Array,
conversionDirection: String,
disableDirection: {
type: String,
default: null,
},
},
data() {
return {
conversionDirectionInternal: this.conversionDirection, // We shouldn't directly mutate a prop because when the parent gets reloaded it'll reset its value
optionsHorizontal: [
{ html: '<i class="fa fa-arrow-circle-right fa-3x"></i>', value: 'convertToRaw', disabled: this.disableDirection === 'convertToRaw' },
{ html: '<i class="fa fa-arrow-circle-left fa-3x"></i>', value: 'convertToFormat', disabled: this.disableDirection === 'convertToFormat' },
],
optionsVertical: [
{ html: '<i class="fa fa-arrow-circle-down fa-3x"></i>', value: 'convertToRaw', disabled: this.disableDirection === 'convertToRaw' },
{ html: '<i class="fa fa-arrow-circle-up fa-3x"></i>', value: 'convertToFormat', disabled: this.disableDirection === 'convertToFormat' },
],
};
},
methods: {
onChange(event) {
this.$emit('change', event);
},
},
};
</script>
================================================
FILE: frontend/src/components/ConvertDreamcast.vue
================================================
<template>
<div>
<b-container>
<b-row no-gutters align-h="center" align-v="start">
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>Raw/emulator</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'">
<input-file
@load="readDreamcastSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert (*.bin, *.vmu, *.flash)"
:leaveRoomForHelpIcon="false"
acceptExtension=".bin,.vmu,.flash"
ref="inputFileDreamcastSaveData"
/>
<file-list
:display="this.dreamcastSaveData !== null"
:files="this.getFileListNames()"
v-model="selectedSaveData"
@change="changeSelectedSaveData($event)"
/>
</div>
<div v-else>
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="false"/>
</div>
</b-col>
<b-col sm=12 md=2 lg=2 xl=2 align-self="start">
<conversion-direction
:horizontalLayout="['md', 'lg', 'xl']"
:verticalLayout="['xs', 'sm']"
:conversionDirection="this.conversionDirection"
@change="changeConversionDirection($event)"
/>
</b-col>
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron
fluid
:header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })"
:class="($mq === 'md') ? 'fix-jumbotron' : ''"
>
<template v-slot:header>{{ individualSavesOrSaveText }}</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'">
<div v-if="this.individualSaveType === 'dci'">
<output-filename
v-model="outputFilename"
:leaveRoomForHelpIcon="true"
:disabled="false"
/>
</div>
<div v-else>
<output-filename
v-model="outputFilenameVmi"
placeholder="Output filename (.vmi)"
:leaveRoomForHelpIcon="true"
:disabled="false"
/>
<output-filename
v-model="outputFilenameVms"
placeholder="Output filename (.vms)"
:leaveRoomForHelpIcon="true"
:disabled="false"
/>
</div>
<dreamcast-individual-save-type-selector
:value="this.individualSaveType"
@change="changeIndividualSaveType($event)"
/>
</div>
<div v-else>
<div v-if="this.individualSaveType === 'dci'">
<input-file
@load="readEmulatorSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose files to add (*.dci)"
:leaveRoomForHelpIcon="false"
:allowMultipleFiles="true"
ref="inputFileIndividualSaveDci"
acceptExtension=".dci"
/>
</div>
<div v-else>
<input-file
@load="readVmiSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose file to add (*.vmi)"
:leaveRoomForHelpIcon="false"
:allowMultipleFiles="false"
acceptExtension=".vmi"
ref="inputFileIndividualSaveVmi"
/>
<input-file
@load="readVmsSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose file to add (*.vms)"
:leaveRoomForHelpIcon="false"
:allowMultipleFiles="false"
acceptExtension=".vms"
ref="inputFileIndividualSaveVms"
/>
</div>
<dreamcast-individual-save-type-selector
:value="this.individualSaveType"
@change="changeIndividualSaveType($event)"
/>
<file-list
:display="this.dreamcastSaveData !== null"
:files="this.getFileListNames()"
:enabled="false"
/>
</div>
</b-col>
</b-row>
<b-row class="justify-content-md-center" align-h="center">
<b-col cols="auto" sm=4 md=3 lg=2 align-self="center">
<b-button
class="dreamcast-convert-button"
variant="success"
block
:disabled="this.convertButtonDisabled"
@click="convertFile()"
>
Convert!
</b-button>
</b-col>
</b-row>
<b-row>
<b-col>
<div class="help">
Help: how can I <router-link to="/original-hardware?sort=dc">copy save files to and from a Dreamcast console</router-link>?
</div>
</b-col>
</b-row>
</b-container>
</div>
</template>
<style scoped>
/* Separate class for each different button to enable tracking in google tag manager */
.dreamcast-convert-button {
margin-top: 1em;
}
.help {
margin-top: 1em;
}
/* Mpve this up rather than deleting the margin under the selector above so that if this isn't visible there's still margin under the one above */
.output-filesize {
margin-top: -1em;
}
/* We have so much text in our jumbotron that at the md size it wants to be vertically larger than the other one. So let's constrain it and move the text upwards inside it */
.fix-jumbotron {
max-height: 11.5em;
}
.fix-jumbotron > div {
margin-top: -1em;
}
</style>
<script>
import { saveAs } from 'file-saver';
import Util from '../util/util';
import InputFile from './InputFile.vue';
import OutputFilename from './OutputFilename.vue';
import ConversionDirection from './ConversionDirection.vue';
import FileList from './FileList.vue';
import DreamcastIndividualSaveTypeSelector from './DreamcastIndividualSaveTypeSelector.vue';
import DreamcastSaveData from '../save-formats/Dreamcast/Dreamcast';
import DreamcastDciSaveData from '../save-formats/Dreamcast/IndividualSaves/Dci';
import DreamcastVmiVmsSaveData from '../save-formats/Dreamcast/IndividualSaves/VmiVms';
import DreamcastBasics from '../save-formats/Dreamcast/Components/Basics';
const DEFAULT_ICON_SHAPE = 0;
const DEFAULT_INDIVIDUAL_SAVE_TYPE = 'dci';
export default {
name: 'ConvertDreamcast',
data() {
return {
dreamcastSaveData: null,
errorMessage: null,
inputFilename: null,
outputFilename: null,
outputFilenameVmi: null,
outputFilenameVms: null,
conversionDirection: 'convertToRaw',
selectedSaveData: null,
individualSaveType: DEFAULT_INDIVIDUAL_SAVE_TYPE,
vmiVmsParts: {},
};
},
components: {
ConversionDirection,
InputFile,
OutputFilename,
FileList,
DreamcastIndividualSaveTypeSelector,
},
computed: {
convertButtonDisabled() {
const haveDataSelected = (this.conversionDirection === 'convertToRaw') ? true : this.selectedSaveData === null;
let hasOutputFilename = false;
if (this.conversionDirection === 'convertToRaw') {
hasOutputFilename = ((this.individualSaveType === 'dci') && (this.outputFilename !== null))
|| ((this.individualSaveType !== 'dci') && (this.outputFilenameVmi !== null) && (this.outputFilenameVms !== null));
} else {
hasOutputFilename = (this.outputFilename !== null);
}
return !this.dreamcastSaveData || this.dreamcastSaveData.getSaveFiles().length === 0 || !haveDataSelected || !hasOutputFilename;
},
individualSavesOrSaveText() {
return ((this.individualSaveType === 'vmivms') && (this.conversionDirection === 'convertToFormat')) ? 'Individual save' : 'Individual saves';
},
},
methods: {
changeIndividualSaveType(newValue) {
if (this.individualSaveType !== newValue) {
this.individualSaveType = newValue;
this.outputFilename = null;
this.outputFilenameVmi = null;
this.outputFilenameVms = null;
this.vmiVmsParts = {};
if (this.conversionDirection === 'convertToFormat') {
// When converting to a memcard image, we want to start over when we select a different input file type
// When when converting from a memcard image, we want to be able to freely select our output file type without having to start over selecting a new memcard image
this.dreamcastSaveData = null;
}
if (this.$refs.inputFileIndividualSaveDci) {
this.$refs.inputFileIndividualSaveDci.reset();
}
if (this.$refs.inputFileIndividualSaveVmi) {
this.$refs.inputFileIndividualSaveVmi.reset();
}
if (this.$refs.inputFileIndividualSaveVms) {
this.$refs.inputFileIndividualSaveVms.reset();
}
this.changeSelectedSaveData(this.selectedSaveData);
}
},
getFileNameFromSaveFile(saveFile) {
return Util.convertDescriptionToFilename(`${saveFile.filename}`);
},
getFileListNames() {
if ((this.dreamcastSaveData !== null) && (this.dreamcastSaveData.getSaveFiles() !== null)) {
return this.dreamcastSaveData.getSaveFiles().map((x) => {
const fileTypeText = (x.fileType === DreamcastBasics.FILE_TYPE_GAME) ? 'Game: ' : '';
const storageComment = x.storageComment.trim();
const fileComment = x.fileComment.trim();
if ((storageComment.length > 0) && (fileComment.length > 0)) {
return { displayText: `${fileTypeText}${storageComment} - ${fileComment}` };
}
if (storageComment.length > 0) {
return { displayText: `${fileTypeText}${storageComment}` };
}
if (fileComment.length > 0) {
return { displayText: `${fileTypeText}${fileComment}` };
}
// The filename isn't great to display, but it always contains something and none of our comments have anything in them
return { displayText: `${fileTypeText}${x.filename}` };
});
}
return [];
},
changeConversionDirection(newDirection) {
this.conversionDirection = newDirection;
this.dreamcastSaveData = null;
this.errorMessage = null;
this.inputFilename = null;
this.outputFilename = null;
this.outputFilenameVmi = null;
this.outputFilenameVms = null;
this.selectedSaveData = null;
this.individualSaveType = DEFAULT_INDIVIDUAL_SAVE_TYPE;
this.vmiVmsParts = {};
// The refs become undefined when the components are removed using a v-if
if (this.$refs.inputFileDreamcastSaveData) {
this.$refs.inputFileDreamcastSaveData.reset();
}
if (this.$refs.inputFileIndividualSaveDci) {
this.$refs.inputFileIndividualSaveDci.reset();
}
if (this.$refs.inputFileIndividualSaveVmi) {
this.$refs.inputFileIndividualSaveVmi.reset();
}
if (this.$refs.inputFileIndividualSaveVms) {
this.$refs.inputFileIndividualSaveVms.reset();
}
},
changeSelectedSaveData(newSaveData) {
if (newSaveData !== null) {
if ((this.dreamcastSaveData !== null) && (this.dreamcastSaveData.getSaveFiles().length > 0)) {
this.selectedSaveData = newSaveData;
const filename = this.getFileNameFromSaveFile(this.dreamcastSaveData.getSaveFiles()[this.selectedSaveData]);
if (this.individualSaveType === 'dci') {
this.outputFilename = `${filename}.dci`;
} else {
this.outputFilenameVmi = `${filename}.vmi`;
this.outputFilenameVms = `${filename}.vms`;
}
} else {
this.selectedSaveData = null;
this.outputFilename = null;
this.outputFilenameVmi = null;
this.outputFilenameVms = null;
}
}
},
readDreamcastSaveData(event) {
this.errorMessage = null;
this.selectedSaveData = null;
this.outputFilename = null;
this.outputFilenameVmi = null;
this.outputFilenameVms = null;
this.inputFilename = event.filename;
try {
this.dreamcastSaveData = DreamcastSaveData.createFromDreamcastData(event.arrayBuffer);
} catch (e) {
this.errorMessage = 'File appears to not be in the correct format';
this.dreamcastSaveData = null;
this.selectedSaveData = null;
}
},
readVmiSaveData(event) {
this.vmiVmsParts.vmiArrayBuffer = event.arrayBuffer;
if (Object.hasOwn(this.vmiVmsParts, 'vmiArrayBuffer') && Object.hasOwn(this.vmiVmsParts, 'vmsArrayBuffer')) {
this.readEmulatorSaveData(null);
}
},
readVmsSaveData(event) {
this.vmiVmsParts.vmsArrayBuffer = event.arrayBuffer;
if (Object.hasOwn(this.vmiVmsParts, 'vmiArrayBuffer') && Object.hasOwn(this.vmiVmsParts, 'vmsArrayBuffer')) {
this.readEmulatorSaveData(null);
}
},
readEmulatorSaveData(event) {
this.errorMessage = null;
this.selectedSaveData = null;
this.inputFilename = null;
try {
let saveFiles = [];
if (this.individualSaveType === 'dci') {
const saveFileArrayBuffers = event.map((f) => f.arrayBuffer);
saveFiles = saveFileArrayBuffers.map((saveFileArrayBuffer) => DreamcastDciSaveData.convertIndividualSaveToSaveFile(saveFileArrayBuffer));
} else {
saveFiles = [DreamcastVmiVmsSaveData.convertIndividualSaveToSaveFile(this.vmiVmsParts.vmiArrayBuffer, this.vmiVmsParts.vmsArrayBuffer)];
}
const volumeInfo = {
useCustomColor: false,
timestamp: new Date(),
iconShape: DEFAULT_ICON_SHAPE,
};
this.dreamcastSaveData = DreamcastSaveData.createFromSaveFiles(saveFiles, volumeInfo);
if (this.dreamcastSaveData.getSaveFiles().length > 0) {
this.outputFilename = `${this.getFileNameFromSaveFile(this.dreamcastSaveData.getSaveFiles()[0])}.bin`;
} else {
this.outputFilename = 'output.bin';
}
} catch (e) {
this.errorMessage = e.message;
this.dreamcastSaveData = null;
this.selectedSaveData = null;
this.outputFilename = null;
this.outputFilenameVmi = null;
this.outputFilenameVms = null;
}
},
convertFile() {
const outputFileList = [];
if (this.conversionDirection === 'convertToRaw') {
const saveFile = this.dreamcastSaveData.getSaveFiles()[this.selectedSaveData];
if (this.individualSaveType === 'dci') {
outputFileList.push({
arrayBuffer: DreamcastDciSaveData.convertSaveFileToDci(saveFile),
filename: this.outputFilename,
});
} else {
const vmiVmsSaveFile = {
...saveFile,
description: 'Created by savefileconverter.com',
copyright: 'savefileconverter.com',
resourceName: saveFile.filename, // Will be truncated from 12 -> 8 characters
};
const { vmiArrayBuffer, vmsArrayBuffer } = DreamcastVmiVmsSaveData.convertSaveFileToVmiVms(vmiVmsSaveFile);
outputFileList.push(
{
arrayBuffer: vmiArrayBuffer,
filename: this.outputFilenameVmi,
},
{
arrayBuffer: vmsArrayBuffer,
filename: this.outputFilenameVms,
},
);
}
} else {
outputFileList.push({
arrayBuffer: this.dreamcastSaveData.getArrayBuffer(),
filename: this.outputFilename,
});
}
outputFileList.forEach((outputFile) => {
const outputBlob = new Blob([outputFile.arrayBuffer], { type: 'application/octet-stream' });
saveAs(outputBlob, outputFile.filename); // Frustratingly, in Firefox the dialog says "from: blob:" and apparently this can't be changed: https://github.com/eligrey/FileSaver.js/issues/101
});
},
},
};
</script>
================================================
FILE: frontend/src/components/ConvertFlashCarts.vue
================================================
<template>
<div>
<b-container>
<b-row no-gutters align-h="center" align-v="start">
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>Flash{{'\xa0'}}cartridge</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'">
<input-file
@load="readFlashCartSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert"
:leaveRoomForHelpIcon="false"
/>
<flash-cart-type
v-model="flashCartType"
id="flash-cart-type"
v-on:input="flashCartTypeChanged()"
:disabled="false"
/>
<div v-if="this.isSegaCdWithTwoOutputFiles">
<sega-cd-save-type-selector
:value="this.segaCdSaveType"
@change="changeSegaCdSaveType($event)"
/>
</div>
<div v-if="this.romIsRequired">
<input-file
id="choose-raw-file-rom"
@load="readRomData($event)"
:errorMessage="null"
:placeholderText="`Choose the ROM for this file ${getFileExtensionsString(this.flashCartTypeClass.requiresRom().clazz)}`"
helpText="These save files require some information from the corresponding ROM.
All processing by this website is done on your local machine, and your ROMs are not sent anywhere."
:acceptExtension="this.flashCartTypeClass.requiresRom().clazz.getFileExtensions().join(',')"
:leaveRoomForHelpIcon="true"
/>
</div>
</div>
<div v-else>
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="false"/>
<div v-if="this.displayOutputFileSize">
<output-filesize v-model="outputFilesize" id="output-filesize" :platform="this.flashCartTypeClass.adjustOutputSizesPlatform()"/>
</div>
</div>
</b-col>
<b-col sm=12 md=2 lg=2 xl=2 align-self="start">
<conversion-direction
:horizontalLayout="['md', 'lg', 'xl']"
:verticalLayout="['xs', 'sm']"
:conversionDirection="this.conversionDirection"
@change="changeConversionDirection($event)"
/>
</b-col>
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>Emulator/Raw</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'">
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="false"/>
<div v-if="this.isSegaCdWithOneOutputFile">
<sega-cd-save-type-selector
:value="this.segaCdSaveType"
@change="changeSegaCdSaveType($event)"
/>
</div>
<div v-if="this.displayOutputFileSize">
<output-filesize v-model="outputFilesize" id="output-filesize" :platform="this.flashCartTypeClass.adjustOutputSizesPlatform()"/>
</div>
</div>
<div v-else>
<div v-if="this.isSegaCdWithOneOutputFile">
<input-file
@load="readEmulatorSaveData($event, 'rawInternalSaveArrayBuffer')"
:errorMessage="this.errorMessage"
placeholderText="Choose an internal memory save file to convert"
:leaveRoomForHelpIcon="false"
ref="inputFileSegaCdInternalMemory"
/>
<input-file
@load="readEmulatorSaveData($event, 'rawRamCartSaveArrayBuffer')"
:errorMessage="this.errorMessage"
placeholderText="Choose a RAM cartridge save file to convert"
:leaveRoomForHelpIcon="false"
ref="inputFileSegaCdRamCart"
/>
</div>
<div v-else>
<input-file
@load="readEmulatorSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert"
:leaveRoomForHelpIcon="false"
ref="inputFileEmulator"
/>
</div>
<flash-cart-type
v-model="flashCartType"
id="flash-cart-type"
v-on:input="flashCartTypeChanged()"
:disabled="false"
/>
<div v-if="this.isSegaCdWithTwoOutputFiles">
<sega-cd-save-type-selector
:value="this.segaCdSaveType"
@change="changeSegaCdSaveType($event)"
/>
</div>
<div v-if="this.romIsRequired">
<input-file
id="choose-raw-file-rom"
@load="readRomData($event)"
:errorMessage="null"
:placeholderText="`Choose the ROM for this file ${getFileExtensionsString(this.flashCartTypeClass.requiresRom().clazz)}`"
helpText="These save files require some information from the corresponding ROM.
All processing by this website is done on your local machine, and your ROMs are not sent anywhere."
:acceptExtension="this.flashCartTypeClass.requiresRom().clazz.getFileExtensions().join(',')"
:leaveRoomForHelpIcon="true"
/>
</div>
</div>
</b-col>
</b-row>
<b-row class="justify-content-md-center" align-h="center">
<b-col cols="auto" sm=4 md=3 lg=2 align-self="center">
<b-button
class="flash-cart-convert-button"
variant="success"
block
:disabled="!this.flashCartSaveData || !this.flashCartType || !outputFilename"
@click="convertFile()"
>
Convert!
</b-button>
</b-col>
</b-row>
<b-row>
<b-col>
<div class="help">
Before copying a save file to or from a flash cart, please launch a different game first.<br>
Please see your flash cart documentation for more details, or check #faqs on the <router-link to="/about">Discord</router-link>.
</div>
</b-col>
</b-row>
</b-container>
</div>
</template>
<style scoped>
/* Separate class for each different button to enable tracking in google tag manager */
.flash-cart-convert-button {
margin-top: 1em;
}
.help {
margin-top: 1em;
}
</style>
<script>
import { saveAs } from 'file-saver';
import Util from '../util/util';
import SegaCdUtil from '../util/SegaCd';
import InputFile from './InputFile.vue';
import OutputFilename from './OutputFilename.vue';
import OutputFilesize from './OutputFilesize.vue';
import ConversionDirection from './ConversionDirection.vue';
import FlashCartType from './FlashCartType.vue';
import SegaCdSaveTypeSelector from './SegaCdSaveTypeSelector.vue';
import GoombaEmulatorSaveData from '../save-formats/FlashCarts/GBA/GoombaEmulator';
import PocketNesEmulatorSaveData from '../save-formats/FlashCarts/GBA/PocketNesEmulator';
import SmsAdvanceEmulatorSaveData from '../save-formats/FlashCarts/GBA/SmsAdvanceEmulator';
import NesFlashCartSaveData from '../save-formats/FlashCarts/NES';
import SnesFlashCartSaveData from '../save-formats/FlashCarts/SNES/SNES';
import SuperGameboyFlashCartSaveData from '../save-formats/FlashCarts/SNES/GB';
import GenesisMegaEverdriveProGenesisFlashCartSaveData from '../save-formats/FlashCarts/Genesis/MegaEverdrivePro/Genesis';
import GenesisMegaEverdriveProSegaCdFlashCartSaveData from '../save-formats/FlashCarts/Genesis/MegaEverdrivePro/SegaCd';
import GenesisMegaEverdriveProNesFlashCartSaveData from '../save-formats/FlashCarts/Genesis/MegaEverdrivePro/NES';
import GenesisMegaEverdriveProSmsFlashCartSaveData from '../save-formats/FlashCarts/Genesis/MegaEverdrivePro/SMS';
import GenesisMegaEverdrivePro32xFlashCartSaveData from '../save-formats/FlashCarts/Genesis/MegaEverdrivePro/32X';
import GenesisMegaSdGenesisFlashCartSaveData from '../save-formats/FlashCarts/Genesis/MegaSD/Genesis';
import GenesisMegaSdSegaCdFlashCartSaveData from '../save-formats/FlashCarts/Genesis/MegaSD/SegaCd';
import GenesisMegaSdSmsFlashCartSaveData from '../save-formats/FlashCarts/Genesis/MegaSD/SMS';
import GenesisMegaSd32xFlashCartSaveData from '../save-formats/FlashCarts/Genesis/MegaSD/32X';
import GbFlashCartSaveData from '../save-formats/FlashCarts/GB';
import GbaFlashCartSaveData from '../save-formats/FlashCarts/GBA/GBA';
import N64FlashCartSaveData from '../save-formats/FlashCarts/N64/N64';
import N64NesFlashCartSaveData from '../save-formats/FlashCarts/N64/NES';
import Neon64EmulatorSaveData from '../save-formats/FlashCarts/N64/Neon64Emulator';
import Gb64EmulatorSaveData from '../save-formats/FlashCarts/N64/GB64Emulator';
import PcEngineFlashCartSaveData from '../save-formats/FlashCarts/PcEngine';
import GameGearFlashCartSaveData from '../save-formats/FlashCarts/GameGear';
import SmsFlashCartSaveData from '../save-formats/FlashCarts/SMS';
export default {
name: 'ConvertFlashCarts',
data() {
return {
flashCartSaveData: null,
romData: null,
flashCartType: null,
flashCartTypePrevious: null,
flashCartTypeClass: null,
errorMessage: null,
outputFilename: null,
outputFilesize: null,
conversionDirection: 'convertToRaw',
inputArrayBuffer: null,
inputFilename: null,
inputSegaCd: {},
segaCdSaveType: 'internal-memory',
};
},
components: {
ConversionDirection,
InputFile,
OutputFilename,
OutputFilesize,
FlashCartType,
SegaCdSaveTypeSelector,
},
computed: {
isSegaCdWithTwoOutputFiles: {
get() { return this.flashCartTypeIsSegaCdWithTwoOutputFiles(this.flashCartType); },
},
isSegaCdWithOneOutputFile: {
get() { return this.flashCartTypeIsSegaCdWithOneOutputFile(this.flashCartType); },
},
isSegaCd: {
get() { return this.flashCartTypeIsSegaCd(this.flashCartType); },
},
displayOutputFileSize: {
get() {
if ((this.flashCartTypeClass !== null) && (this.flashCartTypeClass.adjustOutputSizesPlatform() !== null)) {
if (this.isSegaCd) {
// Flash carts have fixed sizes for their RAM carts, so we don't want to adjust them.
// Emulators may have any size
return ((this.conversionDirection === 'convertToRaw') && (this.segaCdSaveType === 'ram-cart'));
}
return true;
}
return false;
},
},
romIsRequired: {
get() {
if (this.flashCartTypeClass === null) {
return false;
}
let requiresRomToConvert = [];
if (this.flashCartTypeClass.requiresRom() !== null) {
requiresRomToConvert = this.flashCartTypeClass.requiresRom().requiredToConvert;
}
return (requiresRomToConvert.indexOf(this.conversionDirection) >= 0);
},
},
},
methods: {
flashCartTypeIsSegaCdWithTwoOutputFiles(flashCartType) {
return (flashCartType === 'FlashCart-SegaCDGenesisEverdrive');
},
flashCartTypeIsSegaCdWithOneOutputFile(flashCartType) {
return (flashCartType === 'FlashCart-SegaCDMegaSD');
},
flashCartTypeIsSegaCd(flashCartType) {
return (this.flashCartTypeIsSegaCdWithTwoOutputFiles(flashCartType) || this.flashCartTypeIsSegaCdWithOneOutputFile(flashCartType));
},
changeConversionDirection(newDirection) {
this.conversionDirection = newDirection;
this.flastCartSaveData = null;
this.romData = null;
this.flashCartType = null;
this.flashCartTypePrevious = null;
this.flashCartTypeClass = null;
this.errorMessage = null;
this.outputFilename = null;
this.outputFilesize = null;
this.inputArrayBuffer = null;
this.inputFilename = null;
this.inputSegaCd = {};
this.segaCdSaveType = 'internal-memory';
},
getFileExtensionsString(romFormatClass) {
return `(${romFormatClass.getFileExtensions().map((f) => `*${f}`).join(', ')})`;
},
flashCartTypeChanged() {
if (this.flashCartType !== null) {
this.romData = null;
switch (this.flashCartType) {
case 'FlashCart-GoombaEmulator': {
this.flashCartTypeClass = GoombaEmulatorSaveData;
break;
}
case 'FlashCart-PocketNesEmulator': {
this.flashCartTypeClass = PocketNesEmulatorSaveData;
break;
}
case 'FlashCart-SMSAdvanceEmulator': {
this.flashCartTypeClass = SmsAdvanceEmulatorSaveData;
break;
}
case 'FlashCart-NES': {
this.flashCartTypeClass = NesFlashCartSaveData;
break;
}
case 'FlashCart-SNES': {
this.flashCartTypeClass = SnesFlashCartSaveData;
break;
}
case 'FlashCart-SuperGameBoy': {
this.flashCartTypeClass = SuperGameboyFlashCartSaveData;
break;
}
case 'FlashCart-GenesisEverdrive': {
this.flashCartTypeClass = GenesisMegaEverdriveProGenesisFlashCartSaveData;
break;
}
case 'FlashCart-SegaCDGenesisEverdrive': {
this.flashCartTypeClass = GenesisMegaEverdriveProSegaCdFlashCartSaveData;
break;
}
case 'FlashCart-NESGenesisEverdrive': {
this.flashCartTypeClass = GenesisMegaEverdriveProNesFlashCartSaveData;
break;
}
case 'FlashCart-SMSGenesisEverdrive': {
this.flashCartTypeClass = GenesisMegaEverdriveProSmsFlashCartSaveData;
break;
}
case 'FlashCart-32XGenesisEverdrive': {
this.flashCartTypeClass = GenesisMegaEverdrivePro32xFlashCartSaveData;
break;
}
case 'FlashCart-GenesisMegaSD': {
this.flashCartTypeClass = GenesisMegaSdGenesisFlashCartSaveData;
break;
}
case 'FlashCart-SegaCDMegaSD': {
this.flashCartTypeClass = GenesisMegaSdSegaCdFlashCartSaveData;
break;
}
case 'FlashCart-SMSGenesisMegaSD': {
this.flashCartTypeClass = GenesisMegaSdSmsFlashCartSaveData;
break;
}
case 'FlashCart-32XGenesisMegaSD': {
this.flashCartTypeClass = GenesisMegaSd32xFlashCartSaveData;
break;
}
case 'FlashCart-GB': {
this.flashCartTypeClass = GbFlashCartSaveData;
break;
}
case 'FlashCart-GBA': {
this.flashCartTypeClass = GbaFlashCartSaveData;
break;
}
case 'FlashCart-N64': {
this.flashCartTypeClass = N64FlashCartSaveData;
break;
}
case 'FlashCart-NESN64': {
this.flashCartTypeClass = N64NesFlashCartSaveData;
break;
}
case 'FlashCart-Neon64Emulator': {
this.flashCartTypeClass = Neon64EmulatorSaveData;
break;
}
case 'FlashCart-GB64Emulator': {
this.flashCartTypeClass = Gb64EmulatorSaveData;
break;
}
case 'FlashCart-PCE': {
this.flashCartTypeClass = PcEngineFlashCartSaveData;
break;
}
case 'FlashCart-GG': {
this.flashCartTypeClass = GameGearFlashCartSaveData;
break;
}
case 'FlashCart-SMS': {
this.flashCartTypeClass = SmsFlashCartSaveData;
break;
}
default: {
this.flashCartTypeClass = null;
break;
}
}
} else {
this.flashCartTypeClass = null;
}
// We use different input boxes in the UI depending on whether there are 1 or 2 raw files to read,
// and so we want to wipe out any input file info that may be lurking internally when we switch to showing a different input box
// because it's not clear which box we would assign that to
//
// Additionally, there's a browser optimization/bug where when we swap out a different file input that's
// in the same location as a previous one, then the contents of the file box in the DOM carry over to the new box
// even though it's a different element. So, we call reset() here
const currentlySegaCd = this.isSegaCd;
const previouslySegaCd = this.flashCartTypeIsSegaCd(this.flashCartTypePrevious);
if ((currentlySegaCd !== previouslySegaCd) && (this.conversionDirection !== 'convertToRaw')) {
this.inputArrayBuffer = null;
this.flashCartSaveData = null;
this.inputFilename = null;
this.inputSegaCd = {};
this.outputFilesize = null;
// The refs become undefined when the components are removed using a v-if
if (this.$refs.inputFileSegaCdInternalMemory) {
this.$refs.inputFileSegaCdInternalMemory.reset();
}
if (this.$refs.inputFileSegaCdRamCart) {
this.$refs.inputFileSegaCdRamCart.reset();
}
if (this.$refs.inputFileEmulator) {
this.$refs.inputFileEmulator.reset();
}
}
this.flashCartTypePrevious = this.flashCartType;
this.segaCdSaveType = this.getDefaultSegaCdSaveType();
this.updateFlashCartSaveData();
},
changeSegaCdSaveType(newSaveType) {
this.segaCdSaveType = newSaveType;
this.updateFlashCartSaveData();
},
readRomData(event) {
this.romData = event.arrayBuffer;
this.segaCdSaveType = this.getDefaultSegaCdSaveType();
this.updateFlashCartSaveData();
},
hasRequiredRomData() {
return (!this.romIsRequired || (this.romData !== null));
},
hasRequiredInputFileData() {
return (this.inputArrayBuffer !== null) && (this.inputFilename !== null);
},
getOutputFilename(inputFilename, fileExtension) {
if (fileExtension !== null) {
return Util.changeFilenameExtension(inputFilename, fileExtension);
}
return inputFilename;
},
getFlashCartInput() {
if (this.isSegaCdWithTwoOutputFiles) {
return (this.segaCdSaveType === 'internal-memory') ? { flashCartInternalSaveArrayBuffer: this.inputArrayBuffer } : { flashCartRamCartSaveArrayBuffer: this.inputArrayBuffer };
}
return this.inputArrayBuffer;
},
getRawInput() {
if (this.isSegaCdWithTwoOutputFiles) {
return (this.segaCdSaveType === 'internal-memory') ? { rawInternalSaveArrayBuffer: this.inputArrayBuffer } : { rawRamCartSaveArrayBuffer: this.inputArrayBuffer };
}
if (this.isSegaCdWithOneOutputFile) {
return this.inputSegaCd;
}
return this.inputArrayBuffer;
},
getFlashCartFilename() {
if (this.isSegaCdWithTwoOutputFiles) {
return this.flashCartTypeClass.getFlashCartFileName(this.segaCdSaveType);
}
return this.getOutputFilename(this.inputFilename, this.flashCartTypeClass.getFlashCartFileExtension());
},
getRawFilename() {
if (this.isSegaCd) {
const filenameSuffix = (this.segaCdSaveType === 'internal-memory') ? ' - internal memory' : ' - ram cartridge';
return `${Util.removeFilenameExtension(this.inputFilename)}${filenameSuffix}.${this.flashCartTypeClass.getRawFileExtension()}`;
}
return this.getOutputFilename(this.inputFilename, this.flashCartTypeClass.getRawFileExtension());
},
getDefaultOutputFilesize() {
if (this.isSegaCd) {
// All flash cart types have the same internal memory size
if (this.segaCdSaveType === 'internal-memory') {
return SegaCdUtil.INTERNAL_SAVE_SIZE;
}
// RAM cart, so ask the class the default size
if (this.conversionDirection === 'convertToRaw') {
return this.flashCartTypeClass.getRawDefaultRamCartSize();
}
return this.flashCartTypeClass.getFlashCartDefaultRamCartSize();
}
return this.flashCartSaveData.getRawArrayBuffer().byteLength;
},
getDefaultSegaCdSaveType() {
if (this.isSegaCdWithTwoOutputFiles) {
if ((this.inputArrayBuffer !== null) && (this.inputArrayBuffer.byteLength > SegaCdUtil.INTERNAL_SAVE_SIZE)) {
return 'ram-cart';
}
}
return 'internal-memory';
},
updateFlashCartSaveData() {
this.errorMessage = null;
if ((this.flashCartTypeClass !== null) && this.hasRequiredRomData() && this.hasRequiredInputFileData()) {
try {
if (this.conversionDirection === 'convertToRaw') {
this.flashCartSaveData = this.flashCartTypeClass.createFromFlashCartData(this.getFlashCartInput(), this.romData);
this.outputFilename = this.getRawFilename();
} else {
this.flashCartSaveData = this.flashCartTypeClass.createFromRawData(this.getRawInput(), this.romData);
this.outputFilename = this.getFlashCartFilename();
}
this.outputFilesize = this.getDefaultOutputFilesize();
} catch (e) {
this.errorMessage = 'This file does not seem to be in the correct format';
this.flashCartSaveData = null;
this.outputFilename = null;
this.segaCdSaveType = 'internal-memory';
}
} else {
this.flashCartSaveData = null;
this.outputFilename = null;
}
},
readFlashCartSaveData(event) {
this.inputArrayBuffer = event.arrayBuffer;
this.inputFilename = event.filename;
this.segaCdSaveType = this.getDefaultSegaCdSaveType();
this.inputSegaCd = {};
this.updateFlashCartSaveData();
},
readEmulatorSaveData(event, inputSegaCdType = null) {
this.inputArrayBuffer = event.arrayBuffer;
this.inputFilename = event.filename;
this.segaCdSaveType = this.getDefaultSegaCdSaveType();
if (inputSegaCdType !== null) {
this.inputSegaCd[inputSegaCdType] = event.arrayBuffer;
} else {
this.inputSegaCd = {};
}
this.updateFlashCartSaveData();
},
convertFile() {
let finalFlashCartSaveData = this.flashCartSaveData;
let needsResize = false;
if (this.isSegaCd) {
needsResize = this.flashCartSaveData.getRawArrayBuffer(this.flashCartTypeClass.RAM_CART).byteLength !== this.outputFilesize;
} else {
needsResize = this.flashCartSaveData.getRawArrayBuffer().byteLength !== this.outputFilesize;
}
if (needsResize) {
finalFlashCartSaveData = this.flashCartTypeClass.createWithNewSize(this.flashCartSaveData, this.outputFilesize);
}
let output = null;
if (this.conversionDirection === 'convertToRaw') {
if (this.isSegaCd) {
output = finalFlashCartSaveData.getRawArrayBuffer(this.segaCdSaveType);
} else {
output = finalFlashCartSaveData.getRawArrayBuffer();
}
} else {
if (this.isSegaCd) { // eslint-disable-line no-lonely-if
output = finalFlashCartSaveData.getFlashCartArrayBuffer(this.segaCdSaveType);
} else {
output = finalFlashCartSaveData.getFlashCartArrayBuffer();
}
}
const outputBlob = new Blob([output], { type: 'application/octet-stream' });
saveAs(outputBlob, this.outputFilename);
},
},
};
</script>
================================================
FILE: frontend/src/components/ConvertGameCube.vue
================================================
<template>
<div>
<b-container>
<b-row no-gutters align-h="center" align-v="start">
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>Raw/emulator</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'">
<input-file
@load="readGameCubeSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert (*.raw, *.gcp)"
:leaveRoomForHelpIcon="false"
acceptExtension=".raw,.gcp"
ref="inputFileGameCubeSaveData"
/>
<file-list
:display="this.gameCubeSaveDataLargest !== null"
:files="this.getFileListNames()"
v-model="selectedSaveData"
@change="changeSelectedSaveData($event)"
/>
</div>
<div v-else>
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="false"/>
<output-filesize
:value="this.outputFilesize"
@input="changeOutputFilesize($event)"
platform="gamecube"
:customFormatter="formatSize"
overrideHelpText="Select the size of memory card that you wish to create"
/>
<game-cube-encoding-selector
:value="this.outputEncoding"
@input="changeOutputEncoding($event)"
id="gameCubeEncodingSelector"
/>
<input-file
@load="readGameCubeExampleFileSaveData($event)"
:errorMessage="this.errorMessageExampleFile"
placeholderText="Optional: example file (*.raw, *.gcp)"
:leaveRoomForHelpIcon="false"
acceptExtension=".raw,.gcp"
helpText="When copying a .raw file to an original memory card, the file must contain a special ID number specific to that individual memory card.
Provide an example file here from that memory card so that the ID number can be copied from it. This is not required when using an emulator or the Memcard Pro GC."
ref="inputFileGameCubeExampleSaveData"
id="inputFileGameCubeExampleSaveData"
/>
</div>
</b-col>
<b-col sm=12 md=2 lg=2 xl=2 align-self="start">
<conversion-direction
:horizontalLayout="['md', 'lg', 'xl']"
:verticalLayout="['xs', 'sm']"
:conversionDirection="this.conversionDirection"
@change="changeConversionDirection($event)"
/>
</b-col>
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron
fluid
:header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })"
:class="($mq === 'md') && (this.individualSavesOrMemoryCard === 'individual-saves') ? 'fix-jumbotron' : ''"
>
<template v-slot:header>{{ individualSavesOrMemoryCardText }}</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'">
<div v-if="this.individualSavesOrMemoryCard === 'individual-saves'">
<output-filename
v-model="outputFilename"
:leaveRoomForHelpIcon="true"
:disabled="false"
/>
</div>
<div v-else>
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="false"/>
</div>
<individual-saves-or-memory-card-selector
:value="this.individualSavesOrMemoryCard"
@change="changeIndividualSavesOrMemoryCard($event)"
:individualSavesText="this.individualSavesText"
:memoryCardText="this.memoryCardText"
/>
<div v-if="this.individualSavesOrMemoryCard === 'memory-card'">
<output-filesize
class="output-filesize"
:value="this.outputFilesize"
@input="changeOutputFilesize($event)"
platform="gamecube"
:customFormatter="formatSize"
overrideHelpText="Select the size of memory card that you wish to create"
/>
</div>
</div>
<div v-else>
<input-file
@load="readEmulatorSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose files to add (*.gci, *.gcs, *.sav)"
:leaveRoomForHelpIcon="false"
:allowMultipleFiles="true"
acceptExtension=".gci,.gcs,.sav"
/>
<file-list
:display="this.gameCubeSaveDataLargest !== null"
:files="this.getFileListNames()"
:enabled="false"
/>
</div>
</b-col>
</b-row>
<b-row class="justify-content-md-center" align-h="center">
<b-col cols="auto" sm=4 md=3 lg=2 align-self="center">
<b-button
class="gamecube-convert-button"
variant="success"
block
:disabled="this.convertButtonDisabled"
@click="convertFile()"
>
Convert!
</b-button>
</b-col>
</b-row>
<b-row>
<b-col>
<div class="help">
Help: how can I <router-link to="/original-hardware?sort=gcn">copy save files to and from a GameCube console</router-link>?
</div>
</b-col>
</b-row>
</b-container>
</div>
</template>
<style scoped>
/* Separate class for each different button to enable tracking in google tag manager */
.gamecube-convert-button {
margin-top: 1em;
}
.help {
margin-top: 1em;
}
/* Mpve this up rather than deleting the margin under the selector above so that if this isn't visible there's still margin under the one above */
.output-filesize {
margin-top: -1em;
}
/* We have so much text in our jumbotron that at the md size it wants to be vertically larger than the other one. So let's constrain it and move the text upwards insie it */
.fix-jumbotron {
max-height: 11.5em;
}
.fix-jumbotron > div {
margin-top: -1em;
}
</style>
<script>
import { saveAs } from 'file-saver';
import Util from '../util/util';
import InputFile from './InputFile.vue';
import OutputFilename from './OutputFilename.vue';
import OutputFilesize from './OutputFilesize.vue';
import ConversionDirection from './ConversionDirection.vue';
import FileList from './FileList.vue';
import IndividualSavesOrMemoryCardSelector from './IndividualSavesOrMemoryCardSelector.vue';
import GameCubeEncodingSelector from './GameCubeEncodingSelector.vue';
import GameCubeSaveData from '../save-formats/GameCube/GameCube';
import GameCubeGciSaveData from '../save-formats/GameCube/IndividualSaves/Gci';
import GameCubeIndividualSaves from '../save-formats/GameCube/IndividualSaves/IndividualSaves';
import GameCubeUtil from '../save-formats/GameCube/Util';
import GameCubeHeader from '../save-formats/GameCube/Components/Header';
import PlatformSaveSizes from '../save-formats/PlatformSaveSizes';
const DEFAULT_OUTPUT_FILE_SIZE = 2097152; // 251 blocks (16 megabits)
const DEFAULT_OUTPUT_ENCODING = 'US-ASCII';
export default {
name: 'ConvertGameCube',
data() {
return {
gameCubeSaveDataLargest: null,
gameCubeSaveDataResized: null,
gameCubeSaveDataExample: null,
errorMessage: null,
errorMessageExampleFile: null,
inputFilename: null,
outputFilename: null,
outputFilesize: DEFAULT_OUTPUT_FILE_SIZE,
outputEncoding: DEFAULT_OUTPUT_ENCODING,
conversionDirection: 'convertToRaw',
selectedSaveData: null,
individualSavesOrMemoryCard: 'individual-saves',
individualSavesText: 'Individual saves',
memoryCardText: 'Raw/emulator',
};
},
components: {
ConversionDirection,
InputFile,
OutputFilename,
OutputFilesize,
FileList,
IndividualSavesOrMemoryCardSelector,
GameCubeEncodingSelector,
},
computed: {
convertButtonDisabled() {
const haveDataSelected = (this.conversionDirection === 'convertToRaw') ? true : this.selectedSaveData === null;
const gameCubeSaveData = (this.individualSavesOrMemoryCard === 'individual-saves') ? this.gameCubeSaveDataLargest : this.gameCubeSaveDataResized;
return !gameCubeSaveData || gameCubeSaveData.getSaveFiles().length === 0 || !haveDataSelected || !this.outputFilename;
},
individualSavesOrMemoryCardText() {
return (this.individualSavesOrMemoryCard === 'individual-saves') ? this.individualSavesText : this.memoryCardText;
},
largestSaveSize() {
return PlatformSaveSizes.gamecube.at(-1); // Last element of array
},
},
methods: {
formatSize(sizeBytes) {
const sizeMegabits = GameCubeUtil.bytesToMegabits(sizeBytes);
const { numTotalBlocks } = GameCubeUtil.getTotalSizes(sizeMegabits);
return `${numTotalBlocks} blocks (${sizeMegabits} megabits)`;
},
getFileNameFromSaveFile(saveFile) {
// Let's just copy the same format that Dolphin uses:
// https://github.com/dolphin-emu/dolphin/blob/58a70db588dbcdbebcb25531f85dbab5d236b60e/Source/Core/Core/HW/GCMemcard/GCMemcardUtils.cpp#L305
const sanitizedFilename = Util.convertDescriptionToFilename(`${saveFile.publisherCode}-${saveFile.gameCode}-${saveFile.fileName}`);
return `${sanitizedFilename}.gci`;
},
getFileSizeErrorMessage() {
const sizeMegabits = GameCubeUtil.bytesToMegabits(this.outputFilesize);
const { numTotalBlocks } = GameCubeUtil.getTotalSizes(sizeMegabits);
return `A GameCube memory card of size ${numTotalBlocks} blocks (${sizeMegabits} megabits) is not large enough to contain all of the files specified`;
},
getGameCubeDataResized() {
this.gameCubeSaveDataResized = null;
if (this.gameCubeSaveDataLargest !== null) {
try {
this.gameCubeSaveDataResized = GameCubeSaveData.createWithNewSize(this.gameCubeSaveDataLargest, this.outputFilesize);
} catch (e) {
this.errorMessage = this.getFileSizeErrorMessage();
this.gameCubeSaveDataResized = null;
this.selectedSaveData = null;
}
}
},
changeOutputFilesize(newValue) {
this.outputFilesize = newValue;
this.errorMessage = null;
this.getGameCubeDataResized();
},
changeOutputEncoding(newValue) {
this.outputEncoding = newValue;
this.errorMessage = null;
if (this.gameCubeSaveDataLargest !== null) {
try {
this.gameCubeSaveDataLargest = GameCubeSaveData.createWithNewEncoding(this.gameCubeSaveDataLargest, this.outputEncoding);
} catch (e) {
this.errorMessage = 'Could not create save file for this region';
this.gameCubeSaveDataLargest = null;
this.selectedSaveData = null;
}
}
this.getGameCubeDataResized();
},
changeIndividualSavesOrMemoryCard(newValue) {
this.errorMessage = null;
if (this.individualSavesOrMemoryCard !== newValue) {
this.individualSavesOrMemoryCard = newValue;
if (newValue === 'individual-saves') {
if (this.selectedSaveData === null) {
this.changeSelectedSaveData(0);
}
} else {
if (this.inputFilename !== null) {
this.outputFilename = Util.changeFilenameExtension(this.inputFilename, 'raw');
}
this.selectedSaveData = null;
this.getGameCubeDataResized();
}
}
},
getFileListNames() {
if ((this.gameCubeSaveDataLargest !== null) && (this.gameCubeSaveDataLargest.getSaveFiles() !== null)) {
return this.gameCubeSaveDataLargest.getSaveFiles().map((x) => ({ displayText: `${x.comments[0]} - ${x.comments[1]}` }));
}
return [];
},
changeConversionDirection(newDirection) {
this.conversionDirection = newDirection;
this.gameCubeSaveDataLargest = null;
this.gameCubeSaveDataResized = null;
this.gameCubeSaveDataExample = null;
this.errorMessage = null;
this.errorMessageExampleFile = null;
this.inputFilename = null;
this.outputFilename = null;
this.outputFilesize = DEFAULT_OUTPUT_FILE_SIZE;
this.outputEncoding = DEFAULT_OUTPUT_ENCODING;
this.selectedSaveData = null;
this.individualSavesOrMemoryCard = 'individual-saves';
// The refs become undefined when the components are removed using a v-if
if (this.$refs.inputFileGameCubeSaveData) {
this.$refs.inputFileGameCubeSaveData.reset();
}
if (this.$refs.inputFileGameCubeExampleSaveData) {
this.$refs.inputFileGameCubeExampleSaveData.reset();
}
},
changeSelectedSaveData(newSaveData) {
if (newSaveData !== null) {
if ((this.gameCubeSaveDataLargest !== null) && (this.gameCubeSaveDataLargest.getSaveFiles().length > 0)) {
this.selectedSaveData = newSaveData;
this.outputFilename = this.getFileNameFromSaveFile(this.gameCubeSaveDataLargest.getSaveFiles()[this.selectedSaveData]);
this.changeIndividualSavesOrMemoryCard('individual-saves');
} else {
this.selectedSaveData = null;
this.outputFilename = null;
}
}
},
readGameCubeExampleFileSaveData(event) {
this.errorMessageExampleFile = null;
try {
this.gameCubeSaveDataExample = GameCubeSaveData.createFromGameCubeData(event.arrayBuffer);
this.changeOutputFilesize(this.gameCubeSaveDataExample.getArrayBuffer().byteLength);
} catch (e) {
this.errorMessageExampleFile = 'File appears to not be in the correct format';
this.gameCubeSaveDataExample = null;
}
},
readGameCubeSaveData(event) {
this.errorMessage = null;
this.selectedSaveData = null;
this.inputFilename = event.filename;
try {
this.gameCubeSaveDataLargest = GameCubeSaveData.createFromGameCubeData(event.arrayBuffer);
this.individualSavesOrMemoryCard = null;
this.changeIndividualSavesOrMemoryCard('individual-saves');
this.changeOutputFilesize(this.gameCubeSaveDataLargest.getArrayBuffer().byteLength);
this.getGameCubeDataResized();
} catch (e) {
this.errorMessage = 'File appears to not be in the correct format';
this.gameCubeSaveDataLargest = null;
this.gameCubeSaveDataResized = null;
this.selectedSaveData = null;
}
},
readEmulatorSaveData(event) {
this.errorMessage = null;
this.selectedSaveData = null;
this.inputFilename = null;
try {
const saveFileArrayBuffers = event.map((f) => f.arrayBuffer);
const saveFiles = saveFileArrayBuffers.map((saveFileArrayBuffer) => GameCubeIndividualSaves.convertIndividualSaveToSaveFile(saveFileArrayBuffer)); // Note that here we use the inferred encoding. This will be overwritten when we convert to a memory card image below
const volumeInfo = {
formatOsTimeCode: GameCubeUtil.getOsTimeFromDate(new Date()), // Represents now, by the brower's clock
rtcBias: 0,
languageCode: GameCubeUtil.getLanguageCode('English'),
viDtvStatus: 0,
memcardSlot: GameCubeHeader.MEMCARD_SLOT_A,
memcardSizeMegabits: GameCubeUtil.bytesToMegabits(this.largestSaveSize),
encodingCode: GameCubeUtil.getEncodingCode(this.outputEncoding),
};
this.gameCubeSaveDataLargest = GameCubeSaveData.createFromSaveFiles(saveFiles, volumeInfo);
if (this.gameCubeSaveDataLargest.getSaveFiles().length > 0) {
this.outputFilename = `${Util.removeFilenameExtension(this.getFileNameFromSaveFile(this.gameCubeSaveDataLargest.getSaveFiles()[0]))}.raw`;
} else {
this.outputFilename = 'output.raw';
}
this.getGameCubeDataResized();
} catch (e) {
this.errorMessage = e.message;
this.gameCubeSaveDataLargest = null;
this.selectedSaveData = null;
}
},
convertFile() {
let outputArrayBuffer = null;
if ((this.conversionDirection === 'convertToRaw') && (this.individualSavesOrMemoryCard === 'individual-saves')) {
const individualArrayBuffers = GameCubeGciSaveData.convertSaveFilesToGcis(this.gameCubeSaveDataLargest.getSaveFiles());
outputArrayBuffer = individualArrayBuffers[this.selectedSaveData];
} else {
if (this.gameCubeSaveDataExample !== null) {
const volumeInfo = {
...this.gameCubeSaveDataLargest.getVolumeInfo(),
cardFlashId: this.gameCubeSaveDataExample.getVolumeInfo().cardFlashId,
};
this.gameCubeSaveDataLargest = GameCubeSaveData.createFromSaveFiles(this.gameCubeSaveDataLargest.getSaveFiles(), volumeInfo);
this.getGameCubeDataResized();
}
outputArrayBuffer = this.gameCubeSaveDataResized.getArrayBuffer();
}
const outputBlob = new Blob([outputArrayBuffer], { type: 'application/octet-stream' });
saveAs(outputBlob, this.outputFilename); // Frustratingly, in Firefox the dialog says "from: blob:" and apparently this can't be changed: https://github.com/eligrey/FileSaver.js/issues/101
},
},
};
</script>
================================================
FILE: frontend/src/components/ConvertGbaActionReplay.vue
================================================
<template>
<div>
<b-container>
<b-row no-gutters align-h="center" align-v="start">
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>Action Replay</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'">
<input-file
@load="readActionReplaySaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert (*.xps)"
acceptExtension=".xps"
:leaveRoomForHelpIcon="false"
/>
</div>
<div v-else>
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="false"/>
<output-filesize v-model="outputFilesize" id="action-replay-filesize" platform="gba"/>
</div>
</b-col>
<b-col sm=12 md=2 lg=2 xl=2 align-self="start">
<conversion-direction
:horizontalLayout="['md', 'lg', 'xl']"
:verticalLayout="['xs', 'sm']"
:conversionDirection="this.conversionDirection"
@change="changeConversionDirection($event)"
/>
</b-col>
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>Emulator/Raw</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'">
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="false"/>
<output-filesize v-model="outputFilesize" id="action-replay-filesize" platform="gba"/>
</div>
<div v-else>
<input-file
@load="readEmulatorSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert"
:leaveRoomForHelpIcon="false"
/>
</div>
</b-col>
</b-row>
<b-row class="justify-content-md-center" align-h="center">
<b-col cols="auto" sm=4 md=3 lg=2 align-self="center">
<b-button
class="action-replay-convert-button"
variant="success"
block
:disabled="!this.actionReplaySaveData || !outputFilename"
@click="convertFile()"
>
Convert!
</b-button>
</b-col>
</b-row>
<b-row>
<b-col>
<div class="help">
Help: how can I <router-link to="/original-hardware?sort=gba">copy save files to and from a GBA cartridge</router-link>?
</div>
<div class="help">
Help: how do I copy files to and from my <b-link href="https://www.youtube.com/watch?v=o7WQYnYYT6Y">Action Replay DSi</b-link> or <b-link href="http://uk.codejunkies.com/downloads/manuals/armax_gba_ds_english.pdf">Action Replay MAX DUO</b-link>?
</div>
</b-col>
</b-row>
</b-container>
</div>
</template>
<style scoped>
.action-replay-convert-button {
margin-top: 1em;
}
.help {
margin-top: 1em;
}
</style>
<script>
import { saveAs } from 'file-saver';
import Util from '../util/util';
import InputFile from './InputFile.vue';
import OutputFilename from './OutputFilename.vue';
import OutputFilesize from './OutputFilesize.vue';
import ConversionDirection from './ConversionDirection.vue';
import ActionReplaySaveData from '../save-formats/GBA/ActionReplay';
export default {
name: 'ConvertGbaActionReplay',
data() {
return {
actionReplaySaveData: null,
errorMessage: null,
outputFilename: null,
outputFilesize: null,
conversionDirection: 'convertToRaw',
};
},
components: {
ConversionDirection,
InputFile,
OutputFilename,
OutputFilesize,
},
methods: {
changeConversionDirection(newDirection) {
this.conversionDirection = newDirection;
this.actionReplaySaveData = null;
this.errorMessage = null;
this.outputFilename = null;
this.outputFilesize = null;
},
readActionReplaySaveData(event) {
this.errorMessage = null;
try {
this.actionReplaySaveData = ActionReplaySaveData.createFromActionReplayData(event.arrayBuffer);
this.outputFilename = Util.changeFilenameExtension(event.filename, 'srm');
this.outputFilesize = this.actionReplaySaveData.getRawSaveData().byteLength;
} catch (e) {
this.errorMessage = e.message;
this.actionReplaySaveData = null;
}
},
readEmulatorSaveData(event) {
this.errorMessage = null;
try {
this.actionReplaySaveData = ActionReplaySaveData.createFromEmulatorData(event.arrayBuffer);
this.outputFilename = Util.changeFilenameExtension(event.filename, 'xps');
this.outputFilesize = this.actionReplaySaveData.getRawSaveData().byteLength;
} catch (e) {
this.errorMessage = e.message;
this.actionReplaySaveData = null;
}
},
convertFile() {
let finalActionReplaySaveData = this.actionReplaySaveData;
if (this.actionReplaySaveData.getRawSaveData().byteLength !== this.outputFilesize) {
finalActionReplaySaveData = ActionReplaySaveData.createWithNewSize(this.actionReplaySaveData, this.outputFilesize);
}
const outputArrayBuffer = (this.conversionDirection === 'convertToRaw') ? finalActionReplaySaveData.getRawSaveData() : finalActionReplaySaveData.getArrayBuffer();
const outputBlob = new Blob([outputArrayBuffer], { type: 'application/octet-stream' });
saveAs(outputBlob, this.outputFilename); // Frustratingly, in Firefox the dialog says "from: blob:" and apparently this can't be changed: https://github.com/eligrey/FileSaver.js/issues/101
},
},
};
</script>
================================================
FILE: frontend/src/components/ConvertGbaGameShark.vue
================================================
<template>
<div>
<b-container>
<b-row no-gutters align-h="center" align-v="start">
<b-col sm=12 md=5 align-self="center">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>GameShark</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'" class="inputs-row">
<input-file
id="choose-gameshark-file"
@load="readGameSharkSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert (*.sps)"
acceptExtension=".sps"
:leaveRoomForHelpIcon="false"
/>
</div>
<div v-else class="inputs-row">
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="true"/>
<output-filesize v-model="outputFilesize" id="gameshark-filesize" platform="gba"/>
</div>
</b-col>
<b-col sm=12 md=2 lg=2 xl=2 align-self="start">
<conversion-direction
:horizontalLayout="['md', 'lg', 'xl']"
:verticalLayout="['xs', 'sm']"
:conversionDirection="this.conversionDirection"
@change="changeConversionDirection($event)"
/>
</b-col>
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>Emulator/Raw</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'" class="inputs-row">
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="true"/>
<output-filesize v-model="outputFilesize" id="raw-filesize" platform="gba"/>
</div>
<div v-else class="inputs-row">
<input-file
id="choose-raw-file"
@load="readEmulatorSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert"
:leaveRoomForHelpIcon="true"
/>
<input-file
id="choose-raw-file-rom"
@load="readRomData($event)"
:errorMessage="null"
placeholderText="Choose the ROM for this file (*.gba)"
helpText="GameShark save files contain some information from the corresponding ROM, and some emulators check this information before allowing the save to be loaded.
All processing by this website is done on your local machine, and your ROMs are not sent anywhere."
acceptExtension=".gba"
:leaveRoomForHelpIcon="true"
/>
</div>
</b-col>
</b-row>
<b-row class="justify-content-md-center" align-h="center">
<b-col cols="auto" sm=4 md=3 lg=2 align-self="center">
<b-button
class="gameshark-convert-button"
variant="success"
block
:disabled="!this.gameSharkSaveData || !outputFilename"
@click="convertFile()"
>
Convert!
</b-button>
</b-col>
</b-row>
<b-row>
<b-col>
<div class="help">
Help: how can I <router-link to="/original-hardware?sort=gba">copy save files to and from a GBA cartridge</router-link>?
</div>
<div class="help">
Help: how do I <b-link href="https://gamehacking.org/vb/forum/video-game-hacking-and-development/school-of-hacking/14153-gameshark-advance-and-color-save-backup">copy save files to and from my GameShark</b-link>?
</div>
</b-col>
</b-row>
</b-container>
</div>
</template>
<style scoped>
/* Separate class for each different button to enable tracking in google tag manager */
.gameshark-convert-button {
margin-top: 1em;
}
.help {
margin-top: 1em;
}
.inputs-row {
min-height: 4.8em;
}
</style>
<script>
import dayjs from 'dayjs';
import { saveAs } from 'file-saver';
import Util from '../util/util';
import InputFile from './InputFile.vue';
import OutputFilename from './OutputFilename.vue';
import OutputFilesize from './OutputFilesize.vue';
import ConversionDirection from './ConversionDirection.vue';
import GameSharkSaveData from '../save-formats/GBA/GameShark';
export default {
name: 'ConvertGbaGameShark',
data() {
return {
gameSharkSaveData: null,
romData: null,
emulatorSaveData: null,
emulatorSaveDataFilename: null,
errorMessage: null,
outputFilename: null,
outputFilesize: null,
conversionDirection: 'convertToRaw',
};
},
components: {
ConversionDirection,
InputFile,
OutputFilename,
OutputFilesize,
},
methods: {
changeConversionDirection(newDirection) {
this.conversionDirection = newDirection;
this.gameSharkSaveData = null;
this.romData = null;
this.emulatorSaveData = null;
this.emulatorSaveDataFilename = null;
this.errorMessage = null;
this.outputFilename = null;
this.outputFilesize = null;
},
readRomData(event) {
this.romData = event.arrayBuffer;
this.tryToCreateGameSharkSaveDataFromEmulatorSaveData();
},
readEmulatorSaveData(event) {
this.emulatorSaveData = event.arrayBuffer;
this.emulatorSaveDataFilename = event.filename;
this.tryToCreateGameSharkSaveDataFromEmulatorSaveData();
},
readGameSharkSaveData(event) {
this.errorMessage = null;
try {
this.gameSharkSaveData = GameSharkSaveData.createFromGameSharkData(event.arrayBuffer);
this.outputFilename = Util.changeFilenameExtension(event.filename, 'srm');
this.outputFilesize = this.gameSharkSaveData.getRawSaveData().byteLength;
} catch (e) {
this.errorMessage = e.message;
this.gameSharkSaveData = null;
this.outputFilename = null;
this.outputFilesize = null;
}
},
tryToCreateGameSharkSaveDataFromEmulatorSaveData() {
if ((this.romData !== null) && (this.emulatorSaveData !== null) && (this.emulatorSaveDataFilename !== null)) { // Need to be careful that the user can choose the save data and ROM files in any order, so only proceed once both have been chosen
this.errorMessage = null;
try {
const title = Util.removeFilenameExtension(this.emulatorSaveDataFilename);
const date = dayjs().format('DD/MM/YYYY hh:mm:ss a');
const notes = 'Created with savefileconverter.com';
this.gameSharkSaveData = GameSharkSaveData.createFromEmulatorData(this.emulatorSaveData, title, date, notes, this.romData);
this.outputFilename = Util.changeFilenameExtension(this.emulatorSaveDataFilename, 'sps');
this.outputFilesize = this.gameSharkSaveData.getRawSaveData().byteLength;
} catch (e) {
this.errorMessage = e.message;
this.gameSharkSaveData = null;
this.outputFilename = null;
this.outputFilesize = null;
}
}
},
convertFile() {
let finalGameSharkSaveData = this.gameSharkSaveData;
if (this.gameSharkSaveData.getRawSaveData().byteLength !== this.outputFilesize) {
finalGameSharkSaveData = GameSharkSaveData.createWithNewSize(this.gameSharkSaveData, this.outputFilesize);
}
const outputArrayBuffer = (this.conversionDirection === 'convertToRaw') ? finalGameSharkSaveData.getRawSaveData() : finalGameSharkSaveData.getArrayBuffer();
const outputBlob = new Blob([outputArrayBuffer], { type: 'application/octet-stream' });
saveAs(outputBlob, this.outputFilename); // Frustratingly, in Firefox the dialog says "from: blob:" and apparently this can't be changed: https://github.com/eligrey/FileSaver.js/issues/101
},
},
};
</script>
================================================
FILE: frontend/src/components/ConvertGbaGameSharkSP.vue
================================================
<template>
<div>
<b-container>
<b-row no-gutters align-h="center" align-v="start">
<b-col sm=12 md=5 align-self="center">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>GameShark{{'\xa0'}}SP</template> <!-- Not sure why doesn't work here, but this does -->
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'" class="inputs-row">
<input-file
id="choose-gameshark-file"
@load="readGameSharkSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert (*.gsv)"
acceptExtension=".gsv"
:leaveRoomForHelpIcon="false"
/>
</div>
<div v-else class="inputs-row">
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="true"/>
<output-filesize v-model="outputFilesize" id="gameshark-filesize" platform="gba"/>
</div>
</b-col>
<b-col sm=12 md=2 lg=2 xl=2 align-self="start">
<conversion-direction
:horizontalLayout="['md', 'lg', 'xl']"
:verticalLayout="['xs', 'sm']"
:conversionDirection="this.conversionDirection"
disableDirection="convertToFormat"
@change="changeConversionDirection($event)"
id="conversion-direction"
/>
<b-popover target="conversion-direction" triggers="focus hover" placement="bottom">
Not enough is known about GameShark SP saves to be able to write out a file in this format. We can currently only extract the raw save from these files.
</b-popover>
</b-col>
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>Emulator/Raw</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'" class="inputs-row">
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="true"/>
<output-filesize v-model="outputFilesize" id="raw-filesize" platform="gba"/>
</div>
<div v-else class="inputs-row">
<input-file
id="choose-raw-file"
@load="readEmulatorSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert"
:leaveRoomForHelpIcon="true"
/>
<input-file
id="choose-raw-file-rom"
@load="readRomData($event)"
:errorMessage="null"
placeholderText="Choose the ROM for this file (*.gba)"
helpText="GameShark SP save files contain some information from the corresponding ROM, and some emulators check this information before allowing the save to be loaded.
All processing by this website is done on your local machine, and your ROMs are not sent anywhere."
acceptExtension=".gba"
:leaveRoomForHelpIcon="true"
/>
</div>
</b-col>
</b-row>
<b-row class="justify-content-md-center" align-h="center">
<b-col cols="auto" sm=4 md=3 lg=2 align-self="center">
<b-button
class="gameshark-sp-convert-button"
variant="success"
block
:disabled="!this.gameSharkSaveData || !outputFilename"
@click="convertFile()"
>
Convert!
</b-button>
</b-col>
</b-row>
<b-row>
<b-col>
<div class="help">
Help: how can I <router-link to="/original-hardware?sort=gba">copy save files to and from a GBA cartridge</router-link>?
</div>
<div class="help">
Help: how do I <b-link href="https://www.manualslib.com/manual/515605/Mad-Catz-Gameshark-Sp.html?page=17#manual">copy save files to and from my GameShark SP</b-link>?
</div>
</b-col>
</b-row>
</b-container>
</div>
</template>
<style scoped>
/* Separate class for each different button to enable tracking in google tag manager */
.gameshark-sp-convert-button {
margin-top: 1em;
}
.help {
margin-top: 1em;
}
.inputs-row {
min-height: 4.8em;
}
</style>
<script>
import { BPopover } from 'bootstrap-vue';
import { saveAs } from 'file-saver';
import Util from '../util/util';
import SaveFilesUtil from '../util/SaveFiles';
import InputFile from './InputFile.vue';
import OutputFilename from './OutputFilename.vue';
import OutputFilesize from './OutputFilesize.vue';
import ConversionDirection from './ConversionDirection.vue';
import GameSharkSpSaveData from '../save-formats/GBA/GameSharkSP';
export default {
name: 'ConvertGbaGameSharkSP',
data() {
return {
gameSharkSaveData: null,
romData: null,
emulatorSaveData: null,
emulatorSaveDataFilename: null,
errorMessage: null,
outputFilename: null,
outputFilesize: null,
conversionDirection: 'convertToRaw',
};
},
components: {
BPopover,
ConversionDirection,
InputFile,
OutputFilename,
OutputFilesize,
},
methods: {
changeConversionDirection(newDirection) {
this.conversionDirection = newDirection;
this.gameSharkSaveData = null;
this.errorMessage = null;
this.outputFilename = null;
this.outputFilesize = null;
},
readGameSharkSaveData(event) {
this.errorMessage = null;
try {
this.gameSharkSaveData = GameSharkSpSaveData.createFromGameSharkSpData(event.arrayBuffer);
this.outputFilename = Util.changeFilenameExtension(event.filename, 'srm');
this.outputFilesize = this.gameSharkSaveData.getRawSaveData().byteLength;
} catch (e) {
this.errorMessage = e.message;
this.gameSharkSaveData = null;
this.outputFilename = null;
this.outputFilesize = null;
}
},
convertFile() {
let outputArrayBuffer = this.gameSharkSaveData.getRawSaveData();
if (outputArrayBuffer.byteLength !== this.outputFilesize) {
outputArrayBuffer = SaveFilesUtil.resizeRawSave(outputArrayBuffer, this.outputFilesize);
}
const outputBlob = new Blob([outputArrayBuffer], { type: 'application/octet-stream' });
saveAs(outputBlob, this.outputFilename); // Frustratingly, in Firefox the dialog says "from: blob:" and apparently this can't be changed: https://github.com/eligrey/FileSaver.js/issues/101
},
},
};
</script>
================================================
FILE: frontend/src/components/ConvertMister.vue
================================================
<template>
<div>
<b-container>
<b-row no-gutters align-h="center" align-v="start">
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>MiSTer</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'">
<input-file
@load="readMisterSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert"
:leaveRoomForHelpIcon="false"
/>
<mister-platform
v-model="misterPlatform"
id="platform"
v-on:input="misterPlatformChanged()"
:disabled="false"
/>
</div>
<div v-else>
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="false"/>
</div>
</b-col>
<b-col sm=12 md=2 lg=2 xl=2 align-self="start">
<conversion-direction
:horizontalLayout="['md', 'lg', 'xl']"
:verticalLayout="['xs', 'sm']"
:conversionDirection="this.conversionDirection"
@change="changeConversionDirection($event)"
/>
</b-col>
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>Emulator/Raw</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'">
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="false"/>
<div v-if="this.isSegaCd">
<sega-cd-save-type-selector
:value="this.segaCdSaveType"
@change="changeSegaCdSaveType($event)"
:ramCartText="this.misterPlatform === 'Mister-SAT' ? 'Backup cartridge' : 'RAM cartridge'"
/>
</div>
<div v-if="this.displayOutputFileSize">
<output-filesize v-model="outputFilesize" id="output-filesize" :platform="this.misterPlatformClass.adjustOutputSizesPlatform()"/>
</div>
</div>
<div v-else>
<div v-if="this.isSegaCd">
<input-file
@load="readEmulatorSaveData($event, 'rawInternalSaveArrayBuffer')"
:errorMessage="this.segaCdInternalMemoryErrorMessage"
placeholderText="Choose an internal memory save file to convert"
:leaveRoomForHelpIcon="false"
ref="inputFileSegaCdInternalMemory"
/>
<input-file
@load="readEmulatorSaveData($event, 'rawCartSaveArrayBuffer')"
:errorMessage="this.segaCdRamCartridgeErrorMessage"
placeholderText="Choose a RAM cartridge save file to convert"
:leaveRoomForHelpIcon="false"
ref="inputFileSegaCdRamCart"
/>
</div>
<div v-else>
<input-file
@load="readEmulatorSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert"
:leaveRoomForHelpIcon="false"
ref="inputFileEmulator"
/>
</div>
<mister-platform
v-model="misterPlatform"
id="platform"
v-on:input="misterPlatformChanged()"
:disabled="false"
/>
</div>
</b-col>
</b-row>
<b-row class="justify-content-md-center" align-h="center">
<b-col cols="auto" sm=4 md=3 lg=2 align-self="center">
<b-button
class="mister-convert-button"
variant="success"
block
:disabled="!this.misterSaveData || !this.misterPlatform || !outputFilename"
@click="convertFile()"
>
Convert!
</b-button>
</b-col>
</b-row>
</b-container>
</div>
</template>
<style scoped>
/* Separate class for each different button to enable tracking in google tag manager */
.mister-convert-button {
margin-top: 1em;
}
.help {
margin-top: 1em;
}
</style>
<script>
import { saveAs } from 'file-saver';
import Util from '../util/util';
import InputFile from './InputFile.vue';
import OutputFilename from './OutputFilename.vue';
import OutputFilesize from './OutputFilesize.vue';
import ConversionDirection from './ConversionDirection.vue';
import MisterPlatform from './MisterPlatform.vue';
import SegaCdSaveTypeSelector from './SegaCdSaveTypeSelector.vue';
import MisterNesSaveData from '../save-formats/Mister/Nes';
import MisterSnesSaveData from '../save-formats/Mister/Snes';
import MisterN64CartSaveData from '../save-formats/Mister/N64Cart';
import MisterN64MempackSaveData from '../save-formats/Mister/N64Mempack';
import MisterGameboySaveData from '../save-formats/Mister/Gameboy';
import MisterGameboyAdvanceSaveData from '../save-formats/Mister/GameboyAdvance';
import MisterGameGearSaveData from '../save-formats/Mister/GameGear';
import MisterSmsSaveData from '../save-formats/Mister/Sms';
import MisterGenesisSaveData from '../save-formats/Mister/Genesis';
import MisterSegaCdSaveData from '../save-formats/Mister/SegaCd';
import MisterSegaSaturnSaveData from '../save-formats/Mister/SegaSaturn';
import MisterPcEngineSaveData from '../save-formats/Mister/PcEngine';
import MisterPs1SaveData from '../save-formats/Mister/Ps1';
import MisterWonderSwanSaveData from '../save-formats/Mister/WonderSwan';
import SegaError from '../save-formats/SegaError';
export default {
name: 'ConvertMister',
data() {
return {
misterSaveData: null,
misterPlatform: null,
misterPlatformPrevious: null,
misterPlatformClass: null,
errorMessage: null,
segaCdInternalMemoryErrorMessage: null,
segaCdRamCartridgeErrorMessage: null,
outputFilename: null,
outputFilesize: null,
conversionDirection: 'convertToRaw',
inputArrayBuffer: null,
inputFilename: null,
inputFileType: null,
inputSegaCd: {},
segaCdSaveType: 'internal-memory',
};
},
components: {
ConversionDirection,
InputFile,
OutputFilename,
OutputFilesize,
MisterPlatform,
SegaCdSaveTypeSelector,
},
computed: {
isSegaCd: {
get() { return (this.misterPlatform === 'Mister-MCD') || (this.misterPlatform === 'Mister-SAT'); },
},
displayOutputFileSize: {
get() {
if ((this.misterPlatformClass !== null) && (this.misterPlatformClass.adjustOutputSizesPlatform() !== null)) {
if (this.isSegaCd) {
return (this.segaCdSaveType === 'ram-cart');
}
return true;
}
return false;
},
},
},
methods: {
changeConversionDirection(newDirection) {
this.conversionDirection = newDirection;
this.misterSaveData = null;
this.misterPlatform = null;
this.misterPlatformPrevious = null;
this.misterPlatformClass = null;
this.errorMessage = null;
this.segaCdInternalMemoryErrorMessage = null;
this.segaCdRamCartridgeErrorMessage = null;
this.outputFilename = null;
this.outputFilesize = null;
this.inputArrayBuffer = null;
this.inputFilename = null;
this.inputFileType = null;
this.inputSegaCd = {};
this.segaCdSaveType = 'internal-memory';
},
changeSegaCdSaveType(newSaveType) {
this.segaCdSaveType = newSaveType;
if ((this.inputFilename !== null) && (this.misterPlatformClass !== null)) {
this.outputFilename = this.getSegaCdRawFileName();
}
},
getSegaCdRawFileName() {
const filenameSuffix = (this.segaCdSaveType === 'internal-memory') ? ' - internal memory' : ' - cartridge';
return `${Util.removeFilenameExtension(this.inputFilename)}${filenameSuffix}.${this.misterPlatformClass.getRawFileExtension(this.segaCdSaveType)}`;
},
misterPlatformChanged() {
if (this.misterPlatform !== null) {
switch (this.misterPlatform) {
case 'Mister-NES': {
this.misterPlatformClass = MisterNesSaveData;
break;
}
case 'Mister-SNES': {
this.misterPlatformClass = MisterSnesSaveData;
break;
}
case 'Mister-N64-Cart': {
this.misterPlatformClass = MisterN64CartSaveData;
break;
}
case 'Mister-N64-Mempack': {
this.misterPlatformClass = MisterN64MempackSaveData;
break;
}
case 'Mister-GB': {
this.misterPlatformClass = MisterGameboySaveData;
break;
}
case 'Mister-GBA': {
this.misterPlatformClass = MisterGameboyAdvanceSaveData;
break;
}
case 'Mister-GG': {
this.misterPlatformClass = MisterGameGearSaveData;
break;
}
case 'Mister-SMS': {
this.misterPlatformClass = MisterSmsSaveData;
break;
}
case 'Mister-MD': {
this.misterPlatformClass = MisterGenesisSaveData;
break;
}
case 'Mister-MCD': {
this.misterPlatformClass = MisterSegaCdSaveData;
break;
}
case 'Mister-SAT': {
this.misterPlatformClass = MisterSegaSaturnSaveData;
break;
}
case 'Mister-PCE': {
this.misterPlatformClass = MisterPcEngineSaveData;
break;
}
case 'Mister-PS1': {
this.misterPlatformClass = MisterPs1SaveData;
break;
}
case 'Mister-WS': {
this.misterPlatformClass = MisterWonderSwanSaveData;
break;
}
default: {
this.misterPlatformClass = null;
break;
}
}
} else {
this.misterPlatformClass = null;
}
// We use different input boxes in the UI depending on whether there are 1 or 2 raw files to read,
// and so we want to wipe out any input file info that may be lurking internally when we switch to showing a different input box
// because it's not clear which box we would assign that to
//
// Additionally, there's a browser optimization/bug where when we swap out a different file input that's
// in the same location as a previous one, then the contents of the file box in the DOM carry over to the new box
// even though it's a different element. So, we call reset() here
if ((this.misterPlatform !== this.misterPlatformPrevious) && (this.conversionDirection !== 'convertToRaw')) {
this.inputFileType = null;
this.inputArrayBuffer = null;
this.inputFilename = null;
this.inputSegaCd = {};
// The refs become undefined when the components are removed using a v-if
if (this.$refs.inputFileSegaCdInternalMemory) {
this.$refs.inputFileSegaCdInternalMemory.reset();
}
if (this.$refs.inputFileSegaCdRamCart) {
this.$refs.inputFileSegaCdRamCart.reset();
}
if (this.$refs.inputFileEmulator) {
this.$refs.inputFileEmulator.reset();
}
}
this.misterPlatformPrevious = this.misterPlatform;
this.updateMisterSaveData();
},
updateMisterSaveData(inputSegaCdType) {
this.errorMessage = null;
this.segaCdInternalMemoryErrorMessage = null;
this.segaCdRamCartridgeErrorMessage = null;
this.outputFilesize = null;
if ((this.misterPlatformClass !== null) && (this.inputArrayBuffer !== null) && (this.inputFilename !== null) && (this.inputFileType !== null)) {
try {
if (this.inputFileType === 'mister') {
this.misterSaveData = this.misterPlatformClass.createFromMisterData(this.inputArrayBuffer);
if (this.isSegaCd) {
this.outputFilename = this.getSegaCdRawFileName();
} else {
this.outputFilename = Util.changeFilenameExtension(this.inputFilename, this.misterPlatformClass.getRawFileExtension(this.inputArrayBuffer));
}
} else {
if (this.isSegaCd) {
this.misterSaveData = this.misterPlatformClass.createFromRawData(this.inputSegaCd); // It can take up to 2 input array buffers to create this data
} else {
this.misterSaveData = this.misterPlatformClass.createFromRawData(this.inputArrayBuffer);
}
this.outputFilename = Util.changeFilenameExtension(this.inputFilename, this.misterPlatformClass.getMisterFileExtension(this.inputArrayBuffer));
}
if (this.isSegaCd) {
// The internal memory save buffer size can't be changed; only the RAM cart size
this.outputFilesize = this.misterSaveData.getRawArrayBuffer(MisterSegaCdSaveData.RAM_CART).byteLength;
} else {
this.outputFilesize = this.misterSaveData.getRawArrayBuffer().byteLength;
}
} catch (e) {
if (e instanceof SegaError) {
if (e.internalSaveError !== null) {
this.segaCdInternalMemoryErrorMessage = 'This file does not seem to be in the correct format';
}
if (e.ramCartError !== null) {
this.segaCdRamCartridgeErrorMessage = 'This file does not seem to be in the correct format';
}
} else if (inputSegaCdType === null) {
this.errorMessage = 'This file does not seem to be in the correct format';
}
this.misterSaveData = null;
}
} else {
this.misterSaveData = null;
this.outputFilename = null;
this.outputFilesize = null;
this.segaCdSaveType = 'internal-memory';
}
},
readMisterSaveData(event) {
this.inputFileType = 'mister';
this.inputArrayBuffer = event.arrayBuffer;
this.inputFilename = event.filename;
this.inputSegaCd = {};
this.updateMisterSaveData();
},
readEmulatorSaveData(event, inputSegaCdType = null) {
this.inputFileType = 'raw';
this.inputArrayBuffer = event.arrayBuffer;
this.inputFilename = event.filename;
if (inputSegaCdType !== null) {
this.inputSegaCd[inputSegaCdType] = event.arrayBuffer;
} else {
this.inputSegaCd = {};
}
this.updateMisterSaveData(inputSegaCdType);
},
convertFile() {
let finalMisterSaveData = this.misterSaveData;
let needsResize = false;
if (this.isSegaCd) {
needsResize = this.misterSaveData.getRawArrayBuffer(MisterSegaCdSaveData.RAM_CART).byteLength !== this.outputFilesize;
} else {
needsResize = this.misterSaveData.getRawArrayBuffer().byteLength !== this.outputFilesize;
}
if (needsResize) {
finalMisterSaveData = this.misterPlatformClass.createWithNewSize(this.misterSaveData, this.outputFilesize);
}
let output = null;
if (this.conversionDirection === 'convertToRaw') {
if (this.isSegaCd) {
output = finalMisterSaveData.getRawArrayBuffer(this.segaCdSaveType);
} else {
output = finalMisterSaveData.getRawArrayBuffer();
}
} else {
output = finalMisterSaveData.getMisterArrayBuffer();
}
const outputBlob = new Blob([output], { type: 'application/octet-stream' });
saveAs(outputBlob, this.outputFilename);
},
},
};
</script>
================================================
FILE: frontend/src/components/ConvertN64DexDrive.vue
================================================
<template>
<div>
<b-container>
<b-row no-gutters align-h="center" align-v="start">
<b-col sm=12 md=5 align-self="start">
<b-row no-gutters align-h="center" align-v="start">
<b-col cols=12>
<b-jumbotron fluid :header-level="$mq | mq({ xs: 5, sm: 5, md: 5, lg: 5, xl: 4 })">
<template v-slot:header>DexDrive</template>
</b-jumbotron>
</b-col>
</b-row>
<div v-if="this.conversionDirection === 'convertToRaw'">
<input-file
@load="readDexDriveSaveData($event)"
:errorMessage="this.errorMessage"
placeholderText="Choose a file to convert (*.n64)"
acceptExtension=".n64"
:leaveRoomForHelpIcon="false"
/>
<file-list
:display="this.dexDriveSaveData !== null"
:files="this.getFileListNames()"
v-model="selectedSaveData"
@change="changeSelectedSaveData($event)"
/>
</div>
<div v-else>
<output-filename v-model="outputFilename" :leaveRoomForHelpIcon="false"/>
</div>
</b-col>
<b-col sm=12 md=2 lg=2 xl=2 align-self="start">
<conversion-direction
:horizontalLayout="['md', 'lg', 'xl']"
:verticalLayout="['xs', 'sm']"
:conversionDirection="this.conversionDirection"
@change="changeConversionDirection($event)"
gitextract_5fpwvxle/
├── .gitattributes
├── .gitignore
├── .vscode/
│ └── settings.json
├── LICENSE
├── README.md
├── frontend/
│ ├── .editorconfig
│ ├── .eslintignore
│ ├── .gitignore
│ ├── .nvmrc
│ ├── README.md
│ ├── babel.config.js
│ ├── buildspec.yml
│ ├── lib/
│ │ └── minlzo-js/
│ │ └── lzo1x.js
│ ├── package.json
│ ├── public/
│ │ ├── browserconfig.xml
│ │ ├── index.html
│ │ ├── robots.txt
│ │ ├── site.webmanifest
│ │ └── sitemap.txt
│ ├── src/
│ │ ├── App.vue
│ │ ├── components/
│ │ │ ├── AdvancedUtils.vue
│ │ │ ├── ByteExpandContract.vue
│ │ │ ├── CompressionDecompression.vue
│ │ │ ├── CompressionType.vue
│ │ │ ├── ConversionDirection.vue
│ │ │ ├── ConvertDreamcast.vue
│ │ │ ├── ConvertFlashCarts.vue
│ │ │ ├── ConvertGameCube.vue
│ │ │ ├── ConvertGbaActionReplay.vue
│ │ │ ├── ConvertGbaGameShark.vue
│ │ │ ├── ConvertGbaGameSharkSP.vue
│ │ │ ├── ConvertMister.vue
│ │ │ ├── ConvertN64DexDrive.vue
│ │ │ ├── ConvertN64Mempack.vue
│ │ │ ├── ConvertNintendoSwitchOnline.vue
│ │ │ ├── ConvertOnlineEmulators.vue
│ │ │ ├── ConvertPs1DexDrive.vue
│ │ │ ├── ConvertPs1Emulator.vue
│ │ │ ├── ConvertPs1Ps3.vue
│ │ │ ├── ConvertPs1Psp.vue
│ │ │ ├── ConvertRetron5.vue
│ │ │ ├── ConvertSegaCd.vue
│ │ │ ├── ConvertSegaSaturnEmulator.vue
│ │ │ ├── ConvertSegaSaturnSaroo.vue
│ │ │ ├── ConvertSrmSav.vue
│ │ │ ├── ConvertWii.vue
│ │ │ ├── DecryptPsp.vue
│ │ │ ├── DreamcastIndividualSaveTypeSelector.vue
│ │ │ ├── EndiannessWordSize.vue
│ │ │ ├── EraseSave.vue
│ │ │ ├── FileInfo.vue
│ │ │ ├── FileList.vue
│ │ │ ├── FileReader.vue
│ │ │ ├── FileSize.vue
│ │ │ ├── FlashCartType.vue
│ │ │ ├── GameCubeEncodingSelector.vue
│ │ │ ├── HeaderFooter.vue
│ │ │ ├── HelpButton.vue
│ │ │ ├── IndividualSavesOrMemoryCardSelector.vue
│ │ │ ├── InputFile.vue
│ │ │ ├── InputNumber.vue
│ │ │ ├── MemoryCardSelector.vue
│ │ │ ├── MisterPlatform.vue
│ │ │ ├── NintendoSwitchOnlinePlatform.vue
│ │ │ ├── OnlineEmulatorPlatform.vue
│ │ │ ├── OutputFilename.vue
│ │ │ ├── OutputFilesize.vue
│ │ │ ├── PadFillByte.vue
│ │ │ ├── RegionViewer.vue
│ │ │ ├── Retron5EraseSave.vue
│ │ │ ├── SegaCdSaveTypeSelector.vue
│ │ │ ├── TabAddHeaderFooter.vue
│ │ │ ├── TabByteExpansion.vue
│ │ │ ├── TabCompression.vue
│ │ │ ├── TabEndianSwap.vue
│ │ │ ├── TabFileCompare.vue
│ │ │ ├── TabRemoveHeaderFooter.vue
│ │ │ ├── TabResize.vue
│ │ │ ├── TabSlice.vue
│ │ │ ├── TroubleshootingUtils.vue
│ │ │ └── WiiVcPlatform.vue
│ │ ├── main.js
│ │ ├── plugins/
│ │ │ ├── bootstrap-vue.js
│ │ │ ├── fontawesome-vue.js
│ │ │ ├── google-tag-manager-vue.js
│ │ │ ├── mediaquery-vue.js
│ │ │ └── vue-async-computed.js
│ │ ├── rom-formats/
│ │ │ ├── PspIso.js
│ │ │ ├── SegaSaturnCueBin.js
│ │ │ ├── gb.js
│ │ │ ├── gba.js
│ │ │ ├── nes.js
│ │ │ └── sms.js
│ │ ├── router/
│ │ │ └── index.js
│ │ ├── save-formats/
│ │ │ ├── Dreamcast/
│ │ │ │ ├── Components/
│ │ │ │ │ ├── Basics.js
│ │ │ │ │ ├── Directory.js
│ │ │ │ │ ├── DirectoryEntry.js
│ │ │ │ │ ├── FileAllocationTable.js
│ │ │ │ │ └── SystemInfo.js
│ │ │ │ ├── Dreamcast.js
│ │ │ │ ├── IndividualSaves/
│ │ │ │ │ ├── Dci.js
│ │ │ │ │ └── VmiVms.js
│ │ │ │ └── Util.js
│ │ │ ├── FlashCarts/
│ │ │ │ ├── GB.js
│ │ │ │ ├── GBA/
│ │ │ │ │ ├── EmulatorBase.js
│ │ │ │ │ ├── GBA.js
│ │ │ │ │ ├── GoombaEmulator.js
│ │ │ │ │ ├── PocketNesEmulator.js
│ │ │ │ │ └── SmsAdvanceEmulator.js
│ │ │ │ ├── GameGear.js
│ │ │ │ ├── Genesis/
│ │ │ │ │ ├── MegaEverdrivePro/
│ │ │ │ │ │ ├── 32X.js
│ │ │ │ │ │ ├── Genesis.js
│ │ │ │ │ │ ├── NES.js
│ │ │ │ │ │ ├── SMS.js
│ │ │ │ │ │ └── SegaCd.js
│ │ │ │ │ └── MegaSD/
│ │ │ │ │ ├── 32X.js
│ │ │ │ │ ├── Genesis.js
│ │ │ │ │ ├── GenesisBase.js
│ │ │ │ │ ├── SMS.js
│ │ │ │ │ └── SegaCd.js
│ │ │ │ ├── N64/
│ │ │ │ │ ├── GB64Emulator.js
│ │ │ │ │ ├── N64.js
│ │ │ │ │ ├── NES.js
│ │ │ │ │ └── Neon64Emulator.js
│ │ │ │ ├── NES.js
│ │ │ │ ├── PcEngine.js
│ │ │ │ ├── SMS.js
│ │ │ │ └── SNES/
│ │ │ │ ├── GB.js
│ │ │ │ └── SNES.js
│ │ │ ├── GBA/
│ │ │ │ ├── ActionReplay.js
│ │ │ │ ├── GameShark.js
│ │ │ │ └── GameSharkSP.js
│ │ │ ├── GameCube/
│ │ │ │ ├── Components/
│ │ │ │ │ ├── Basics.js
│ │ │ │ │ ├── BlockAllocationTable.js
│ │ │ │ │ ├── Directory.js
│ │ │ │ │ ├── DirectoryEntry.js
│ │ │ │ │ └── Header.js
│ │ │ │ ├── GameCube.js
│ │ │ │ ├── GameSpecificFixups/
│ │ │ │ │ ├── FZeroGx.js
│ │ │ │ │ ├── GameSpecificFixups.js
│ │ │ │ │ └── PhantasyStarOnline.js
│ │ │ │ ├── IndividualSaves/
│ │ │ │ │ ├── GameShark.js
│ │ │ │ │ ├── Gci.js
│ │ │ │ │ ├── IndividualSaves.js
│ │ │ │ │ └── MaxDrive.js
│ │ │ │ └── Util.js
│ │ │ ├── Mister/
│ │ │ │ ├── GameGear.js
│ │ │ │ ├── Gameboy.js
│ │ │ │ ├── GameboyAdvance.js
│ │ │ │ ├── Genesis.js
│ │ │ │ ├── N64Cart.js
│ │ │ │ ├── N64Mempack.js
│ │ │ │ ├── Nes.js
│ │ │ │ ├── PcEngine.js
│ │ │ │ ├── Ps1.js
│ │ │ │ ├── SegaCd.js
│ │ │ │ ├── SegaSaturn.js
│ │ │ │ ├── Sms.js
│ │ │ │ ├── Snes.js
│ │ │ │ └── WonderSwan.js
│ │ │ ├── N64/
│ │ │ │ ├── Components/
│ │ │ │ │ ├── Basics.js
│ │ │ │ │ ├── GameSerialCodeUtil.js
│ │ │ │ │ ├── IdArea.js
│ │ │ │ │ ├── InodeTable.js
│ │ │ │ │ ├── NoteTable.js
│ │ │ │ │ └── TextDecoder.js
│ │ │ │ ├── DexDrive.js
│ │ │ │ ├── IndividualSaveFilename.js
│ │ │ │ └── Mempack.js
│ │ │ ├── NintendoSwitchOnline/
│ │ │ │ ├── Gameboy.js
│ │ │ │ ├── GameboyAdvance.js
│ │ │ │ ├── Genesis.js
│ │ │ │ ├── N64.js
│ │ │ │ ├── Nes.js
│ │ │ │ └── Snes.js
│ │ │ ├── OnlineEmulators/
│ │ │ │ ├── Emulators/
│ │ │ │ │ ├── EmulatorBase.js
│ │ │ │ │ ├── Gambatte.js
│ │ │ │ │ ├── Gb.js
│ │ │ │ │ ├── Snes9x.js
│ │ │ │ │ ├── VBA-Next.js
│ │ │ │ │ └── mGba.js
│ │ │ │ └── OnlineEmulatorWrapper.js
│ │ │ ├── PS1/
│ │ │ │ ├── Components/
│ │ │ │ │ ├── Basics.js
│ │ │ │ │ ├── DirectoryBlock.js
│ │ │ │ │ ├── SaveBlocks.js
│ │ │ │ │ └── SonyUtil.js
│ │ │ │ ├── DexDrive.js
│ │ │ │ ├── Memcard.js
│ │ │ │ ├── Ps3.js
│ │ │ │ └── Psp.js
│ │ │ ├── PSP/
│ │ │ │ ├── Executable.js
│ │ │ │ ├── ParamSfo.js
│ │ │ │ ├── PspEncryptionUtil.js
│ │ │ │ ├── Savefile.js
│ │ │ │ └── psp-encryption/
│ │ │ │ ├── psp-encryption.js
│ │ │ │ └── psp-encryption.wasm
│ │ │ ├── PlatformSaveSizes.js
│ │ │ ├── Retron5/
│ │ │ │ └── Retron5.js
│ │ │ ├── SegaCd/
│ │ │ │ ├── Crc16.js
│ │ │ │ ├── ReedSolomon.js
│ │ │ │ └── SegaCd.js
│ │ │ ├── SegaError.js
│ │ │ ├── SegaSaturn/
│ │ │ │ ├── Emulators/
│ │ │ │ │ ├── Emulators.js
│ │ │ │ │ ├── mednafen.js
│ │ │ │ │ ├── yabasanshiro.js
│ │ │ │ │ └── yabause.js
│ │ │ │ ├── IndividualSaves/
│ │ │ │ │ └── Bup.js
│ │ │ │ ├── Saroo/
│ │ │ │ │ ├── Cart.js
│ │ │ │ │ ├── Internal.js
│ │ │ │ │ ├── System.js
│ │ │ │ │ └── Util.js
│ │ │ │ ├── SegaSaturn.js
│ │ │ │ └── Util.js
│ │ │ └── Wii/
│ │ │ ├── ConvertFrom/
│ │ │ │ ├── ConvertFromN64.js
│ │ │ │ ├── ConvertFromPcEngine.js
│ │ │ │ ├── ConvertFromPlatform.js
│ │ │ │ └── ConvertFromSega.js
│ │ │ ├── GetPlatform/
│ │ │ │ ├── GetPlatform.js
│ │ │ │ └── HttpClient.js
│ │ │ └── Wii.js
│ │ ├── store/
│ │ │ └── index.js
│ │ ├── util/
│ │ │ ├── Array.js
│ │ │ ├── CompressionGzip.js
│ │ │ ├── CompressionLzo.js
│ │ │ ├── CompressionRzip.js
│ │ │ ├── CompressionZlib.js
│ │ │ ├── Endian.js
│ │ │ ├── Genesis.js
│ │ │ ├── Hash.js
│ │ │ ├── Math.js
│ │ │ ├── N64.js
│ │ │ ├── Padding.js
│ │ │ ├── PcEngine.js
│ │ │ ├── SaveFiles.js
│ │ │ ├── SegaCd.js
│ │ │ ├── crypto-aes.js
│ │ │ ├── crypto-des.js
│ │ │ └── util.js
│ │ └── views/
│ │ ├── About.vue
│ │ ├── AdvancedView.vue
│ │ ├── DownloadSaves.vue
│ │ ├── Dreamcast.vue
│ │ ├── EraseSaveView.vue
│ │ ├── FlashCarts.vue
│ │ ├── GameCube.vue
│ │ ├── GbaActionReplay.vue
│ │ ├── GbaGameShark.vue
│ │ ├── GbaGameSharkSP.vue
│ │ ├── Mister.vue
│ │ ├── N64DexDrive.vue
│ │ ├── N64Mempack.vue
│ │ ├── NintendoSwitchOnline.vue
│ │ ├── OnlineEmulators.vue
│ │ ├── OriginalHardware.vue
│ │ ├── OtherConverters.vue
│ │ ├── Ps1DexDrive.vue
│ │ ├── Ps1Emulator.vue
│ │ ├── Ps1Ps3.vue
│ │ ├── Ps1Psp.vue
│ │ ├── PspDecrypt.vue
│ │ ├── Retron5.vue
│ │ ├── Retron5EraseSaveView.vue
│ │ ├── SegaCd.vue
│ │ ├── SegaSaturnEmulator.vue
│ │ ├── SegaSaturnSaroo.vue
│ │ ├── SrmSav.vue
│ │ ├── Troubleshooting.vue
│ │ └── Wii.vue
│ ├── tests/
│ │ ├── config.js
│ │ ├── config.local.js.example
│ │ ├── data/
│ │ │ ├── rom-formats/
│ │ │ │ ├── gb/
│ │ │ │ │ ├── Wario Land 3 header.gbc
│ │ │ │ │ └── Zelda - Link's Awakening header.gb
│ │ │ │ ├── gba/
│ │ │ │ │ └── Zelda - Minish Cap header.gba
│ │ │ │ ├── nes/
│ │ │ │ │ └── Zelda II - header.nes
│ │ │ │ └── psp/
│ │ │ │ ├── encrypted-executable-alternative-boot - EBOOT.DNR
│ │ │ │ ├── encrypted-executable-alternative-boot.iso
│ │ │ │ ├── encrypted-executable-incorrect-magic.iso
│ │ │ │ ├── encrypted-executable-magic0.iso
│ │ │ │ ├── encrypted-executable-magic1.iso
│ │ │ │ ├── encrypted-executable-other-alternative-boot - GBL
│ │ │ │ ├── encrypted-executable-other-alternative-boot-wrong-game-id.iso
│ │ │ │ ├── encrypted-executable-other-alternative-boot.iso
│ │ │ │ └── unencrypted-executable.iso
│ │ │ ├── save-formats/
│ │ │ │ ├── dreamcast/
│ │ │ │ │ ├── individualsaves/
│ │ │ │ │ │ ├── FLPPYBRD-recreated.VMI
│ │ │ │ │ │ ├── FLPPYBRD.VMI
│ │ │ │ │ │ ├── FLPPYBRD.vms
│ │ │ │ │ │ ├── IKARUGA-recreated.VMI
│ │ │ │ │ │ ├── IKARUGA.VMI
│ │ │ │ │ │ ├── IKARUGA.VMS
│ │ │ │ │ │ ├── KISSPC-recreated.VMI
│ │ │ │ │ │ ├── KISSPC.VMI
│ │ │ │ │ │ ├── KISSPC.VMS
│ │ │ │ │ │ ├── kiss-psycho-circus-the-nightmare-child.29341-recreated.dci
│ │ │ │ │ │ ├── kiss-psycho-circus-the-nightmare-child.29341.dci
│ │ │ │ │ │ ├── project-justice.882-recreated.dci
│ │ │ │ │ │ ├── project-justice.882.dci
│ │ │ │ │ │ ├── tetr-recreated.dci
│ │ │ │ │ │ ├── tetr.dci
│ │ │ │ │ │ ├── v4596-recreated.vmi
│ │ │ │ │ │ ├── v4596.VMS
│ │ │ │ │ │ ├── v4596.vmi
│ │ │ │ │ │ ├── v93102-recreated.vmi
│ │ │ │ │ │ ├── v93102.VMS
│ │ │ │ │ │ └── v93102.vmi
│ │ │ │ │ ├── vmoooo.bin-0
│ │ │ │ │ └── vmu5_FUCKED.vmu
│ │ │ │ ├── flashcarts/
│ │ │ │ │ ├── gamegear/
│ │ │ │ │ │ └── Crystalis.sav
│ │ │ │ │ ├── gb/
│ │ │ │ │ │ └── Final Fantasy Legend II.srm
│ │ │ │ │ ├── gba/
│ │ │ │ │ │ ├── Metroid - Zero Mission (USA).sav
│ │ │ │ │ │ ├── goombaemulator/
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe) (32k - compressed save data).sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe) (32k - compressed save data).srm
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-from-cart.esv
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-from-cart.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-from-goomba.esv
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-from-goomba.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia) (32kB - uncompressed save data).sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia) (32kB - uncompressed save data).srm
│ │ │ │ │ │ │ ├── Wario Land 3.sav
│ │ │ │ │ │ │ └── Wario Land 3.srm
│ │ │ │ │ │ ├── pocketnesemulator/
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-from-cart.esv
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-from-cart.sav
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-from-pocketnes.esv
│ │ │ │ │ │ │ └── Zelda II - The Adventure of Link (USA)-from-pocketnes.sav
│ │ │ │ │ │ └── smsadvanceemulator/
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev 1)-from-coury-raw.srm
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev 1)-from-coury.srm
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev A)-from-emulator-to-smsadvance.sav
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev A)-from-emulator.sav
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (v1.3)-from-reddit-raw.srm
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (v1.3)-from-reddit.srm
│ │ │ │ │ │ ├── Phantasy Star-from-smsadvance-bundled-raw.sav
│ │ │ │ │ │ └── Phantasy Star-from-smsadvance-bundled.sav
│ │ │ │ │ ├── genesis/
│ │ │ │ │ │ ├── megaeverdrivepro/
│ │ │ │ │ │ │ ├── 36 Great Holes Starring Fred Couples (Japan, USA).srm
│ │ │ │ │ │ │ ├── Dark Wizard (USA) cd-bram.brm
│ │ │ │ │ │ │ ├── Knuckles' Chaotix (Japan, USA) (En).srm
│ │ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev A).srm
│ │ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A).srm
│ │ │ │ │ │ │ ├── Phantasy_Star_USA_Europe_Rev_A-byte-collapsed.srm
│ │ │ │ │ │ │ ├── Phantasy_Star_USA_Europe_Rev_A-byte-expanded.srm
│ │ │ │ │ │ │ ├── Popful Mail (USA) (RE) cd-cart-raw.srm
│ │ │ │ │ │ │ ├── Popful Mail (USA) (RE) cd-cart.srm
│ │ │ │ │ │ │ ├── Popful Mail (USA) (RE)-from-emulator cart.brm
│ │ │ │ │ │ │ ├── Popful Mail (USA) (RE)-from-emulator-to-med cd-cart.srm
│ │ │ │ │ │ │ ├── Sonic The Hedgehog 3 (USA).srm
│ │ │ │ │ │ │ ├── Wonder Boy in Monster World (USA, Europe).srm
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA).srm
│ │ │ │ │ │ │ └── emulator/
│ │ │ │ │ │ │ └── Sonic The Hedgehog 3 (USA).sav
│ │ │ │ │ │ └── megasd/
│ │ │ │ │ │ ├── 36 Great Holes Starring Fred Couples (Japan, USA)-raw.sav
│ │ │ │ │ │ ├── 36 Great Holes Starring Fred Couples (Japan, USA).SRM
│ │ │ │ │ │ ├── Knuckles' Chaotix (Japan, USA) (En)-raw.sav
│ │ │ │ │ │ ├── Knuckles' Chaotix (Japan, USA) (En).SRM
│ │ │ │ │ │ ├── Lunar_The_Silver_Star-internal-memory.brm
│ │ │ │ │ │ ├── Lunar_The_Silver_Star-ram-cart.brm
│ │ │ │ │ │ ├── Lunar_The_Silver_Star.SRM
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev 1)-raw.sav
│ │ │ │ │ │ ├── Phantasy Star (USA, Europe) (Rev 1).SRM
│ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A)-new-style-raw.sav
│ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A)-new-style.SRM
│ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A)-old-style-raw.sav
│ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A)-old-style.srm
│ │ │ │ │ │ ├── Phantasy Star IV (USA)-new-style-converted-back.SRM
│ │ │ │ │ │ ├── Phantasy Star IV (USA)-new-style-raw.sav
│ │ │ │ │ │ ├── Phantasy Star IV (USA)-new-style.SRM
│ │ │ │ │ │ ├── Popful Mail (U)-converted-back-internal-memory.SRM
│ │ │ │ │ │ ├── Popful Mail (U)-converted-back-ram-cart.SRM
│ │ │ │ │ │ ├── Popful Mail (U)-internal-memory-only.SRM
│ │ │ │ │ │ ├── Popful Mail (U)-internal-memory.brm
│ │ │ │ │ │ ├── Popful Mail (U)-ram-cart.brm
│ │ │ │ │ │ ├── Popful Mail (U).SRM
│ │ │ │ │ │ ├── Sonic the Hedgehog 3 (USA)-new-style-raw.sav
│ │ │ │ │ │ ├── Sonic the Hedgehog 3 (USA)-new-style.SRM
│ │ │ │ │ │ ├── Sword of Vermilion (USA, Europe)-new-style-raw.sav
│ │ │ │ │ │ ├── Sword of Vermilion (USA, Europe)-new-style.SRM
│ │ │ │ │ │ ├── Wonder Boy in Monster World (USA, Europe)-new-style-raw.sav
│ │ │ │ │ │ ├── Wonder Boy in Monster World (USA, Europe)-new-style.SRM
│ │ │ │ │ │ ├── Wonder Boy in Monster World (USA, Europe)-old-style.srm
│ │ │ │ │ │ └── emulator/
│ │ │ │ │ │ └── Sonic The Hedgehog 3 (USA).sav
│ │ │ │ │ ├── n64/
│ │ │ │ │ │ ├── Pokemon Snap-flashcart.fla
│ │ │ │ │ │ ├── Pokemon Snap.fla
│ │ │ │ │ │ ├── Star Fox 64.eep
│ │ │ │ │ │ ├── f-zero-x.15165-flashcart.sra
│ │ │ │ │ │ ├── f-zero-x.15165.sra
│ │ │ │ │ │ ├── gb64emulator/
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-emulator-to-everdrive.fla
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-emulator.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-everdrive-to-raw.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-everdrive-uncompressed-data.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Link's Awakening (USA, Europe)-everdrive.fla
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia)-emulator-to-everdrive.fla
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia)-emulator.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia)-everdrive-to-raw.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia)-everdrive-uncompressed-data.sav
│ │ │ │ │ │ │ ├── Legend of Zelda, The - Oracle of Seasons (USA, Australia)-everdrive.fla
│ │ │ │ │ │ │ ├── Wario Land 3 (World) (En,Ja)-emulator-to-everdrive.fla
│ │ │ │ │ │ │ ├── Wario Land 3 (World) (En,Ja)-emulator.sav
│ │ │ │ │ │ │ ├── Wario Land 3 (World) (En,Ja)-everdrive-to-raw.sav
│ │ │ │ │ │ │ ├── Wario Land 3 (World) (En,Ja)-everdrive-uncompressed-data.sav
│ │ │ │ │ │ │ └── Wario Land 3 (World) (En,Ja)-everdrive.fla
│ │ │ │ │ │ ├── neon64emulator/
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-neon.srm
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-to-raw.sav
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link-cart-to-neon.srm
│ │ │ │ │ │ │ └── Zelda II - The Adventure of Link-cart.sav
│ │ │ │ │ │ ├── nes/
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-from-cart-to-everdrive.sav
│ │ │ │ │ │ │ ├── Zelda II - The Adventure of Link (USA)-from-cart.sav
│ │ │ │ │ │ │ └── Zelda II - The Adventure of Link (USA)-from-everdrive.srm
│ │ │ │ │ │ └── yoshis-story.17238.eep
│ │ │ │ │ ├── nes/
│ │ │ │ │ │ └── Crystalis.sav
│ │ │ │ │ ├── pcengine/
│ │ │ │ │ │ └── Castlevania - Rondo of Blood (my save) - raw.sav
│ │ │ │ │ ├── sms/
│ │ │ │ │ │ └── Phantasy Star (USA, Europe) (Rev A).srm
│ │ │ │ │ └── snes/
│ │ │ │ │ ├── Donkey Kong Country 2 - Diddy's Kong Quest.srm
│ │ │ │ │ └── Legend of Zelda, The - Link's Awakening (USA, Europe).srm
│ │ │ │ ├── gamecube/
│ │ │ │ │ ├── GameShark/
│ │ │ │ │ │ ├── soulcalibur-ii.20763.gcs
│ │ │ │ │ │ └── soulcalibur-ii.20766.gcs
│ │ │ │ │ ├── GameSpecificFixups/
│ │ │ │ │ │ ├── f_zero_gx_usa.gci
│ │ │ │ │ │ └── phantasy-star-online-SNUGGLES-WEAPONS.gcp
│ │ │ │ │ ├── MaxDrive/
│ │ │ │ │ │ ├── soulcalibur-ii.20764.sav
│ │ │ │ │ │ └── soulcalibur-ii.8736.sav
│ │ │ │ │ ├── gci/
│ │ │ │ │ │ ├── bleach_gc_tasogare_ni_mamieru_shinigami_jp.gci
│ │ │ │ │ │ ├── dokapon_dx_wataru_sekai_wa_oni_darake_jp_1.gci
│ │ │ │ │ │ ├── hikaru_no_go_3_jp.gci
│ │ │ │ │ │ ├── konjiki_no_gashbell__yuujou_no_tag_battle_jp.gci
│ │ │ │ │ │ ├── need_for_speed_underground_2_usa-recreated.gci
│ │ │ │ │ │ └── need_for_speed_underground_2_usa.gci
│ │ │ │ │ ├── jpn-empty-0251b-16mb.raw
│ │ │ │ │ ├── memcard-image-empty-no-serial.raw
│ │ │ │ │ ├── memcard-image-japan-nintendont.raw
│ │ │ │ │ ├── memcard-image-recreated-fzero-no-serial.raw
│ │ │ │ │ ├── memcard-image-recreated-fzero.raw
│ │ │ │ │ ├── memcard-image-recreated-resized.raw
│ │ │ │ │ ├── memcard-image-recreated.raw
│ │ │ │ │ ├── memcard-image.raw
│ │ │ │ │ ├── mine-different-flash-id-different-date.raw
│ │ │ │ │ ├── mine-different-flash-id.raw
│ │ │ │ │ ├── mine-same-flash-id-different-date.raw
│ │ │ │ │ ├── mine-same-flash-id.raw
│ │ │ │ │ └── usa-empty-0251b-16mb.raw
│ │ │ │ ├── gba/
│ │ │ │ │ ├── action-replay/
│ │ │ │ │ │ ├── the-legend-of-zelda-the-minish-cap.11439.srm
│ │ │ │ │ │ └── the-legend-of-zelda-the-minish-cap.11439.xps
│ │ │ │ │ ├── gameshark/
│ │ │ │ │ │ ├── mario-and-luigi-superstar-saga.25949.sps
│ │ │ │ │ │ ├── the-legend-of-zelda-the-minish-cap.6650.sps
│ │ │ │ │ │ ├── the-legend-of-zelda-the-minish-cap.6650.sps-2
│ │ │ │ │ │ └── the-legend-of-zelda-the-minish-cap.6650.srm
│ │ │ │ │ └── gameshark-sp/
│ │ │ │ │ ├── final-fantasy-tactics-advance.22864.gsv
│ │ │ │ │ └── final-fantasy-tactics-advance.22864.srm
│ │ │ │ ├── mister/
│ │ │ │ │ ├── gba/
│ │ │ │ │ │ ├── Final_Fight_One_Japan-mister.sav
│ │ │ │ │ │ ├── Final_Fight_One_Japan-raw-converted-back.srm
│ │ │ │ │ │ ├── Final_Fight_One_Japan-raw.srm
│ │ │ │ │ │ ├── pokemon-sapphire-mister-fake-rtc.sav
│ │ │ │ │ │ ├── pokemon-sapphire-mister-no-rtc.sav
│ │ │ │ │ │ ├── pokemon-sapphire-raw.srm
│ │ │ │ │ │ ├── the-legend-of-zelda-the-minish-cap.sav
│ │ │ │ │ │ └── the-legend-of-zelda-the-minish-cap.srm
│ │ │ │ │ ├── genesis/
│ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A)-from-mega-sd.sav
│ │ │ │ │ │ ├── Phantasy Star II (USA, Europe) (Rev A)-from-mega-sd.srm
│ │ │ │ │ │ ├── Phantasy_Star_IV_USA-from-mister-zero-padded-to-raw.srm
│ │ │ │ │ │ ├── Phantasy_Star_IV_USA-from-mister-zero-padded.sav
│ │ │ │ │ │ ├── Phantasy_Star_IV_USA-from-retrode-to-mister.sav
│ │ │ │ │ │ ├── Phantasy_Star_IV_USA-from-retrode.srm
│ │ │ │ │ │ ├── Wonder Boy in Monster World mister.sav
│ │ │ │ │ │ ├── Wonder Boy in Monster World raw.srm
│ │ │ │ │ │ ├── phantasy-star-ii.18168-mister.sav
│ │ │ │ │ │ └── phantasy-star-ii.18168-raw.srm
│ │ │ │ │ ├── n64/
│ │ │ │ │ │ ├── 007 - The World Is Not Enough (USA)_1.cpk
│ │ │ │ │ │ ├── Banjo-Kazooie (USA).eep
│ │ │ │ │ │ ├── Donkey Kong 64 (USA).eep
│ │ │ │ │ │ ├── Legend of Zelda, The - Majora's Mask (USA).fla
│ │ │ │ │ │ └── Legend of Zelda, The - Ocarina of Time (USA).sra
│ │ │ │ │ ├── segacd/
│ │ │ │ │ │ ├── Empty-mister-save.sav
│ │ │ │ │ │ ├── Popful Mail (USA) (RE)-internal-plus-raw-cart-to-mister.sav
│ │ │ │ │ │ ├── Popful Mail (USA) (RE)-mister-internal-only.sav
│ │ │ │ │ │ ├── Popful Mail (USA) (RE)-ram-cart-only.brm
│ │ │ │ │ │ ├── Popful Mail (USA) (RE)-raw-cart-only-to-mister.sav
│ │ │ │ │ │ ├── Popful Mail (USA) (RE)-raw-internal.brm
│ │ │ │ │ │ ├── Popful Mail (USA) Internal plus Cart to-emulator-internal.brm
│ │ │ │ │ │ ├── Popful Mail (USA) Internal plus Cart to-emulator-ram-cart.brm
│ │ │ │ │ │ ├── Popful Mail (USA) Internal plus Cart-mister.sav
│ │ │ │ │ │ ├── Shining Force CD (USA) (3R)-mister-internal-only-padded.sav
│ │ │ │ │ │ └── Shining Force CD (USA) (3R)-to-emulator-internal.brm
│ │ │ │ │ └── segasaturn/
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA)-recreated.sav
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA).bkr
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA).sav
│ │ │ │ │ ├── Empty-mister-save.sav
│ │ │ │ │ ├── Pretend-mister-save-only-cart.sav
│ │ │ │ │ ├── Rayman (USA) (R2)-cart-uncompressed.bcr
│ │ │ │ │ ├── Rayman (USA) (R2)-cart.bcr
│ │ │ │ │ ├── Rayman (USA) (R2)-internal.bkr
│ │ │ │ │ ├── Rayman (USA) (R2).sav
│ │ │ │ │ ├── Sega Rally Championship Plus (Japan).bkr
│ │ │ │ │ └── Sega Rally Championship Plus (Japan).sav
│ │ │ │ ├── n64/
│ │ │ │ │ ├── dexdrive/
│ │ │ │ │ │ ├── Ready 2 Rumble Boxing (U) [!]-fixed-1
│ │ │ │ │ │ ├── Ready 2 Rumble Boxing (U) [!]-fixed-2
│ │ │ │ │ │ ├── Ready 2 Rumble Boxing (U) [!]-fixed.mpk
│ │ │ │ │ │ ├── Ready 2 Rumble Boxing (U) [!].n64
│ │ │ │ │ │ ├── banjo-kazooie.1141-1
│ │ │ │ │ │ ├── banjo-kazooie.1141-2
│ │ │ │ │ │ ├── banjo-kazooie.1141-3
│ │ │ │ │ │ ├── banjo-kazooie.1141-4
│ │ │ │ │ │ ├── banjo-kazooie.1141.mpk
│ │ │ │ │ │ ├── banjo-kazooie.1141.n64
│ │ │ │ │ │ ├── banjokaz-1
│ │ │ │ │ │ ├── banjokaz-2
│ │ │ │ │ │ ├── banjokaz.mpk
│ │ │ │ │ │ ├── banjokaz.n64
│ │ │ │ │ │ ├── donkey-kong-64.1156-1
│ │ │ │ │ │ ├── donkey-kong-64.1156.mpk
│ │ │ │ │ │ ├── donkey-kong-64.1156.n64
│ │ │ │ │ │ ├── ecw-hardcore-revolution-empty-header.1000.n64
│ │ │ │ │ │ ├── ecw-hardcore-revolution-no-header.1000.n64
│ │ │ │ │ │ ├── ecw-hardcore-revolution.1000-1
│ │ │ │ │ │ ├── ecw-hardcore-revolution.1000.mpk
│ │ │ │ │ │ ├── ecw-hardcore-revolution.1000.n64
│ │ │ │ │ │ ├── mario-kart-64.1102.eep
│ │ │ │ │ │ ├── mario-kart-64.1102.n64
│ │ │ │ │ │ ├── mario-kart-64.1116-1
│ │ │ │ │ │ ├── mario-kart-64.1116.mpk
│ │ │ │ │ │ ├── mario-kart-64.1116.n64
│ │ │ │ │ │ ├── perfect-dark.1043.1116-1
│ │ │ │ │ │ ├── perfect-dark.1043.mpk
│ │ │ │ │ │ ├── perfect-dark.1043.n64
│ │ │ │ │ │ ├── san-francisco-rush-extreme-racing.1103-1
│ │ │ │ │ │ ├── san-francisco-rush-extreme-racing.1103.mpk
│ │ │ │ │ │ ├── san-francisco-rush-extreme-racing.1103.n64
│ │ │ │ │ │ ├── super-mario-64.1091-1
│ │ │ │ │ │ ├── super-mario-64.1091.mpk
│ │ │ │ │ │ ├── super-mario-64.1091.n64
│ │ │ │ │ │ ├── tony-hawks-pro-skater-2.1077-1
│ │ │ │ │ │ ├── tony-hawks-pro-skater-2.1077-2
│ │ │ │ │ │ ├── tony-hawks-pro-skater-2.1077-output.n64
│ │ │ │ │ │ ├── tony-hawks-pro-skater-2.1077.mpk
│ │ │ │ │ │ └── tony-hawks-pro-skater-2.1077.n64
│ │ │ │ │ └── mempack/
│ │ │ │ │ ├── banjokaz-1
│ │ │ │ │ ├── mario-kart-64.1116-1
│ │ │ │ │ ├── mario-kart-64.1116.mpk
│ │ │ │ │ ├── san-francisco-rush-extreme-racing.1103-1
│ │ │ │ │ ├── super-mario-64.1091-1
│ │ │ │ │ ├── tony-hawks-pro-skater-2.1077-1
│ │ │ │ │ ├── tony-hawks-pro-skater-2.1077-2
│ │ │ │ │ └── tony-hawks-pro-skater-2.1077.mpk
│ │ │ │ ├── nintendoswitchonline/
│ │ │ │ │ ├── gb/
│ │ │ │ │ │ ├── Kirbys_Dreamland_2.sav
│ │ │ │ │ │ ├── Kirbys_Dreamland_2.sram
│ │ │ │ │ │ ├── Links_Awakening_DX.sav
│ │ │ │ │ │ ├── Links_Awakening_DX.sram
│ │ │ │ │ │ ├── Metroid_II_Return_of_Samus.sav
│ │ │ │ │ │ ├── Metroid_II_Return_of_Samus.sram
│ │ │ │ │ │ ├── Pokemon Cristal.sav
│ │ │ │ │ │ ├── Pokemon Cristal.sram
│ │ │ │ │ │ ├── Pokemon_-_Crystal_Version.sav
│ │ │ │ │ │ ├── Pokemon_-_Crystal_Version.sram
│ │ │ │ │ │ ├── Pokemon_TCG.sav
│ │ │ │ │ │ ├── Pokemon_TCG.sram
│ │ │ │ │ │ ├── Pokemon_TCG_Europe.sav
│ │ │ │ │ │ ├── Pokemon_TCG_Europe.sram
│ │ │ │ │ │ ├── Wario_Land_3.sav
│ │ │ │ │ │ └── Wario_Land_3.sram
│ │ │ │ │ ├── gba/
│ │ │ │ │ │ └── The_Legend_of_Zelda_The_Minish_Cap.sram
│ │ │ │ │ ├── genesis/
│ │ │ │ │ │ ├── MegaMan Wily Wars SEGA GENESIS.sav
│ │ │ │ │ │ ├── MegaMan Wily Wars SEGA GENESIS.sram
│ │ │ │ │ │ ├── Phantasy Star 4 SEGA GENESIS.sav
│ │ │ │ │ │ └── Phantasy Star 4 SEGA GENESIS.sram
│ │ │ │ │ ├── n64/
│ │ │ │ │ │ ├── F-Zero N64.sra
│ │ │ │ │ │ ├── F-Zero N64.sram
│ │ │ │ │ │ ├── Majoras Mask N64.fla
│ │ │ │ │ │ ├── Majoras Mask N64.sram
│ │ │ │ │ │ ├── Mario 64 N64.sram
│ │ │ │ │ │ ├── Mario Tennis N64.sram
│ │ │ │ │ │ └── Operation Winback N64.sram
│ │ │ │ │ ├── nes/
│ │ │ │ │ │ ├── Legend_of_Zelda_The_USA_Rev_1.sram
│ │ │ │ │ │ └── Zelda-converted.srm
│ │ │ │ │ └── snes/
│ │ │ │ │ └── Super Mario World SNES.sram
│ │ │ │ ├── online-emulators/
│ │ │ │ │ ├── arcadespot.com/
│ │ │ │ │ │ ├── gb/
│ │ │ │ │ │ │ ├── final-fantasy-legend.sav
│ │ │ │ │ │ │ ├── final-fantasy-legend.save
│ │ │ │ │ │ │ ├── invalid-save-state.save
│ │ │ │ │ │ │ ├── legend-of-zelda-the-links-awakening.sav
│ │ │ │ │ │ │ ├── legend-of-zelda-the-links-awakening.save
│ │ │ │ │ │ │ ├── pokemon-crystal.sav
│ │ │ │ │ │ │ ├── pokemon-crystal.save
│ │ │ │ │ │ │ ├── pokemon-yellow.sav
│ │ │ │ │ │ │ ├── pokemon-yellow.save
│ │ │ │ │ │ │ ├── the-legend-of-zelda-links-awakening-dx.sav
│ │ │ │ │ │ │ ├── the-legend-of-zelda-links-awakening-dx.save
│ │ │ │ │ │ │ ├── the-legend-of-zelda-oracle-of-seasons.sav
│ │ │ │ │ │ │ ├── the-legend-of-zelda-oracle-of-seasons.save
│ │ │ │ │ │ │ ├── wario-land-2.sav
│ │ │ │ │ │ │ └── wario-land-2.save
│ │ │ │ │ │ ├── gba/
│ │ │ │ │ │ │ ├── advance-wars.sav
│ │ │ │ │ │ │ ├── advance-wars.save
│ │ │ │ │ │ │ ├── donkey-kong-country-3.sav
│ │ │ │ │ │ │ ├── donkey-kong-country-3.save
│ │ │ │ │ │ │ ├── golden-sun.sav
│ │ │ │ │ │ │ ├── golden-sun.save
│ │ │ │ │ │ │ ├── invalid-save-state.save
│ │ │ │ │ │ │ ├── metroid-fusion.sav
│ │ │ │ │ │ │ ├── metroid-fusion.save
│ │ │ │ │ │ │ ├── metroid-zero-mission.sav
│ │ │ │ │ │ │ ├── metroid-zero-mission.save
│ │ │ │ │ │ │ ├── pokemon-sapphire.sav
│ │ │ │ │ │ │ ├── pokemon-sapphire.save
│ │ │ │ │ │ │ ├── super-mario-advance-4.sav
│ │ │ │ │ │ │ ├── super-mario-advance-4.save
│ │ │ │ │ │ │ ├── the-legend-of-zelda-the-minish-cap.sav
│ │ │ │ │ │ │ └── the-legend-of-zelda-the-minish-cap.save
│ │ │ │ │ │ ├── genesis/
│ │ │ │ │ │ │ ├── phantasy-star-ii.save
│ │ │ │ │ │ │ └── readme
│ │ │ │ │ │ └── snes/
│ │ │ │ │ │ ├── Legend-of-Zelda-The-A-Link-to-the-Past-U-.sav
│ │ │ │ │ │ └── Legend-of-Zelda-The-A-Link-to-the-Past-U-.save
│ │ │ │ │ ├── myemulator.online/
│ │ │ │ │ │ ├── gba/
│ │ │ │ │ │ │ ├── gbazelda-0.sav
│ │ │ │ │ │ │ ├── gbazelda-1.sav
│ │ │ │ │ │ │ ├── gbazelda-2.sav
│ │ │ │ │ │ │ ├── gbazelda-3.sav
│ │ │ │ │ │ │ └── gbazelda.ggz
│ │ │ │ │ │ ├── genesis/
│ │ │ │ │ │ │ ├── genesisphantasystar4.ggz
│ │ │ │ │ │ │ └── readme
│ │ │ │ │ │ └── snes/
│ │ │ │ │ │ ├── sneszelda1.ggz
│ │ │ │ │ │ └── sneszelda1.sav
│ │ │ │ │ └── retrogames.onl/
│ │ │ │ │ ├── gb/
│ │ │ │ │ │ ├── final-fantasy-legend-gboy.sav
│ │ │ │ │ │ ├── final-fantasy-legend-gboy.state
│ │ │ │ │ │ ├── invalid-file.state
│ │ │ │ │ │ ├── legend-zelda-link-awakening-dx.sav
│ │ │ │ │ │ ├── legend-zelda-link-awakening-dx.state
│ │ │ │ │ │ ├── pokemon-crystal.sav
│ │ │ │ │ │ ├── pokemon-crystal.state
│ │ │ │ │ │ ├── pokemon-yellow.sav
│ │ │ │ │ │ ├── pokemon-yellow.state
│ │ │ │ │ │ ├── wario-land-2-gbcolor.sav
│ │ │ │ │ │ ├── wario-land-2-gbcolor.state
│ │ │ │ │ │ ├── wrong-size.state
│ │ │ │ │ │ ├── zelda-oracle-sesion.sav
│ │ │ │ │ │ └── zelda-oracle-sesion.state
│ │ │ │ │ └── gba/
│ │ │ │ │ ├── advance-wars-gmba.sav
│ │ │ │ │ ├── advance-wars-gmba.state
│ │ │ │ │ ├── baldurs-gate.sav
│ │ │ │ │ ├── baldurs-gate.state
│ │ │ │ │ ├── golden-sun-gmba.sav
│ │ │ │ │ ├── golden-sun-gmba.state
│ │ │ │ │ ├── invalid-file.state
│ │ │ │ │ ├── metroid-fusion.sav
│ │ │ │ │ ├── metroid-fusion.state
│ │ │ │ │ ├── metroid-zero-mission.sav
│ │ │ │ │ ├── metroid-zero-mission.state
│ │ │ │ │ ├── pokemon-sapphire.sav
│ │ │ │ │ ├── pokemon-sapphire.state
│ │ │ │ │ ├── super-mario-advance-4.sav
│ │ │ │ │ ├── super-mario-advance-4.state
│ │ │ │ │ ├── wrong-size.state
│ │ │ │ │ ├── zelda-minish-cap.sav
│ │ │ │ │ └── zelda-minish-cap.state
│ │ │ │ ├── ps1/
│ │ │ │ │ ├── dexdrive/
│ │ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.BASLUS-00067DRAX00.srm
│ │ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.gme
│ │ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.mcr
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1368-BASLUS-00067DRAX01.srm
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1368.gme
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1782-BASLUS-00067DRAX00.srm
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1782-BASLUS-00067DRAX01.srm
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1782.gme
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.3172.gme
│ │ │ │ │ │ ├── digimon-world.21133-BASLUS-01032DMR0.srm
│ │ │ │ │ │ ├── digimon-world.21133.gme
│ │ │ │ │ │ ├── gran-turismo.26535-BASCUS-94194GT.srm
│ │ │ │ │ │ ├── gran-turismo.26535.gme
│ │ │ │ │ │ ├── gran-turismo.26537-BASCUS-94194GT.srm
│ │ │ │ │ │ ├── gran-turismo.26537-BASCUS-94194RT.srm
│ │ │ │ │ │ ├── gran-turismo.26537-output.gme
│ │ │ │ │ │ ├── gran-turismo.26537.gme
│ │ │ │ │ │ ├── tony-hawks-pro-skater-4.24197-BASLUS-01485PNMOG01.srm
│ │ │ │ │ │ └── tony-hawks-pro-skater-4.24197.gme
│ │ │ │ │ ├── memcard/
│ │ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.BASLUS-00067DRAX00.srm
│ │ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.mcr
│ │ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).1.mcr
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1782-BASLUS-00067DRAX00.srm
│ │ │ │ │ │ ├── castlevania-symphony-of-the-night.1782-BASLUS-00067DRAX01.srm
│ │ │ │ │ │ ├── gran-turismo.26537-BASCUS-94194GT.srm
│ │ │ │ │ │ └── gran-turismo.26537-BASCUS-94194RT.srm
│ │ │ │ │ ├── ps3/
│ │ │ │ │ │ ├── Street Fighter EX2 Plus-BASLUS-0110553595354454D.PSV
│ │ │ │ │ │ ├── Suikoden 2-BASLUS-009584753322D37.PSV
│ │ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-7.srm
│ │ │ │ │ │ └── street-fighter-ex2-plus.17782.mcr
│ │ │ │ │ └── psp/
│ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.BASLUS-00067DRAX00.srm
│ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.VMP
│ │ │ │ │ ├── Castlevania - Symphony of the Night (USA).0.mcr
│ │ │ │ │ ├── Suikoden 1-save-editor-signature.VMP
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-1.srm
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-2.srm
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-3.srm
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-4.srm
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-5.srm
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-6.srm
│ │ │ │ │ ├── Suikoden 2-BASLUS-00958GS2-7.srm
│ │ │ │ │ ├── Suikoden 2-no-signature.VMP
│ │ │ │ │ ├── Suikoden 2-psp-signature.VMP
│ │ │ │ │ ├── Suikoden 2-vita-mcr2vmp-signature.VMP
│ │ │ │ │ ├── Suikoden 2.VMP
│ │ │ │ │ ├── gran-turismo.26537-BASCUS-94194GT.srm
│ │ │ │ │ ├── gran-turismo.26537-BASCUS-94194RT.srm
│ │ │ │ │ └── gran-turismo.26537-output.vmp
│ │ │ │ ├── psp/
│ │ │ │ │ ├── DRACULA-PARAM-reencrypted-debug.SFO
│ │ │ │ │ ├── DRACULA-PARAM-reencrypted-release.SFO
│ │ │ │ │ ├── DRACULA-PARAM.SFO
│ │ │ │ │ └── PARAM.SFO
│ │ │ │ ├── retron5/
│ │ │ │ │ ├── Final Fantasy III (USA).sav
│ │ │ │ │ ├── Final Fantasy III (USA).srm
│ │ │ │ │ ├── Tomato Adventure (Japan)-truncated.srm
│ │ │ │ │ └── Tomato Adventure (Japan).sav
│ │ │ │ ├── segacd/
│ │ │ │ │ ├── Multiple titles - corrupted.brm
│ │ │ │ │ ├── Multiple titles - created by program.brm
│ │ │ │ │ ├── Multiple titles-1.srm
│ │ │ │ │ ├── Multiple titles-2.srm
│ │ │ │ │ ├── Multiple titles-3.srm
│ │ │ │ │ ├── Multiple titles-4.srm
│ │ │ │ │ ├── Multiple titles-5.srm
│ │ │ │ │ ├── Multiple titles-6.srm
│ │ │ │ │ ├── Multiple titles-7.srm
│ │ │ │ │ ├── Multiple titles.brm
│ │ │ │ │ ├── Popful Mail (U)-internal-memory-1.srm
│ │ │ │ │ ├── Popful Mail (U)-internal-memory.brm
│ │ │ │ │ ├── SHINING FORCE CD-0.srm
│ │ │ │ │ ├── SHINING FORCE CD-1.srm
│ │ │ │ │ ├── SHINING FORCE CD-2.srm
│ │ │ │ │ ├── SHINING FORCE CD-3.srm
│ │ │ │ │ ├── SHINING FORCE CD-4.srm
│ │ │ │ │ └── SHINING FORCE CD.brm
│ │ │ │ ├── segasaturn/
│ │ │ │ │ ├── DRACULAX-recreated.BUP
│ │ │ │ │ ├── DRACULAX.BUP
│ │ │ │ │ ├── DRACULAX.raw
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA)-1.raw
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA)-2.raw
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA)-uncompressed-recreated.bcr
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA)-uncompressed.bcr
│ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA).bcr
│ │ │ │ │ ├── Dezaemon 2 (Japan)-1.raw
│ │ │ │ │ ├── Dezaemon 2 (Japan).bkr
│ │ │ │ │ ├── Empty save.bkr
│ │ │ │ │ ├── Hyper Duel (Japan)-1.raw
│ │ │ │ │ ├── Hyper Duel (Japan).bkr
│ │ │ │ │ ├── SFORCE31-recreated.BUP
│ │ │ │ │ ├── SFORCE31.BUP
│ │ │ │ │ ├── SFORCE31.raw
│ │ │ │ │ ├── Shining Force III Scenario 3 (English v25.1)-1.raw
│ │ │ │ │ ├── Shining Force III Scenario 3 (English v25.1)-cart-1.raw
│ │ │ │ │ ├── Shining Force III Scenario 3 (English v25.1)-recreated.bcr
│ │ │ │ │ ├── Shining Force III Scenario 3 (English v25.1)-uncompressed.bcr
│ │ │ │ │ ├── Shining Force III Scenario 3 (English v25.1).bcr
│ │ │ │ │ ├── Shining Force III Scenario 3 (English v25.1).bkr
│ │ │ │ │ ├── saroo/
│ │ │ │ │ │ ├── Blast Wind (Japan).raw
│ │ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA) 1-1.raw
│ │ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA) 1-2.raw
│ │ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA) 2-1.raw
│ │ │ │ │ │ ├── Daytona USA - Championship Circuit Edition (USA) 2-2.raw
│ │ │ │ │ │ ├── Dungeons and Dragons Collection (Japan) (Disc 2) (Shadows over Mystara).raw
│ │ │ │ │ │ ├── Hyper Duel (Japan).raw
│ │ │ │ │ │ ├── Shining Force III Scenario 1 (English v25.1)-1.raw
│ │ │ │ │ │ └── Shining Force III Scenario 1 (English v25.1)-2.raw
│ │ │ │ │ └── yabause/
│ │ │ │ │ ├── Akumajou Dracula X - Gekka no Yasoukyoku (Japan) (2M).srm
│ │ │ │ │ └── Akumajou Dracula X - Gekka no Yasoukyoku (Japan) (2M).srm-1.raw
│ │ │ │ └── wii/
│ │ │ │ ├── gametdb/
│ │ │ │ │ ├── C97E.html
│ │ │ │ │ ├── D40A.html
│ │ │ │ │ ├── DAXE01.html
│ │ │ │ │ ├── E6ZJ.html
│ │ │ │ │ ├── EAEP.html
│ │ │ │ │ ├── FBNE.html
│ │ │ │ │ ├── JECE.html
│ │ │ │ │ ├── LADE.html
│ │ │ │ │ ├── MC4E.html
│ │ │ │ │ ├── NADJ.html
│ │ │ │ │ ├── NAJE.html
│ │ │ │ │ ├── QAPN.html
│ │ │ │ │ ├── R3OP01.html
│ │ │ │ │ └── WKTE.html
│ │ │ │ ├── n64/
│ │ │ │ │ ├── f-zero-x.15165-raw.sra
│ │ │ │ │ ├── mario-golf.23681-raw.sra
│ │ │ │ │ ├── mario-kart-64.14534-raw.eep
│ │ │ │ │ ├── paper-mario.17225-raw.fla
│ │ │ │ │ ├── super-mario-64.14546-raw.eep
│ │ │ │ │ ├── the-legend-of-zelda-majoras-mask.19354-raw.fla
│ │ │ │ │ └── yoshis-story.17238-raw.eep
│ │ │ │ └── pcengine/
│ │ │ │ ├── Castlevania - Rondo of Blood (my save) - extracted.bup
│ │ │ │ ├── Castlevania - Rondo of Blood (my save) - raw.sav
│ │ │ │ ├── Castlevania - Rondo of Blood (test save) - extracted.bup
│ │ │ │ ├── Castlevania - Rondo of Blood (test save) - raw.sav
│ │ │ │ ├── battle-lode-runner.16193 - extracted.bup
│ │ │ │ ├── battle-lode-runner.16193 - raw.sav
│ │ │ │ ├── bomberman-93.20114 - extracted.bup
│ │ │ │ ├── bomberman-93.20114 - raw.sav
│ │ │ │ ├── neutopia-ii.21439 - extracted.bup
│ │ │ │ └── neutopia-ii.21439 - raw.sav
│ │ │ └── util/
│ │ │ ├── Multiple titles-to-ram-cart.brm
│ │ │ ├── Multiple titles.brm
│ │ │ ├── Popful Mail (USA) (RE)-internal-to-ram-cart.brm
│ │ │ ├── Popful Mail (USA) (RE)-internal.sav
│ │ │ ├── Tomato Adventure (Japan) extra padding at end.srm
│ │ │ ├── Tomato Adventure (Japan) fixed extra padding at end.srm
│ │ │ ├── Tomato Adventure (Japan) fixed extra padding at start.srm
│ │ │ ├── Tomato Adventure (Japan) fixed.srm
│ │ │ ├── Tomato Adventure (Japan) test save all padding.srm
│ │ │ ├── Tomato Adventure (Japan).srm
│ │ │ ├── Xenogears (USA) (Disc 1)-compressed.srm
│ │ │ ├── Xenogears (USA) (Disc 1)-uncompressed.srm
│ │ │ └── endian/
│ │ │ ├── 2ByteWord-input.sav
│ │ │ ├── 2ByteWord-output.sav
│ │ │ ├── 4ByteWord-input.sav
│ │ │ ├── 4ByteWord-output.sav
│ │ │ ├── 8ByteWord-input.sav
│ │ │ └── 8ByteWord-output.sav
│ │ ├── unit/
│ │ │ ├── rom-formats/
│ │ │ │ ├── GB/
│ │ │ │ │ └── gb.spec.js
│ │ │ │ ├── GBA/
│ │ │ │ │ └── gba.spec.js
│ │ │ │ ├── NES/
│ │ │ │ │ └── nes.spec.js
│ │ │ │ ├── PSP/
│ │ │ │ │ └── PspIso.spec.js
│ │ │ │ ├── SMS/
│ │ │ │ │ └── sms.spec.js
│ │ │ │ └── SegaSaturn/
│ │ │ │ └── SegaSaturnCueBin.spec.js
│ │ │ ├── save-formats/
│ │ │ │ ├── Dreamcast/
│ │ │ │ │ ├── Dreamcast.spec.js
│ │ │ │ │ └── IndividualSaves/
│ │ │ │ │ ├── Dci.spec.js
│ │ │ │ │ └── VmiVms.spec.js
│ │ │ │ ├── FlashCarts/
│ │ │ │ │ ├── GB.spec.js
│ │ │ │ │ ├── GBA/
│ │ │ │ │ │ ├── GBA.spec.js
│ │ │ │ │ │ ├── GoombaEmulator.spec.js
│ │ │ │ │ │ ├── PocketNesEmulator.spec.js
│ │ │ │ │ │ └── SmsAdvanceEmulator.spec.js
│ │ │ │ │ ├── GameGear.spec.js
│ │ │ │ │ ├── Genesis/
│ │ │ │ │ │ ├── MegaEverdrivePro/
│ │ │ │ │ │ │ ├── 32X.spec.js
│ │ │ │ │ │ │ ├── Genesis.spec.js
│ │ │ │ │ │ │ ├── NES.spec.js
│ │ │ │ │ │ │ ├── SMS.spec.js
│ │ │ │ │ │ │ └── SegaCd.spec.js
│ │ │ │ │ │ └── MegaSD/
│ │ │ │ │ │ ├── 32X.spec.js
│ │ │ │ │ │ ├── Genesis.spec.js
│ │ │ │ │ │ ├── SMS.spec.js
│ │ │ │ │ │ └── SegaCd.spec.js
│ │ │ │ │ ├── N64/
│ │ │ │ │ │ ├── GB64.spec.js
│ │ │ │ │ │ ├── N64.spec.js
│ │ │ │ │ │ ├── NES.spec.js
│ │ │ │ │ │ └── Neon64Emulator.spec.js
│ │ │ │ │ ├── NES.spec.js
│ │ │ │ │ ├── PcEngine.spec.js
│ │ │ │ │ ├── SMS.spec.js
│ │ │ │ │ └── SNES/
│ │ │ │ │ ├── GB.spec.js
│ │ │ │ │ └── SNES.spec.js
│ │ │ │ ├── GBA/
│ │ │ │ │ ├── ActionReplay.spec.js
│ │ │ │ │ ├── GameShark.spec.js
│ │ │ │ │ └── GameSharkSP.spec.js
│ │ │ │ ├── GameCube/
│ │ │ │ │ ├── GameCube.spec.js
│ │ │ │ │ ├── GameSpecificFixups/
│ │ │ │ │ │ ├── FZeroGx.spec.js
│ │ │ │ │ │ └── PhantasyStarOnline.spec.js
│ │ │ │ │ └── IndividualSaves/
│ │ │ │ │ ├── GameShark.spec.js
│ │ │ │ │ ├── Gci.spec.js
│ │ │ │ │ └── MaxDrive.spec.js
│ │ │ │ ├── Mister/
│ │ │ │ │ ├── GameboyAdvance.spec.js
│ │ │ │ │ ├── Genesis.spec.js
│ │ │ │ │ ├── N64Cart.spec.js
│ │ │ │ │ ├── N64Mempack.spec.js
│ │ │ │ │ ├── SegaCd.spec.js
│ │ │ │ │ └── SegaSaturn.spec.js
│ │ │ │ ├── N64/
│ │ │ │ │ ├── DexDrive.spec.js
│ │ │ │ │ ├── IndividualSaveFilename.spec.js
│ │ │ │ │ └── Mempack.spec.js
│ │ │ │ ├── NintendoSwitchOnline/
│ │ │ │ │ ├── Gameboy.spec.js
│ │ │ │ │ ├── GameboyAdvance.spec.js
│ │ │ │ │ ├── Genesis.spec.js
│ │ │ │ │ ├── N64.spec.js
│ │ │ │ │ ├── Nes.spec.js
│ │ │ │ │ └── Snes.spec.js
│ │ │ │ ├── OnlineEmulators/
│ │ │ │ │ ├── Emulators/
│ │ │ │ │ │ ├── Gambatte.spec.js
│ │ │ │ │ │ ├── Gb.spec.js
│ │ │ │ │ │ ├── Snes9x.spec.js
│ │ │ │ │ │ ├── VBA-Next.spec.js
│ │ │ │ │ │ └── mGba.spec.js
│ │ │ │ │ └── OnlineEmulatorWrapper.spec.js
│ │ │ │ ├── PS1/
│ │ │ │ │ ├── DexDrive.spec.js
│ │ │ │ │ ├── Memcard.spec.js
│ │ │ │ │ ├── Ps3.spec.js
│ │ │ │ │ └── Psp.spec.js
│ │ │ │ ├── PSP/
│ │ │ │ │ ├── Executable.spec.js
│ │ │ │ │ ├── ParamSfo.spec.js
│ │ │ │ │ └── Savefile.spec.js
│ │ │ │ ├── Retron5/
│ │ │ │ │ └── Retron5.spec.js
│ │ │ │ ├── SegaCd/
│ │ │ │ │ └── SegaCd.spec.js
│ │ │ │ ├── SegaSaturn/
│ │ │ │ │ ├── Emulators/
│ │ │ │ │ │ ├── mednafen.spec.js
│ │ │ │ │ │ ├── yabasanshiro.spec.js
│ │ │ │ │ │ └── yabause.spec.js
│ │ │ │ │ ├── IndividualSaves/
│ │ │ │ │ │ └── Bup.spec.js
│ │ │ │ │ ├── Saroo/
│ │ │ │ │ │ ├── Cart.spec.js
│ │ │ │ │ │ ├── Internal.spec.js
│ │ │ │ │ │ └── System.spec.js
│ │ │ │ │ └── SegaSaturn.spec.js
│ │ │ │ └── Wii/
│ │ │ │ ├── ConvertFrom/
│ │ │ │ │ ├── ConvertFromN64.spec.js
│ │ │ │ │ ├── ConvertFromPcEngine.spec.js
│ │ │ │ │ └── ConvertFromSega.spec.js
│ │ │ │ ├── GetPlatform/
│ │ │ │ │ ├── GetPlatform.spec.js
│ │ │ │ │ └── MockHttpClient.js
│ │ │ │ └── Wii.spec.js
│ │ │ └── util/
│ │ │ ├── CompressionGzip.spec.js
│ │ │ ├── CompressionLzo.spec.js
│ │ │ ├── CompressionRzip.spec.js
│ │ │ ├── CompressionZlib.spec.js
│ │ │ ├── Endian.spec.js
│ │ │ ├── Math.spec.js
│ │ │ ├── Padding.spec.js
│ │ │ ├── SaveFiles.spec.js
│ │ │ ├── SegaCdUtil.spec.js
│ │ │ ├── Troubleshooting test files.spec.js
│ │ │ ├── crypto-aes.spec.js
│ │ │ ├── crypto-des.spec.js
│ │ │ └── util.spec.js
│ │ └── util/
│ │ ├── ArrayBuffer.js
│ │ └── Crypto.js
│ └── vue.config.js
└── terraform/
├── .gitignore
├── aws_credentials.example
├── dev/
│ ├── main.tf
│ ├── provider.tf
│ ├── variables.tf
│ └── versions.tf
├── modules/
│ ├── alarms/
│ │ ├── outputs.tf
│ │ ├── sns-topic.tf
│ │ ├── variables.tf
│ │ └── versions.tf
│ ├── build-common-infrastructure/
│ │ ├── logs-bucket.tf
│ │ ├── outputs.tf
│ │ ├── role.tf
│ │ ├── variables.tf
│ │ └── versions.tf
│ ├── build-pipeline-frontend/
│ │ ├── alarms.tf
│ │ ├── code-build.tf
│ │ ├── email-logs.tf
│ │ ├── eventbridge.tf
│ │ ├── python/
│ │ │ └── email-logs.py
│ │ ├── variables.tf
│ │ └── versions.tf
│ └── frontend/
│ ├── build.tf
│ ├── cloudfront.tf
│ ├── dns.tf
│ ├── outputs.tf
│ ├── s3.tf
│ ├── variables.tf
│ └── versions.tf
├── prod/
│ ├── main.tf
│ ├── provider.tf
│ ├── variables.tf
│ └── versions.tf
└── terraform.tfvars.example
Showing preview only (278K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2856 symbols across 249 files)
FILE: frontend/lib/minlzo-js/lzo1x.js
function _lzo1x (line 34) | function _lzo1x() {
FILE: frontend/src/rom-formats/PspIso.js
constant EXECUTABLE_MAGIC_ENCODING (line 9) | const EXECUTABLE_MAGIC_ENCODING = 'US-ASCII';
constant EXECUTABLE_MAGIC (line 10) | const EXECUTABLE_MAGIC = ['~PSP', '\x7FELF'];
constant EXECUTABLE_MAGIC_OFFSET (line 11) | const EXECUTABLE_MAGIC_OFFSET = 0;
constant MAIN_EXECUTABLE_PATH (line 13) | const MAIN_EXECUTABLE_PATH = '/PSP_GAME/SYSDIR/EBOOT.BIN';
constant UNENCRYPTED_EXECUTABLE_PATH (line 14) | const UNENCRYPTED_EXECUTABLE_PATH = '/PSP_GAME/SYSDIR/BOOT.BIN';
constant PARAM_SFO_PATH (line 16) | const PARAM_SFO_PATH = '/PSP_GAME/PARAM.SFO';
constant ALTERNATIVE_EXECUTABLE_PATHS (line 23) | const ALTERNATIVE_EXECUTABLE_PATHS = [
constant OTHER_ALTERNATIVE_EXECUTABLE_PATHS (line 47) | const OTHER_ALTERNATIVE_EXECUTABLE_PATHS = [
function getFileSystem (line 52) | async function getFileSystem(isoArrayBuffer, name) {
function fileExists (line 70) | async function fileExists(fs, path) {
function readFile (line 84) | async function readFile(fs, path) {
function getGameId (line 90) | async function getGameId(fs) {
function findFirstPathThatExists (line 104) | async function findFirstPathThatExists(fs, pathsArray) {
function getExecutable (line 115) | async function getExecutable(fs, gameId) {
class PspIso (line 187) | class PspIso {
method Create (line 188) | static async Create(isoArrayBuffer, name) {
method constructor (line 197) | constructor(executableInfo) {
method getExecutableInfo (line 201) | getExecutableInfo() {
FILE: frontend/src/rom-formats/SegaSaturnCueBin.js
constant MAGIC (line 6) | const MAGIC = 'SEGA SEGASATURN ';
constant MAGIC_OFFSET (line 7) | const MAGIC_OFFSET = 0x10;
constant MAGIC_ENCODING (line 8) | const MAGIC_ENCODING = 'US-ASCII';
constant GAME_ID_OFFSET (line 10) | const GAME_ID_OFFSET = 0x30;
constant GAME_ID_LENGTH (line 11) | const GAME_ID_LENGTH = 0x10;
constant GAME_ID_ENCODING (line 12) | const GAME_ID_ENCODING = 'US-ASCII';
class SegaSaturnCueBin (line 14) | class SegaSaturnCueBin {
method constructor (line 15) | constructor(binArrayBuffer) {
method getGameId (line 23) | getGameId() {
method getFileExtensions (line 27) | static getFileExtensions() {
FILE: frontend/src/rom-formats/gb.js
constant INTERNAL_NAME_OFFSET (line 6) | const INTERNAL_NAME_OFFSET = 0x134;
constant INTERNAL_NAME_LENGTH_GB (line 7) | const INTERNAL_NAME_LENGTH_GB = 0x10;
constant INTERNAL_NAME_LENGTH_GBC (line 8) | const INTERNAL_NAME_LENGTH_GBC = 0xB;
constant INTERNAL_NAME_ENCODING (line 9) | const INTERNAL_NAME_ENCODING = 'US-ASCII';
constant GBC_FLAG_OFFSET (line 11) | const GBC_FLAG_OFFSET = 0x143;
constant GBC_FLAG_GB_AND_GBC (line 12) | const GBC_FLAG_GB_AND_GBC = 0x80;
constant GBC_FLAG_GBC_ONLY (line 13) | const GBC_FLAG_GBC_ONLY = 0xC0;
constant CARTRIDGE_TYPE_OFFSET (line 15) | const CARTRIDGE_TYPE_OFFSET = 0x147;
constant SRAM_SIZE_OFFSET (line 16) | const SRAM_SIZE_OFFSET = 0x149;
constant CARTRIDGE_TYPE_MBC2 (line 18) | const CARTRIDGE_TYPE_MBC2 = 0x5;
constant CARTRIDGE_TYPE_MBC2_PLUS_BATTERY (line 19) | const CARTRIDGE_TYPE_MBC2_PLUS_BATTERY = 0x6;
function isMbc2 (line 21) | function isMbc2(cartridgeType) {
function getSramSize (line 25) | function getSramSize(sramValue, cartridgeType) {
class GbRom (line 55) | class GbRom {
method constructor (line 56) | constructor(romArrayBuffer) {
method getInternalName (line 70) | getInternalName() {
method getRomArrayBuffer (line 74) | getRomArrayBuffer() {
method getIsGbc (line 78) | getIsGbc() {
method getCartridgeType (line 82) | getCartridgeType() {
method getSramSize (line 86) | getSramSize() {
method getFileExtensions (line 90) | static getFileExtensions() {
FILE: frontend/src/rom-formats/gba.js
constant INTERNAL_NAME_OFFSET (line 4) | const INTERNAL_NAME_OFFSET = 0xA0;
constant INTERNAL_NAME_LENGTH (line 5) | const INTERNAL_NAME_LENGTH = 0x10;
constant CHECKSUM_OFFSET (line 6) | const CHECKSUM_OFFSET = 0xBE;
constant COMPLIMENT_CHECK_OFFSET (line 7) | const COMPLIMENT_CHECK_OFFSET = 0xBD;
constant MAKER_OFFSET (line 8) | const MAKER_OFFSET = 0xB0;
constant LITTLE_ENDIAN (line 9) | const LITTLE_ENDIAN = true;
class GbaRom (line 11) | class GbaRom {
method constructor (line 12) | constructor(romArrayBuffer) {
method getInternalName (line 25) | getInternalName() {
method getChecksum (line 29) | getChecksum() {
method getComplimentCheck (line 33) | getComplimentCheck() {
method getMaker (line 37) | getMaker() {
FILE: frontend/src/rom-formats/nes.js
constant LITTLE_ENDIAN (line 9) | const LITTLE_ENDIAN = true;
constant HEADER_LENGTH (line 11) | const HEADER_LENGTH = 16;
constant MAGIC_OFFSET (line 13) | const MAGIC_OFFSET = 0;
constant MAGIC (line 14) | const MAGIC = 0x1A53454E;
class NesRom (line 16) | class NesRom {
method constructor (line 17) | constructor(romArrayBuffer) {
method getIsNes20Header (line 34) | getIsNes20Header() {
method getRomArrayBufferWithHeader (line 38) | getRomArrayBufferWithHeader() {
method getRomArrayBufferWithoutHeader (line 42) | getRomArrayBufferWithoutHeader() {
method getFileExtensions (line 46) | static getFileExtensions() {
FILE: frontend/src/rom-formats/sms.js
constant LITTLE_ENDIAN (line 9) | const LITTLE_ENDIAN = true;
constant MAGIC_OFFSET (line 11) | const MAGIC_OFFSET = 0x7FF0;
constant MAGIC (line 12) | const MAGIC = 'TMR SEGA';
constant MAGIC_ENCODING (line 13) | const MAGIC_ENCODING = 'US-ASCII';
constant CHECKSUM_OFFSET (line 15) | const CHECKSUM_OFFSET = 0x7FFA;
class SmsRom (line 17) | class SmsRom {
method constructor (line 18) | constructor(romArrayBuffer) {
method getChecksum (line 28) | getChecksum() {
method getFileExtensions (line 32) | static getFileExtensions() {
FILE: frontend/src/save-formats/Dreamcast/Components/Basics.js
class DreamcastBasics (line 1) | class DreamcastBasics {
FILE: frontend/src/save-formats/Dreamcast/Components/Directory.js
constant DIRECTORY_PADDING_VALUE (line 23) | const DIRECTORY_PADDING_VALUE = 0x00;
constant MAX_DIRECTORY_ENTRIES (line 25) | const MAX_DIRECTORY_ENTRIES = SAVE_AREA_SIZE_IN_BLOCKS;
constant DIRECTORY_ENTRY_LENGTH (line 26) | const DIRECTORY_ENTRY_LENGTH = DreamcastDirectoryEntry.LENGTH;
class DreamcastDirectory (line 28) | class DreamcastDirectory {
method writeDirectory (line 29) | static writeDirectory(saveFilesWithBlockInfo) {
method readDirectory (line 39) | static readDirectory(arrayBuffer) {
FILE: frontend/src/save-formats/Dreamcast/Components/DirectoryEntry.js
constant FILE_TYPE_OFFSET (line 37) | const FILE_TYPE_OFFSET = 0x00;
constant COPY_PROTECT_OFFSET (line 38) | const COPY_PROTECT_OFFSET = 0x01;
constant FIRST_BLOCK_NUMBER_OFFSET (line 39) | const FIRST_BLOCK_NUMBER_OFFSET = 0x02;
constant FILENAME_OFFSET (line 40) | const FILENAME_OFFSET = 0x04;
constant FILENAME_LENGTH (line 41) | const FILENAME_LENGTH = 12;
constant FILENAME_ENCODING (line 42) | const FILENAME_ENCODING = 'shift-jis';
constant FILE_CREATION_TIME_OFFSET (line 43) | const FILE_CREATION_TIME_OFFSET = 0x10;
constant FILE_SIZE_IN_BLOCKS_OFFSET (line 44) | const FILE_SIZE_IN_BLOCKS_OFFSET = 0x18;
constant FILE_HEADER_BLOCK_NUMBER_OFFSET (line 45) | const FILE_HEADER_BLOCK_NUMBER_OFFSET = 0x1A;
constant FILE_TYPE_LOOKUP (line 47) | const FILE_TYPE_LOOKUP = {
constant UNKNOWN_FILE_TYPE_STRING (line 53) | const UNKNOWN_FILE_TYPE_STRING = 'Unknown';
constant UNKNOWN_FILE_TYPE (line 54) | const UNKNOWN_FILE_TYPE = 0xFF;
constant POSSIBLE_FILE_TYPES (line 56) | const POSSIBLE_FILE_TYPES = Object.keys(FILE_TYPE_LOOKUP);
constant COPY_PROTECT_COPY_OKAY (line 58) | const COPY_PROTECT_COPY_OKAY = 0x00;
constant COPY_PROTECT_NO_COPY (line 59) | const COPY_PROTECT_NO_COPY = 0xFF;
constant DIRECTORY_ENTRY_PADDING_VALUE (line 61) | const DIRECTORY_ENTRY_PADDING_VALUE = 0x00;
constant DIRECTORY_ENTRY_LENGTH (line 63) | const DIRECTORY_ENTRY_LENGTH = 32;
constant FILE_HEADER_COMMENT_ENCODING (line 65) | const FILE_HEADER_COMMENT_ENCODING = 'shift-jis';
constant FILE_HEADER_STORAGE_COMMENT_OFFSET (line 66) | const FILE_HEADER_STORAGE_COMMENT_OFFSET = 0x00;
constant FILE_HEADER_STORAGE_COMMENT_LENGTH (line 67) | const FILE_HEADER_STORAGE_COMMENT_LENGTH = 0x10;
constant FILE_HEADER_FILE_COMMENT_OFFSET (line 68) | const FILE_HEADER_FILE_COMMENT_OFFSET = 0x10;
constant FILE_HEADER_FILE_COMMENT_LENGTH (line 69) | const FILE_HEADER_FILE_COMMENT_LENGTH = 0x30;
function getFileTypeString (line 71) | function getFileTypeString(fileType) {
function getFileTypeValue (line 79) | function getFileTypeValue(fileTypeString) {
class DreamcastDirectoryEntry (line 89) | class DreamcastDirectoryEntry {
method writeDirectoryEntry (line 92) | static writeDirectoryEntry(saveFile) {
method getComments (line 109) | static getComments(fileHeaderBlockNumber, rawData) {
method readDirectoryEntry (line 127) | static readDirectoryEntry(arrayBuffer) {
FILE: frontend/src/save-formats/Dreamcast/Components/FileAllocationTable.js
constant UNALLOCATED_BLOCK (line 33) | const UNALLOCATED_BLOCK = 0xFFFC;
constant LAST_BLOCK_IN_FILE (line 34) | const LAST_BLOCK_IN_FILE = 0xFFFA;
constant BLOCK_PHYSICALLY_DAMAGED (line 35) | const BLOCK_PHYSICALLY_DAMAGED = 0xFFFF;
constant PADDING_VALUE (line 37) | const PADDING_VALUE = 0x00;
class DreamcastFileAllocationTable (line 39) | class DreamcastFileAllocationTable {
method writeFileAllocationTable (line 46) | static writeFileAllocationTable(gameFilesWithBlockInfo, dataFilesWithB...
method readFileAllocationTable (line 86) | static readFileAllocationTable(arrayBuffer) {
FILE: frontend/src/save-formats/Dreamcast/Components/SystemInfo.js
constant MAGIC_OFFSET (line 51) | const MAGIC_OFFSET = 0;
constant MAGIC_LENGTH (line 52) | const MAGIC_LENGTH = 0x10;
constant MAGIC_VALUE (line 53) | const MAGIC_VALUE = 0x55;
constant MAGIC_BYTES (line 54) | const MAGIC_BYTES = new Uint8Array(Util.getFilledArrayBuffer(MAGIC_LENGT...
constant USE_CUSTOM_COLOR_OFFSET (line 56) | const USE_CUSTOM_COLOR_OFFSET = 0x10;
constant CUSTOM_COLOR_BLUE_OFFSET (line 57) | const CUSTOM_COLOR_BLUE_OFFSET = 0x11;
constant CUSTOM_COLOR_GREEN_OFFSET (line 58) | const CUSTOM_COLOR_GREEN_OFFSET = 0x12;
constant CUSTOM_COLOR_RED_OFFSET (line 59) | const CUSTOM_COLOR_RED_OFFSET = 0x13;
constant CUSTOM_COLOR_ALPHA_OFFSET (line 60) | const CUSTOM_COLOR_ALPHA_OFFSET = 0x14;
constant TIMESTAMP_OFFSET (line 61) | const TIMESTAMP_OFFSET = 0x30;
constant LARGEST_BLOCK_NUMBER_OFFSET (line 62) | const LARGEST_BLOCK_NUMBER_OFFSET = 0x40;
constant PARTITION_NUMBER_OFFSET (line 63) | const PARTITION_NUMBER_OFFSET = 0x42;
constant SYSTEM_INFO_BLOCK_NUMBER_OFFSET (line 64) | const SYSTEM_INFO_BLOCK_NUMBER_OFFSET = 0x44;
constant FILE_ALLOCATION_TABLE_BLOCK_NUMBER_OFFSET (line 65) | const FILE_ALLOCATION_TABLE_BLOCK_NUMBER_OFFSET = 0x46;
constant FILE_ALLOCATION_TABLE_SIZE_IN_BLOCKS_OFFSET (line 66) | const FILE_ALLOCATION_TABLE_SIZE_IN_BLOCKS_OFFSET = 0x48;
constant DIRECTORY_BLOCK_NUMBER_OFFSET (line 67) | const DIRECTORY_BLOCK_NUMBER_OFFSET = 0x4A;
constant DIRECTORY_SIZE_IN_BLOCKS_OFFSET (line 68) | const DIRECTORY_SIZE_IN_BLOCKS_OFFSET = 0x4C;
constant ICON_SHAPE_OFFSET (line 69) | const ICON_SHAPE_OFFSET = 0x4E;
constant SAVE_AREA_SIZE_IN_BLOCKS_OFFSET (line 70) | const SAVE_AREA_SIZE_IN_BLOCKS_OFFSET = 0x50;
constant EXTRA_AREA_SIZE_IN_BLOCKS_OFFSET (line 71) | const EXTRA_AREA_SIZE_IN_BLOCKS_OFFSET = 0x52;
constant GAME_BLOCK_OFFSET (line 72) | const GAME_BLOCK_OFFSET = 0x54;
constant MAX_GAME_SIZE_OFFSET (line 73) | const MAX_GAME_SIZE_OFFSET = 0x56;
constant DEFAULT_PARTITION_NUMBER (line 75) | const DEFAULT_PARTITION_NUMBER = 0;
constant PADDING_VALUE (line 77) | const PADDING_VALUE = 0x00;
class DreamcastSystemInfo (line 79) | class DreamcastSystemInfo {
method writeSystemInfo (line 80) | static writeSystemInfo(volumeInfo) {
method readSystemInfo (line 126) | static readSystemInfo(arrayBuffer) {
FILE: frontend/src/save-formats/Dreamcast/Dreamcast.js
constant FILL_VALUE (line 46) | const FILL_VALUE = 0x00;
function concatBlocks (line 48) | function concatBlocks(blockNumbers, arrayBuffer) {
function getBlocks (line 54) | function getBlocks(blockNumber, sizeInBlocks, arrayBuffer) {
function getBlocksForward (line 64) | function getBlocksForward(blockNumber, sizeInBlocks, arrayBuffer) {
function createBlocksForward (line 70) | function createBlocksForward(arrayBuffer) {
function createBlocks (line 85) | function createBlocks(arrayBuffer) {
function getBlockNumbers (line 91) | function getBlockNumbers(directoryEntry, fileAllocationTable) {
function getSaveFileWithBlockInfo (line 120) | function getSaveFileWithBlockInfo(saveFile, currentBlockNumber) {
function getGameFilesWithBlockInfo (line 130) | function getGameFilesWithBlockInfo(gameFiles) {
function getDataFilesWithBlockInfo (line 142) | function getDataFilesWithBlockInfo(dataFiles) {
function splitArray (line 154) | function splitArray(array, predicate) {
class DreamcastSaveData (line 168) | class DreamcastSaveData {
method createFromDreamcastData (line 169) | static createFromDreamcastData(arrayBuffer) {
method createFromSaveFiles (line 211) | static createFromSaveFiles(saveFiles, volumeInfo) {
method constructor (line 262) | constructor(arrayBuffer, saveFiles, volumeInfo) {
method getSaveFiles (line 268) | getSaveFiles() {
method getVolumeInfo (line 272) | getVolumeInfo() {
method getArrayBuffer (line 276) | getArrayBuffer() {
FILE: frontend/src/save-formats/Dreamcast/IndividualSaves/Dci.js
constant DATA_OFFSET (line 23) | const DATA_OFFSET = DreamcastDirectoryEntry.LENGTH;
constant DEFAULT_FIRST_BLOCK_NUMBER (line 25) | const DEFAULT_FIRST_BLOCK_NUMBER = 0;
class DreamcastDciSaveData (line 27) | class DreamcastDciSaveData {
method convertSaveFileToDci (line 28) | static convertSaveFileToDci(saveFile) {
method convertIndividualSaveToSaveFile (line 40) | static convertIndividualSaveToSaveFile(arrayBuffer, checkSaveSize = fa...
FILE: frontend/src/save-formats/Dreamcast/IndividualSaves/VmiVms.js
constant ENCODING (line 33) | const ENCODING = 'shift-jis';
constant HEADER_LENGTH (line 40) | const HEADER_LENGTH = 108;
constant CHECKSUM_OFFSET (line 42) | const CHECKSUM_OFFSET = 0;
constant CHECKSUM_LITTLE_ENDIAN (line 43) | const CHECKSUM_LITTLE_ENDIAN = false;
constant CHECKSUM_MASK (line 44) | const CHECKSUM_MASK = 'SEGA';
constant DESCRIPTION_OFFSET (line 45) | const DESCRIPTION_OFFSET = 0x04;
constant DESCRIPTION_LENGTH (line 46) | const DESCRIPTION_LENGTH = 32;
constant COPYRIGHT_OFFSET (line 47) | const COPYRIGHT_OFFSET = 0x24;
constant COPYRIGHT_LENGTH (line 48) | const COPYRIGHT_LENGTH = 32;
constant TIMESTAMP_OFFSET (line 49) | const TIMESTAMP_OFFSET = 0x44;
constant VERSION_OFFSET (line 50) | const VERSION_OFFSET = 0x4C;
constant FILE_NUMBER_OFFSET (line 51) | const FILE_NUMBER_OFFSET = 0x4E;
constant RESOURCE_NAME_OFFSET (line 52) | const RESOURCE_NAME_OFFSET = 0x50;
constant RESOURCE_NAME_LENGTH (line 53) | const RESOURCE_NAME_LENGTH = 8;
constant FILE_NAME_OFFSET (line 54) | const FILE_NAME_OFFSET = 0x58;
constant FILE_NAME_LENGTH (line 55) | const FILE_NAME_LENGTH = 12;
constant FILE_MODE_OFFSET (line 56) | const FILE_MODE_OFFSET = 0x64;
constant FILE_SIZE_OFFSET (line 57) | const FILE_SIZE_OFFSET = 0x68;
constant FILE_MODE_GAME (line 59) | const FILE_MODE_GAME = 0x02;
constant FILE_MODE_COPY_PROTECTED (line 60) | const FILE_MODE_COPY_PROTECTED = 0x01;
constant FILE_MODE_NONE (line 61) | const FILE_MODE_NONE = 0x00;
constant DEFAULT_HEADER_FILL_VALUE (line 63) | const DEFAULT_HEADER_FILL_VALUE = 0x00;
constant DEFAULT_VERSION (line 65) | const DEFAULT_VERSION = 0;
constant DEFAULT_FILE_NUMBER (line 66) | const DEFAULT_FILE_NUMBER = 1;
constant DEFAULT_FIRST_BLOCK_NUMBER (line 68) | const DEFAULT_FIRST_BLOCK_NUMBER = 0;
constant HEADER_BLOCK_NUMBER_FOR_DATA (line 70) | const HEADER_BLOCK_NUMBER_FOR_DATA = 0;
constant HEADER_BLOCK_NUMBER_FOR_GAME (line 71) | const HEADER_BLOCK_NUMBER_FOR_GAME = 1;
function calculateChecksum (line 74) | function calculateChecksum(resourceName) {
class DreamcastVmiVmsSaveData (line 87) | class DreamcastVmiVmsSaveData {
method convertSaveFileToVmiVms (line 98) | static convertSaveFileToVmiVms(saveFile) {
method convertIndividualSaveToSaveFile (line 135) | static convertIndividualSaveToSaveFile(vmiArrayBuffer, vmsArrayBuffer) {
FILE: frontend/src/save-formats/Dreamcast/Util.js
constant TIMESTAMP_YEAR_OFFSET (line 9) | const TIMESTAMP_YEAR_OFFSET = 0;
constant TIMESTAMP_MONTH_OFFSET (line 10) | const TIMESTAMP_MONTH_OFFSET = 2;
constant TIMESTAMP_DAY_OFFSET (line 11) | const TIMESTAMP_DAY_OFFSET = 3;
constant TIMESTAMP_HOUR_OFFSET (line 12) | const TIMESTAMP_HOUR_OFFSET = 4;
constant TIMESTAMP_MINUTE_OFFSET (line 13) | const TIMESTAMP_MINUTE_OFFSET = 5;
constant TIMESTAMP_SECOND_OFFSET (line 14) | const TIMESTAMP_SECOND_OFFSET = 6;
constant TIMESTAMP_DAY_OF_WEEK_OFFSET (line 15) | const TIMESTAMP_DAY_OF_WEEK_OFFSET = 7;
constant BCD_TIMESTAMP_CENTURY_OFFSET (line 17) | const BCD_TIMESTAMP_CENTURY_OFFSET = 0;
constant BCD_TIMESTAMP_YEAR_WITHIN_CENTURY_OFFSET (line 18) | const BCD_TIMESTAMP_YEAR_WITHIN_CENTURY_OFFSET = 1;
constant TIMESTAMP_LENGTH (line 20) | const TIMESTAMP_LENGTH = 8;
function readBcdByte (line 22) | function readBcdByte(val) {
function writeBcdByte (line 29) | function writeBcdByte(val) {
function formatDateWithoutTimezone (line 36) | function formatDateWithoutTimezone(date) {
class DreamcastUtil (line 49) | class DreamcastUtil {
method readTimestamp (line 50) | static readTimestamp(arrayBuffer, offset) {
method writeTimestamp (line 67) | static writeTimestamp(arrayBuffer, offset, date) {
method readBcdTimestamp (line 86) | static readBcdTimestamp(arrayBuffer, offset) {
method writeBcdTimestamp (line 109) | static writeBcdTimestamp(arrayBuffer, offset, date) {
method formatDateWithoutTimezone (line 129) | static formatDateWithoutTimezone(date) {
FILE: frontend/src/save-formats/FlashCarts/GB.js
class GbFlashCartSaveData (line 3) | class GbFlashCartSaveData {
method createFromFlashCartData (line 4) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 8) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 12) | static createWithNewSize(gbFlashCartSaveData, newSize) {
method getFlashCartFileExtension (line 18) | static getFlashCartFileExtension() {
method getRawFileExtension (line 22) | static getRawFileExtension() {
method requiresRom (line 26) | static requiresRom() {
method adjustOutputSizesPlatform (line 30) | static adjustOutputSizesPlatform() {
method constructor (line 34) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 39) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 43) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/GBA/EmulatorBase.js
constant LITTLE_ENDIAN (line 14) | const LITTLE_ENDIAN = true;
constant MAGIC_OFFSET (line 16) | const MAGIC_OFFSET = 0;
constant MAGIC_LENGTH (line 17) | const MAGIC_LENGTH = 4;
constant SIZE_OFFSET (line 21) | const SIZE_OFFSET = 0;
constant TYPE_OFFSET (line 23) | const TYPE_OFFSET = 2;
constant TYPE_SAVE_STATE (line 24) | const TYPE_SAVE_STATE = 0;
constant TYPE_SRAM_SAVE (line 25) | const TYPE_SRAM_SAVE = 1;
constant TYPE_CONFIG_DATA (line 26) | const TYPE_CONFIG_DATA = 2;
constant TYPE_PALETTE (line 27) | const TYPE_PALETTE = 5;
constant UNCOMPRESSED_SIZE_OFFSET (line 29) | const UNCOMPRESSED_SIZE_OFFSET = 4;
constant FRAME_COUNT_OFFSET (line 30) | const FRAME_COUNT_OFFSET = 8;
constant ROM_CHECKSUM_OFFSET (line 31) | const ROM_CHECKSUM_OFFSET = 12;
constant GAME_TITLE_OFFSET (line 33) | const GAME_TITLE_OFFSET = 16;
constant GAME_TITLE_LENGTH (line 34) | const GAME_TITLE_LENGTH = 32;
constant GAME_TITLE_ENCODING (line 35) | const GAME_TITLE_ENCODING = 'US-ASCII';
constant STATE_HEADER_TYPE_NAMES (line 37) | const STATE_HEADER_TYPE_NAMES = {
constant STATE_HEADER_LENGTH (line 44) | const STATE_HEADER_LENGTH = GAME_TITLE_OFFSET + GAME_TITLE_LENGTH;
constant LARGEST_GBC_SAVE_SIZE (line 46) | const LARGEST_GBC_SAVE_SIZE = 0x10000;
constant GOOMBA_COLOR_AVAILABLE_SIZE (line 66) | const GOOMBA_COLOR_AVAILABLE_SIZE = 0xE000;
constant GOOMBA_COLOR_SMALLER_AVAILABLE_SIZE (line 67) | const GOOMBA_COLOR_SMALLER_AVAILABLE_SIZE = 0x6000;
constant GOOMBA_COLOR_SRAM_SIZE (line 69) | const GOOMBA_COLOR_SRAM_SIZE = 0x10000;
function readStateHeader (line 71) | function readStateHeader(arrayBuffer) {
function createStateHeaderArrayBuffer (line 85) | function createStateHeaderArrayBuffer(stateHeader) {
function stateHeaderIsPlausible (line 108) | function stateHeaderIsPlausible(stateHeader) {
function createMagicArrayBuffer (line 132) | function createMagicArrayBuffer(magic, length) {
function createEmulatorArrayBuffer (line 141) | function createEmulatorArrayBuffer(rawArrayBuffer, romInternalName, romC...
function findStateHeaderOfType (line 169) | function findStateHeaderOfType(arrayBuffer, stateHeaderType) {
class EmulatorBaseSaveData (line 198) | class EmulatorBaseSaveData {
method createFromRawDataInternal (line 205) | static createFromRawDataInternal(rawArrayBuffer, romInternalName, romC...
method getFlashCartFileExtension (line 211) | static getFlashCartFileExtension() {
method getRawFileExtension (line 215) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 219) | static adjustOutputSizesPlatform() {
method constructor (line 223) | constructor(emulatorArrayBuffer) {
method getSramRomChecksumFromConfigData (line 286) | getSramRomChecksumFromConfigData(arrayBuffer) {
method calculateRomChecksum (line 299) | static calculateRomChecksum(romArrayBuffer) {
method saveDataIsCompressed (line 322) | static saveDataIsCompressed() {
method getRawArrayBuffer (line 326) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 330) | getFlashCartArrayBuffer() {
method getCompressedSize (line 334) | getCompressedSize() {
method getUncompressedSize (line 338) | getUncompressedSize() {
method getGameTitle (line 342) | getGameTitle() {
method getRomChecksum (line 346) | getRomChecksum() {
method getFrameCount (line 350) | getFrameCount() {
FILE: frontend/src/save-formats/FlashCarts/GBA/GBA.js
class GbaFlashCartSaveData (line 3) | class GbaFlashCartSaveData {
method createFromFlashCartData (line 4) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 8) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 12) | static createWithNewSize(gbaFlashCartSaveData, newSize) {
method getFlashCartFileExtension (line 18) | static getFlashCartFileExtension() {
method getRawFileExtension (line 22) | static getRawFileExtension() {
method requiresRom (line 26) | static requiresRom() {
method adjustOutputSizesPlatform (line 30) | static adjustOutputSizesPlatform() {
method constructor (line 34) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 39) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 43) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/GBA/GoombaEmulator.js
constant GOOMBA_MAGIC (line 7) | const GOOMBA_MAGIC = 0x57A731D8;
constant GOOMBA_CONFIG_DATA_SIZE_OFFSET (line 9) | const GOOMBA_CONFIG_DATA_SIZE_OFFSET = 0;
constant GOOMBA_CONFIG_DATA_TYPE_OFFSET (line 10) | const GOOMBA_CONFIG_DATA_TYPE_OFFSET = 2;
constant GOOMBA_CONFIG_DATA_BORDER_COLOR_OFFSET (line 11) | const GOOMBA_CONFIG_DATA_BORDER_COLOR_OFFSET = 4;
constant GOOMBA_CONFIG_DATA_PALETTE_BANK_OFFSET (line 12) | const GOOMBA_CONFIG_DATA_PALETTE_BANK_OFFSET = 5;
constant GOOMBA_CONFIG_DATA_SRAM_ROM_CHECKSUM_OFFSET (line 13) | const GOOMBA_CONFIG_DATA_SRAM_ROM_CHECKSUM_OFFSET = 8;
constant GOOMBA_CONFIG_DATA_RESERVED_OFFSET (line 14) | const GOOMBA_CONFIG_DATA_RESERVED_OFFSET = 16;
constant GOOMBA_CONFIG_DATA_RESERVED_LENGTH (line 15) | const GOOMBA_CONFIG_DATA_RESERVED_LENGTH = 32;
constant GOOMBA_CONFIG_DATA_RESERVED_DATA (line 16) | const GOOMBA_CONFIG_DATA_RESERVED_DATA = 'CFG';
constant GOOMBA_CONFIG_DATA_RESERVED_ENCODING (line 17) | const GOOMBA_CONFIG_DATA_RESERVED_ENCODING = 'US-ASCII';
constant GOOMBA_CONFIG_DATA_LENGTH (line 18) | const GOOMBA_CONFIG_DATA_LENGTH = GOOMBA_CONFIG_DATA_RESERVED_OFFSET + G...
constant GOOMBA_CONFIG_DATA_DEFAULT_BORDER_COLOR (line 20) | const GOOMBA_CONFIG_DATA_DEFAULT_BORDER_COLOR = 0;
constant GOOMBA_CONFIG_DATA_DEFAULT_PALETTE_BANK (line 21) | const GOOMBA_CONFIG_DATA_DEFAULT_PALETTE_BANK = 0;
class GoombaEmulatorSaveData (line 23) | class GoombaEmulatorSaveData extends EmulatorBase {
method getMagic (line 24) | static getMagic() {
method getConfigDataLength (line 28) | static getConfigDataLength() {
method createFromRawData (line 32) | static createFromRawData(rawArrayBuffer, romArrayBuffer) {
method createFromRawDataInternal (line 41) | static createFromRawDataInternal(rawArrayBuffer, romInternalName, romC...
method createFromFlashCartData (line 45) | static createFromFlashCartData(goombaArrayBuffer) {
method requiresRom (line 49) | static requiresRom() {
method createEmptyConfigDataArrayBuffer (line 57) | static createEmptyConfigDataArrayBuffer() {
method getPlatformSramRomChecksumFromConfigData (line 79) | static getPlatformSramRomChecksumFromConfigData(arrayBuffer, currentBy...
method concatEmulatorArrayBuffer (line 85) | static concatEmulatorArrayBuffer(magicArrayBuffer, stateHeaderArrayBuf...
FILE: frontend/src/save-formats/FlashCarts/GBA/PocketNesEmulator.js
constant POCKETNES_MAGIC (line 9) | const POCKETNES_MAGIC = 0x57A731D7;
constant POCKETNES_CONFIG_DATA_SIZE_OFFSET (line 11) | const POCKETNES_CONFIG_DATA_SIZE_OFFSET = 0;
constant POCKETNES_CONFIG_DATA_TYPE_OFFSET (line 12) | const POCKETNES_CONFIG_DATA_TYPE_OFFSET = 2;
constant POCKETNES_CONFIG_DATA_DISPLAY_TYPE_OFFSET (line 13) | const POCKETNES_CONFIG_DATA_DISPLAY_TYPE_OFFSET = 4;
constant POCKETNES_CONFIG_DATA_MISC_OFFSET (line 14) | const POCKETNES_CONFIG_DATA_MISC_OFFSET = 5;
constant POCKETNES_CONFIG_DATA_SRAM_ROM_CHECKSUM_OFFSET (line 15) | const POCKETNES_CONFIG_DATA_SRAM_ROM_CHECKSUM_OFFSET = 8;
constant POCKETNES_CONFIG_DATA_RESERVED_OFFSET (line 16) | const POCKETNES_CONFIG_DATA_RESERVED_OFFSET = 16;
constant POCKETNES_CONFIG_DATA_RESERVED_LENGTH (line 17) | const POCKETNES_CONFIG_DATA_RESERVED_LENGTH = 32;
constant POCKETNES_CONFIG_DATA_RESERVED_DATA (line 18) | const POCKETNES_CONFIG_DATA_RESERVED_DATA = 'CFG';
constant POCKETNES_CONFIG_DATA_RESERVED_ENCODING (line 19) | const POCKETNES_CONFIG_DATA_RESERVED_ENCODING = 'US-ASCII';
constant POCKETNES_CONFIG_DATA_LENGTH (line 20) | const POCKETNES_CONFIG_DATA_LENGTH = POCKETNES_CONFIG_DATA_RESERVED_OFFS...
constant DEFAULT_SCALING (line 34) | const DEFAULT_SCALING = 3;
constant DEFAULT_GAMMA (line 35) | const DEFAULT_GAMMA = 0;
constant DEFAULT_AUTOSLEEP_TIME (line 37) | const DEFAULT_AUTOSLEEP_TIME = 0;
constant DEFAULT_AUTOSTATE (line 38) | const DEFAULT_AUTOSTATE = 0;
constant DEFAULT_FLICKER (line 39) | const DEFAULT_FLICKER = 1;
constant POCKETNES_CONFIG_DATA_DEFAULT_DISPLAY_TYPE (line 41) | const POCKETNES_CONFIG_DATA_DEFAULT_DISPLAY_TYPE = ((DEFAULT_GAMMA & 0x7...
constant POCKETNES_CONFIG_DATA_DEFAULT_MISC (line 42) | const POCKETNES_CONFIG_DATA_DEFAULT_MISC = (((DEFAULT_FLICKER & 0x1) ^ 1...
constant GAME_TITLE (line 44) | const GAME_TITLE = 'SAVE';
class PocketNesEmulatorSaveData (line 46) | class PocketNesEmulatorSaveData extends EmulatorBase {
method getMagic (line 49) | static getMagic() {
method getConfigDataLength (line 53) | static getConfigDataLength() {
method createFromRawData (line 57) | static createFromRawData(rawArrayBuffer, romArrayBuffer) {
method createFromRawDataInternal (line 63) | static createFromRawDataInternal(rawArrayBuffer, romChecksum) { // es-...
method createFromFlashCartData (line 67) | static createFromFlashCartData(pocketNesArrayBuffer) {
method requiresRom (line 71) | static requiresRom() {
method createEmptyConfigDataArrayBuffer (line 79) | static createEmptyConfigDataArrayBuffer() {
method getPlatformSramRomChecksumFromConfigData (line 101) | static getPlatformSramRomChecksumFromConfigData(arrayBuffer, currentBy...
method calculateRomChecksum (line 107) | static calculateRomChecksum(romArrayBuffer) {
method concatEmulatorArrayBuffer (line 120) | static concatEmulatorArrayBuffer(magicArrayBuffer, stateHeaderArrayBuf...
FILE: frontend/src/save-formats/FlashCarts/GBA/SmsAdvanceEmulator.js
constant SMSADVANCE_MAGIC (line 9) | const SMSADVANCE_MAGIC = 0x57A731DC;
constant SMSADVANCE_CONFIG_DATA_SIZE_OFFSET (line 11) | const SMSADVANCE_CONFIG_DATA_SIZE_OFFSET = 0;
constant SMSADVANCE_CONFIG_DATA_TYPE_OFFSET (line 12) | const SMSADVANCE_CONFIG_DATA_TYPE_OFFSET = 2;
constant SMSADVANCE_CONFIG_DATA_DISPLAY_TYPE_OFFSET (line 13) | const SMSADVANCE_CONFIG_DATA_DISPLAY_TYPE_OFFSET = 4;
constant SMSADVANCE_CONFIG_DATA_GAMMA_VALUE_OFFSET (line 14) | const SMSADVANCE_CONFIG_DATA_GAMMA_VALUE_OFFSET = 5;
constant SMSADVANCE_CONFIG_DATA_REGION_OFFSET (line 15) | const SMSADVANCE_CONFIG_DATA_REGION_OFFSET = 6;
constant SMSADVANCE_CONFIG_DATA_SLEEP_FLICK_OFFSET (line 16) | const SMSADVANCE_CONFIG_DATA_SLEEP_FLICK_OFFSET = 7;
constant SMSADVANCE_CONFIG_DATA_CONFIG_OFFSET (line 17) | const SMSADVANCE_CONFIG_DATA_CONFIG_OFFSET = 8;
constant SMSADVANCE_CONFIG_DATA_BORDER_COLOR_OFFSET (line 18) | const SMSADVANCE_CONFIG_DATA_BORDER_COLOR_OFFSET = 9;
constant SMSADVANCE_CONFIG_DATA_SRAM_ROM_CHECKSUM_OFFSET (line 19) | const SMSADVANCE_CONFIG_DATA_SRAM_ROM_CHECKSUM_OFFSET = 12;
constant SMSADVANCE_CONFIG_DATA_RESERVED_OFFSET (line 20) | const SMSADVANCE_CONFIG_DATA_RESERVED_OFFSET = 20;
constant SMSADVANCE_CONFIG_DATA_RESERVED_LENGTH (line 21) | const SMSADVANCE_CONFIG_DATA_RESERVED_LENGTH = 32;
constant SMSADVANCE_CONFIG_DATA_RESERVED_DATA (line 22) | const SMSADVANCE_CONFIG_DATA_RESERVED_DATA = 'CFG';
constant SMSADVANCE_CONFIG_DATA_RESERVED_ENCODING (line 23) | const SMSADVANCE_CONFIG_DATA_RESERVED_ENCODING = 'US-ASCII';
constant SMSADVANCE_CONFIG_DATA_LENGTH (line 24) | const SMSADVANCE_CONFIG_DATA_LENGTH = SMSADVANCE_CONFIG_DATA_RESERVED_OF...
constant SMSADVANCE_CONFIG_DATA_DEFAULT_DISPLAY_TYPE (line 27) | const SMSADVANCE_CONFIG_DATA_DEFAULT_DISPLAY_TYPE = 3;
constant SMSADVANCE_CONFIG_DATA_DEFAULT_GAMMA_VALUE (line 28) | const SMSADVANCE_CONFIG_DATA_DEFAULT_GAMMA_VALUE = 2;
constant SMSADVANCE_CONFIG_DATA_DEFAULT_REGION (line 29) | const SMSADVANCE_CONFIG_DATA_DEFAULT_REGION = 0;
constant SMSADVANCE_CONFIG_DATA_DEFAULT_SLEEP_FLICK (line 30) | const SMSADVANCE_CONFIG_DATA_DEFAULT_SLEEP_FLICK = 0;
constant SMSADVANCE_CONFIG_DATA_DEFAULT_CONFIG (line 31) | const SMSADVANCE_CONFIG_DATA_DEFAULT_CONFIG = 0x40;
constant SMSADVANCE_CONFIG_DATA_DEFAULT_BORDER_COLOR (line 32) | const SMSADVANCE_CONFIG_DATA_DEFAULT_BORDER_COLOR = 0;
constant GAME_TITLE (line 34) | const GAME_TITLE = 'Made with savefileconverter.com';
class SmsAdvanceEmulatorSaveData (line 36) | class SmsAdvanceEmulatorSaveData extends EmulatorBase {
method getMagic (line 39) | static getMagic() {
method getConfigDataLength (line 43) | static getConfigDataLength() {
method getFlashCartFileExtension (line 47) | static getFlashCartFileExtension() {
method getRawFileExtension (line 51) | static getRawFileExtension() {
method createFromRawData (line 55) | static createFromRawData(rawArrayBuffer, romArrayBuffer) {
method createFromRawDataInternal (line 61) | static createFromRawDataInternal(rawArrayBuffer, romChecksum) { // es-...
method createFromFlashCartData (line 65) | static createFromFlashCartData(flashCartArrayBuffer) {
method requiresRom (line 69) | static requiresRom() {
method createEmptyConfigDataArrayBuffer (line 77) | static createEmptyConfigDataArrayBuffer() {
method getPlatformSramRomChecksumFromConfigData (line 105) | static getPlatformSramRomChecksumFromConfigData(arrayBuffer, currentBy...
method concatEmulatorArrayBuffer (line 111) | static concatEmulatorArrayBuffer(magicArrayBuffer, stateHeaderArrayBuf...
method getUncompressedSize (line 117) | getUncompressedSize() {
FILE: frontend/src/save-formats/FlashCarts/GameGear.js
class GameGearFlashCartSaveData (line 3) | class GameGearFlashCartSaveData {
method createFromFlashCartData (line 4) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 8) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 12) | static createWithNewSize(flashCartSaveData, newSize) {
method getFlashCartFileExtension (line 18) | static getFlashCartFileExtension() {
method getRawFileExtension (line 22) | static getRawFileExtension() {
method requiresRom (line 26) | static requiresRom() {
method adjustOutputSizesPlatform (line 30) | static adjustOutputSizesPlatform() {
method constructor (line 34) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 39) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 43) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/Genesis/MegaEverdrivePro/32X.js
class GenesisMegaEverdrivePro32xFlashCartSaveData (line 3) | class GenesisMegaEverdrivePro32xFlashCartSaveData extends GenesisMegaEve...
FILE: frontend/src/save-formats/FlashCarts/Genesis/MegaEverdrivePro/Genesis.js
constant FILL_BYTE (line 4) | const FILL_BYTE = 0x00;
class GenesisMegaEverdriveProGenesisFlashCartSaveData (line 6) | class GenesisMegaEverdriveProGenesisFlashCartSaveData {
method createFromFlashCartData (line 7) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 13) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 22) | static createWithNewSize(flashCartSaveData, newSize) {
method getFlashCartFileExtension (line 28) | static getFlashCartFileExtension() {
method getRawFileExtension (line 32) | static getRawFileExtension() {
method requiresRom (line 36) | static requiresRom() {
method adjustOutputSizesPlatform (line 40) | static adjustOutputSizesPlatform() {
method constructor (line 44) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 49) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 53) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/Genesis/MegaEverdrivePro/NES.js
class GenesisMegaEverdriveProNesFlashCartSaveData (line 3) | class GenesisMegaEverdriveProNesFlashCartSaveData {
method createFromFlashCartData (line 4) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 8) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 12) | static createWithNewSize(flashCartSaveData, newSize) {
method getFlashCartFileExtension (line 18) | static getFlashCartFileExtension() {
method getRawFileExtension (line 22) | static getRawFileExtension() {
method requiresRom (line 26) | static requiresRom() {
method adjustOutputSizesPlatform (line 30) | static adjustOutputSizesPlatform() {
method constructor (line 34) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 39) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 43) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/Genesis/MegaEverdrivePro/SMS.js
class GenesisMegaEverdriveProSmsFlashCartSaveData (line 13) | class GenesisMegaEverdriveProSmsFlashCartSaveData {
method createFromFlashCartData (line 14) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 24) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 28) | static createWithNewSize(flashCartSaveData, newSize) {
method getFlashCartFileExtension (line 34) | static getFlashCartFileExtension() {
method getRawFileExtension (line 38) | static getRawFileExtension() {
method requiresRom (line 42) | static requiresRom() {
method adjustOutputSizesPlatform (line 46) | static adjustOutputSizesPlatform() {
method constructor (line 50) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 55) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 59) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/Genesis/MegaEverdrivePro/SegaCd.js
class GenesisMegaEverdriveProSegaCdFlashCartSaveData (line 3) | class GenesisMegaEverdriveProSegaCdFlashCartSaveData {
method createFromFlashCartData (line 12) | static createFromFlashCartData({ flashCartInternalSaveArrayBuffer = nu...
method createFromRawData (line 38) | static createFromRawData({ rawInternalSaveArrayBuffer = null, rawRamCa...
method createWithNewSize (line 64) | static createWithNewSize(flashCartSaveData, newSize) {
method getFlashCartFileExtension (line 75) | static getFlashCartFileExtension() {
method getFlashCartFileName (line 79) | static getFlashCartFileName(index = GenesisMegaEverdriveProSegaCdFlash...
method getRawFileExtension (line 92) | static getRawFileExtension() {
method requiresRom (line 96) | static requiresRom() {
method adjustOutputSizesPlatform (line 100) | static adjustOutputSizesPlatform() {
method getRawDefaultRamCartSize (line 104) | static getRawDefaultRamCartSize() {
method getFlashCartDefaultRamCartSize (line 108) | static getFlashCartDefaultRamCartSize() {
method constructor (line 112) | constructor(flashCartInternalSaveArrayBuffer, flashCartRamCartSaveArra...
method getRawArrayBuffer (line 119) | getRawArrayBuffer(index = GenesisMegaEverdriveProSegaCdFlashCartSaveDa...
method getFlashCartArrayBuffer (line 132) | getFlashCartArrayBuffer(index = GenesisMegaEverdriveProSegaCdFlashCart...
FILE: frontend/src/save-formats/FlashCarts/Genesis/MegaSD/32X.js
constant MEGA_SD_NEW_STYLE_PADDING_BYTE_SRAM (line 3) | const MEGA_SD_NEW_STYLE_PADDING_BYTE_SRAM = 0x00;
constant MEGA_SD_NEW_STYLE_PADDING_BYTE_EEPROM (line 4) | const MEGA_SD_NEW_STYLE_PADDING_BYTE_EEPROM = 0x00;
constant PLATFORM_INFO (line 6) | const PLATFORM_INFO = {
class GenesisMegaSd32xFlashCartSaveData (line 13) | class GenesisMegaSd32xFlashCartSaveData extends GenesisBase {
method createFromRawData (line 14) | static createFromRawData(rawArrayBuffer) {
method createFromFlashCartData (line 18) | static createFromFlashCartData(flashCartArrayBuffer) {
method createWithNewSize (line 22) | static createWithNewSize(flashCartSaveData, newSize) {
FILE: frontend/src/save-formats/FlashCarts/Genesis/MegaSD/Genesis.js
constant MEGA_SD_NEW_STYLE_PADDING_BYTE_SRAM (line 3) | const MEGA_SD_NEW_STYLE_PADDING_BYTE_SRAM = 0x00;
constant MEGA_SD_NEW_STYLE_PADDING_BYTE_EEPROM (line 4) | const MEGA_SD_NEW_STYLE_PADDING_BYTE_EEPROM = 0xFF;
constant PLATFORM_INFO (line 6) | const PLATFORM_INFO = {
class GenesisMegaSdGenesisFlashCartSaveData (line 13) | class GenesisMegaSdGenesisFlashCartSaveData extends GenesisBase {
method createFromRawData (line 14) | static createFromRawData(rawArrayBuffer) {
method createFromFlashCartData (line 18) | static createFromFlashCartData(flashCartArrayBuffer) {
method createWithNewSize (line 22) | static createWithNewSize(flashCartSaveData, newSize) {
FILE: frontend/src/save-formats/FlashCarts/Genesis/MegaSD/GenesisBase.js
constant MAGIC (line 16) | const MAGIC = 'BUP2';
constant MAGIC_OFFSET (line 17) | const MAGIC_OFFSET = 0;
constant MAGIC_ENCODING (line 18) | const MAGIC_ENCODING = 'US-ASCII';
constant MEGA_SD_NEW_STYLE_PADDED_SIZE (line 20) | const MEGA_SD_NEW_STYLE_PADDED_SIZE = 32768;
constant RAW_FILL_BYTE (line 23) | const RAW_FILL_BYTE = 0x00;
constant RAW_EEPROM_MIN_SIZE (line 25) | const RAW_EEPROM_MIN_SIZE = 128;
constant RAW_SRAM_MIN_SIZE (line 26) | const RAW_SRAM_MIN_SIZE = 16384;
function isNewStyleSave (line 31) | function isNewStyleSave(flashCartArrayBuffer) {
function isOldStyleSave (line 41) | function isOldStyleSave(flashCartArrayBuffer) {
function isRawSave (line 47) | function isRawSave(rawArrayBuffer) {
function convertFromOldStyleToRaw (line 51) | function convertFromOldStyleToRaw(flashCartArrayBuffer) {
function convertFromNewStyleToRaw (line 64) | function convertFromNewStyleToRaw(flashCartArrayBuffer) {
function convertFromRawToNewStyle (line 80) | function convertFromRawToNewStyle(rawArrayBuffer, platformInfo) {
class GenesisMegaSdGenesisFlashCartSaveData (line 100) | class GenesisMegaSdGenesisFlashCartSaveData {
method isRawSave (line 103) | static isRawSave(rawArrayBuffer) {
method convertFromRawToNewStyle (line 107) | static convertFromRawToNewStyle(rawArrayBuffer, paddingByteSram, paddi...
method createFromFlashCartData (line 111) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 123) | static createFromRawData(rawArrayBuffer, platformInfo) {
method createWithNewSize (line 133) | static createWithNewSize(flashCartSaveData, newSize, platformInfo) {
method getFlashCartFileExtension (line 139) | static getFlashCartFileExtension() {
method getRawFileExtension (line 143) | static getRawFileExtension() {
method requiresRom (line 147) | static requiresRom() {
method adjustOutputSizesPlatform (line 151) | static adjustOutputSizesPlatform() {
method constructor (line 155) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 160) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 164) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/Genesis/MegaSD/SMS.js
constant MAGIC (line 11) | const MAGIC = 'BUP2';
constant MAGIC_OFFSET (line 12) | const MAGIC_OFFSET = 0;
constant MAGIC_ENCODING (line 13) | const MAGIC_ENCODING = 'US-ASCII';
function isNewStyleSave (line 15) | function isNewStyleSave(flashCartArrayBuffer) {
function isOldStyleSave (line 25) | function isOldStyleSave(flashCartArrayBuffer) {
function convertFromNewStyleToRaw (line 29) | function convertFromNewStyleToRaw(flashCartArrayBuffer) {
function convertFromRawToNewStyle (line 33) | function convertFromRawToNewStyle(rawArrayBuffer) {
class GenesisMegaSdSmsFlashCartSaveData (line 40) | class GenesisMegaSdSmsFlashCartSaveData {
method createFromFlashCartData (line 41) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 54) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 58) | static createWithNewSize(flashCartSaveData, newSize) {
method getFlashCartFileExtension (line 64) | static getFlashCartFileExtension() {
method getRawFileExtension (line 68) | static getRawFileExtension() {
method requiresRom (line 72) | static requiresRom() {
method adjustOutputSizesPlatform (line 76) | static adjustOutputSizesPlatform() {
method constructor (line 80) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 85) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 89) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/Genesis/MegaSD/SegaCd.js
constant MAGIC (line 16) | const MAGIC = 'BUP3';
constant MAGIC_OFFSET (line 17) | const MAGIC_OFFSET = 0;
constant MAGIC_ENCODING (line 18) | const MAGIC_ENCODING = 'US-ASCII';
constant INTERNAL_MEMORY_OFFSET (line 20) | const INTERNAL_MEMORY_OFFSET = 4;
constant RAM_CART_OFFSET (line 21) | const RAM_CART_OFFSET = INTERNAL_MEMORY_OFFSET + SegaCdUtil.INTERNAL_SAV...
class GenesisMegaSdSegaCdFlashCartSaveData (line 23) | class GenesisMegaSdSegaCdFlashCartSaveData {
method createFromFlashCartData (line 32) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 72) | static createFromRawData({ rawInternalSaveArrayBuffer = null, rawRamCa...
method createWithNewSize (line 102) | static createWithNewSize(flashCartSaveData, newSize) {
method getFlashCartFileExtension (line 112) | static getFlashCartFileExtension() {
method getRawFileExtension (line 116) | static getRawFileExtension() {
method requiresRom (line 120) | static requiresRom() {
method adjustOutputSizesPlatform (line 124) | static adjustOutputSizesPlatform() {
method getRawDefaultRamCartSize (line 128) | static getRawDefaultRamCartSize() {
method getFlashCartDefaultRamCartSize (line 132) | static getFlashCartDefaultRamCartSize() {
method constructor (line 136) | constructor(flashCartArrayBuffer, rawInternalSaveArrayBuffer, rawRamCa...
method getRawArrayBuffer (line 142) | getRawArrayBuffer(index = GenesisMegaSdSegaCdFlashCartSaveData.INTERNA...
method getFlashCartArrayBuffer (line 155) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/N64/GB64Emulator.js
constant LITTLE_ENDIAN (line 72) | const LITTLE_ENDIAN = false;
constant MAGIC (line 74) | const MAGIC = 'GB64';
constant MAGIC_OFFSET (line 75) | const MAGIC_OFFSET = 0;
constant MAGIC_ENCODING (line 76) | const MAGIC_ENCODING = 'US-ASCII';
constant VERSION_OFFSET (line 78) | const VERSION_OFFSET = 4;
constant FLAGS_OFFSET (line 79) | const FLAGS_OFFSET = 8;
constant BGP_INDEX_OFFSET (line 80) | const BGP_INDEX_OFFSET = 10;
constant OBP0_INDEX_OFFSET (line 81) | const OBP0_INDEX_OFFSET = 12;
constant OBP1_INDEX_OFFSET (line 82) | const OBP1_INDEX_OFFSET = 14;
constant INPUT_MAPPING_OFFSET (line 83) | const INPUT_MAPPING_OFFSET = 16;
constant INPUT_MAPPING_LENGTH (line 84) | const INPUT_MAPPING_LENGTH = 16;
constant GRAPHICS_SETTINGS_OFFSET (line 85) | const GRAPHICS_SETTINGS_OFFSET = 32;
constant TIMER_OFFSET (line 86) | const TIMER_OFFSET = 40;
constant STORED_INFO_TYPE_OFFSET (line 87) | const STORED_INFO_TYPE_OFFSET = 48;
constant COMPRESSED_SIZE_OFFSET (line 88) | const COMPRESSED_SIZE_OFFSET = 52;
constant GAMEBOY_STATE_DATA_OFFSET (line 89) | const GAMEBOY_STATE_DATA_OFFSET = 0x80;
constant HEADER_SIZE (line 91) | const HEADER_SIZE = GAMEBOY_STATE_DATA_OFFSET;
constant HEADER_FILL_VALUE (line 92) | const HEADER_FILL_VALUE = 0x00;
constant FILE_LENGTH (line 94) | const FILE_LENGTH = 0x20000;
constant FILE_PADDING_VALUE (line 95) | const FILE_PADDING_VALUE = 0xAA;
constant DESIRED_VERSION (line 97) | const DESIRED_VERSION = 2;
constant DEFAULT_FLAGS (line 99) | const DEFAULT_FLAGS = 0x0000;
constant DEFAULT_BGP_INDEX (line 100) | const DEFAULT_BGP_INDEX = 0;
constant DEFAULT_OBP0_INDEX (line 101) | const DEFAULT_OBP0_INDEX = 0;
constant DEFAULT_OBP1_INDEX (line 102) | const DEFAULT_OBP1_INDEX = 0;
constant DEFAULT_GRAPHICS_SETTINGS (line 103) | const DEFAULT_GRAPHICS_SETTINGS = 0x00000002;
constant DEFAULT_TIMER (line 104) | const DEFAULT_TIMER = 0x02C445F9n;
constant STORED_INFO_TYPE_ALL (line 106) | const STORED_INFO_TYPE_ALL = 0;
constant STORED_INFO_TYPE_SETTINGS (line 109) | const STORED_INFO_TYPE_SETTINGS = 3;
constant STORED_INFO_TYPE_NONE (line 110) | const STORED_INFO_TYPE_NONE = 4;
constant GAMEBOY_STATE_DATA_SRAM_OFFSET (line 112) | const GAMEBOY_STATE_DATA_SRAM_OFFSET = 0;
constant GAMEBOY_STATE_DATA_FILL_VALUE (line 113) | const GAMEBOY_STATE_DATA_FILL_VALUE = 0x00;
constant MIN_SRAM_SIZE (line 114) | const MIN_SRAM_SIZE = 8192;
constant GAMEBOY_DATA_DATA_LENGTH_GB (line 116) | const GAMEBOY_DATA_DATA_LENGTH_GB = (25472 - 8192);
constant GAMEBOY_DATA_DATA_LENGTH_GBC (line 117) | const GAMEBOY_DATA_DATA_LENGTH_GBC = (58240 - 8192);
function calculateGameboyStateDataSize (line 131) | function calculateGameboyStateDataSize(isGbc) {
function getDefaultInputMapping (line 155) | function getDefaultInputMapping() {
class Gb64EmulatorSaveData (line 169) | class Gb64EmulatorSaveData {
method createFromFlashCartData (line 170) | static createFromFlashCartData(flashCartArrayBuffer, romArrayBuffer) {
method createFromFlashCartDataInternal (line 176) | static createFromFlashCartDataInternal(flashCartArrayBuffer, sramSize) {
method createFromRawData (line 226) | static createFromRawData(rawArrayBuffer, romArrayBuffer) {
method createFromRawDataInternal (line 232) | static createFromRawDataInternal(rawArrayBuffer, sramLength, isGbc) {
method createWithNewSize (line 271) | static createWithNewSize(gb64EmulatorSaveData, newSize) {
method getFlashCartFileExtension (line 277) | static getFlashCartFileExtension() {
method getRawFileExtension (line 281) | static getRawFileExtension() {
method requiresRom (line 285) | static requiresRom() {
method adjustOutputSizesPlatform (line 292) | static adjustOutputSizesPlatform() {
method constructor (line 296) | constructor(flashCartArrayBuffer, rawArrayBuffer, gameboyStateDataArra...
method getRawArrayBuffer (line 302) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 306) | getFlashCartArrayBuffer() {
method getGameboyStateDataArrayBuffer (line 310) | getGameboyStateDataArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/N64/N64.js
class N64FlashCartSaveData (line 8) | class N64FlashCartSaveData {
method createFromFlashCartData (line 9) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 15) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 21) | static createWithNewSize(n64FlashCartSaveData, newSize) {
method getFlashCartFileExtension (line 27) | static getFlashCartFileExtension() {
method getRawFileExtension (line 31) | static getRawFileExtension() {
method requiresRom (line 35) | static requiresRom() {
method adjustOutputSizesPlatform (line 39) | static adjustOutputSizesPlatform() {
method constructor (line 43) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 48) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 52) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/N64/NES.js
constant PADDED_SIZE (line 12) | const PADDED_SIZE = 131072;
constant PADDING_VALUE (line 13) | const PADDING_VALUE = 0xAA;
function padArrayBuffer (line 15) | function padArrayBuffer(arrayBuffer, paddedSize) {
class N64NesFlashCartSaveData (line 25) | class N64NesFlashCartSaveData {
method createFromFlashCartData (line 26) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 30) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 36) | static createWithNewSize(flashCartSaveData, newSize) {
method getFlashCartFileExtension (line 43) | static getFlashCartFileExtension() {
method getRawFileExtension (line 47) | static getRawFileExtension() {
method requiresRom (line 51) | static requiresRom() {
method adjustOutputSizesPlatform (line 55) | static adjustOutputSizesPlatform() {
method constructor (line 59) | constructor(flashCartArrayBuffer, rawArrayBuffer, originalRawArrayBuff...
method getRawArrayBuffer (line 65) | getRawArrayBuffer() {
method getOriginalRawArrayBuffer (line 69) | getOriginalRawArrayBuffer() {
method getFlashCartArrayBuffer (line 73) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/N64/Neon64Emulator.js
constant LITTLE_ENDIAN (line 22) | const LITTLE_ENDIAN = false;
constant HEADER (line 24) | const HEADER = [
constant FOOTER (line 29) | const FOOTER = [
constant HEADER_OFFSET (line 34) | const HEADER_OFFSET = 0x10000;
constant HEADER_LENGTH (line 35) | const HEADER_LENGTH = HEADER.length * 4;
constant SAVE_OFFSET (line 36) | const SAVE_OFFSET = HEADER_OFFSET + HEADER_LENGTH;
constant SAVE_LENGTH (line 37) | const SAVE_LENGTH = 8192;
constant FOOTER_OFFSET (line 38) | const FOOTER_OFFSET = HEADER_OFFSET + HEADER_LENGTH + SAVE_LENGTH;
constant FILL_BYTE (line 40) | const FILL_BYTE = 0xAA;
constant FILE_LENGTH (line 41) | const FILE_LENGTH = 0x20000;
function checkHeaderAndFooter (line 43) | function checkHeaderAndFooter(flashCartArrayBuffer) {
function fillInHeaderAndFooter (line 54) | function fillInHeaderAndFooter(flashCartArrayBuffer) {
class Neon64EmulatorSaveData (line 61) | class Neon64EmulatorSaveData {
method createFromFlashCartData (line 62) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 72) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 86) | static createWithNewSize(neon64EmulatorSaveData, newSize) {
method getFlashCartFileExtension (line 93) | static getFlashCartFileExtension() {
method getRawFileExtension (line 97) | static getRawFileExtension() {
method requiresRom (line 101) | static requiresRom() {
method adjustOutputSizesPlatform (line 105) | static adjustOutputSizesPlatform() {
method constructor (line 109) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 114) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 118) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/NES.js
class NesFlashCartSaveData (line 3) | class NesFlashCartSaveData {
method createFromFlashCartData (line 4) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 8) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 12) | static createWithNewSize(nesFlashCartSaveData, newSize) {
method getFlashCartFileExtension (line 18) | static getFlashCartFileExtension() {
method getRawFileExtension (line 22) | static getRawFileExtension() {
method requiresRom (line 26) | static requiresRom() {
method adjustOutputSizesPlatform (line 30) | static adjustOutputSizesPlatform() {
method constructor (line 34) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 39) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 43) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/PcEngine.js
class PcEngineFlashCartSaveData (line 3) | class PcEngineFlashCartSaveData {
method createFromFlashCartData (line 4) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 9) | static createFromRawData(rawArrayBuffer) {
method getFlashCartFileExtension (line 14) | static getFlashCartFileExtension() {
method getRawFileExtension (line 18) | static getRawFileExtension() {
method requiresRom (line 22) | static requiresRom() {
method adjustOutputSizesPlatform (line 26) | static adjustOutputSizesPlatform() {
method constructor (line 30) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 35) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 39) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/SMS.js
class SmsFlashCartSaveData (line 3) | class SmsFlashCartSaveData {
method createFromFlashCartData (line 4) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 8) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 12) | static createWithNewSize(flashCartSaveData, newSize) {
method getFlashCartFileExtension (line 18) | static getFlashCartFileExtension() {
method getRawFileExtension (line 22) | static getRawFileExtension() {
method requiresRom (line 26) | static requiresRom() {
method adjustOutputSizesPlatform (line 30) | static adjustOutputSizesPlatform() {
method constructor (line 34) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 39) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 43) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/SNES/GB.js
class SuperGameboyFlashCartSaveData (line 3) | class SuperGameboyFlashCartSaveData {
method createFromFlashCartData (line 4) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 8) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 12) | static createWithNewSize(gbFlashCartSaveData, newSize) {
method getFlashCartFileExtension (line 18) | static getFlashCartFileExtension() {
method getRawFileExtension (line 22) | static getRawFileExtension() {
method requiresRom (line 26) | static requiresRom() {
method adjustOutputSizesPlatform (line 30) | static adjustOutputSizesPlatform() {
method constructor (line 34) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 39) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 43) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/FlashCarts/SNES/SNES.js
class SnesFlashCartSaveData (line 3) | class SnesFlashCartSaveData {
method createFromFlashCartData (line 4) | static createFromFlashCartData(flashCartArrayBuffer) {
method createFromRawData (line 8) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 12) | static createWithNewSize(snesFlashCartSaveData, newSize) {
method getFlashCartFileExtension (line 18) | static getFlashCartFileExtension() {
method getRawFileExtension (line 22) | static getRawFileExtension() {
method requiresRom (line 26) | static requiresRom() {
method adjustOutputSizesPlatform (line 30) | static adjustOutputSizesPlatform() {
method constructor (line 34) | constructor(flashCartArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 39) | getRawArrayBuffer() {
method getFlashCartArrayBuffer (line 43) | getFlashCartArrayBuffer() {
FILE: frontend/src/save-formats/GBA/ActionReplay.js
class ActionReplaySaveData (line 7) | class ActionReplaySaveData {
method createFromActionReplayData (line 8) | static createFromActionReplayData(actionReplayArrayBuffer) {
method createFromEmulatorData (line 12) | static createFromEmulatorData(emulatorArrayBuffer) {
method createWithNewSize (line 16) | static createWithNewSize(actionReplaySaveData, newSize) {
method constructor (line 34) | constructor(arrayBuffer) {
method getRawSaveData (line 38) | getRawSaveData() {
method getArrayBuffer (line 42) | getArrayBuffer() {
FILE: frontend/src/save-formats/GBA/GameShark.js
constant LITTLE_ENDIAN (line 35) | const LITTLE_ENDIAN = true;
constant SHARK_PORT_SAVE (line 36) | const SHARK_PORT_SAVE = 'SharkPortSave';
constant CODE_GBA (line 37) | const CODE_GBA = 0x000f0000;
constant SECOND_HEADER_LENGTH (line 38) | const SECOND_HEADER_LENGTH = 0x1C;
constant SECOND_HEADER_INTERNAL_NAME_LENGTH (line 39) | const SECOND_HEADER_INTERNAL_NAME_LENGTH = 0x10;
function getText (line 41) | function getText(arrayBuffer, dataView, textDecoder, currentByte) {
function copyUint8ArrayUpToMaxLength (line 60) | function copyUint8ArrayUpToMaxLength(copyFrom, maxLength) {
function parseSecondHeader (line 72) | function parseSecondHeader(arrayBuffer, textDecoder) {
function createSecondHeaderFromRom (line 87) | function createSecondHeaderFromRom(romArrayBuffer) {
function createSecondHeaderArrayBuffer (line 101) | function createSecondHeaderArrayBuffer(secondHeader, textEncoder) {
function calculateCrc (line 118) | function calculateCrc(arrayBuffer) {
class GameSharkSaveData (line 136) | class GameSharkSaveData {
method createFromGameSharkData (line 137) | static createFromGameSharkData(gameSharkArrayBuffer) {
method createWithNewSize (line 141) | static createWithNewSize(gameSharkSaveData, newSize) {
method createFromEmulatorData (line 164) | static createFromEmulatorData(emulatorArrayBuffer, title, date, notes,...
method createFromEmulatorDataAndSecondHeader (line 170) | static createFromEmulatorDataAndSecondHeader(emulatorArrayBuffer, titl...
method constructor (line 244) | constructor(arrayBuffer) {
method getTitle (line 333) | getTitle() {
method getDate (line 337) | getDate() {
method getNotes (line 341) | getNotes() {
method getSecondHeader (line 345) | getSecondHeader() {
method getCrc (line 349) | getCrc() {
method getCalculatedCrc (line 353) | getCalculatedCrc() {
method getRawSaveData (line 357) | getRawSaveData() {
method getArrayBuffer (line 361) | getArrayBuffer() {
FILE: frontend/src/save-formats/GBA/GameSharkSP.js
constant LITTLE_ENDIAN (line 16) | const LITTLE_ENDIAN = true;
constant HEADER_START_MARKER (line 17) | const HEADER_START_MARKER = 'ADVSAVEG';
constant HEADER_START_MARKER_POS (line 18) | const HEADER_START_MARKER_POS = 0;
constant TITLE_START_POS (line 19) | const TITLE_START_POS = 12;
constant TITLE_LENGTH (line 20) | const TITLE_LENGTH = 12;
constant NOTES_START_POS (line 21) | const NOTES_START_POS = 44;
constant NOTES_LENGTH (line 22) | const NOTES_LENGTH = 1023;
constant HEADER_END_MARKER (line 23) | const HEADER_END_MARKER = 0x12345678;
constant HEADER_END_MARKER_POS (line 24) | const HEADER_END_MARKER_POS = 1068;
constant HEADER_LENGTH (line 25) | const HEADER_LENGTH = 1072;
function getText (line 27) | function getText(arrayBuffer, startPos, length, textDecoder) {
class GameSharkSpSaveData (line 34) | class GameSharkSpSaveData {
method createFromGameSharkSpData (line 35) | static createFromGameSharkSpData(gameSharkSpArrayBuffer) {
method constructor (line 40) | constructor(arrayBuffer) {
method getTitle (line 71) | getTitle() {
method getNotes (line 75) | getNotes() {
method getRawSaveData (line 79) | getRawSaveData() {
method getArrayBuffer (line 83) | getArrayBuffer() {
FILE: frontend/src/save-formats/GameCube/Components/Basics.js
class GameCubeBasics (line 1) | class GameCubeBasics {
FILE: frontend/src/save-formats/GameCube/Components/BlockAllocationTable.js
constant NUM_BLOCK_ALLOCATION_TABLE_ENTRIES (line 31) | const NUM_BLOCK_ALLOCATION_TABLE_ENTRIES = 0xFFB;
constant BLOCK_ALLOCATION_TABLE_ENTRY_SIZE (line 32) | const BLOCK_ALLOCATION_TABLE_ENTRY_SIZE = 2;
constant DEFAULT_UPDATE_COUNTER (line 34) | const DEFAULT_UPDATE_COUNTER = 0;
constant CHECKSUM_OFFSET (line 36) | const CHECKSUM_OFFSET = 0x0000;
constant CHECKSUM_INVERSE_OFFSET (line 37) | const CHECKSUM_INVERSE_OFFSET = 0x0002;
constant UPDATE_COUNTER_OFFSET (line 38) | const UPDATE_COUNTER_OFFSET = 0x0004;
constant NUM_FREE_BLOCKS_OFFSET (line 39) | const NUM_FREE_BLOCKS_OFFSET = 0x0006;
constant LAST_ALLOCATED_BLOCK_OFFSET (line 40) | const LAST_ALLOCATED_BLOCK_OFFSET = 0x0008;
constant BLOCK_ALLOCATION_TABLE_OFFSET (line 41) | const BLOCK_ALLOCATION_TABLE_OFFSET = 0x000A;
constant CHECKSUMMED_DATA_BEGIN_OFFSET (line 43) | const CHECKSUMMED_DATA_BEGIN_OFFSET = UPDATE_COUNTER_OFFSET;
constant CHECKSUMMED_DATA_SIZE (line 44) | const CHECKSUMMED_DATA_SIZE = BLOCK_SIZE - CHECKSUMMED_DATA_BEGIN_OFFSET;
constant TABLE_ENTRY_BLOCK_IS_FREE (line 46) | const TABLE_ENTRY_BLOCK_IS_FREE = 0x0000;
constant TABLE_ENTRY_LAST_BLOCK (line 47) | const TABLE_ENTRY_LAST_BLOCK = 0xFFFF;
class GameCubeBlockAllocationTable (line 49) | class GameCubeBlockAllocationTable {
method writeBlockAllocationTable (line 54) | static writeBlockAllocationTable(saveFiles, numTotalBlocks) {
method readBlockAllocationTable (line 108) | static readBlockAllocationTable(arrayBuffer) {
FILE: frontend/src/save-formats/GameCube/Components/Directory.js
constant DIRECTORY_PADDING_VALUE (line 33) | const DIRECTORY_PADDING_VALUE = 0xFF;
constant MAX_DIRECTORY_ENTRIES (line 35) | const MAX_DIRECTORY_ENTRIES = 127;
constant DIRECTORY_ENTRY_LENGTH (line 36) | const DIRECTORY_ENTRY_LENGTH = GameCubeDirectoryEntry.LENGTH;
constant DEFAULT_UPDATE_COUNTER (line 38) | const DEFAULT_UPDATE_COUNTER = 0;
constant UPDATE_COUNTER_OFFSET (line 40) | const UPDATE_COUNTER_OFFSET = 0x1FFA;
constant CHECKSUM_OFFSET (line 41) | const CHECKSUM_OFFSET = 0x1FFC;
constant CHECKSUM_INVERSE_OFFSET (line 42) | const CHECKSUM_INVERSE_OFFSET = 0x1FFE;
constant CHECKSUMMED_DATA_BEGIN_OFFSET (line 43) | const CHECKSUMMED_DATA_BEGIN_OFFSET = 0;
constant CHECKSUMMED_DATA_SIZE (line 44) | const CHECKSUMMED_DATA_SIZE = CHECKSUM_OFFSET - CHECKSUMMED_DATA_BEGIN_O...
class GameCubeDirectory (line 46) | class GameCubeDirectory {
method writeDirectory (line 47) | static writeDirectory(saveFiles) {
method readDirectory (line 74) | static readDirectory(arrayBuffer) {
FILE: frontend/src/save-formats/GameCube/Components/DirectoryEntry.js
constant ENCODING (line 36) | const ENCODING = 'US-ASCII';
constant GAME_CODE_OFFSET (line 38) | const GAME_CODE_OFFSET = 0x00;
constant GAME_CODE_LENGTH (line 39) | const GAME_CODE_LENGTH = 4;
constant REGION_CODE_OFFSET (line 40) | const REGION_CODE_OFFSET = 0x03;
constant REGION_CODE_LENGTH (line 41) | const REGION_CODE_LENGTH = 1;
constant PUBLISHER_CODE_OFFSET (line 42) | const PUBLISHER_CODE_OFFSET = 0x04;
constant PUBLISHER_CODE_LENGTH (line 43) | const PUBLISHER_CODE_LENGTH = 2;
constant BANNER_AND_ICON_FLAGS_OFFSET (line 44) | const BANNER_AND_ICON_FLAGS_OFFSET = 0x07;
constant FILE_NAME_OFFSET (line 45) | const FILE_NAME_OFFSET = 0x08;
constant FILE_NAME_LENGTH (line 46) | const FILE_NAME_LENGTH = 32;
constant DATE_LAST_MODIFIED_OFFSET (line 47) | const DATE_LAST_MODIFIED_OFFSET = 0x28;
constant ICON_START_OFFSET (line 49) | const ICON_START_OFFSET = 0x2C;
constant ICON_FORMAT_OFFSET (line 50) | const ICON_FORMAT_OFFSET = 0x30;
constant ICON_SPEED_OFFSET (line 51) | const ICON_SPEED_OFFSET = 0x32;
constant PERMISSION_ATTRIBUTE_BITFIELD_OFFSET (line 53) | const PERMISSION_ATTRIBUTE_BITFIELD_OFFSET = 0x34;
constant COPY_COUNTER_OFFSET (line 54) | const COPY_COUNTER_OFFSET = 0x35;
constant SAVE_START_BLOCK_OFFSET (line 55) | const SAVE_START_BLOCK_OFFSET = 0x36;
constant SAVE_SIZE_BLOCKS_OFFSET (line 56) | const SAVE_SIZE_BLOCKS_OFFSET = 0x38;
constant COMMENT_START_OFFSET (line 58) | const COMMENT_START_OFFSET = 0x3C;
constant COMMENT_LENGTH (line 59) | const COMMENT_LENGTH = 32;
constant DIRECTORY_ENTRY_LENGTH (line 61) | const DIRECTORY_ENTRY_LENGTH = 0x40;
constant DIRECTORY_ENTRY_PADDING_VALUE (line 62) | const DIRECTORY_ENTRY_PADDING_VALUE = 0xFF;
constant DIRECTORY_ENTRY_FILE_NAME_FILL_VALUE (line 63) | const DIRECTORY_ENTRY_FILE_NAME_FILL_VALUE = 0x00;
class GameCubeDirectoryEntry (line 65) | class GameCubeDirectoryEntry {
method writeDirectoryEntry (line 82) | static writeDirectoryEntry(saveFile) {
method getComments (line 109) | static getComments(commentStart, rawDataArrayBuffer, encoding) {
method readDirectoryEntry (line 120) | static readDirectoryEntry(arrayBuffer) {
FILE: frontend/src/save-formats/GameCube/Components/Header.js
constant HEADER_PADDING_VALUE (line 40) | const HEADER_PADDING_VALUE = 0xFF;
constant SERIAL_OFFSET (line 42) | const SERIAL_OFFSET = 0x0000;
constant SERIAL_LENGTH (line 43) | const SERIAL_LENGTH = 12;
constant FORMAT_OSTIME_OFFSET (line 44) | const FORMAT_OSTIME_OFFSET = 0x000C;
constant RTC_BIAS_OFFSET (line 45) | const RTC_BIAS_OFFSET = 0x0014;
constant LANGUAGE_CODE_OFFSET (line 46) | const LANGUAGE_CODE_OFFSET = 0x0018;
constant VI_DTV_STATUS_OFFSET (line 47) | const VI_DTV_STATUS_OFFSET = 0x001C;
constant MEMCARD_SLOT_OFFSET (line 48) | const MEMCARD_SLOT_OFFSET = 0x0020;
constant MEMCARD_SLOT_A (line 49) | const MEMCARD_SLOT_A = 0;
constant MEMCARD_SLOT_B (line 50) | const MEMCARD_SLOT_B = 1;
constant MEMCARD_SIZE_OFFSET (line 51) | const MEMCARD_SIZE_OFFSET = 0x0022;
constant ENCODING_OFFSET (line 52) | const ENCODING_OFFSET = 0x0024;
constant CHECKSUM_OFFSET (line 53) | const CHECKSUM_OFFSET = 0x01FC;
constant CHECKSUM_INVERSE_OFFSET (line 54) | const CHECKSUM_INVERSE_OFFSET = 0x01FE;
constant CHECKSUMMED_DATA_BEGIN_OFFSET (line 55) | const CHECKSUMMED_DATA_BEGIN_OFFSET = 0;
constant CHECKSUMMED_DATA_SIZE (line 56) | const CHECKSUMMED_DATA_SIZE = CHECKSUM_OFFSET - CHECKSUMMED_DATA_BEGIN_O...
constant DEFAULT_FLASH_ID (line 58) | const DEFAULT_FLASH_ID = Util.getFilledArrayBuffer(SERIAL_LENGTH, 0x00);
function getSerial (line 61) | function getSerial(cardFlashId, formatTime) {
function getCardFlashId (line 79) | function getCardFlashId(serialArrayBuffer, formatTime) {
class GameCubeHeader (line 96) | class GameCubeHeader {
method writeHeader (line 101) | static writeHeader(volumeInfo) {
method readHeader (line 132) | static readHeader(headerBlock) {
FILE: frontend/src/save-formats/GameCube/GameCube.js
constant HEADER_BLOCK_NUMBER (line 31) | const HEADER_BLOCK_NUMBER = 0;
constant DIRECTORY_BLOCK_NUMBER (line 32) | const DIRECTORY_BLOCK_NUMBER = 1;
constant DIRECTORY_BACKUP_BLOCK_NUMBER (line 33) | const DIRECTORY_BACKUP_BLOCK_NUMBER = 2;
constant BLOCK_ALLOCATION_TABLE_BLOCK_NUMBER (line 34) | const BLOCK_ALLOCATION_TABLE_BLOCK_NUMBER = 3;
constant BLOCK_ALLOCATION_TABLE_BACKUP_BLOCK_NUMBER (line 35) | const BLOCK_ALLOCATION_TABLE_BACKUP_BLOCK_NUMBER = 4;
constant BLOCK_PADDING_VALUE (line 37) | const BLOCK_PADDING_VALUE = 0x00;
function getBlock (line 39) | function getBlock(arrayBuffer, blockNumber) {
function createBlocks (line 44) | function createBlocks(numBlocks) {
function getActiveBlock (line 48) | function getActiveBlock(mainInfo, backupInfo) {
function getBlockNumberList (line 100) | function getBlockNumberList(saveStartBlock, blockAllocationTable) {
function getSaveData (line 121) | function getSaveData(saveStartBlock, blockAllocationTable, arrayBuffer) {
function readSaveFiles (line 132) | function readSaveFiles(directoryEntries, blockAllocationTable, arrayBuff...
function checkDesiredSize (line 146) | function checkDesiredSize(sizeBytes) {
class GameCubeSaveData (line 152) | class GameCubeSaveData {
method createWithNewSize (line 153) | static createWithNewSize(gameCubeSaveData, newSize) {
method createWithNewEncoding (line 164) | static createWithNewEncoding(gameCubeSaveData, newEncoding) {
method createFromGameCubeData (line 173) | static createFromGameCubeData(arrayBuffer) {
method createFromSaveFiles (line 209) | static createFromSaveFiles(saveFiles, volumeInfo) {
method constructor (line 272) | constructor(arrayBuffer, saveFiles, volumeInfo) {
method getSaveFiles (line 278) | getSaveFiles() {
method getVolumeInfo (line 282) | getVolumeInfo() {
method getArrayBuffer (line 286) | getArrayBuffer() {
FILE: frontend/src/save-formats/GameCube/GameSpecificFixups/FZeroGx.js
constant CHECKSUM_OFFSET (line 11) | const CHECKSUM_OFFSET = 0;
constant CHECKSUM_LENGTH (line 12) | const CHECKSUM_LENGTH = 2;
class FZeroGxFixups (line 14) | class FZeroGxFixups {
method fixupSaveFile (line 15) | static fixupSaveFile(saveFile, headerSerials) {
FILE: frontend/src/save-formats/GameCube/GameSpecificFixups/GameSpecificFixups.js
constant FIXUP_CLASSES (line 16) | const FIXUP_CLASSES = [
constant HEADER_SERIAL_DATA_LENGTH (line 21) | const HEADER_SERIAL_DATA_LENGTH = 32;
function calculateHeaderSerials (line 27) | function calculateHeaderSerials(headerBlock) {
class GameSpecificFixups (line 41) | class GameSpecificFixups {
method fixupSaveFile (line 42) | static fixupSaveFile(saveFile, headerBlock) {
FILE: frontend/src/save-formats/GameCube/GameSpecificFixups/PhantasyStarOnline.js
constant FILENAME_TO_EXTRA_CHECKSUM_LENGTH (line 11) | const FILENAME_TO_EXTRA_CHECKSUM_LENGTH = new Map([
constant CRC32_LOOK_UP_TABLE_SIZE (line 16) | const CRC32_LOOK_UP_TABLE_SIZE = 256;
constant CRC32_LOOK_UP_TABLE (line 17) | const CRC32_LOOK_UP_TABLE = new Array(CRC32_LOOK_UP_TABLE_SIZE);
function initializeCrc32LookUpTable (line 19) | function initializeCrc32LookUpTable() {
class PhantasyStarOnlineFixups (line 38) | class PhantasyStarOnlineFixups {
method fixupSaveFile (line 39) | static fixupSaveFile(saveFile, headerSerials) {
FILE: frontend/src/save-formats/GameCube/IndividualSaves/GameShark.js
constant HEADER_LENGTH (line 14) | const HEADER_LENGTH = 0x110;
constant MAGIC (line 16) | const MAGIC = 'GCSAVE';
constant MAGIC_OFFSET (line 17) | const MAGIC_OFFSET = 0;
constant MAGIC_ENCODING (line 18) | const MAGIC_ENCODING = 'US-ASCII';
constant COMMENT_OFFSET (line 20) | const COMMENT_OFFSET = 0x10;
constant COMMENT_LENGTH (line 21) | const COMMENT_LENGTH = HEADER_LENGTH - COMMENT_OFFSET;
class GameCubeGameSharkSaveData (line 23) | class GameCubeGameSharkSaveData {
method convertIndividualSaveToSaveFile (line 24) | static convertIndividualSaveToSaveFile(arrayBuffer) {
FILE: frontend/src/save-formats/GameCube/IndividualSaves/Gci.js
constant GAME_CODE_AND_FILE_NAME_ENCODING (line 40) | const GAME_CODE_AND_FILE_NAME_ENCODING = 'US-ASCII';
constant SHIFT_JIS_COMMENT_REGIONS (line 42) | const SHIFT_JIS_COMMENT_REGIONS = ['Japan', 'Korea'];
constant DATA_OFFSET (line 44) | const DATA_OFFSET = GameCubeDirectoryEntry.LENGTH;
constant DEFAULT_START_BLOCK_NUMBER (line 46) | const DEFAULT_START_BLOCK_NUMBER = 0;
class GameCubeGciSaveData (line 48) | class GameCubeGciSaveData {
method convertSaveFilesToGcis (line 49) | static convertSaveFilesToGcis(saveFiles) {
method convertIndividualSaveToSaveFile (line 64) | static convertIndividualSaveToSaveFile(arrayBuffer, checkSaveSizes = t...
FILE: frontend/src/save-formats/GameCube/IndividualSaves/IndividualSaves.js
constant INDIVIDUAL_SAVE_CLASSES (line 12) | const INDIVIDUAL_SAVE_CLASSES = [
class GameCubeIndividualSaves (line 18) | class GameCubeIndividualSaves {
method convertIndividualSaveToSaveFile (line 19) | static convertIndividualSaveToSaveFile(individualSave) {
FILE: frontend/src/save-formats/GameCube/IndividualSaves/MaxDrive.js
constant HEADER_LENGTH (line 14) | const HEADER_LENGTH = 0x80;
constant MAGIC (line 16) | const MAGIC = 'DATELGC_SAVE';
constant MAGIC_OFFSET (line 17) | const MAGIC_OFFSET = 0;
constant MAGIC_ENCODING (line 18) | const MAGIC_ENCODING = 'US-ASCII';
constant COMMENT_OFFSETS (line 20) | const COMMENT_OFFSETS = [0x10, 0x48];
constant COMMENT_LENGTH (line 21) | const COMMENT_LENGTH = 0x38;
constant BYTE_SWAP_OFFSETS (line 23) | const BYTE_SWAP_OFFSETS = [ // https://github.com/dolphin-emu/dolphin/bl...
class GameCubeMaxDriveSaveData (line 37) | class GameCubeMaxDriveSaveData {
method convertIndividualSaveToSaveFile (line 38) | static convertIndividualSaveToSaveFile(arrayBuffer) {
FILE: frontend/src/save-formats/GameCube/Util.js
constant REGION_DECODE (line 12) | const REGION_DECODE = new Map([
constant UNKNOWN_REGION_STRING (line 26) | const UNKNOWN_REGION_STRING = 'Unknown';
constant UNKNOWN_REGION_CODE (line 27) | const UNKNOWN_REGION_CODE = 'X';
constant ENCODING_DECODE (line 30) | const ENCODING_DECODE = new Map([
constant UNKNOWN_ENCODING_STRING (line 35) | const UNKNOWN_ENCODING_STRING = 'Unknown';
constant UNKNOWN_ENCODING_CODE (line 36) | const UNKNOWN_ENCODING_CODE = -1;
constant LANGUAGE_DECODE (line 39) | const LANGUAGE_DECODE = new Map([
constant UNKNOWN_LANGUAGE_STRING (line 48) | const UNKNOWN_LANGUAGE_STRING = 'Unknown';
constant UNKNOWN_LANGUAGE_CODE (line 49) | const UNKNOWN_LANGUAGE_CODE = -1;
constant MILLISECONDS_BETWEEN_EPOCHS (line 52) | const MILLISECONDS_BETWEEN_EPOCHS = 946684800000;
constant OS_BUS_CLOCK (line 57) | const OS_BUS_CLOCK = 162000000n;
constant OS_TIMER_CLOCK (line 58) | const OS_TIMER_CLOCK = OS_BUS_CLOCK / 4n;
function getString (line 60) | function getString(code, decodeMap, unknownString) {
function getCode (line 68) | function getCode(string, decodeMap, unknownCode) {
class GameCubeUtil (line 80) | class GameCubeUtil {
method getRegionString (line 81) | static getRegionString(regionCode) {
method getRegionCode (line 85) | static getRegionCode(regionString) {
method getEncodingString (line 89) | static getEncodingString(encodingCode) {
method getEncodingCode (line 93) | static getEncodingCode(encodingString) {
method getLanguageString (line 97) | static getLanguageString(languageCode) {
method getLanguageCode (line 101) | static getLanguageCode(languageString) {
method getDate (line 105) | static getDate(dateEncoded) {
method getDateCode (line 113) | static getDateCode(date) {
method getDateFromOsTime (line 117) | static getDateFromOsTime(osTime) {
method getOsTimeFromDate (line 123) | static getOsTimeFromDate(date) {
method calculateChecksums (line 130) | static calculateChecksums(arrayBuffer, beginOffset, length) {
method megabitsToBytes (line 159) | static megabitsToBytes(numMegabits) {
method bytesToMegabits (line 163) | static bytesToMegabits(numBytes) {
method getTotalSizes (line 167) | static getTotalSizes(numMegabits) {
FILE: frontend/src/save-formats/Mister/GameGear.js
class MisterGameGearSaveData (line 11) | class MisterGameGearSaveData {
method getMisterFileExtension (line 12) | static getMisterFileExtension() {
method getRawFileExtension (line 16) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 20) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 24) | static createWithNewSize(misterSaveData, newSize) {
method createFromMisterData (line 30) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 34) | static createFromRawData(rawArrayBuffer) {
method constructor (line 39) | constructor(rawArrayBuffer, misterArrayBuffer) {
method getRawArrayBuffer (line 44) | getRawArrayBuffer() {
method getMisterArrayBuffer (line 48) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/Gameboy.js
class MisterGameboySaveData (line 7) | class MisterGameboySaveData {
method getMisterFileExtension (line 8) | static getMisterFileExtension() {
method getRawFileExtension (line 12) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 16) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 20) | static createWithNewSize(misterSaveData, newSize) {
method createFromMisterData (line 26) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 30) | static createFromRawData(rawArrayBuffer) {
method constructor (line 35) | constructor(rawArrayBuffer, misterArrayBuffer) {
method getRawArrayBuffer (line 40) | getRawArrayBuffer() {
method getMisterArrayBuffer (line 44) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/GameboyAdvance.js
constant MISTER_MINIMUM_FILE_SIZE (line 17) | const MISTER_MINIMUM_FILE_SIZE = 8192;
constant MISTER_PADDING_VALUE (line 18) | const MISTER_PADDING_VALUE = 0x00;
class MisterGameboyAdvanceSaveData (line 20) | class MisterGameboyAdvanceSaveData {
method getMisterFileExtension (line 21) | static getMisterFileExtension() {
method getRawFileExtension (line 25) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 29) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 33) | static createWithNewSize(misterSaveData, newSize) {
method createFromMisterData (line 39) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 51) | static createFromRawData(rawArrayBuffer) {
method constructor (line 56) | constructor(rawArrayBuffer, misterArrayBuffer) {
method getRawArrayBuffer (line 61) | getRawArrayBuffer() {
method getMisterArrayBuffer (line 65) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/Genesis.js
constant MISTER_FILE_SIZE (line 15) | const MISTER_FILE_SIZE = 65536;
constant MISTER_PADDING_VALUE (line 16) | const MISTER_PADDING_VALUE = 0xFF;
class MisterGenesisSaveData (line 18) | class MisterGenesisSaveData {
method getMisterFileExtension (line 19) | static getMisterFileExtension() {
method getRawFileExtension (line 23) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 27) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 31) | static createWithNewSize(misterSaveData, newSize) {
method createFromMisterData (line 37) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 63) | static createFromRawData(rawArrayBuffer) {
method constructor (line 89) | constructor(rawArrayBuffer, misterArrayBuffer) {
method getRawArrayBuffer (line 94) | getRawArrayBuffer() {
method getMisterArrayBuffer (line 98) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/N64Cart.js
class MisterN64CartSaveData (line 12) | class MisterN64CartSaveData {
method getMisterFileExtension (line 13) | static getMisterFileExtension(arrayBuffer) {
method getRawFileExtension (line 17) | static getRawFileExtension(arrayBuffer) {
method adjustOutputSizesPlatform (line 21) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 25) | static createWithNewSize(misterSaveData, newSize) {
method createFromMisterData (line 31) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 35) | static createFromRawData(rawArrayBuffer) {
method constructor (line 40) | constructor(rawArrayBuffer, misterArrayBuffer) {
method getRawArrayBuffer (line 45) | getRawArrayBuffer() {
method getMisterArrayBuffer (line 49) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/N64Mempack.js
class MisterN64MempackSaveData (line 7) | class MisterN64MempackSaveData {
method getMisterFileExtension (line 8) | static getMisterFileExtension() {
method getRawFileExtension (line 12) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 16) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 20) | static createWithNewSize(misterSaveData) {
method createFromMisterData (line 24) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 30) | static createFromRawData(rawArrayBuffer) {
method constructor (line 37) | constructor(rawArrayBuffer, misterArrayBuffer) {
method getRawArrayBuffer (line 42) | getRawArrayBuffer() {
method getMisterArrayBuffer (line 46) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/Nes.js
constant MISTER_MINIMUM_FILE_SIZE (line 17) | const MISTER_MINIMUM_FILE_SIZE = 32768;
constant MISTER_PADDING_VALUE (line 18) | const MISTER_PADDING_VALUE = 0x00;
class MisterNesSaveData (line 20) | class MisterNesSaveData {
method getMisterFileExtension (line 21) | static getMisterFileExtension() {
method getRawFileExtension (line 25) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 29) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 33) | static createWithNewSize(misterSaveData, newSize) {
method createFromMisterData (line 39) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 44) | static createFromRawData(rawArrayBuffer) {
method constructor (line 50) | constructor(rawArrayBuffer, misterArrayBuffer) {
method getRawArrayBuffer (line 55) | getRawArrayBuffer() {
method getMisterArrayBuffer (line 59) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/PcEngine.js
class MisterPcEngineSaveData (line 9) | class MisterPcEngineSaveData {
method getMisterFileExtension (line 10) | static getMisterFileExtension() {
method getRawFileExtension (line 14) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 18) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 22) | static createWithNewSize(misterSaveData) {
method createFromMisterData (line 26) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 31) | static createFromRawData(rawArrayBuffer) {
method constructor (line 37) | constructor(rawArrayBuffer, misterArrayBuffer) {
method getRawArrayBuffer (line 42) | getRawArrayBuffer() {
method getMisterArrayBuffer (line 46) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/Ps1.js
class MisterPs1SaveData (line 7) | class MisterPs1SaveData {
method getMisterFileExtension (line 8) | static getMisterFileExtension() {
method getRawFileExtension (line 12) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 16) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 20) | static createWithNewSize(misterSaveData) {
method createFromMisterData (line 24) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 30) | static createFromRawData(rawArrayBuffer) {
method constructor (line 37) | constructor(rawArrayBuffer, misterArrayBuffer) {
method getRawArrayBuffer (line 42) | getRawArrayBuffer() {
method getMisterArrayBuffer (line 46) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/SegaCd.js
class MisterSegaCdSaveData (line 16) | class MisterSegaCdSaveData {
method getMisterFileExtension (line 23) | static getMisterFileExtension() {
method getRawFileExtension (line 27) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 31) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 35) | static createWithNewSize(misterSaveData, newSize) {
method createFromMisterData (line 43) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 60) | static createFromRawData({ rawInternalSaveArrayBuffer = null, rawCartS...
method constructor (line 122) | constructor(rawInternalSaveArrayBuffer, rawCartSaveArrayBuffer, mister...
method getRawArrayBuffer (line 128) | getRawArrayBuffer(index = MisterSegaCdSaveData.INTERNAL_MEMORY) {
method getMisterArrayBuffer (line 141) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/SegaSaturn.js
constant MISTER_INTERNAL_SAVE_SIZE (line 15) | const MISTER_INTERNAL_SAVE_SIZE = SegaSaturnSaveData.INTERNAL_SAVE_SIZE ...
constant MISTER_CARTRIDGE_SAVE_SIZE (line 16) | const MISTER_CARTRIDGE_SAVE_SIZE = SegaSaturnSaveData.CARTRIDGE_SAVE_SIZ...
constant MISTER_PADDING_VALUE (line 18) | const MISTER_PADDING_VALUE = 0xFF;
class MisterSegaSaturnSaveData (line 20) | class MisterSegaSaturnSaveData {
method getMisterFileExtension (line 25) | static getMisterFileExtension() {
method getRawFileExtension (line 29) | static getRawFileExtension(saveType) {
method adjustOutputSizesPlatform (line 33) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 37) | static createWithNewSize(/* misterSaveData, newSize */) {
method createFromMisterData (line 47) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 71) | static createFromRawData({ rawInternalSaveArrayBuffer = null, rawCartS...
method constructor (line 140) | constructor(rawInternalSaveArrayBuffer, rawCartSaveArrayBuffer, mister...
method getRawArrayBuffer (line 146) | getRawArrayBuffer(index = MisterSegaSaturnSaveData.INTERNAL_MEMORY) {
method getMisterArrayBuffer (line 159) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/Sms.js
constant MISTER_MINIMUM_FILE_SIZE (line 11) | const MISTER_MINIMUM_FILE_SIZE = 32768;
constant MISTER_PADDING_VALUE (line 12) | const MISTER_PADDING_VALUE = 0x00;
class MisterSmsSaveData (line 14) | class MisterSmsSaveData {
method getMisterFileExtension (line 15) | static getMisterFileExtension() {
method getRawFileExtension (line 19) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 23) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 27) | static createWithNewSize(misterSaveData, newSize) {
method createFromMisterData (line 33) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 38) | static createFromRawData(rawArrayBuffer) {
method constructor (line 44) | constructor(rawArrayBuffer, misterArrayBuffer) {
method getRawArrayBuffer (line 49) | getRawArrayBuffer() {
method getMisterArrayBuffer (line 53) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/Snes.js
class MisterSnesSaveData (line 7) | class MisterSnesSaveData {
method getMisterFileExtension (line 8) | static getMisterFileExtension() {
method getRawFileExtension (line 12) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 16) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 20) | static createWithNewSize(misterSaveData, newSize) {
method createFromMisterData (line 26) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 30) | static createFromRawData(rawArrayBuffer) {
method constructor (line 35) | constructor(rawArrayBuffer, misterArrayBuffer) {
method getRawArrayBuffer (line 40) | getRawArrayBuffer() {
method getMisterArrayBuffer (line 44) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/Mister/WonderSwan.js
constant MISTER_REALTIME_CLOCK_SIZE (line 10) | const MISTER_REALTIME_CLOCK_SIZE = 0x200;
constant MISTER_PADDING_VALUE (line 11) | const MISTER_PADDING_VALUE = 0x00;
function addUninitializedRealtimeClockData (line 13) | function addUninitializedRealtimeClockData(inputArrayBuffer) {
function removeRealtimeClockData (line 22) | function removeRealtimeClockData(inputArrayBuffer) {
class MisterWonderSwanSaveData (line 30) | class MisterWonderSwanSaveData {
method getMisterFileExtension (line 31) | static getMisterFileExtension() {
method getRawFileExtension (line 35) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 39) | static adjustOutputSizesPlatform() {
method createWithNewSize (line 43) | static createWithNewSize(misterSaveData) {
method createFromMisterData (line 47) | static createFromMisterData(misterArrayBuffer) {
method createFromRawData (line 51) | static createFromRawData(rawArrayBuffer) {
method constructor (line 57) | constructor(rawArrayBuffer, misterArrayBuffer) {
method getRawArrayBuffer (line 62) | getRawArrayBuffer() {
method getMisterArrayBuffer (line 66) | getMisterArrayBuffer() {
FILE: frontend/src/save-formats/N64/Components/Basics.js
class N64Basics (line 3) | class N64Basics {
method createEmptyBlock (line 16) | static createEmptyBlock(size) {
FILE: frontend/src/save-formats/N64/Components/GameSerialCodeUtil.js
constant GAME_SERIAL_CODE_MEDIA_INDEX (line 1) | const GAME_SERIAL_CODE_MEDIA_INDEX = 0;
constant GAME_SERIAL_CODE_REGION_INDEX (line 2) | const GAME_SERIAL_CODE_REGION_INDEX = 3;
constant REGION_CODE_TO_NAME (line 5) | const REGION_CODE_TO_NAME = {
constant GAMESHARK_ACTIONREPLAY_CART_SAVE_GAME_SERIAL_CODE (line 28) | const GAMESHARK_ACTIONREPLAY_CART_SAVE_GAME_SERIAL_CODE = '\x3B\xAD\xD1\...
constant GAMESHARK_ACTIONREPLAY_CART_SAVE_PUBLISHER_CODE (line 29) | const GAMESHARK_ACTIONREPLAY_CART_SAVE_PUBLISHER_CODE = '\xFA\xDE';
constant BLACKBAG_CART_SAVE_GAME_SERIAL_CODE (line 30) | const BLACKBAG_CART_SAVE_GAME_SERIAL_CODE = '\xDE\xAD\xBE\xEF';
constant BLACKBAG_CART_SAVE_PUBLISHER_CODE (line 31) | const BLACKBAG_CART_SAVE_PUBLISHER_CODE = '\x12\x34';
class N64GameSerialCodeUtil (line 33) | class N64GameSerialCodeUtil {
method getRegionCode (line 50) | static getRegionCode(gameSerialCode) {
method getMediaCode (line 54) | static getMediaCode(gameSerialCode) {
method getRegionName (line 58) | static getRegionName(gameSerialCode) {
method isCartSave (line 68) | static isCartSave(saveFile) {
FILE: frontend/src/save-formats/N64/Components/IdArea.js
constant ID_AREA_BLOCK_SIZE (line 12) | const ID_AREA_BLOCK_SIZE = 32;
constant ID_AREA_CHECKSUM_OFFSETS (line 13) | const ID_AREA_CHECKSUM_OFFSETS = [0x20, 0x60, 0x80, 0xC0];
constant ID_AREA_CHECKSUM_LENGTH (line 14) | const ID_AREA_CHECKSUM_LENGTH = 28;
constant ID_AREA_DEVICE_OFFSET (line 15) | const ID_AREA_DEVICE_OFFSET = 25;
constant ID_AREA_BANK_SIZE_OFFSET (line 16) | const ID_AREA_BANK_SIZE_OFFSET = 26;
constant ID_AREA_CHECKSUM_DESIRED_SUM_A_OFFSET (line 17) | const ID_AREA_CHECKSUM_DESIRED_SUM_A_OFFSET = 28;
constant ID_AREA_CHECKSUM_DESIRED_SUM_B_OFFSET (line 18) | const ID_AREA_CHECKSUM_DESIRED_SUM_B_OFFSET = 30;
constant DEVICE_CONTROLLER_PAK (line 19) | const DEVICE_CONTROLLER_PAK = 0x1;
constant BANK_SIZE (line 20) | const BANK_SIZE = 0x1;
function randomByte (line 22) | function randomByte(randomNumberGenerator = null) {
function calculateChecksumsOfBlock (line 29) | function calculateChecksumsOfBlock(arrayBuffer) {
class N64IdArea (line 48) | class N64IdArea {
method createIdAreaPage (line 50) | static createIdAreaPage(randomNumberGenerator = null) {
method checkIdArea (line 91) | static checkIdArea(arrayBuffer) {
FILE: frontend/src/save-formats/N64/Components/InodeTable.js
constant INODE_TABLE_ENTRY_STOP (line 14) | const INODE_TABLE_ENTRY_STOP = 1;
constant INODE_TABLE_ENTRY_EMPTY (line 15) | const INODE_TABLE_ENTRY_EMPTY = 3;
function setNextPageNumber (line 17) | function setNextPageNumber(inodePageDataView, pageNumber, nextPageNumber) {
function getNextPageNumber (line 21) | function getNextPageNumber(inodePageDataView, pageNumber) {
class N64InodeTable (line 25) | class N64InodeTable {
method getNextPageNumber (line 28) | static getNextPageNumber(inodePageDataView, pageNumber) {
method createInodeTablePage (line 32) | static createInodeTablePage(saveFiles) {
method checkIndexes (line 73) | static checkIndexes(inodeArrayBuffer, noteTableKeys) {
FILE: frontend/src/save-formats/N64/Components/NoteTable.js
constant NOTE_TABLE_BLOCK_SIZE (line 17) | const NOTE_TABLE_BLOCK_SIZE = 32;
constant NOTE_TABLE_GAME_SERIAL_CODE_OFFSET (line 18) | const NOTE_TABLE_GAME_SERIAL_CODE_OFFSET = 0;
constant NOTE_TABLE_GAME_SERIAL_CODE_LENGTH (line 19) | const NOTE_TABLE_GAME_SERIAL_CODE_LENGTH = 4;
constant NOTE_TABLE_PUBLISHER_CODE_OFFSET (line 20) | const NOTE_TABLE_PUBLISHER_CODE_OFFSET = 4;
constant NOTE_TABLE_PUBLISHER_CODE_LENGTH (line 21) | const NOTE_TABLE_PUBLISHER_CODE_LENGTH = 2;
constant NOTE_TABLE_STARTING_PAGE_OFFSET (line 22) | const NOTE_TABLE_STARTING_PAGE_OFFSET = 6;
constant NOTE_TABLE_STATUS_OFFSET (line 23) | const NOTE_TABLE_STATUS_OFFSET = 8;
constant NOTE_TABLE_OCCUPIED_BIT (line 24) | const NOTE_TABLE_OCCUPIED_BIT = 0x2;
constant NOTE_TABLE_UNUSED_OFFSET (line 25) | const NOTE_TABLE_UNUSED_OFFSET = 10;
constant NOTE_TABLE_NOTE_NAME_EXTENSION_OFFSET (line 26) | const NOTE_TABLE_NOTE_NAME_EXTENSION_OFFSET = 12;
constant NOTE_TABLE_NOTE_NAME_EXTENSION_LENGTH (line 27) | const NOTE_TABLE_NOTE_NAME_EXTENSION_LENGTH = 4;
constant NOTE_TABLE_NOTE_NAME_OFFSET (line 28) | const NOTE_TABLE_NOTE_NAME_OFFSET = 16;
constant NOTE_TABLE_NOTE_NAME_LENGTH (line 29) | const NOTE_TABLE_NOTE_NAME_LENGTH = 16;
function decodeString (line 31) | function decodeString(uint8Array) {
function encodeString (line 53) | function encodeString(string, encodedLength) {
class N64NoteTable (line 67) | class N64NoteTable {
method createNoteTablePage (line 68) | static createNoteTablePage(saveFilesWithStartingPage) {
method readNoteTable (line 101) | static readNoteTable(inodePageArrayBuffer, noteTableArrayBuffer) {
FILE: frontend/src/save-formats/N64/Components/TextDecoder.js
constant CHARACTER_CODE_LOOKUP (line 8) | const CHARACTER_CODE_LOOKUP = {
constant CHARACTER_LOOKUP (line 45) | const CHARACTER_LOOKUP = invert(CHARACTER_CODE_LOOKUP);
class N64TextDecoder (line 47) | class N64TextDecoder {
method decode (line 48) | static decode(uint8array) {
method encode (line 59) | static encode(string, encodedLength) {
FILE: frontend/src/save-formats/N64/DexDrive.js
constant HEADER_LENGTH (line 24) | const HEADER_LENGTH = 4160;
constant HEADER_MAGIC (line 26) | const HEADER_MAGIC = '123-456-STD';
constant MAGIC_ENCODING (line 27) | const MAGIC_ENCODING = 'US-ASCII';
constant COMMENT_ENCODING (line 29) | const COMMENT_ENCODING = 'US-ASCII';
constant FIRST_COMMENT_OFFSET (line 30) | const FIRST_COMMENT_OFFSET = 64;
constant COMMENT_LENGTH (line 31) | const COMMENT_LENGTH = 256;
function getCommentStartOffset (line 33) | function getCommentStartOffset(i) {
function getComments (line 37) | function getComments(headerArrayBuffer) {
class N64DexDriveSaveData (line 51) | class N64DexDriveSaveData {
method createFromDexDriveData (line 52) | static createFromDexDriveData(dexDriveArrayBuffer, randomNumberGenerat...
method createFromSaveFiles (line 56) | static createFromSaveFiles(saveFiles, randomNumberGenerator = null) {
method constructor (line 97) | constructor(arrayBuffer, randomNumberGenerator = null) {
method getSaveFiles (line 133) | getSaveFiles() {
method getMempack (line 137) | getMempack() {
method getArrayBuffer (line 141) | getArrayBuffer() {
FILE: frontend/src/save-formats/N64/IndividualSaveFilename.js
constant FILENAME_ENCODING (line 6) | const FILENAME_ENCODING = 'utf8';
function parseNoteNameAndExtension (line 8) | function parseNoteNameAndExtension(noteNameAndExtension) {
class N64IndividualSaveFilename (line 27) | class N64IndividualSaveFilename {
method getDisplayName (line 28) | static getDisplayName(saveFile) {
method createFilename (line 36) | static createFilename(saveFile) {
method parseFilename (line 58) | static parseFilename(filename) {
FILE: frontend/src/save-formats/N64/Mempack.js
constant ID_AREA_PAGE (line 33) | const ID_AREA_PAGE = 0;
constant INODE_TABLE_PAGE (line 34) | const INODE_TABLE_PAGE = 1;
constant INODE_TABLE_BACKUP_PAGE (line 35) | const INODE_TABLE_BACKUP_PAGE = 2;
constant NOTE_TABLE_PAGES (line 36) | const NOTE_TABLE_PAGES = [3, 4];
constant MAX_DATA_SIZE (line 38) | const MAX_DATA_SIZE = (NUM_PAGES - FIRST_SAVE_DATA_PAGE) * PAGE_SIZE;
constant CART_SAVE_SIZES (line 49) | const CART_SAVE_SIZES = [
function getPage (line 54) | function getPage(pageNumber, arrayBuffer) {
function concatPages (line 59) | function concatPages(pageNumbers, arrayBuffer) {
function padCartSave (line 67) | function padCartSave(saveFile) {
class N64MempackSaveData (line 94) | class N64MempackSaveData {
method createFromN64MempackData (line 95) | static createFromN64MempackData(mempackArrayBuffer) {
method createFromSaveFiles (line 99) | static createFromSaveFiles(saveFiles, randomNumberGenerator = null) {
method constructor (line 145) | constructor(mempackArrayBuffer) {
method getSaveFiles (line 182) | getSaveFiles() {
method getArrayBuffer (line 186) | getArrayBuffer() {
FILE: frontend/src/save-formats/NintendoSwitchOnline/Gameboy.js
constant MAGIC_OFFSET (line 32) | const MAGIC_OFFSET = 0;
constant MAGIC (line 33) | const MAGIC = [0x53, 0x52, 0x41, 0x4D, 0x03];
constant ROM_HASH_OFFSET (line 35) | const ROM_HASH_OFFSET = 0x08;
constant HASH_ALGORITHM (line 37) | const HASH_ALGORITHM = 'sha1';
constant HASH_LENGTH (line 38) | const HASH_LENGTH = 0x28;
constant HASH_ENCODING (line 39) | const HASH_ENCODING = 'US-ASCII';
constant GIT_REVISION_NUMBER_LENGTH_OFFSET (line 41) | const GIT_REVISION_NUMBER_LENGTH_OFFSET = 0x30;
constant GIT_REVISION_NUMBER_OFFSET (line 42) | const GIT_REVISION_NUMBER_OFFSET = 0x34;
constant NO_RTC_DATA (line 45) | const NO_RTC_DATA = 0x00;
constant HAS_RTC_DATA (line 46) | const HAS_RTC_DATA = 0x01;
constant HAS_RTC_DATA_POTENTIAL_VALUES (line 47) | const HAS_RTC_DATA_POTENTIAL_VALUES = [NO_RTC_DATA, HAS_RTC_DATA];
constant RTC_DATA_LENGTH (line 48) | const RTC_DATA_LENGTH = 0x20;
constant HEADER_FILL_VALUE (line 50) | const HEADER_FILL_VALUE = 0x00;
function getFileInfo (line 52) | function getFileInfo(nsoArrayBuffer) {
class NsoGameboySaveData (line 84) | class NsoGameboySaveData {
method getNsoFileExtension (line 85) | static getNsoFileExtension() {
method getRawFileExtension (line 89) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 93) | static adjustOutputSizesPlatform() {
method nsoDataRequiresRomInfo (line 97) | static nsoDataRequiresRomInfo() {
method createWithNewSize (line 101) | static createWithNewSize(nsoSaveData, newSize) {
method createFromNsoData (line 107) | static createFromNsoData(nsoArrayBuffer) {
method createFromRawData (line 117) | static createFromRawData(rawArrayBuffer, romHashArrayBuffer, gitRevisi...
method constructor (line 150) | constructor(rawArrayBuffer, nsoArrayBuffer, romHashArrayBuffer, gitRev...
method getRawArrayBuffer (line 158) | getRawArrayBuffer() {
method getNsoArrayBuffer (line 162) | getNsoArrayBuffer() {
method getRomHashArrayBuffer (line 166) | getRomHashArrayBuffer() {
method getGitRevisionNumberArrayBuffer (line 170) | getGitRevisionNumberArrayBuffer() {
method getRtcDataArrayBuffer (line 174) | getRtcDataArrayBuffer() {
FILE: frontend/src/save-formats/NintendoSwitchOnline/GameboyAdvance.js
class GbaNsoSaveData (line 5) | class GbaNsoSaveData {
method createFromNsoData (line 6) | static createFromNsoData(nsoArrayBuffer) {
method createFromRawData (line 10) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 14) | static createWithNewSize(nsoSaveData, newSize) {
method getNsoFileExtension (line 20) | static getNsoFileExtension() {
method getRawFileExtension (line 24) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 28) | static adjustOutputSizesPlatform() {
method nsoDataRequiresRomInfo (line 32) | static nsoDataRequiresRomInfo() {
method constructor (line 36) | constructor(nsoArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 41) | getRawArrayBuffer() {
method getNsoArrayBuffer (line 45) | getNsoArrayBuffer() {
FILE: frontend/src/save-formats/NintendoSwitchOnline/Genesis.js
constant EMULATOR_BYTE_EXPAND_FILL_BYTE (line 6) | const EMULATOR_BYTE_EXPAND_FILL_BYTE = 0x00;
class GenesisNsoSaveData (line 8) | class GenesisNsoSaveData {
method createFromNsoData (line 9) | static createFromNsoData(nsoArrayBuffer) {
method createFromRawData (line 21) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 31) | static createWithNewSize(nsoSaveData, newSize) {
method getNsoFileExtension (line 37) | static getNsoFileExtension() {
method getRawFileExtension (line 41) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 45) | static adjustOutputSizesPlatform() {
method nsoDataRequiresRomInfo (line 49) | static nsoDataRequiresRomInfo() {
method constructor (line 53) | constructor(nsoArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 58) | getRawArrayBuffer() {
method getNsoArrayBuffer (line 62) | getNsoArrayBuffer() {
FILE: frontend/src/save-formats/NintendoSwitchOnline/N64.js
class NsoN64SaveData (line 6) | class NsoN64SaveData {
method createFromNsoData (line 7) | static createFromNsoData(nsoArrayBuffer) {
method createFromRawData (line 13) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 19) | static createWithNewSize(n64FlashCartSaveData, newSize) {
method getNsoFileExtension (line 25) | static getNsoFileExtension() {
method getRawFileExtension (line 29) | static getRawFileExtension(rawArrayBuffer) {
method adjustOutputSizesPlatform (line 33) | static adjustOutputSizesPlatform() {
method nsoDataRequiresRomInfo (line 37) | static nsoDataRequiresRomInfo() {
method constructor (line 41) | constructor(nsoArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 46) | getRawArrayBuffer() {
method getNsoArrayBuffer (line 50) | getNsoArrayBuffer() {
FILE: frontend/src/save-formats/NintendoSwitchOnline/Nes.js
constant NSO_NES_FILE_SIZE (line 11) | const NSO_NES_FILE_SIZE = 32768;
constant NSO_NES_PADDING_VALUE (line 12) | const NSO_NES_PADDING_VALUE = 0x00;
constant NES_FILE_SIZE (line 14) | const NES_FILE_SIZE = 8192;
constant HASH_ALGORITHM (line 16) | const HASH_ALGORITHM = 'sha1';
constant HASH_LENGTH (line 17) | const HASH_LENGTH = 40;
constant HASH_ENCODING (line 18) | const HASH_ENCODING = 'US-ASCII';
constant HASH_OFFSET (line 20) | const HASH_OFFSET = 0;
constant DATA_BEGIN_OFFSET (line 21) | const DATA_BEGIN_OFFSET = HASH_OFFSET + HASH_LENGTH;
function padArrayBuffer (line 23) | function padArrayBuffer(inputArrayBuffer) {
class NsoNesSaveData (line 32) | class NsoNesSaveData {
method getNsoFileExtension (line 33) | static getNsoFileExtension() {
method getRawFileExtension (line 37) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 41) | static adjustOutputSizesPlatform() {
method nsoDataRequiresRomInfo (line 45) | static nsoDataRequiresRomInfo() {
method createWithNewSize (line 49) | static createWithNewSize(nsoSaveData, newSize) {
method createFromNsoData (line 55) | static createFromNsoData(nsoArrayBuffer) {
method createFromRawData (line 59) | static createFromRawData(rawArrayBuffer) {
method constructor (line 71) | constructor(rawArrayBuffer, nsoArrayBuffer) {
method getRawArrayBuffer (line 76) | getRawArrayBuffer() {
method getNsoArrayBuffer (line 80) | getNsoArrayBuffer() {
FILE: frontend/src/save-formats/NintendoSwitchOnline/Snes.js
class SnesNsoSaveData (line 5) | class SnesNsoSaveData {
method createFromNsoData (line 6) | static createFromNsoData(nsoArrayBuffer) {
method createFromRawData (line 10) | static createFromRawData(rawArrayBuffer) {
method createWithNewSize (line 14) | static createWithNewSize(nsoSaveData, newSize) {
method getNsoFileExtension (line 20) | static getNsoFileExtension() {
method getRawFileExtension (line 24) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 28) | static adjustOutputSizesPlatform() {
method nsoDataRequiresRomInfo (line 32) | static nsoDataRequiresRomInfo() {
method constructor (line 36) | constructor(nsoArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 41) | getRawArrayBuffer() {
method getNsoArrayBuffer (line 45) | getNsoArrayBuffer() {
FILE: frontend/src/save-formats/OnlineEmulators/Emulators/EmulatorBase.js
class EmulatorBase (line 7) | class EmulatorBase {
method createFromSaveStateData (line 8) | static createFromSaveStateData(emulatorSaveStateArrayBuffer, saveSize,...
method createWithNewSize (line 17) | static createWithNewSize(emulatorSaveStateData, newSize, clazz) {
method constructor (line 26) | constructor(emulatorSaveStateArrayBuffer, rawArrayBuffer, saveSize) {
method getRawArrayBuffer (line 32) | getRawArrayBuffer() {
method getEmulatorSaveStateArrayBuffer (line 36) | getEmulatorSaveStateArrayBuffer() {
method getOriginalSaveSize (line 40) | getOriginalSaveSize() {
FILE: frontend/src/save-formats/OnlineEmulators/Emulators/Gambatte.js
constant LITTLE_ENDIAN (line 17) | const LITTLE_ENDIAN = false;
constant MAGIC (line 19) | const MAGIC = 'sram';
constant MAGIC_OFFSET (line 20) | const MAGIC_OFFSET = 0x747;
constant MAGIC_ENCODING (line 21) | const MAGIC_ENCODING = 'US-ASCII';
constant SAVE_SIZE_OFFSET (line 23) | const SAVE_SIZE_OFFSET = 0x74B;
constant SAVE_OFFSET (line 24) | const SAVE_OFFSET = 0x74F;
class GambatteSaveStateData (line 26) | class GambatteSaveStateData extends EmulatorBase {
method getRawArrayBufferFromSaveStateArrayBuffer (line 27) | static getRawArrayBufferFromSaveStateArrayBuffer(emulatorSaveStateArra...
method createFromSaveStateData (line 45) | static createFromSaveStateData(emulatorSaveStateArrayBuffer, saveSize) {
method createWithNewSize (line 49) | static createWithNewSize(emulatorSaveStateData, newSize) {
method getRawFileExtension (line 53) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 57) | static adjustOutputSizesPlatform() {
method fileSizeIsRequiredToConvert (line 61) | static fileSizeIsRequiredToConvert() {
FILE: frontend/src/save-formats/OnlineEmulators/Emulators/Gb.js
constant SRAM_OFFSET (line 7) | const SRAM_OFFSET = 0x72D;
class GbSaveStateData (line 9) | class GbSaveStateData extends EmulatorBase {
method getRawArrayBufferFromSaveStateArrayBuffer (line 10) | static getRawArrayBufferFromSaveStateArrayBuffer(emulatorSaveStateArra...
method createFromSaveStateData (line 18) | static createFromSaveStateData(emulatorSaveStateArrayBuffer, saveSize) {
method createWithNewSize (line 22) | static createWithNewSize(emulatorSaveStateData, newSize) {
method getRawFileExtension (line 26) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 30) | static adjustOutputSizesPlatform() {
method fileSizeIsRequiredToConvert (line 34) | static fileSizeIsRequiredToConvert() {
FILE: frontend/src/save-formats/OnlineEmulators/Emulators/Snes9x.js
constant MAGIC (line 8) | const MAGIC = 'SRA:';
constant SIZE_END_MAGIC (line 9) | const SIZE_END_MAGIC = ':';
constant MAGIC_ENCODING (line 10) | const MAGIC_ENCODING = 'US-ASCII';
class Snes9xSaveStateData (line 12) | class Snes9xSaveStateData extends EmulatorBase {
method getRawArrayBufferFromSaveStateArrayBuffer (line 13) | static getRawArrayBufferFromSaveStateArrayBuffer(emulatorSaveStateArra...
method createFromSaveStateData (line 32) | static createFromSaveStateData(emulatorSaveStateArrayBuffer) {
method createWithNewSize (line 36) | static createWithNewSize(emulatorSaveStateData, newSize) {
method getRawFileExtension (line 40) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 44) | static adjustOutputSizesPlatform() {
method fileSizeIsRequiredToConvert (line 48) | static fileSizeIsRequiredToConvert() {
FILE: frontend/src/save-formats/OnlineEmulators/Emulators/VBA-Next.js
constant EEPROM_OFFSET (line 26) | const EEPROM_OFFSET = 0x91000;
constant SRAM_OFFSET (line 27) | const SRAM_OFFSET = 0x93010;
constant FLASH_RAM_OFFSET (line 28) | const FLASH_RAM_OFFSET = 0x93010;
constant SAVE_OFFSET (line 30) | const SAVE_OFFSET = {
class VbaNextSaveStateData (line 38) | class VbaNextSaveStateData extends EmulatorBase {
method getRawArrayBufferFromSaveStateArrayBuffer (line 39) | static getRawArrayBufferFromSaveStateArrayBuffer(emulatorSaveStateArra...
method createFromSaveStateData (line 53) | static createFromSaveStateData(emulatorSaveStateArrayBuffer, saveSize) {
method createWithNewSize (line 57) | static createWithNewSize(emulatorSaveStateData, newSize) {
method getRawFileExtension (line 61) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 65) | static adjustOutputSizesPlatform() {
method fileSizeIsRequiredToConvert (line 69) | static fileSizeIsRequiredToConvert() {
FILE: frontend/src/save-formats/OnlineEmulators/Emulators/mGba.js
constant LITTLE_ENDIAN (line 15) | const LITTLE_ENDIAN = true;
constant SAVE_SIZE_OFFSET (line 22) | const SAVE_SIZE_OFFSET = 0x61004;
constant SAVE_OFFSET (line 23) | const SAVE_OFFSET = 0x61030;
class MGbaSaveStateData (line 25) | class MGbaSaveStateData extends EmulatorBase {
method getRawArrayBufferFromSaveStateArrayBuffer (line 26) | static getRawArrayBufferFromSaveStateArrayBuffer(emulatorSaveStateArra...
method createFromSaveStateData (line 42) | static createFromSaveStateData(emulatorSaveStateArrayBuffer, saveSize) {
method createWithNewSize (line 46) | static createWithNewSize(emulatorSaveStateData, newSize) {
method getRawFileExtension (line 50) | static getRawFileExtension() {
method adjustOutputSizesPlatform (line 54) | static adjustOutputSizesPlatform() {
method fileSizeIsRequiredToConvert (line 58) | static fileSizeIsRequiredToConvert() {
FILE: frontend/src/save-formats/OnlineEmulators/OnlineEmulatorWrapper.js
constant IMAGE_FILE_TYPES (line 21) | const IMAGE_FILE_TYPES = ['.png', '.jpg', '.jpeg', '.tif', '.tiff', '.gi...
constant GB_SAVE_STATE_TYPES (line 23) | const GB_SAVE_STATE_TYPES = [
constant GBA_SAVE_STATE_TYPES (line 29) | const GBA_SAVE_STATE_TYPES = [
function getSaveStatesFromZip (line 35) | async function getSaveStatesFromZip(zipContents) {
function getSaveStateFromSingleFile (line 43) | function getSaveStateFromSingleFile(arrayBuffer, filename) {
function getSaveStates (line 47) | async function getSaveStates(arrayBuffer, filename) {
function getSaveStateType (line 73) | function getSaveStateType(saveStateTypes, arrayBuffer, smallestSaveSize) {
function getClass (line 90) | function getClass(platform, saveStateArrayBuffer) {
class OnlineEmulatorWrapper (line 106) | class OnlineEmulatorWrapper {
method createFromEmulatorData (line 107) | static async createFromEmulatorData(emulatorSaveStateArrayBuffer, emul...
method getRawFileExtension (line 125) | static getRawFileExtension() {
method createWithNewSize (line 129) | static createWithNewSize(onlineEmulatorWrapperData, newSize) {
method fileSizeIsRequiredToConvert (line 138) | static async fileSizeIsRequiredToConvert(emulatorSaveStateArrayBuffer,...
method constructor (line 150) | constructor(files, platform, clazz) {
method adjustOutputSizesPlatform (line 156) | adjustOutputSizesPlatform() {
method getFiles (line 160) | getFiles() {
method getPlatform (line 164) | getPlatform() {
method getClass (line 168) | getClass() {
FILE: frontend/src/save-formats/PS1/Components/Basics.js
class Ps1Basics (line 1) | class Ps1Basics {
FILE: frontend/src/save-formats/PS1/Components/DirectoryBlock.js
constant HEADER_MAGIC (line 18) | const HEADER_MAGIC = 'MC';
constant MAGIC_OFFSET (line 19) | const MAGIC_OFFSET = 0;
constant DIRECTORY_FRAME_AVAILABLE_OFFSET (line 23) | const DIRECTORY_FRAME_AVAILABLE_OFFSET = 0x00;
constant DIRECTORY_FRAME_NEXT_BLOCK_OFFSET (line 24) | const DIRECTORY_FRAME_NEXT_BLOCK_OFFSET = 0x08;
constant DIRECTORY_FRAME_NO_NEXT_BLOCK (line 25) | const DIRECTORY_FRAME_NO_NEXT_BLOCK = 0xFFFF;
constant DIRECTORY_FRAME_FILENAME_OFFSET (line 26) | const DIRECTORY_FRAME_FILENAME_OFFSET = 0x0A;
constant DIRECTORY_FRAME_FILENAME_LENGTH (line 27) | const DIRECTORY_FRAME_FILENAME_LENGTH = 20;
constant DIRECTORY_FRAME_FILENAME_ENCODING (line 28) | const DIRECTORY_FRAME_FILENAME_ENCODING = 'US-ASCII';
constant DIRECTORY_FRAME_FILE_SIZE_OFFSET (line 29) | const DIRECTORY_FRAME_FILE_SIZE_OFFSET = 0x04;
constant DIRECTORY_FRAME_UNUSED_BLOCK (line 32) | const DIRECTORY_FRAME_UNUSED_BLOCK = 0xA0;
constant DIRECTORY_FRAME_FIRST_LINK_BLOCK (line 33) | const DIRECTORY_FRAME_FIRST_LINK_BLOCK = 0x51;
constant DIRECTORY_FRAME_MIDDLE_LINK_BLOCK (line 34) | const DIRECTORY_FRAME_MIDDLE_LINK_BLOCK = 0x52;
constant DIRECTORY_FRAME_LAST_LINK_BLOCK (line 35) | const DIRECTORY_FRAME_LAST_LINK_BLOCK = 0x53;
constant DIRECTORY_FRAME_UNUSABLE_BLOCK (line 36) | const DIRECTORY_FRAME_UNUSABLE_BLOCK = 0xFF;
function getDirectoryFrame (line 38) | function getDirectoryFrame(headerArrayBuffer, blockNum) {
function xorAllBytes (line 43) | function xorAllBytes(arrayBuffer) {
function createDirectoryFrame (line 49) | function createDirectoryFrame() {
function createDirectoryFrameMagic (line 53) | function createDirectoryFrameMagic() {
function createDirectoryFrameEmpty (line 62) | function createDirectoryFrameEmpty() {
function createDirectoryFrameUnused (line 74) | function createDirectoryFrameUnused() {
function encodeFilename (line 88) | function encodeFilename(filename, filenameTextEncoder) {
function getRegionName (line 94) | function getRegionName(filename) {
function createDirectoryFramesForSave (line 116) | function createDirectoryFramesForSave(saveFile, blockNumber, filenameTex...
class Ps1DirectoryBlock (line 184) | class Ps1DirectoryBlock {
method getDirectoryFrame (line 189) | static getDirectoryFrame(headerArrayBuffer, blockNum) {
method encodeFilename (line 193) | static encodeFilename(filename, filenameTextEncoder) {
method createHeaderBlock (line 197) | static createHeaderBlock(saveFiles) {
method readDirectoryBlock (line 227) | static readDirectoryBlock(headerArrayBuffer) {
FILE: frontend/src/save-formats/PS1/Components/SaveBlocks.js
constant SAVE_BLOCK_MAGIC (line 11) | const SAVE_BLOCK_MAGIC = 'SC';
constant MAGIC_OFFSET (line 12) | const MAGIC_OFFSET = 0;
constant SAVE_BLOCK_DESCRIPTION_OFFSET (line 14) | const SAVE_BLOCK_DESCRIPTION_OFFSET = 0x04;
constant SAVE_BLOCK_DESCRIPTION_LENGTH (line 15) | const SAVE_BLOCK_DESCRIPTION_LENGTH = 64;
constant SAVE_BLOCK_DESCRIPTION_ENCODING (line 16) | const SAVE_BLOCK_DESCRIPTION_ENCODING = 'shift-jis';
function getBlock (line 18) | function getBlock(dataBlocksArrayBuffer, blockNum) {
function createSaveBlockEmpty (line 23) | function createSaveBlockEmpty() {
function convertTextToHalfWidth (line 27) | function convertTextToHalfWidth(s) {
class Ps1SaveBlocks (line 33) | class Ps1SaveBlocks {
method checkMagic (line 34) | static checkMagic(rawData) {
method readSaveBlocks (line 38) | static readSaveBlocks(saveFile, dataBlocksArrayBuffer) {
method createSaveBlocks (line 68) | static createSaveBlocks(saveFiles) {
FILE: frontend/src/save-formats/PS1/Components/SonyUtil.js
constant ENCRYPTION_ALGORITHM (line 9) | const ENCRYPTION_ALGORITHM = 'aes-128-ecb';
constant ENCRYPTION_ALGORITHM_BLOCK_LENGTH (line 10) | const ENCRYPTION_ALGORITHM_BLOCK_LENGTH = 0x10;
constant ENCRYPTION_KEY (line 11) | const ENCRYPTION_KEY = Buffer.from('AB5ABC9FC1F49DE6A051DBAEFA518859', '...
constant ENCRYPTION_IV (line 12) | const ENCRYPTION_IV = Buffer.alloc(0);
constant ENCRYPTION_IV_PRETEND (line 13) | const ENCRYPTION_IV_PRETEND = Buffer.from('B30FFEEDB7DC5EB7133DA60D1B6B2...
constant ENCRYPTION_KEY_LENGTH (line 14) | const ENCRYPTION_KEY_LENGTH = ENCRYPTION_KEY.length;
constant HASH_ALGORITHM (line 15) | const HASH_ALGORITHM = 'sha1';
constant SALT_LENGTH (line 16) | const SALT_LENGTH = 0x40;
constant SALT_SEED_INIT (line 25) | const SALT_SEED_INIT = Buffer.from('000102030405060708090A0B0C0D0E0F1011...
function xorWithIv (line 28) | function xorWithIv(arrayBuffer, startingOffset, ivBuffer) {
function xorWithByte (line 45) | function xorWithByte(arrayBuffer, xorValue, length) {
class SonyUtil (line 58) | class SonyUtil {
method calculateSignature (line 63) | static calculateSignature(arrayBuffer, saltSeed, saltSeedLength, signa...
FILE: frontend/src/save-formats/PS1/DexDrive.js
constant HEADER_LENGTH (line 24) | const HEADER_LENGTH = 3904;
constant HEADER_MAGIC (line 26) | const HEADER_MAGIC = '123-456-STD';
constant MAGIC_ENCODING (line 27) | const MAGIC_ENCODING = 'US-ASCII';
constant AVAILABLE_BLOCKS_OFFSET (line 29) | const AVAILABLE_BLOCKS_OFFSET = 22;
constant LINK_BLOCKS_OFFSET (line 30) | const LINK_BLOCKS_OFFSET = 38;
constant COMMENT_ENCODING (line 35) | const COMMENT_ENCODING = 'utf8';
constant FIRST_COMMENT_OFFSET (line 36) | const FIRST_COMMENT_OFFSET = 64;
constant COMMENT_LENGTH (line 37) | const COMMENT_LENGTH = 256;
function getCommentStartOffset (line 39) | function getCommentStartOffset(i) {
function getComments (line 44) | function getComments(headerArrayBuffer) {
class Ps1DexDriveSaveData (line 58) | class Ps1DexDriveSaveData {
method createFromDexDriveData (line 59) | static createFromDexDriveData(dexDriveArrayBuffer) {
method createFromMemoryCardData (line 63) | static createFromMemoryCardData(memcardArrayBuffer, comment) {
method createFromSaveFiles (line 71) | static createFromSaveFiles(saveFiles) {
method constructor (line 131) | constructor(arrayBuffer) {
method getSaveFiles (line 171) | getSaveFiles() {
method getMemoryCard (line 175) | getMemoryCard() {
method getArrayBuffer (line 179) | getArrayBuffer() {
FILE: frontend/src/save-formats/PS1/Memcard.js
function checkFile (line 18) | function checkFile(file) {
class Ps1MemcardSaveData (line 30) | class Ps1MemcardSaveData {
method encodeFilename (line 31) | static encodeFilename(filename, filenameTextEncoder) {
method createFromPs1MemcardData (line 35) | static createFromPs1MemcardData(memcardArrayBuffer) {
method createFromSaveFiles (line 39) | static createFromSaveFiles(saveFiles) {
method constructor (line 64) | constructor(arrayBuffer) {
method getDirectoryFrame (line 75) | getDirectoryFrame(i) {
method getSaveFiles (line 80) | getSaveFiles() {
method getArrayBuffer (line 84) | getArrayBuffer() {
FILE: frontend/src/save-formats/PS1/Ps3.js
constant HEADER_LENGTH (line 25) | const HEADER_LENGTH = 0x84;
constant HEADER_MAGIC (line 27) | const HEADER_MAGIC = '\x00VSP\x00\x00\x00\x00';
constant MAGIC_ENCODING (line 28) | const MAGIC_ENCODING = 'US-ASCII';
constant SALT_SEED_OFFSET (line 30) | const SALT_SEED_OFFSET = 0x08;
constant SALT_SEED_LENGTH (line 31) | const SALT_SEED_LENGTH = 0x14;
constant SIGNATURE_OFFSET (line 33) | const SIGNATURE_OFFSET = 0x1C;
constant SIGNATURE_LENGTH (line 34) | const SIGNATURE_LENGTH = 0x14;
constant PLATFORM_INDICATOR_1_OFFSET (line 36) | const PLATFORM_INDICATOR_1_OFFSET = 0x38;
constant PLATFORM_INDICATOR_2_OFFSET (line 37) | const PLATFORM_INDICATOR_2_OFFSET = 0x3C;
constant PLATFORM_INDICATOR_1_PS1 (line 39) | const PLATFORM_INDICATOR_1_PS1 = 0x14;
constant PLATFORM_INDICATOR_2_PS1 (line 41) | const PLATFORM_INDICATOR_2_PS1 = 0x1;
constant SAVE_SIZE_OFFSET (line 44) | const SAVE_SIZE_OFFSET = 0x40;
constant SAVE_START_BYTE_OFFSET (line 45) | const SAVE_START_BYTE_OFFSET = 0x44;
constant SAVE_HEADER_SIZE_OFFSET (line 46) | const SAVE_HEADER_SIZE_OFFSET = 0x48;
constant SAVE_HEADER_SIZE_PS1 (line 47) | const SAVE_HEADER_SIZE_PS1 = FRAME_SIZE * 4;
constant FILENAME_PRODUCT_CODE_OFFSET (line 49) | const FILENAME_PRODUCT_CODE_OFFSET = 0x64;
constant FILENAME_PRODUCT_CODE_LENGTH (line 50) | const FILENAME_PRODUCT_CODE_LENGTH = 0x0C;
constant FILENAME_DESCRIPTION_OFFSET (line 51) | const FILENAME_DESCRIPTION_OFFSET = 0x70;
constant FILENAME_DESCRIPTION_LENGTH (line 52) | const FILENAME_DESCRIPTION_LENGTH = 0x08;
constant FILENAME_ENCODING (line 53) | const FILENAME_ENCODING = 'US-ASCII';
function getPs1IndividualFilename (line 56) | function getPs1IndividualFilename(ps3HeaderArrayBuffer, filenameTextDeco...
function getPs3IndividualFilename (line 66) | function getPs3IndividualFilename(ps3HeaderArrayBuffer, filenameTextDeco...
function createPs3SaveFile (line 79) | function createPs3SaveFile(ps1SaveFile) {
class Ps3SaveData (line 129) | class Ps3SaveData {
method createFromPs3SaveFiles (line 130) | static createFromPs3SaveFiles(ps3SaveFiles) {
method createFromPs1SaveFiles (line 200) | static createFromPs1SaveFiles(ps1SaveFiles) {
method constructor (line 207) | constructor(arrayBuffer) {
method getSaveFiles (line 215) | getSaveFiles() {
method getPs3SaveFiles (line 219) | getPs3SaveFiles() {
method getMemoryCard (line 223) | getMemoryCard() {
FILE: frontend/src/save-formats/PS1/Psp.js
constant HEADER_LENGTH (line 22) | const HEADER_LENGTH = 0x80;
constant HEADER_MAGIC (line 23) | const HEADER_MAGIC = [0, 0x50, 0x4D, 0x56, HEADER_LENGTH, 0, 0, 0, 0, 0,...
constant SALT_SEED_OFFSET (line 25) | const SALT_SEED_OFFSET = 0x0C;
constant SALT_SEED_LENGTH (line 26) | const SALT_SEED_LENGTH = 0x14;
constant SIGNATURE_OFFSET (line 28) | const SIGNATURE_OFFSET = 0x20;
constant SIGNATURE_LENGTH (line 29) | const SIGNATURE_LENGTH = 0x14;
class PspSaveData (line 31) | class PspSaveData {
method createFromPspData (line 32) | static createFromPspData(pspArrayBuffer) {
method createFromMemoryCardData (line 36) | static createFromMemoryCardData(memcardArrayBuffer) {
method createFromSaveFiles (line 68) | static createFromSaveFiles(saveFiles) {
method constructor (line 75) | constructor(arrayBuffer) {
method getSaveFiles (line 103) | getSaveFiles() {
method getMemoryCard (line 107) | getMemoryCard() {
method getArrayBuffer (line 111) | getArrayBuffer() {
FILE: frontend/src/save-formats/PSP/Executable.js
constant LITTLE_ENDIAN (line 9) | const LITTLE_ENDIAN = true;
constant MAGIC_ENCODING (line 11) | const MAGIC_ENCODING = 'US-ASCII';
constant ENCRYPTED_MAGIC_OFFSET (line 13) | const ENCRYPTED_MAGIC_OFFSET = 0;
constant UNENCRYPTED_MAGIC_OFFSET (line 14) | const UNENCRYPTED_MAGIC_OFFSET = 0;
constant ENCRYPTED_MAGIC (line 15) | const ENCRYPTED_MAGIC = '~PSP';
constant ELF_MAGIC (line 16) | const ELF_MAGIC = '\x7FELF';
constant ELF_MAGIC_OFFSET (line 17) | const ELF_MAGIC_OFFSET = 0x150;
constant COMPRESSION_ATTRIBUTES_OFFSET (line 19) | const COMPRESSION_ATTRIBUTES_OFFSET = 0x06;
constant ELF_SIZE_OFFSET (line 20) | const ELF_SIZE_OFFSET = 0x28;
constant PSP_SIZE_OFFSET (line 21) | const PSP_SIZE_OFFSET = 0x2C;
constant COMPRESSION_ATTRIBUTES_IS_GZIP (line 23) | const COMPRESSION_ATTRIBUTES_IS_GZIP = 0x01;
class PspExecutable (line 25) | class PspExecutable {
method createFromEncryptedData (line 27) | static createFromEncryptedData(encryptedExecutableArrayBuffer) {
method constructor (line 83) | constructor(encryptedArrayBuffer, unencryptedArrayBuffer, executableIn...
method getUnencryptedArrayBuffer (line 89) | getUnencryptedArrayBuffer() {
method getEncryptedArrayBuffer (line 93) | getEncryptedArrayBuffer() {
method getExecutableInfo (line 97) | getExecutableInfo() {
FILE: frontend/src/save-formats/PSP/ParamSfo.js
constant LITTLE_ENDIAN (line 13) | const LITTLE_ENDIAN = true;
constant MAGIC (line 15) | const MAGIC = '\x00PSF';
constant MAGIC_ENCODING (line 16) | const MAGIC_ENCODING = 'US-ASCII';
constant EXPECTED_VERSION (line 18) | const EXPECTED_VERSION = 0x00000101;
constant MAGIC_OFFSET (line 21) | const MAGIC_OFFSET = 0;
constant VERSION_OFFSET (line 22) | const VERSION_OFFSET = 4;
constant KEY_TABLE_START_OFFSET (line 23) | const KEY_TABLE_START_OFFSET = 8;
constant VALUE_TABLE_START_OFFSET (line 24) | const VALUE_TABLE_START_OFFSET = 12;
constant NUM_INDEX_TABLE_ENTRIES_OFFSET (line 25) | const NUM_INDEX_TABLE_ENTRIES_OFFSET = 16;
constant FIRST_INDEX_TABLE_ENTRY_OFFSET (line 26) | const FIRST_INDEX_TABLE_ENTRY_OFFSET = 20;
constant INDEX_TABLE_KEY_OFFSET (line 29) | const INDEX_TABLE_KEY_OFFSET = 0;
constant INDEX_TABLE_VALUE_FORMAT_OFFSET (line 30) | const INDEX_TABLE_VALUE_FORMAT_OFFSET = 2;
constant INDEX_TABLE_VALUE_LENGTH_OFFSET (line 31) | const INDEX_TABLE_VALUE_LENGTH_OFFSET = 4;
constant INDEX_TABLE_VALUE_MAX_LENGTH_OFFSET (line 32) | const INDEX_TABLE_VALUE_MAX_LENGTH_OFFSET = 8;
constant INDEX_TABLE_VALUE_OFFSET (line 33) | const INDEX_TABLE_VALUE_OFFSET = 12;
constant INDEX_TABLE_ENTRY_SIZE (line 34) | const INDEX_TABLE_ENTRY_SIZE = 16;
constant VALUE_FORMAT_UINT32 (line 36) | const VALUE_FORMAT_UINT32 = 0x0404;
constant VALUE_FORMAT_UTF8_STRING (line 37) | const VALUE_FORMAT_UTF8_STRING = 0x0204;
constant VALUE_FORMAT_SPECIAL_UTF8_STRING (line 38) | const VALUE_FORMAT_SPECIAL_UTF8_STRING = 0x0004;
constant KEY_ENCODING (line 40) | const KEY_ENCODING = 'US-ASCII';
constant VALUE_ENCODING_UTF8 (line 41) | const VALUE_ENCODING_UTF8 = 'UTF-8';
function getErrorMessage (line 43) | function getErrorMessage(fileVersion) {
class PspParamSfo (line 51) | class PspParamSfo {
method constructor (line 52) | constructor(arrayBuffer) {
method getValue (line 119) | getValue(key) {
FILE: frontend/src/save-formats/PSP/PspEncryptionUtil.js
function getModuleInstance (line 6) | async function getModuleInstance() {
class PspEncryptionUtil (line 42) | class PspEncryptionUtil {
method init (line 43) | static async init(deterministicSeed = null) {
method bufferToPtr (line 57) | static bufferToPtr(buffer) {
method ptrToArrayBuffer (line 69) | static ptrToArrayBuffer(ptr, length) {
method intToPtr (line 80) | static intToPtr(n) {
method ptrToInt (line 88) | static ptrToInt(ptr) {
method free (line 92) | static free(ptr) {
FILE: frontend/src/save-formats/PSP/Savefile.js
class PspSaveData (line 5) | class PspSaveData {
method createFromEncryptedData (line 6) | static createFromEncryptedData(encryptedArrayBuffer, gameKey) {
method createFromUnencryptedData (line 31) | static createFromUnencryptedData(unencryptedArrayBuffer, encryptedFile...
method constructor (line 66) | constructor(encryptedArrayBuffer, unencryptedArrayBuffer, paramSfoArra...
method getUnencryptedArrayBuffer (line 72) | getUnencryptedArrayBuffer() {
method getEncryptedArrayBuffer (line 76) | getEncryptedArrayBuffer() {
method getParamSfoArrayBuffer (line 80) | getParamSfoArrayBuffer() {
FILE: frontend/src/save-formats/PSP/psp-encryption/psp-encryption.js
function locateFile (line 8) | function locateFile(path){if(Module["locateFile"]){return Module["locate...
function updateMemoryViews (line 8) | function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEA...
function preRun (line 8) | function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="func...
function initRuntime (line 8) | function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__AT...
function postRun (line 8) | function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="f...
function addOnPreRun (line 8) | function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}
function addOnInit (line 8) | function addOnInit(cb){__ATINIT__.unshift(cb)}
function addOnPostRun (line 8) | function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}
function addRunDependency (line 8) | function addRunDependency(id){runDependencies++;Module["monitorRunDepend...
function removeRunDependency (line 8) | function removeRunDependency(id){runDependencies--;Module["monitorRunDep...
function abort (line 8) | function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";...
function findWasmBinary (line 8) | function findWasmBinary(){if(Module["locateFile"]){var f="psp-encryption...
function getBinarySync (line 8) | function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return...
function getWasmBinary (line 8) | async function getWasmBinary(binaryFile){if(!wasmBinary){try{var respons...
function instantiateArrayBuffer (line 8) | async function instantiateArrayBuffer(binaryFile,imports){try{var binary...
function instantiateAsync (line 8) | async function instantiateAsync(binary,binaryFile,imports){if(!binary&&t...
function getWasmImports (line 8) | function getWasmImports(){return{a:wasmImports}}
function createWasm (line 8) | async function createWasm(){function receiveInstance(instance,module){wa...
class ExitStatus (line 8) | class ExitStatus{name="ExitStatus";constructor(status){this.message=`Pro...
method constructor (line 8) | constructor(status){this.message=`Program terminated with exit(${statu...
function getValue (line 8) | function getValue(ptr,type="i8"){if(type.endsWith("*"))type="*";switch(t...
function setValue (line 8) | function setValue(ptr,value,type="i8"){if(type.endsWith("*"))type="*";sw...
function convertReturnValue (line 8) | function convertReturnValue(ret){if(returnType==="string"){return UTF8To...
function onDone (line 8) | function onDone(ret){if(stack!==0)stackRestore(stack);return convertRetu...
function run (line 8) | function run(){if(runDependencies>0){dependenciesFulfilled=run;return}pr...
FILE: frontend/src/save-formats/PlatformSaveSizes.js
constant PLATFORM_SAVE_SIZES (line 4) | const PLATFORM_SAVE_SIZES = {
constant OMIT_FROM_ALL_SIZES (line 110) | const OMIT_FROM_ALL_SIZES = [
constant ALL_SIZES_KEYS (line 115) | const ALL_SIZES_KEYS = Object.keys(PLATFORM_SAVE_SIZES).filter((key) => ...
constant ALL_SIZES (line 117) | const ALL_SIZES = ALL_SIZES_KEYS.reduce((accumulator, currentPlatform) =...
constant ALL_SIZES_NO_DUPLICATES_SORTED (line 118) | const ALL_SIZES_NO_DUPLICATES_SORTED = [...new Set(ALL_SIZES)].sort((a, ...
FILE: frontend/src/save-formats/Retron5/Retron5.js
constant LITTLE_ENDIAN (line 25) | const LITTLE_ENDIAN = true;
constant MAGIC (line 27) | const MAGIC = 'RTN5';
constant MAGIC_ENCODING (line 28) | const MAGIC_ENCODING = 'US-ASCII';
constant FORMAT_VERSION (line 29) | const FORMAT_VERSION = 1;
constant FLAG_ZLIB_PACKED (line 30) | const FLAG_ZLIB_PACKED = 0x01;
constant MAGIC_OFFSET (line 32) | const MAGIC_OFFSET = 0;
constant FORMAT_VERSION_OFFSET (line 33) | const FORMAT_VERSION_OFFSET = 4;
constant FLAGS_OFFSET (line 34) | const FLAGS_OFFSET = 6;
constant ORIGINAL_SIZE_OFFSET (line 35) | const ORIGINAL_SIZE_OFFSET = 8;
constant PACKED_SIZE_OFFSET (line 36) | const PACKED_SIZE_OFFSET = 12;
constant DATA_OFFSET_OFFSET (line 37) | const DATA_OFFSET_OFFSET = 16;
constant CRC32_OFFSET (line 38) | const CRC32_OFFSET = 20;
constant HEADER_SIZE (line 40) | const HEADER_SIZE = 24;
class Retron5SaveData (line 42) | class Retron5SaveData {
method createFromRetron5Data (line 43) | static createFromRetron5Data(retron5ArrayBuffer) {
method createFromEmulatorData (line 108) | static createFromEmulatorData(rawArrayBuffer) {
method constructor (line 131) | constructor(retron5ArrayBuffer, rawArrayBuffer) {
method getRawArrayBuffer (line 136) | getRawArrayBuffer() {
method getRetron5ArrayBuffer (line 140) | getRetron5ArrayBuffer() {
FILE: frontend/src/save-formats/SegaCd/Crc16.js
constant CRC_TABLE_SIZE (line 8) | const CRC_TABLE_SIZE = 256;
FILE: frontend/src/save-formats/SegaCd/ReedSolomon.js
constant GENERATOR_POLYNOMIAL_REED_SOLOMON_8 (line 12) | const GENERATOR_POLYNOMIAL_REED_SOLOMON_8 = [87, 166, 113, 75, 198, 25, ...
constant GENERATOR_POLYNOMIAL_REED_SOLOMON_6 (line 13) | const GENERATOR_POLYNOMIAL_REED_SOLOMON_6 = [20, 58, 56, 18, 26, 6, 59, ...
constant GALOIS_FIELD_TABLE_SIZE (line 15) | const GALOIS_FIELD_TABLE_SIZE = 256;
constant DATA_SIZE (line 17) | const DATA_SIZE = 6;
constant PARITY_OFFSETS (line 18) | const PARITY_OFFSETS = [DATA_SIZE, DATA_SIZE + 1];
constant PARITY_SIZE (line 19) | const PARITY_SIZE = PARITY_OFFSETS.length;
constant TOTAL_SIZE (line 20) | const TOTAL_SIZE = DATA_SIZE + PARITY_SIZE;
function initReedSolomon (line 23) | function initReedSolomon(poly, bitsPerSymbol, generatorPolynomial) {
constant REED_SOLOMON (line 54) | const REED_SOLOMON = {
function checkInputDataSize (line 59) | function checkInputDataSize(inputArrayBuffer) {
function addMod (line 67) | function addMod(reedSolomon, i, d) {
class ReedSolomon (line 73) | class ReedSolomon {
method encode (line 75) | static encode(inputArrayBuffer, reedSolomonType) {
method decode (line 100) | static decode(inputArrayBuffer, reedSolomonType) {
FILE: frontend/src/save-formats/SegaCd/SegaCd.js
constant LITTLE_ENDIAN (line 51) | const LITTLE_ENDIAN = false;
constant DIRECTORY_SIZE (line 53) | const DIRECTORY_SIZE = 0x40;
constant DIRECTORY_FORMAT_OFFSET (line 55) | const DIRECTORY_FORMAT_OFFSET = 0x20;
constant DIRECTORY_VOLUME_OFFSET (line 56) | const DIRECTORY_VOLUME_OFFSET = 0x00;
constant DIRECTORY_ENTRY_SIZE_ENCODED (line 58) | const DIRECTORY_ENTRY_SIZE_ENCODED = 0x20;
constant DIRECTORY_ENTRY_SIZE_PLAINTEXT (line 59) | const DIRECTORY_ENTRY_SIZE_PLAINTEXT = DIRECTORY_ENTRY_SIZE_ENCODED / 2;
constant DIRECTORY_ENTRY_FILENAME_OFFSET (line 60) | const DIRECTORY_ENTRY_FILENAME_OFFSET = 0;
constant DIRECTORY_ENTRY_FILENAME_LENGTH (line 61) | const DIRECTORY_ENTRY_FILENAME_LENGTH = 11;
constant DIRECTORY_ENTRY_FILE_DATA_IS_ENCODED_OFFSET (line 62) | const DIRECTORY_ENTRY_FILE_DATA_IS_ENCODED_OFFSET = 11;
constant DIRECTORY_ENTRY_FILE_DATA_START_BLOCK_OFFSET (line 63) | const DIRECTORY_ENTRY_FILE_DATA_START_BLOCK_OFFSET = 12;
constant DIRECTORY_ENTRY_FILE_SIZE_OFFSET (line 64) | const DIRECTORY_ENTRY_FILE_SIZE_OFFSET = 14;
constant BLOCK_SIZE (line 66) | const BLOCK_SIZE = 0x40;
constant SUB_BLOCK_SIZE (line 67) | const SUB_BLOCK_SIZE = 0x08;
constant NUM_SUB_BLOCKS (line 68) | const NUM_SUB_BLOCKS = BLOCK_SIZE / SUB_BLOCK_SIZE;
constant BLOCK_DATA_BEGIN_OFFSET (line 71) | const BLOCK_DATA_BEGIN_OFFSET = 2;
constant BLOCK_DATA_SIZE (line 72) | const BLOCK_DATA_SIZE = 32;
constant BLOCK_CRC_1_OFFSET (line 73) | const BLOCK_CRC_1_OFFSET = 0;
constant BLOCK_CRC_2_OFFSET (line 74) | const BLOCK_CRC_2_OFFSET = BLOCK_DATA_BEGIN_OFFSET + BLOCK_DATA_SIZE;
constant BLOCK_TOTAL_CRC_SIZE (line 75) | const BLOCK_TOTAL_CRC_SIZE = 4;
constant REED_SOLOMON_6_LAST_DATA_BYTE (line 77) | const REED_SOLOMON_6_LAST_DATA_BYTE = [0x2d, 0x2e, 0x2f, 0x08, 0x11, 0x1...
constant TEXT_ENCODING (line 79) | const TEXT_ENCODING = 'US-ASCII';
constant VOLUME_LENGTH (line 80) | const VOLUME_LENGTH = 11;
constant FORMAT_LENGTH (line 81) | const FORMAT_LENGTH = 11;
constant MEDIA_ID_LENGTH (line 82) | const MEDIA_ID_LENGTH = 16;
function sanitizeText (line 84) | function sanitizeText(rawText) {
function decodeText (line 89) | function decodeText(arrayBuffer, offset, length) {
function encodeText (line 97) | function encodeText(text, length) {
function deinterleaveData (line 106) | function deinterleaveData(inputBlockArrayBuffer) {
function interleaveData (line 148) | function interleaveData(inputBlockArrayBuffer) {
function interleaveReedSolomon8 (line 188) | function interleaveReedSolomon8(subBlockIndex, deinterleavedSubBlockArra...
function deinterleaveReedSolomon8 (line 209) | function deinterleaveReedSolomon8(subBlockIndex, blockArrayBuffer) {
function interleaveReedSolomon6 (line 229) | function interleaveReedSolomon6(subBlockIndex, deinterleavedSubBlockArra...
function deinterleaveReedSolomon6 (line 248) | function deinterleaveReedSolomon6(subBlockIndex, blockArrayBuffer) {
function getErrorCorrectedData (line 267) | function getErrorCorrectedData(blockArrayBuffer) {
function addErrorCorrectionData (line 286) | function addErrorCorrectionData(blockArrayBuffer) {
function checkCrc (line 305) | function checkCrc(deinterleavedBlockArrayBuffer) {
function decodeBlock (line 327) | function decodeBlock(arrayBuffer, offset) {
function encodeBlock (line 347) | function encodeBlock(destinationArrayBuffer, sourceArrayBuffer, destinat...
function readSaveFiles (line 374) | function readSaveFiles(arrayBuffer, numSaveFiles) {
function getRequiredBlocks (line 420) | function getRequiredBlocks(saveFile) {
function getEmptyDirectoryEntry (line 427) | function getEmptyDirectoryEntry() {
function getDirectoryEntry (line 437) | function getDirectoryEntry(saveFile, startingBlock) {
function writeSaveFile (line 454) | function writeSaveFile(saveFile, startingBlock, segaCdArrayBuffer) {
function getVolumeInfo (line 474) | function getVolumeInfo(segaCdArrayBuffer) {
class SegaCdSaveData (line 483) | class SegaCdSaveData {
method createWithNewSize (line 484) | static createWithNewSize(segaCdSaveData, newSize) {
method createFromSegaCdData (line 490) | static createFromSegaCdData(arrayBuffer) {
method createFromSaveFiles (line 532) | static createFromSaveFiles(saveFiles, size) {
method constructor (line 599) | constructor(arrayBuffer, saveFiles) {
method getSaveFiles (line 605) | getSaveFiles() {
method getNumFreeBlocks (line 609) | getNumFreeBlocks() {
method getFormat (line 613) | getFormat() {
method getVolume (line 617) | getVolume() {
method getMediaId (line 621) | getMediaId() {
method getArrayBuffer (line 625) | getArrayBuffer() {
FILE: frontend/src/save-formats/SegaError.js
class SegaError (line 1) | class SegaError extends Error {
method constructor (line 2) | constructor(internalSaveError = null, ramCartError = null) {
FILE: frontend/src/save-formats/SegaSaturn/Emulators/Emulators.js
constant EMULATOR_CLASSES (line 11) | const EMULATOR_CLASSES = [
class EmulatorSegaSaturnSaveData (line 17) | class EmulatorSegaSaturnSaveData {
method createWithNewSize (line 18) | static createWithNewSize(segaSaturnSaveData, newSize) {
method createFromSegaSaturnData (line 30) | static createFromSegaSaturnData(arrayBuffer) {
method createFromSaveFiles (line 42) | static createFromSaveFiles(saveFiles, blockSize) {
FILE: frontend/src/save-formats/SegaSaturn/Emulators/mednafen.js
class MednafenSegaSaturnSaveData (line 14) | class MednafenSegaSaturnSaveData {
method createWithNewSize (line 15) | static createWithNewSize(/* segaSaturnSaveData, newSize */) {
method createFromSegaSaturnData (line 23) | static createFromSegaSaturnData(arrayBuffer) {
method createFromSaveFiles (line 36) | static createFromSaveFiles(saveFiles, blockSize) {
FILE: frontend/src/save-formats/SegaSaturn/Emulators/yabasanshiro.js
constant PADDING_VALUE (line 13) | const PADDING_VALUE = 0xFF;
constant BLOCK_SIZE (line 15) | const BLOCK_SIZE = 0x40;
constant FILE_SIZE (line 16) | const FILE_SIZE = 0x800000;
class YabaSanshiroSegaSaturnSaveData (line 18) | class YabaSanshiroSegaSaturnSaveData {
method createWithNewSize (line 19) | static createWithNewSize(/* segaSaturnSaveData, newSize */) {
method createFromSegaSaturnData (line 27) | static createFromSegaSaturnData(arrayBuffer) {
method createFromSaveFiles (line 39) | static createFromSaveFiles(saveFiles) {
FILE: frontend/src/save-formats/SegaSaturn/Emulators/yabause.js
constant PADDING_VALUE (line 11) | const PADDING_VALUE = 0xFF;
class YabauseSegaSaturnSaveData (line 13) | class YabauseSegaSaturnSaveData {
method createWithNewSize (line 14) | static createWithNewSize(/* segaSaturnSaveData, newSize */) {
method createFromSegaSaturnData (line 22) | static createFromSegaSaturnData(arrayBuffer) {
method createFromSaveFiles (line 34) | static createFromSaveFiles(saveFiles, blockSize) {
FILE: frontend/src/save-formats/SegaSaturn/IndividualSaves/Bup.js
constant LITTLE_ENDIAN (line 38) | const LITTLE_ENDIAN = false;
constant HEADER_SIZE (line 40) | const HEADER_SIZE = 64;
constant MAGIC (line 42) | const MAGIC = 'Vmem';
constant MAGIC_OFFSET (line 43) | const MAGIC_OFFSET = 0x00;
constant MAGIC_ENCODING (line 44) | const MAGIC_ENCODING = 'US-ASCII';
constant SAVE_ID_OFFSET (line 46) | const SAVE_ID_OFFSET = 0x04;
constant SAVE_NAME_OFFSET (line 48) | const SAVE_NAME_OFFSET = 0x10;
constant SAVE_NAME_LENGTH (line 49) | const SAVE_NAME_LENGTH = SegaSaturnSaveData.ARCHIVE_ENTRY_NAME_LENGTH + 1;
constant COMMENT_OFFSET (line 51) | const COMMENT_OFFSET = 0x1C;
constant COMMENT_LENGTH (line 52) | const COMMENT_LENGTH = SegaSaturnSaveData.ARCHIVE_ENTRY_COMMENT_LENGTH + 1;
constant LANGUAGE_OFFSET (line 54) | const LANGUAGE_OFFSET = 0x27;
constant DATE_OFFSET_1 (line 55) | const DATE_OFFSET_1 = 0x28;
constant SAVE_SIZE_OFFSET (line 56) | const SAVE_SIZE_OFFSET = 0x2C;
constant DATE_OFFSET_2 (line 57) | const DATE_OFFSET_2 = 0x34;
class SegaSaturnBupSaveData (line 59) | class SegaSaturnBupSaveData {
method convertSaveFilesToBups (line 61) | static convertSaveFilesToBups(saveFiles) {
method convertBupsToSaveFiles (line 81) | static convertBupsToSaveFiles(arrayBuffers) {
FILE: frontend/src/save-formats/SegaSaturn/Saroo/Cart.js
constant LITTLE_ENDIAN (line 46) | const LITTLE_ENDIAN = false;
constant BLOCK_SIZE (line 48) | const BLOCK_SIZE = 1024;
constant TOTAL_BLOCKS (line 49) | const TOTAL_BLOCKS = 8192;
constant FILL_VALUE (line 50) | const FILL_VALUE = 0x00;
constant HEADER_NUM_BLOCKS (line 52) | const HEADER_NUM_BLOCKS = 1;
constant MAGIC (line 54) | const MAGIC = 'SaroMems';
constant MAGIC_OFFSET (line 55) | const MAGIC_OFFSET = 0;
constant MAGIC_ENCODING (line 56) | const MAGIC_ENCODING = 'US-ASCII';
constant TOTAL_SIZE_OFFSET (line 58) | const TOTAL_SIZE_OFFSET = 0x08;
constant FREE_BLOCKS_OFFSET (line 59) | const FREE_BLOCKS_OFFSET = 0x0C;
constant BITMAP_OFFSET (line 60) | const BITMAP_OFFSET = 0x10;
constant BITMAP_LENGTH (line 61) | const BITMAP_LENGTH = BLOCK_SIZE - BITMAP_OFFSET;
constant AVAILABLE_BLOCKS (line 63) | const AVAILABLE_BLOCKS = BITMAP_LENGTH * 8;
constant DIRECTORY_OFFSET (line 65) | const DIRECTORY_OFFSET = BLOCK_SIZE;
constant DIRECTORY_NUM_BLOCKS (line 66) | const DIRECTORY_NUM_BLOCKS = 7;
constant DIRECTORY_ENTRY_NAME_OFFSET (line 67) | const DIRECTORY_ENTRY_NAME_OFFSET = 0x00;
constant DIRECTORY_ENTRY_STARTING_BLOCK (line 68) | const DIRECTORY_ENTRY_STARTING_BLOCK = 0x0E;
constant DIRECTORY_ENTRY_LENGTH (line 69) | const DIRECTORY_ENTRY_LENGTH = 0x10;
constant TOTAL_DIRECTORY_ENTRIES (line 71) | const TOTAL_DIRECTORY_ENTRIES = (DIRECTORY_NUM_BLOCKS * BLOCK_SIZE) / DI...
constant ARCHIVE_ENTRY_NAME_OFFSET (line 73) | const ARCHIVE_ENTRY_NAME_OFFSET = 0x00;
constant ARCHIVE_ENTRY_SIZE_OFFSET (line 74) | const ARCHIVE_ENTRY_SIZE_OFFSET = 0x0C;
constant ARCHIVE_ENTRY_COMMENT_OFFSET (line 75) | const ARCHIVE_ENTRY_COMMENT_OFFSET = 0x10;
constant ARCHIVE_ENTRY_LANGUAGE_OFFSET (line 76) | const ARCHIVE_ENTRY_LANGUAGE_OFFSET = 0x1B;
constant ARCHIVE_ENTRY_DATE_OFFSET (line 77) | const ARCHIVE_ENTRY_DATE_OFFSET = 0x1C;
constant ARCHIVE_ENTRY_BLOCK_LIST_OFFSET (line 78) | const ARCHIVE_ENTRY_BLOCK_LIST_OFFSET = 0x40;
constant ARCHIVE_ENTRY_BLOCK_LIST_ENTRY_SIZE (line 79) | const ARCHIVE_ENTRY_BLOCK_LIST_ENTRY_SIZE = 2;
constant ARCHIVE_ENTRY_BLOCK_LIST_END (line 80) | const ARCHIVE_ENTRY_BLOCK_LIST_END = 0x0000;
constant ARCHIVE_ENTRY_BLOCK_LIST_AVAILABLE_SIZE (line 82) | const ARCHIVE_ENTRY_BLOCK_LIST_AVAILABLE_SIZE = BLOCK_SIZE - ARCHIVE_ENT...
constant ARCHIVE_ENTRY_MAX_NUM_BLOCKS (line 83) | const ARCHIVE_ENTRY_MAX_NUM_BLOCKS = (ARCHIVE_ENTRY_BLOCK_LIST_AVAILABLE...
constant NUM_RESERVED_BLOCKS (line 85) | const NUM_RESERVED_BLOCKS = HEADER_NUM_BLOCKS + DIRECTORY_NUM_BLOCKS;
function createEmptyBlock (line 87) | function createEmptyBlock() {
function createHeaderBlock (line 91) | function createHeaderBlock(volumeInfo) {
function createDirectoryEntry (line 106) | function createDirectoryEntry(saveFile, startingBlockNum) {
function createDirectory (line 117) | function createDirectory(gameSaveFilesWithBlockList) {
function createBlockListForSaveFile (line 139) | function createBlockListForSaveFile(saveFile, startingBlockNum) {
function getBlock (line 203) | function getBlock(arrayBuffer, blockNumber) {
function getDirectoryArrayBuffer (line 207) | function getDirectoryArrayBuffer(arrayBuffer) {
function getOccupiedDirectoryEntryIndexes (line 211) | function getOccupiedDirectoryEntryIndexes(arrayBuffer) {
function getSaveFile (line 219) | function getSaveFile(arrayBuffer, directoryEntryIndex) {
class SarooSegaSaturnCartSaveData (line 298) | class SarooSegaSaturnCartSaveData {
method createWithNewSize (line 299) | static createWithNewSize(/* segaSaturnSaveData, newSize */) {
method saveFilesContainsFile (line 307) | static saveFilesContainsFile(saveFiles, saveFile) {
method saveFilesAreEqual (line 311) | static saveFilesAreEqual(saveFile1, saveFile2) {
method upsertGameSaveFiles (line 315) | static upsertGameSaveFiles(existingGameSaveFiles, newGameSaveFiles) {
method isCartSarooData (line 336) | static isCartSarooData(arrayBuffer) {
method createFromSarooData (line 345) | static createFromSarooData(arrayBuffer) {
method createFromSaveFiles (line 369) | static createFromSaveFiles(gameSaveFiles) {
method constructor (line 417) | constructor(arrayBuffer, saveFiles, volumeInfo) {
method getSaveFiles (line 423) | getSaveFiles() {
method getVolumeInfo (line 427) | getVolumeInfo() {
method getArrayBuffer (line 431) | getArrayBuffer() {
FILE: frontend/src/save-formats/SegaSaturn/Saroo/Internal.js
constant LITTLE_ENDIAN (line 50) | const LITTLE_ENDIAN = false;
constant MAGIC (line 52) | const MAGIC = 'Saroo Save File';
constant MAGIC_OFFSET (line 53) | const MAGIC_OFFSET = 0;
constant MAGIC_ENCODING (line 54) | const MAGIC_ENCODING = 'US-ASCII';
constant SLOT_SIZE (line 56) | const SLOT_SIZE = 0x10000;
constant DEFAULT_BLOCK_SIZE (line 57) | const DEFAULT_BLOCK_SIZE = 0x80;
constant BITMAP_LENGTH (line 59) | const BITMAP_LENGTH = 64;
constant GAME_ID_LENGTH (line 61) | const GAME_ID_LENGTH = 0x10;
constant GAME_ID_ENCODING (line 62) | const GAME_ID_ENCODING = 'US-ASCII';
constant NUM_RESERVED_SLOTS (line 64) | const NUM_RESERVED_SLOTS = 1;
constant NUM_SLOTS (line 65) | const NUM_SLOTS = SLOT_SIZE / GAME_ID_LENGTH;
constant NUM_AVAILABLE_SLOTS (line 66) | const NUM_AVAILABLE_SLOTS = NUM_SLOTS - NUM_RESERVED_SLOTS;
constant FILL_VALUE (line 68) | const FILL_VALUE = 0x00;
constant SLOT_MAGIC (line 70) | const SLOT_MAGIC = 'SaroSave';
constant SLOT_MAGIC_OFFSET (line 71) | const SLOT_MAGIC_OFFSET = 0;
constant SLOT_MAGIC_ENCODING (line 72) | const SLOT_MAGIC_ENCODING = 'US-ASCII';
constant SLOT_TOTAL_SIZE_OFFSET (line 74) | const SLOT_TOTAL_SIZE_OFFSET = 0x08;
constant SLOT_BLOCK_SIZE_OFFSET (line 75) | const SLOT_BLOCK_SIZE_OFFSET = 0x0C;
constant SLOT_FREE_BLOCKS_OFFSET (line 76) | const SLOT_FREE_BLOCKS_OFFSET = 0x0E;
constant SLOT_GAME_ID_OFFSET (line 77) | const SLOT_GAME_ID_OFFSET = 0x20;
constant SLOT_FIRST_SAVE_BLOCK_OFFSET (line 78) | const SLOT_FIRST_SAVE_BLOCK_OFFSET = 0x3E;
constant SLOT_BITMAP_OFFSET (line 79) | const SLOT_BITMAP_OFFSET = 0x40;
constant NUM_RESERVED_BLOCKS (line 81) | const NUM_RESERVED_BLOCKS = 1;
constant ARCHIVE_ENTRY_NAME_OFFSET (line 83) | const ARCHIVE_ENTRY_NAME_OFFSET = 0x00;
constant ARCHIVE_ENTRY_SAVE_SIZE_OFFSET (line 84) | const ARCHIVE_ENTRY_SAVE_SIZE_OFFSET = 0x0C;
constant ARCHIVE_ENTRY_COMMENT_OFFSET (line 85) | const ARCHIVE_ENTRY_COMMENT_OFFSET = 0x10;
constant ARCHIVE_ENTRY_LANGUAGE_OFFSET (line 86) | const ARCHIVE_ENTRY_LANGUAGE_OFFSET = 0x1B;
constant ARCHIVE_ENTRY_DATE_OFFSET (line 87) | const ARCHIVE_ENTRY_DATE_OFFSET = 0x1C;
constant ARCHIVE_ENTRY_NEXT_SAVE_BLOCK_OFFSET (line 88) | const ARCHIVE_ENTRY_NEXT_SAVE_BLOCK_OFFSET = 0x3E;
constant ARCHIVE_ENTRY_BITMAP_OFFSET (line 89) | const ARCHIVE_ENTRY_BITMAP_OFFSET = 0x40;
constant NO_NEXT_SAVE (line 91) | const NO_NEXT_SAVE = 0;
function slotContainsValidSaves (line 93) | function slotContainsValidSaves(slotNum, arrayBuffer) {
function getSlot (line 109) | function getSlot(slotNum, arrayBuffer) {
function getBlock (line 113) | function getBlock(slotArrayBuffer, blockSize, blockNumber) {
function getNextBlockNum (line 126) | function getNextBlockNum(blockNum, blockOccupancy) {
function getRawDataBlockList (line 139) | function getRawDataBlockList(blockNum, blockSize, saveSize, blockOccupan...
function getRawData (line 150) | function getRawData(blockList, blockSize, saveSize, slotArrayBuffer) {
function getSaveFiles (line 156) | function getSaveFiles(slotNum, arrayBuffer) {
function getVolumeInfo (line 228) | function getVolumeInfo(arrayBuffer) {
function createReservedSlot (line 236) | function createReservedSlot(gameSaveFiles) {
function createGameSlot (line 250) | function createGameSlot(gameInfo) {
class SarooSegaSaturnInternalSaveData (line 351) | class SarooSegaSaturnInternalSaveData {
method createWithNewSize (line 352) | static createWithNewSize(/* segaSaturnSaveData, newSize */) {
method gameSaveFilesContainsFile (line 360) | static gameSaveFilesContainsFile(gameSaveFiles, gameId, saveFile) {
method gameSaveFilesAreEqual (line 370) | static gameSaveFilesAreEqual(gameId1, saveFile1, gameId2, saveFile2) {
method upsertGameSaveFiles (line 374) | static upsertGameSaveFiles(existingGameSaveFiles, newGameSaveFiles) {
method isInternalSarooData (line 407) | static isInternalSarooData(arrayBuffer) {
method createFromSarooData (line 416) | static createFromSarooData(arrayBuffer) {
method createFromSaveFiles (line 430) | static createFromSaveFiles(gameSaveFiles) {
method constructor (line 444) | constructor(arrayBuffer, gameSaveFiles, volumeInfo) {
method getGameSaveFiles (line 451) | getGameSaveFiles() {
method getSaveFiles (line 455) | getSaveFiles() {
method getVolumeInfo (line 459) | getVolumeInfo() {
method getArrayBuffer (line 463) | getArrayBuffer() {
FILE: frontend/src/save-formats/SegaSaturn/Saroo/System.js
constant PADDING_VALUE (line 11) | const PADDING_VALUE = 0xFF;
class SarooSegaSaturnSystemSaveData (line 13) | class SarooSegaSaturnSystemSaveData {
method createWithNewSize (line 14) | static createWithNewSize(/* segaSaturnSaveData, newSize */) {
method isSystemSarooData (line 22) | static isSystemSarooData(arrayBuffer) {
method createFromSarooData (line 31) | static createFromSarooData(arrayBuffer) {
method createFromSaveFiles (line 37) | static createFromSaveFiles(saveFiles) {
FILE: frontend/src/save-formats/SegaSaturn/Saroo/Util.js
function getByteAndBitForBlockNum (line 6) | function getByteAndBitForBlockNum(blockNum) {
function isBlockOccupied (line 13) | function isBlockOccupied(blockNum, bitmapUint8Array) {
function setBlockOccupied (line 19) | function setBlockOccupied(blockNum, bitmapUint8Array) {
class SegaSaturnSarooUtil (line 29) | class SegaSaturnSarooUtil {
method getBlockOccupancy (line 30) | static getBlockOccupancy(bitmapArrayBuffer, totalSize, blockSize) {
method createBlockOccupancyBitmap (line 48) | static createBlockOccupancyBitmap(usedBlocks, bitmapSize) {
FILE: frontend/src/save-formats/SegaSaturn/SegaSaturn.js
constant LITTLE_ENDIAN (line 57) | const LITTLE_ENDIAN = false;
constant MAGIC (line 59) | const MAGIC = 'BackUpRam Format';
constant MAGIC_ENCODING (line 60) | const MAGIC_ENCODING = 'US-ASCII';
constant MIN_LENGTH_OF_REPEATING_MAGIC (line 61) | const MIN_LENGTH_OF_REPEATING_MAGIC = 0x40;
constant TOTAL_BLOCKS (line 63) | const TOTAL_BLOCKS = new Map([ // Total number of blocks in a save file,...
constant POSSIBLE_BLOCK_SIZES (line 68) | const POSSIBLE_BLOCK_SIZES = Array.from(TOTAL_BLOCKS.keys());
constant INTERNAL_SAVE_SIZE (line 70) | const INTERNAL_SAVE_SIZE = TOTAL_BLOCKS.get(POSSIBLE_BLOCK_SIZES[0]) * P...
constant CARTRIDGE_SAVE_SIZE (line 71) | const CARTRIDGE_SAVE_SIZE = TOTAL_BLOCKS.get(POSSIBLE_BLOCK_SIZES[1]) * ...
constant RESERVED_BLOCKS (line 73) | const RESERVED_BLOCKS = [0, 1];
constant BLOCK_TYPE_OFFSET (line 75) | const BLOCK_TYPE_OFFSET = 0x00;
constant BLOCK_TYPE_ARCHIVE_ENTRY (line 76) | const BLOCK_TYPE_ARCHIVE_ENTRY = 0x80000000;
constant BLOCK_TYPE_DATA (line 77) | const BLOCK_TYPE_DATA = 0x00000000;
constant DATA_BLOCK_DATA_OFFSET (line 79) | const DATA_BLOCK_DATA_OFFSET = 0x04;
constant ARCHIVE_ENTRY_NAME_OFFSET (line 81) | const ARCHIVE_ENTRY_NAME_OFFSET = 0x04;
constant ARCHIVE_ENTRY_NAME_LENGTH (line 82) | const ARCHIVE_ENTRY_NAME_LENGTH = 11;
constant ARCHIVE_ENTRY_NAME_ENCODING (line 83) | const ARCHIVE_ENTRY_NAME_ENCODING = 'US-ASCII';
constant ARCHIVE_ENTRY_LANGUAGE_OFFSET (line 85) | const ARCHIVE_ENTRY_LANGUAGE_OFFSET = 0x0F;
constant ARCHIVE_ENTRY_COMMENT_OFFSET (line 87) | const ARCHIVE_ENTRY_COMMENT_OFFSET = 0x10;
constant ARCHIVE_ENTRY_COMMENT_LENGTH (line 88) | const ARCHIVE_ENTRY_COMMENT_LENGTH = 10;
constant ARCHIVE_ENTRY_COMMENT_ENCODING (line 89) | const ARCHIVE_ENTRY_COMMENT_ENCODING = 'shift-jis';
constant ARCHIVE_ENTRY_DATE_OFFSET (line 91) | const ARCHIVE_ENTRY_DATE_OFFSET = 0x1A;
constant ARCHIVE_ENTRY_SAVE_SIZE_OFFSET (line 92) | const ARCHIVE_ENTRY_SAVE_SIZE_OFFSET = 0x1E;
constant ARCHIVE_ENTRY_BLOCK_LIST_OFFSET (line 94) | const ARCHIVE_ENTRY_BLOCK_LIST_OFFSET = 0x22;
constant ARCHIVE_ENTRY_BLOCK_LIST_END (line 95) | const ARCHIVE_ENTRY_BLOCK_LIST_END = 0x0000;
constant ARCHIVE_ENTRY_BLOCK_LIST_ENTRY_SIZE (line 96) | const ARCHIVE_ENTRY_BLOCK_LIST_ENTRY_SIZE = 2;
function getBlockSize (line 98) | function getBlockSize(arrayBuffer) {
function checkHeader (line 121) | function checkHeader(arrayBuffer, blockSize) {
function getBlock (line 164) | function getBlock(arrayBuffer, blockSize, blockNumber) {
function makeEmptyBlock (line 168) | function makeEmptyBlock(blockSize) {
function makeSequentialArray (line 172) | function makeSequentialArray(startValue, numValues) {
function makeReservedBlocks (line 176) | function makeReservedBlocks(blockSize) {
function getVolumeInfo (line 189) | function getVolumeInfo(segaSaturnArrayBuffer, blockSize, usedBlocks) {
function readSaveFiles (line 201) | function readSaveFiles(arrayBuffer, blockSize) {
function getNumDataBlocksForSaveFile (line 297) | function getNumDataBlocksForSaveFile(saveFile, blockSize) {
function getBlocksForSaveFile (line 326) | function getBlocksForSaveFile(saveFile, blockSize, startingBlockNumber) {
class SegaSaturnSaveData (line 399) | class SegaSaturnSaveData {
method createEmptySave (line 416) | static createEmptySave(blockSize) {
method isCorrectlyFormatted (line 420) | static isCorrectlyFormatted(arrayBuffer) {
method createWithNewSize (line 429) | static createWithNewSize(/* segaSaturnSaveData, newSize */) {
method createFromSegaSaturnData (line 437) | static createFromSegaSaturnData(arrayBuffer, forceBlockSize) {
method createFromSaveFiles (line 451) | static createFromSaveFiles(saveFiles, blockSize, forceFileSize) {
method constructor (line 496) | constructor(arrayBuffer, saveFiles, volumeInfo) {
method getSaveFiles (line 502) | getSaveFiles() {
method getVolumeInfo (line 506) | getVolumeInfo() {
method getArrayBuffer (line 510) | getArrayBuffer() {
FILE: frontend/src/save-formats/SegaSaturn/Util.js
constant LANGUAGE_DECODE (line 2) | const LANGUAGE_DECODE = new Map([
constant UNKNOWN_LANGUAGE_STRING (line 11) | const UNKNOWN_LANGUAGE_STRING = 'Unknown';
constant UNKNOWN_LANGUAGE_CODE (line 12) | const UNKNOWN_LANGUAGE_CODE = 0xFF;
constant POSSIBLE_LANGUAGE_CODES (line 14) | const POSSIBLE_LANGUAGE_CODES = Array.from(LANGUAGE_DECODE.keys());
constant MILLISECONDS_BETWEEN_EPOCHS (line 17) | const MILLISECONDS_BETWEEN_EPOCHS = 315529200000;
class SegaSaturnUtil (line 19) | class SegaSaturnUtil {
method getLanguageString (line 20) | static getLanguageString(languageEncoded) {
method getLanguageCode (line 31) | static getLanguageCode(languageString) {
method getDate (line 41) | static getDate(dateEncoded) {
method getDateCode (line 49) | static getDateCode(date) {
FILE: frontend/src/save-formats/Wii/ConvertFrom/ConvertFromN64.js
constant EEPROM_SIZES (line 24) | const EEPROM_SIZES = [4 * 1024, 16 * 1024];
constant SRAM_SIZES_SRA (line 25) | const SRAM_SIZES_SRA = [32 * 1024];
constant SRAM_SIZES_FLA (line 26) | const SRAM_SIZES_FLA = [128 * 1024, 256 * 1024];
constant SRAM_SIZES (line 27) | const SRAM_SIZES = SRAM_SIZES_SRA.concat(SRAM_SIZES_FLA);
constant ALL_SIZES (line 28) | const ALL_SIZES = EEPROM_SIZES.concat(SRAM_SIZES);
function convertSram (line 30) | function convertSram(arrayBuffer) {
function convertEeprom (line 51) | function convertEeprom(arrayBuffer) {
FILE: frontend/src/save-formats/Wii/ConvertFrom/ConvertFromPcEngine.js
constant LITTLE_ENDIAN (line 29) | const LITTLE_ENDIAN = true;
constant BLOCK_SIZE (line 30) | const BLOCK_SIZE = 4;
constant BRAM_MEMORY_ADDRESS (line 31) | const BRAM_MEMORY_ADDRESS = 0x8000;
constant BRAM_SIZE (line 32) | const BRAM_SIZE = 2048;
constant POINTER_TO_FIRST_BYTE_AFTER_BRAM_OFFSET (line 33) | const POINTER_TO_FIRST_BYTE_AFTER_BRAM_OFFSET = 4;
constant HEADER_LENGTH (line 34) | const HEADER_LENGTH = 16;
constant SEED_START (line 35) | const SEED_START = 4;
constant FOOTER_LENGTH (line 36) | const FOOTER_LENGTH = 16;
constant MAGIC (line 37) | const MAGIC = 'HUBM';
constant MAGIC_ENCODING (line 38) | const MAGIC_ENCODING = 'US-ASCII';
constant MAGIC_OFFSET (line 39) | const MAGIC_OFFSET = 0;
function getBlock (line 41) | function getBlock(array, currentByte) {
function xorBlocks (line 45) | function xorBlocks(block1, block2) {
function notBlock (line 55) | function notBlock(block) {
FILE: frontend/src/save-formats/Wii/ConvertFrom/ConvertFromSega.js
constant MAGIC (line 25) | const MAGIC = 'VCSD';
constant SRAM (line 26) | const SRAM = 'SRAM';
constant COMPOUND_DATA (line 27) | const COMPOUND_DATA = 'compound data'.concat(String.fromCharCode(0, 0, 0));
constant CHARSET (line 28) | const CHARSET = 'US-ASCII';
constant LITTLE_ENDIAN (line 29) | const LITTLE_ENDIAN = true;
constant GENESIS_EEPROM_GAME_IDS (line 39) | const GENESIS_EEPROM_GAME_IDS = [
constant GENESIS_FRAM_GAME_IDS (line 68) | const GENESIS_FRAM_GAME_IDS = [
function seekEndOfString (line 73) | function seekEndOfString(desiredString, arrayBuffer, startingByteOffset,...
FILE: frontend/src/save-formats/Wii/GetPlatform/GetPlatform.js
constant BASE_URL (line 25) | const BASE_URL = 'https://api.allorigins.win/raw?url=https://www.gametdb...
constant PLATFORMS (line 28) | const PLATFORMS = [
constant REGIONS (line 43) | const REGIONS = {
constant PLATFORMS_LOWERCASE (line 49) | const PLATFORMS_LOWERCASE = PLATFORMS.map((x) => x.toLowerCase());
constant UNKNOWN_PLATFORM (line 51) | const UNKNOWN_PLATFORM = 'Unknown';
constant UNKNOWN_REGION (line 52) | const UNKNOWN_REGION = 'Unknown region';
class GetPlatform (line 54) | class GetPlatform {
method constructor (line 55) | constructor(httpClient) {
method getBaseUrl (line 59) | static getBaseUrl() {
method unknownPlatform (line 63) | static unknownPlatform() {
method unknownRegion (line 67) | static unknownRegion() {
method get (line 71) | async get(gameId) {
FILE: frontend/src/save-formats/Wii/GetPlatform/HttpClient.js
constant NUM_RETRIES (line 4) | const NUM_RETRIES = 3;
constant RETRY_DELAY (line 5) | const RETRY_DELAY = 500;
function getHttpClient (line 7) | function getHttpClient(baseUrl) {
FILE: frontend/src/save-formats/Wii/Wii.js
constant LITTLE_ENDIAN (line 22) | const LITTLE_ENDIAN = false;
constant GAME_TITLE_ENCODING (line 23) | const GAME_TITLE_ENCODING = 'utf-16be';
constant GAME_ID_ENCODING (line 24) | const GAME_ID_ENCODING = 'US-ASCII';
constant ENCRYPTION_ALGORITHM (line 25) | const ENCRYPTION_ALGORITHM = 'aes-128-cbc';
constant SD_KEY (line 26) | const SD_KEY = Buffer.from('ab01b9d8e1622b08afbad84dbfc2a55d', 'hex');
constant SD_INITIALIZATION_VECTOR (line 27) | const SD_INITIALIZATION_VECTOR = Buffer.from('216712e6aa1f689f95c5a22324...
constant MAIN_HEADER_SIZE (line 29) | const MAIN_HEADER_SIZE = 0x20;
constant BANNER_MAGIC (line 30) | const BANNER_MAGIC = 0x5749424E;
constant BACKUP_HEADER_SIZE (line 31) | const BACKUP_HEADER_SIZE = 0x70;
constant BACKUP_HEADER_PADDING_SIZE (line 32) | const BACKUP_HEADER_PADDING_SIZE = 0x10;
constant BACKUP_HEADER_MAGIC (line 33) | const BACKUP_HEADER_MAGIC = 0x426B;
constant FILE_HEADER_SIZE (line 34) | const FILE_HEADER_SIZE = 0x80;
constant FILE_HEADER_MAGIC (line 35) | const FILE_HEADER_MAGIC = 0x03ADF17E;
constant INCORRECT_FORMAT_ERROR_MESSAGE (line 37) | const INCORRECT_FORMAT_ERROR_MESSAGE = 'This does not appear to be a Wii...
function getString (line 39) | function getString(arrayBuffer, byteOffset, byteLength, textDecoder) {
function getNullTerminatedString (line 44) | function getNullTerminatedString(arrayBuffer, byteOffset, textDecoder) {
function parseFile (line 55) | function parseFile(arrayBuffer, currentByte, asciiDecoder) {
class WiiSaveData (line 92) | class WiiSaveData {
method createFromWiiData (line 93) | static createFromWiiData(wiiArrayBuffer) {
method createFromEmulatorData (line 97) | static createFromEmulatorData(emulatorArrayBuffer) {
method constructor (line 107) | constructor(arrayBuffer) {
method getGameTitle (line 172) | getGameTitle() {
method getGameSubtitle (line 176) | getGameSubtitle() {
method getNumberOfFiles (line 180) | getNumberOfFiles() {
method getSizeOfFiles (line 184) | getSizeOfFiles() {
method getFiles (line 188) | getFiles() {
method getTotalSize (line 192) | getTotalSize() {
method getGameId (line 196) | getGameId() {
method getArrayBuffer (line 200) | getArrayBuffer() {
FILE: frontend/src/util/Array.js
class ArrayUtil (line 1) | class ArrayUtil {
method arraysEqual (line 2) | static arraysEqual(a1, a2) {
method createSequentialArray (line 16) | static createSequentialArray(startValue, numValues) {
method createReverseSequentialArray (line 20) | static createReverseSequentialArray(endValue, numValues) {
FILE: frontend/src/util/CompressionGzip.js
class CompressionGzip (line 10) | class CompressionGzip {
method decompress (line 11) | static decompress(arrayBuffer) {
method compress (line 20) | static compress(arrayBuffer) {
FILE: frontend/src/util/CompressionLzo.js
class CompressionLzo (line 4) | class CompressionLzo {
method decompress (line 5) | static decompress(arrayBuffer, uncompressedSize) {
method compress (line 22) | static compress(arrayBuffer) {
FILE: frontend/src/util/CompressionRzip.js
class CompressionRzip (line 5) | class CompressionRzip {
method decompress (line 6) | static decompress(arrayBuffer) {
method compress (line 20) | static compress(arrayBuffer) {
FILE: frontend/src/util/CompressionZlib.js
class CompressionZlib (line 8) | class CompressionZlib {
method decompress (line 9) | static decompress(arrayBuffer) {
method compress (line 18) | static compress(arrayBuffer) {
FILE: frontend/src/util/Endian.js
function swap2ByteWord (line 1) | function swap2ByteWord(inputDataView, outputDataView) {
function swap4ByteWord (line 8) | function swap4ByteWord(inputDataView, outputDataView) {
function swap8ByteWord (line 15) | function swap8ByteWord(inputDataView, outputDataView) {
constant SWAP_FUNCTIONS (line 22) | const SWAP_FUNCTIONS = {
class EndianUtil (line 28) | class EndianUtil {
method swap (line 29) | static swap(inputArrayBuffer, wordSizeInBytes) {
FILE: frontend/src/util/Genesis.js
constant LITTLE_ENDIAN (line 5) | const LITTLE_ENDIAN = false;
constant SMALLEST_SRAM_SAVE (line 25) | const SMALLEST_SRAM_SAVE = 512;
class GenesisUtil (line 27) | class GenesisUtil {
method isEepromSave (line 30) | static isEepromSave(inputArrayBuffer) {
method isByteExpanded (line 41) | static isByteExpanded(inputArrayBuffer) {
method isEmpty (line 56) | static isEmpty(inputArrayBuffer) {
method byteExpand (line 72) | static byteExpand(inputArrayBuffer, fillByte) {
method byteCollapse (line 92) | static byteCollapse(inputArrayBuffer) {
method changeFillByte (line 107) | static changeFillByte(inputArrayBuffer, fillByte) {
FILE: frontend/src/util/Hash.js
class HashUtil (line 5) | class HashUtil {
method getEncodedHash (line 6) | static getEncodedHash(arrayBuffer, hashAlgorithm, hashEncoding) {
FILE: frontend/src/util/Math.js
function countNumberOfBitsUsed (line 3) | function countNumberOfBitsUsed(n) {
class MathUtil (line 16) | class MathUtil {
method getNextLargestPowerOf2 (line 17) | static getNextLargestPowerOf2(n) {
method getNextSmallestPowerOf2 (line 30) | static getNextSmallestPowerOf2(n) {
method isPowerOf2 (line 43) | static isPowerOf2(n) {
method getNextMultipleOf16 (line 51) | static getNextMultipleOf16(n) {
method roundUpToNearest64Bytes (line 60) | static roundUpToNearest64Bytes(num) {
FILE: frontend/src/util/N64.js
constant EEPROM_SIZES (line 6) | const EEPROM_SIZES = [512, 2 * 1024];
constant SRAM_SIZES (line 7) | const SRAM_SIZES = [32 * 1024];
constant FLASH_RAM_SIZES (line 8) | const FLASH_RAM_SIZES = [128 * 1024];
constant N64_WORD_LENGTH (line 10) | const N64_WORD_LENGTH = 4;
class N64Util (line 12) | class N64Util {
method needsEndianSwap (line 13) | static needsEndianSwap(arrayBuffer) {
method isEepromSave (line 17) | static isEepromSave(arrayBuffer) {
method isSramSave (line 21) | static isSramSave(arrayBuffer) {
method isFlashRamSave (line 25) | static isFlashRamSave(arrayBuffer) {
method getFileExtension (line 29) | static getFileExtension(arrayBuffer) {
method endianSwap (line 45) | static endianSwap(inputArrayBuffer) {
FILE: frontend/src/util/Padding.js
function fixCountSoSaveSizeIsPowerOf2 (line 5) | function fixCountSoSaveSizeIsPowerOf2(arrayBuffer, count) {
class PaddingUtil (line 18) | class PaddingUtil {
method attemptFix (line 19) | static attemptFix(testSaveArrayBuffer, brokenSaveArrayBuffer) {
method fileSizeAndPaddingFromStartIsSame (line 50) | static fileSizeAndPaddingFromStartIsSame(arrayBuffer1, arrayBuffer2) {
method getPadFromStartValueAndCount (line 65) | static getPadFromStartValueAndCount(arrayBuffer) {
method getPadFromEndValueAndCount (line 85) | static getPadFromEndValueAndCount(arrayBuffer) {
method removePaddingFromStart (line 105) | static removePaddingFromStart(arrayBuffer, paddingCount) {
method removePaddingFromEnd (line 109) | static removePaddingFromEnd(arrayBuffer, paddingCount) {
method addPaddingToStart (line 113) | static addPaddingToStart(arrayBuffer, padding) {
method addPaddingToEnd (line 127) | static addPaddingToEnd(arrayBuffer, padding) {
method padAtEndToMinimumSize (line 141) | static padAtEndToMinimumSize(arrayBuffer, paddingValue, minimumPadding...
method countPaddingFromStart (line 145) | static countPaddingFromStart(arrayBuffer, padValue) {
method countPaddingFromEnd (line 167) | static countPaddingFromEnd(arrayBuffer, padValue) {
FILE: frontend/src/util/PcEngine.js
constant BRAM_SIZE (line 5) | const BRAM_SIZE = 2048;
constant MAGIC (line 7) | const MAGIC = 'HUBM';
constant MAGIC_ENCODING (line 8) | const MAGIC_ENCODING = 'US-ASCII';
constant MAGIC_OFFSET (line 9) | const MAGIC_OFFSET = 0;
class PcEngineUtil (line 11) | class PcEngineUtil {
method verifyPcEngineData (line 12) | static verifyPcEngineData(arrayBuffer) {
FILE: frontend/src/util/SaveFiles.js
class SaveFilesUtil (line 1) | class SaveFilesUtil {
method resizeRawSave (line 2) | static resizeRawSave(arrayBuffer, newSize, fillValue = 0) {
method getEraseCartridgeSave (line 20) | static getEraseCartridgeSave(arrayBuffer) {
FILE: frontend/src/util/SegaCd.js
constant LITTLE_ENDIAN (line 9) | const LITTLE_ENDIAN = false;
constant BRAM_FORMAT (line 14) | const BRAM_FORMAT = [
constant BRAM_FORMAT_FIXED_OFFSET (line 21) | const BRAM_FORMAT_FIXED_OFFSET = 0x20;
constant DIRECTORY_REPEAT_COUNT (line 23) | const DIRECTORY_REPEAT_COUNT = 4;
constant DIRECTORY_NUM_FREE_BLOCKS_OFFSET (line 24) | const DIRECTORY_NUM_FREE_BLOCKS_OFFSET = 0x10;
constant DIRECTORY_NUM_FILES_OFFSET (line 25) | const DIRECTORY_NUM_FILES_OFFSET = 0x18;
constant BLOCK_SIZE (line 27) | const BLOCK_SIZE = 0x40;
constant NUM_RESERVED_BLOCKS (line 28) | const NUM_RESERVED_BLOCKS = 2;
constant NUM_INITIAL_RESERVED_BLOCKS (line 29) | const NUM_INITIAL_RESERVED_BLOCKS = NUM_RESERVED_BLOCKS + 1;
constant DIRECTORY_SIZE (line 31) | const DIRECTORY_SIZE = 0x40;
constant DIRECTORY_ENTRY_SIZE (line 32) | const DIRECTORY_ENTRY_SIZE = 0x20;
function readRepeatCode (line 35) | function readRepeatCode(arrayBuffer, offsetFromDirectory) {
function writeRepeatCode (line 65) | function writeRepeatCode(arrayBuffer, offsetFromDirectory, value) {
class SegaCdUtil (line 77) | class SegaCdUtil {
method getActualSize (line 80) | static getActualSize(inputArrayBuffer) {
method isCorrectlyFormatted (line 100) | static isCorrectlyFormatted(inputArrayBuffer) {
method truncateToActualSize (line 110) | static truncateToActualSize(inputArrayBuffer) {
method makeEmptySave (line 114) | static makeEmptySave(size) {
method getNumFiles (line 131) | static getNumFiles(inputArrayBuffer) {
method getNumFreeBlocks (line 135) | static getNumFreeBlocks(inputArrayBuffer) {
method setNumFiles (line 139) | static setNumFiles(inputArrayBuffer, value) {
method setNumFreeBlocks (line 143) | static setNumFreeBlocks(inputArrayBuffer, value) {
method getTotalAvailableBlocks (line 147) | static getTotalAvailableBlocks(inputArrayBuffer) {
method resize (line 151) | static resize(inputArrayBuffer, newSize) {
FILE: frontend/src/util/crypto-aes.js
class CryptoAes (line 10) | class CryptoAes {
method decrypt (line 11) | static decrypt(encryptedArrayBuffer, algorithm, key, initializationVec...
method encrypt (line 21) | static encrypt(decryptedArrayBuffer, algorithm, key, initializationVec...
FILE: frontend/src/util/crypto-des.js
class CryptoDes (line 10) | class CryptoDes {
method decrypt (line 11) | static decrypt(encryptedArrayBuffer, algorithm, key, initializationVec...
method encrypt (line 25) | static encrypt(decryptedArrayBuffer, algorithm, key, initializationVec...
FILE: frontend/src/util/util.js
class Util (line 6) | class Util {
method clampValue (line 7) | static clampValue(value, min, max) {
method changeFilenameExtension (line 11) | static changeFilenameExtension(filename, newExtension) {
method removeFilenameExtension (line 15) | static removeFilenameExtension(filename) {
method getFilename (line 19) | static getFilename(filename) {
method getExtension (line 23) | static getExtension(filename) {
method appendToFilename (line 27) | static appendToFilename(filename, stringToAppend) {
method convertDescriptionToFilename (line 31) | static convertDescriptionToFilename(description) {
method bufferToArrayBuffer (line 47) | static bufferToArrayBuffer(b) {
method concatArrayBuffers (line 51) | static concatArrayBuffers(arrayBufferList) {
method setString (line 57) | static setString(arrayBuffer, offset, string, stringEncoding, maxLengt...
method setMagic (line 75) | static setMagic(arrayBuffer, offset, magic, magicEncoding) {
method checkMagic (line 80) | static checkMagic(arrayBuffer, offset, magic, magicEncoding) {
method checkMagicBytes (line 90) | static checkMagicBytes(arrayBuffer, offset, magic) {
method setMagicBytes (line 101) | static setMagicBytes(arrayBuffer, offset, magic) {
method findMagic (line 112) | static findMagic(arrayBuffer, magic, magicEncoding, startOffset = 0) {
method trimNull (line 126) | static trimNull(s) {
method getNullTerminatedArray (line 130) | static getNullTerminatedArray(uint8Array, startOffset, maxLength = -1) {
method readString (line 146) | static readString(uint8Array, startOffset, encoding, length) {
method readNullTerminatedString (line 152) | static readNullTerminatedString(uint8Array, startOffset, encoding, max...
method uint8ArrayToHex (line 158) | static uint8ArrayToHex(uint8Array) {
method copyArrayBuffer (line 162) | static copyArrayBuffer(source) {
method padArrayBuffer (line 170) | static padArrayBuffer(inputArrayBuffer, desiredLength, fillValue) {
method setArrayBufferPortion (line 184) | static setArrayBufferPortion(destination, source, destinationOffset, s...
method fillArrayBufferPortion (line 197) | static fillArrayBufferPortion(arrayBuffer, startIndex, length, fillVal...
method getFilledArrayBuffer (line 208) | static getFilledArrayBuffer(length, fillValue) {
method fillArrayBuffer (line 217) | static fillArrayBuffer(arrayBuffer, fillValue) {
method arrayBuffersEqual (line 221) | static arrayBuffersEqual(arrayBuffer1, arrayBuffer2) {
method allBytesEqual (line 234) | static allBytesEqual(arrayBuffer, value) {
method copyHeaderFromArrayBuffer (line 242) | static copyHeaderFromArrayBuffer(sourceArrayBuffer, headerByteCount, d...
method copyFooterFromArrayBuffer (line 247) | static copyFooterFromArrayBuffer(sourceArrayBuffer, footerByteCount, d...
FILE: frontend/tests/config.js
class Config (line 7) | class Config {
method Create (line 8) | static Create() {
method constructor (line 23) | constructor(configData) {
method get (line 27) | get() {
FILE: frontend/tests/unit/rom-formats/GB/gb.spec.js
constant DIR (line 5) | const DIR = './tests/data/rom-formats/gb';
constant GB_FILENAME (line 7) | const GB_FILENAME = `${DIR}/Zelda - Link's Awakening header.gb`;
constant GBC_FILENAME (line 8) | const GBC_FILENAME = `${DIR}/Wario Land 3 header.gbc`;
FILE: frontend/tests/unit/rom-formats/GBA/gba.spec.js
constant DIR (line 5) | const DIR = './tests/data/rom-formats/gba';
constant FILENAME (line 7) | const FILENAME = `${DIR}/Zelda - Minish Cap header.gba`;
FILE: frontend/tests/unit/rom-formats/NES/nes.spec.js
constant DIR (line 5) | const DIR = './tests/data/rom-formats/nes';
constant INES_FILENAME (line 7) | const INES_FILENAME = `${DIR}/Zelda II - header.nes`;
FILE: frontend/tests/unit/rom-formats/PSP/PspIso.spec.js
constant TEST_ISOS (line 9) | const TEST_ISOS = config.get().testPspIsos;
constant TEST_RETAIL_ISOS (line 10) | const TEST_RETAIL_ISOS = config.get().testPspRetailIsos;
constant TIMEOUT_MS (line 12) | const TIMEOUT_MS = 40000;
constant DIR (line 14) | const DIR = './tests/data/rom-formats/psp';
constant CASTLEVANIA_ISO_FILENAME (line 16) | const CASTLEVANIA_ISO_FILENAME = `${DIR}/retail/Castlevania - Dracula X ...
constant CASTLEVANIA_EXECUTABLE_FILENAME (line 17) | const CASTLEVANIA_EXECUTABLE_FILENAME = `${DIR}/retail/Castlevania - Dra...
constant CASTLEVANIA_EXECUTABLE_PATH (line 18) | const CASTLEVANIA_EXECUTABLE_PATH = '/PSP_GAME/SYSDIR/EBOOT.BIN';
constant CASTLEVANIA_GAME_ID (line 19) | const CASTLEVANIA_GAME_ID = 'ULUS10277';
constant FINAL_FANTASY_TACTICS_ISO_FILENAME (line 21) | const FINAL_FANTASY_TACTICS_ISO_FILENAME = `${DIR}/retail/Final Fantasy ...
constant FINAL_FANTASY_TACTICS_EXECUTABLE_FILENAME (line 22) | const FINAL_FANTASY_TACTICS_EXECUTABLE_FILENAME = `${DIR}/retail/Final F...
constant FINAL_FANTASY_TACTICS_EXECUTABLE_PATH (line 23) | const FINAL_FANTASY_TACTICS_EXECUTABLE_PATH = '/PSP_GAME/SYSDIR/EBOOT.BIN';
constant FINAL_FANTASY_TACTICS_GAME_ID (line 24) | const FINAL_FANTASY_TACTICS_GAME_ID = 'ULUS10297';
constant MEGA_MAN_ISO_FILENAME (line 26) | const MEGA_MAN_ISO_FILENAME = `${DIR}/retail/Mega Man Maverick Hunter X....
constant MEGA_MAN_EXECUTABLE_FILENAME (line 27) | const MEGA_MAN_EXECUTABLE_FILENAME = `${DIR}/retail/Mega Man Maverick Hu...
constant MEGA_MAN_EXECUTABLE_PATH (line 28) | const MEGA_MAN_EXECUTABLE_PATH = '/PSP_GAME/SYSDIR/EBOOT.BIN';
constant MEGA_MAN_GAME_ID (line 29) | const MEGA_MAN_GAME_ID = 'ULUS10068';
constant NEED_FOR_SPEED_ISO_FILENAME (line 31) | const NEED_FOR_SPEED_ISO_FILENAME = `${DIR}/retail/Need for Speed Underg...
constant NEED_FOR_SPEED_EXECUTABLE_FILENAME (line 32) | const NEED_FOR_SPEED_EXECUTABLE_FILENAME = `${DIR}/retail/Need for Speed...
constant NEED_FOR_SPEED_EXECUTABLE_PATH (line 33) | const NEED_FOR_SPEED_EXECUTABLE_PATH = '/PSP_GAME/SYSDIR/EBOOT.BIN';
constant NEED_FOR_SPEED_GAME_ID (line 34) | const NEED_FOR_SPEED_GAME_ID = 'ULUS10007';
constant ENCRYPTED_EXECUTABLE_MAGIC0_ISO (line 36) | const ENCRYPTED_EXECUTABLE_MAGIC0_ISO = `${DIR}/encrypted-executable-mag...
constant ENCRYPTED_EXECUTABLE_MAGIC0 (line 37) | const ENCRYPTED_EXECUTABLE_MAGIC0 = `${DIR}/encrypted-executable-magic0 ...
constant ENCRYPTED_EXECUTABLE_MAGIC0_EXECUTABLE_PATH (line 38) | const ENCRYPTED_EXECUTABLE_MAGIC0_EXECUTABLE_PATH = '/PSP_GAME/SYSDIR/EB...
constant ENCRYPTED_EXECUTABLE_MAGIC0_GAME_ID (line 39) | const ENCRYPTED_EXECUTABLE_MAGIC0_GAME_ID = 'ULUS12345';
constant ENCRYPTED_EXECUTABLE_MAGIC1_ISO (line 41) | const ENCRYPTED_EXECUTABLE_MAGIC1_ISO = `${DIR}/encrypted-executable-mag...
constant ENCRYPTED_EXECUTABLE_MAGIC1 (line 42) | const ENCRYPTED_EXECUTABLE_MAGIC1 = `${DIR}/encrypted-executable-magic1 ...
constant ENCRYPTED_EXECUTABLE_MAGIC1_EXECUTABLE_PATH (line 43) | const ENCRYPTED_EXECUTABLE_MAGIC1_EXECUTABLE_PATH = '/PSP_GAME/SYSDIR/EB...
constant ENCRYPTED_EXECUTABLE_MAGIC1_GAME_ID (line 44) | const ENCRYPTED_EXECUTABLE_MAGIC1_GAME_ID = 'ULUS12345';
constant UNENCRYPTED_EXECUTABLE_ISO (line 46) | const UNENCRYPTED_EXECUTABLE_ISO = `${DIR}/unencrypted-executable.iso`;
constant UNENCRYPTED_EXECUTABLE (line 47) | const UNENCRYPTED_EXECUTABLE = `${DIR}/unencrypted-executable - BOOT.BIN`;
constant UNENCRYPTED_EXECUTABLE_EXECUTABLE_PATH (line 48) | const UNENCRYPTED_EXECUTABLE_EXECUTABLE_PATH = '/PSP_GAME/SYSDIR/BOOT.BIN';
constant UNENCRYPTED_EXECUTABLE_GAME_ID (line 49) | const UNENCRYPTED_EXECUTABLE_GAME_ID = 'ULUS12345';
constant ENCRYPTED_EXECUTABLE_INCORRECT_MAGIC_ISO (line 51) | const ENCRYPTED_EXECUTABLE_INCORRECT_MAGIC_ISO = `${DIR}/encrypted-execu...
constant ENCRYPTED_EXECUTABLE_INCORRECT_MAGIC (line 52) | const ENCRYPTED_EXECUTABLE_INCORRECT_MAGIC = `${DIR}/encrypted-executabl...
constant ENCRYPTED_EXECUTABLE_INCORRECT_MAGIC_EXECUTABLE_PATH (line 53) | const ENCRYPTED_EXECUTABLE_INCORRECT_MAGIC_EXECUTABLE_PATH = '/PSP_GAME/...
constant ENCRYPTED_EXECUTABLE_INCORRECT_MAGIC_GAME_ID (line 54) | const ENCRYPTED_EXECUTABLE_INCORRECT_MAGIC_GAME_ID = 'ULUS12345';
constant ENCRYPTED_EXECUTABLE_ALTERNATIVE_BOOT_ISO (line 56) | const ENCRYPTED_EXECUTABLE_ALTERNATIVE_BOOT_ISO = `${DIR}/encrypted-exec...
constant ENCRYPTED_EXECUTABLE_ALTERNATIVE_BOOT (line 57) | const ENCRYPTED_EXECUTABLE_ALTERNATIVE_BOOT = `${DIR}/encrypted-executab...
constant ENCRYPTED_EXECUTABLE_ALTERNATIVE_BOOT_EXECUTABLE_PATH (line 58) | const ENCRYPTED_EXECUTABLE_ALTERNATIVE_BOOT_EXECUTABLE_PATH = '/PSP_GAME...
constant ENCRYPTED_EXECUTABLE_ALTERNATIVE_BOOT_GAME_ID (line 59) | const ENCRYPTED_EXECUTABLE_ALTERNATIVE_BOOT_GAME_ID = 'ULUS12345';
constant ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_ISO (line 61) | const ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_ISO = `${DIR}/encrypte...
constant ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT (line 62) | const ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT = `${DIR}/encrypted-ex...
constant ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_EXECUTABLE_PATH (line 63) | const ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_EXECUTABLE_PATH = '/PS...
constant ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_GAME_ID (line 64) | const ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_GAME_ID = 'NPJH00100';
constant ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_WRONG_GAME_ID_ISO (line 66) | const ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_WRONG_GAME_ID_ISO = `$...
constant ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_WRONG_GAME_ID (line 67) | const ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_WRONG_GAME_ID = `${DIR...
constant ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_WRONG_GAME_ID_EXECUTABLE_PATH (line 68) | const ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_WRONG_GAME_ID_EXECUTAB...
constant ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_WRONG_GAME_ID_GAME_ID (line 69) | const ENCRYPTED_EXECUTABLE_OTHER_ALTERNATIVE_BOOT_WRONG_GAME_ID_GAME_ID ...
FILE: frontend/tests/unit/rom-formats/SMS/sms.spec.js
constant TEST_RETAIL_ROMS (line 8) | const TEST_RETAIL_ROMS = config.get().testFlashCartRetailGames;
constant DIR (line 10) | const DIR = './tests/data/rom-formats/sms';
constant SMS_FILENAME (line 12) | const SMS_FILENAME = `${DIR}/retail/Phantasy Star (USA, Europe) (Rev A)....
constant ROM_CHECKSUM (line 14) | const ROM_CHECKSUM = 0xEAD8;
FILE: frontend/tests/unit/rom-formats/SegaSaturn/SegaSaturnCueBin.spec.js
constant DIR (line 5) | const DIR = './tests/data/rom-formats/segasaturn';
constant GAME_1_FILENAME (line 7) | const GAME_1_FILENAME = `${DIR}/Thunder Force V - track 1 header.bin`;
constant GAME_2_FILENAME (line 8) | const GAME_2_FILENAME = `${DIR}/Saturn Bomberman - track 1 header.bin`;
FILE: frontend/tests/unit/save-formats/Dreamcast/Dreamcast.spec.js
constant DIR (line 11) | const DIR = './tests/data/save-formats/dreamcast';
constant EMPTY_DREAMCAST_FILENAME (line 13) | const EMPTY_DREAMCAST_FILENAME = `${DIR}/empty_vmu_image.bin`;
constant DREAMCAST_FILENAME (line 15) | const DREAMCAST_FILENAME = `${DIR}/vmu_save_A1.bin`;
constant RECREATED_DREAMCAST_FILENAME (line 16) | const RECREATED_DREAMCAST_FILENAME = `${DIR}/vmu_save_A1-created.bin`;
constant DREAMCAST_SAVE_FILENAME (line 17) | const DREAMCAST_SAVE_FILENAME = [
constant DREAMCAST_EXTRA_SAVE_BLOCKS_FILENAME (line 29) | const DREAMCAST_EXTRA_SAVE_BLOCKS_FILENAME = `${DIR}/need_defrag_chao_ad...
constant DREAMCAST_EXTRA_SAVE_BLOCKS_SAVE_FILENAME (line 30) | const DREAMCAST_EXTRA_SAVE_BLOCKS_SAVE_FILENAME = [
constant DREAMCAST_EMPTY_COMMENTS_FILENAME (line 38) | const DREAMCAST_EMPTY_COMMENTS_FILENAME = `${DIR}/vmu_extended_blocks_2....
constant DREAMCAST_EMPTY_COMMENTS_SAVE_FILENAME (line 39) | const DREAMCAST_EMPTY_COMMENTS_SAVE_FILENAME = [
constant DREAMCAST_GAME_FILENAME (line 43) | const DREAMCAST_GAME_FILENAME = `${DIR}/chao_adv2_mod.bin`;
constant RECREATED_DREAMCAST_GAME_FILENAME (line 44) | const RECREATED_DREAMCAST_GAME_FILENAME = `${DIR}/chao_adv2_mod-created....
constant DREAMCAST_GAME_SAVE_FILENAME (line 45) | const DREAMCAST_GAME_SAVE_FILENAME = [
constant DREAMCAST_INCORRECT_LARGEST_BLOCK_NUMBER_FILENAME (line 49) | const DREAMCAST_INCORRECT_LARGEST_BLOCK_NUMBER_FILENAME = `${DIR}/vmoooo...
constant DREAMCAST_INCORRECT_LARGEST_BLOCK_NUMBER_SAVE_FILENAME (line 50) | const DREAMCAST_INCORRECT_LARGEST_BLOCK_NUMBER_SAVE_FILENAME = [
constant DREAMCAST_INCORRECT_SIZE_FILENAME (line 54) | const DREAMCAST_INCORRECT_SIZE_FILENAME = `${DIR}/vmu5_FUCKED.vmu`;
constant DREAMCAST_GAME_AND_DATA_FILENAME (line 56) | const DREAMCAST_GAME_AND_DATA_FILENAME = `${DIR}/PACit.bin`;
constant RECREATED_DREAMCAST_GAME_AND_DATA_FILENAME (line 57) | const RECREATED_DREAMCAST_GAME_AND_DATA_FILENAME = `${DIR}/PACit-created...
constant DREAMCAST_GAME_AND_DATA_SAVE_FILENAME (line 58) | const DREAMCAST_GAME_AND_DATA_SAVE_FILENAME = [
FILE: frontend/tests/unit/save-formats/Dreamcast/IndividualSaves/Dci.spec.js
constant DIR (line 7) | const DIR = './tests/data/save-formats/dreamcast/individualsaves';
constant DCI_FILENAME (line 9) | const DCI_FILENAME = `${DIR}/kiss-psycho-circus-the-nightmare-child.2934...
constant DCI_RECREATED_FILENAME (line 10) | const DCI_RECREATED_FILENAME = `${DIR}/kiss-psycho-circus-the-nightmare-...
constant RAW_FILENAME (line 11) | const RAW_FILENAME = `${DIR}/kiss-psycho-circus-the-nightmare-child.2934...
constant DCI_NO_COPY_FILENAME (line 13) | const DCI_NO_COPY_FILENAME = `${DIR}/project-justice.882.dci`;
constant DCI_NO_COPY_RECREATED_FILENAME (line 14) | const DCI_NO_COPY_RECREATED_FILENAME = `${DIR}/project-justice.882-recre...
constant RAW_NO_COPY_FILENAME (line 15) | const RAW_NO_COPY_FILENAME = `${DIR}/project-justice.882.bin`;
constant DCI_GAME_FILENAME (line 17) | const DCI_GAME_FILENAME = `${DIR}/tetr.dci`;
constant DCI_GAME_RECREATED_FILENAME (line 18) | const DCI_GAME_RECREATED_FILENAME = `${DIR}/tetr-recreated.dci`;
constant RAW_GAME_FILENAME (line 19) | const RAW_GAME_FILENAME = `${DIR}/tetr.bin`;
FILE: frontend/tests/unit/save-formats/Dreamcast/IndividualSaves/VmiVms.spec.js
constant DIR (line 7) | const DIR = './tests/data/save-formats/dreamcast/individualsaves';
constant VMI_1_FILENAME (line 9) | const VMI_1_FILENAME = `${DIR}/IKARUGA.VMI`;
constant VMI_1_RECREATED_FILENAME (line 10) | const VMI_1_RECREATED_FILENAME = `${DIR}/IKARUGA-recreated.VMI`;
constant VMS_1_FILENAME (line 11) | const VMS_1_FILENAME = `${DIR}/IKARUGA.VMS`;
constant VMI_2_FILENAME (line 13) | const VMI_2_FILENAME = `${DIR}/v93102.vmi`;
constant VMI_2_RECREATED_FILENAME (line 14) | const VMI_2_RECREATED_FILENAME = `${DIR}/v93102-recreated.vmi`;
constant VMS_2_FILENAME (line 15) | const VMS_2_FILENAME = `${DIR}/v93102.VMS`;
constant VMI_3_FILENAME (line 17) | const VMI_3_FILENAME = `${DIR}/v4596.vmi`;
constant VMI_3_RECREATED_FILENAME (line 18) | const VMI_3_RECREATED_FILENAME = `${DIR}/v4596-recreated.vmi`;
constant VMS_3_FILENAME (line 19) | const VMS_3_FILENAME = `${DIR}/v4596.VMS`;
constant VMI_4_FILENAME (line 21) | const VMI_4_FILENAME = `${DIR}/KISSPC.VMI`;
constant VMI_4_RECREATED_FILENAME (line 22) | const VMI_4_RECREATED_FILENAME = `${DIR}/KISSPC-recreated.VMI`;
constant VMS_4_FILENAME (line 23) | const VMS_4_FILENAME = `${DIR}/KISSPC.VMS`;
constant VMI_GAME_FILENAME (line 25) | const VMI_GAME_FILENAME = `${DIR}/FLPPYBRD.VMI`;
constant VMS_GAME_FILENAME (line 26) | const VMS_GAME_FILENAME = `${DIR}/FLPPYBRD.vms`;
FILE: frontend/tests/unit/save-formats/FlashCarts/GB.spec.js
constant DIR (line 6) | const DIR = './tests/data/save-formats/flashcarts/gb';
constant GB_FILENAME (line 8) | const GB_FILENAME = `${DIR}/Final Fantasy Legend II.srm`;
FILE: frontend/tests/unit/save-formats/FlashCarts/GBA/GBA.spec.js
constant DIR (line 6) | const DIR = './tests/data/save-formats/flashcarts/gba';
constant GBA_FILENAME (line 8) | const GBA_FILENAME = `${DIR}/Metroid - Zero Mission (USA).sav`;
FILE: frontend/tests/unit/save-formats/FlashCarts/GBA/GoombaEmulator.spec.js
constant TEST_RETAIL_ROMS (line 8) | const TEST_RETAIL_ROMS = config.get().testFlashCartRetailGames;
constant DIR (line 10) | const DIR = './tests/data/save-formats/flashcarts/gba/goombaemulator';
constant RAW_ZELDA_FILENAME (line 12) | const RAW_ZELDA_FILENAME = `${DIR}/Legend of Zelda, The - Link's Awakeni...
constant GOOMBA_ZELDA_FILENAME (line 13) | const GOOMBA_ZELDA_FILENAME = `${DIR}/Legend of Zelda, The - Link's Awak...
constant RAW_CART_ZELDA_FILENAME (line 15) | const RAW_CART_ZELDA_FILENAME = `${DIR}/Legend of Zelda, The - Link's Aw...
constant GOOMBA_CART_ZELDA_FILENAME (line 16) | const GOOMBA_CART_ZELDA_FILENAME = `${DIR}/Legend of Zelda, The - Link's...
constant ZELDA_ROM_FILENAME (line 18) | const ZELDA_ROM_FILENAME = `${DIR}/retail/Legend of Zelda, The - Link's ...
constant ZELDA_ROM_CHECKSUM (line 19) | const ZELDA_ROM_CHECKSUM = 0x377aa60f;
constant ZELDA_INTERNAL_NAME (line 20) | const ZELDA_INTERNAL_NAME = 'ZELDA';
constant RAW_WARIO_FILENAME (line 22) | const RAW_WARIO_FILENAME = `${DIR}/Wario Land 3.sav`;
constant GOOMBA_WARIO_FILENAME (line 23) | const GOOMBA_WARIO_FILENAME = `${DIR}/Wario Land 3.srm`;
constant WARIO_ROM_CHECKSUM (line 25) | const WARIO_ROM_CHECKSUM = 0xb2380b51;
constant GOOMBA_COMPRESSED_32KB_FILENAME (line 27) | const GOOMBA_COMPRESSED_32KB_FILENAME = `${DIR}/Legend of Zelda, The - L...
constant RAW_COMPRESSED_32KB_FILENAME (line 28) | const RAW_COMPRESSED_32KB_FILENAME = `${DIR}/Legend of Zelda, The - Link...
constant COMPRESSED_ROM_CHECKSUM (line 29) | const COMPRESSED_ROM_CHECKSUM = 0xFB11D9B8;
constant GOOMBA_UNCOMPRESSED_32KB_FILENAME (line 31) | const GOOMBA_UNCOMPRESSED_32KB_FILENAME = `${DIR}/Legend of Zelda, The -...
constant RAW_UNCOMPRESSED_32KB_FILENAME (line 32) | const RAW_UNCOMPRESSED_32KB_FILENAME = `${DIR}/Legend of Zelda, The - Or...
constant UNCOMPRESSED_ROM_CHECKSUM (line 33) | const UNCOMPRESSED_ROM_CHECKSUM = 0x91AF9A29;
FILE: frontend/tests/unit/save-formats/FlashCarts/GBA/PocketNesEmulator.spec.js
constant TEST_RETAIL_ROMS (line 8) | const TEST_RETAIL_ROMS = config.get().testFlashCartRetailGames;
constant DIR (line 10) | const DIR = './tests/data/save-formats/flashcarts/gba/pocketnesemulator';
constant RAW_POCKETNES_ZELDA_FILENAME (line 12) | const RAW_POCKETNES_ZELDA_FILENAME = `${DIR}/Zelda II - The Adventure of...
constant POCKETNES_ZELDA_FILENAME (line 13) | const POCKETNES_ZELDA_FILENAME = `${DIR}/Zelda II - The Adventure of Lin...
constant RAW_CART_ZELDA_FILENAME (line 15) | const RAW_CART_ZELDA_FILENAME = `${DIR}/Zelda II - The Adventure of Link...
constant POCKETNES_CART_ZELDA_FILENAME (line 16) | const POCKETNES_CART_ZELDA_FILENAME = `${DIR}/Zelda II - The Adventure o...
constant ZELDA_ROM_FILENAME (line 18) | const ZELDA_ROM_FILENAME = `${DIR}/retail/Zelda II - The Adventure of Li...
constant ZELDA_ROM_CHECKSUM (line 19) | const ZELDA_ROM_CHECKSUM = 0x4665B580;
FILE: frontend/tests/unit/save-formats/FlashCarts/GBA/SmsAdvanceEmulator.spec.js
constant TEST_RETAIL_ROMS (line 8) | const TEST_RETAIL_ROMS = config.get().testFlashCartRetailGames;
constant DIR (line 10) | const DIR = './tests/data/save-formats/flashcarts/gba/smsadvanceemulator';
constant RAW_PHANTASY_STAR_ON_GBA_FILENAME (line 12) | const RAW_PHANTASY_STAR_ON_GBA_FILENAME = `${DIR}/Phantasy Star (USA, Eu...
constant SMS_ADVANCE_PHANTASY_STAR_ON_GBA_FILENAME (line 13) | const SMS_ADVANCE_PHANTASY_STAR_ON_GBA_FILENAME = `${DIR}/Phantasy Star ...
constant RAW_PHANTASY_STAR_AGAIN_ON_GBA_FILENAME (line 16) | const RAW_PHANTASY_STAR_AGAIN_ON_GBA_FILENAME = `${DIR}/Phantasy Star (U...
constant SMS_ADVANCE_PHANTASY_STAR_AGAIN_ON_GBA_FILENAME (line 17) | const SMS_ADVANCE_PHANTASY_STAR_AGAIN_ON_GBA_FILENAME = `${DIR}/Phantasy...
constant RAW_PHANTASY_STAR_BUNDLED_ON_GBA_FILENAME (line 22) | const RAW_PHANTASY_STAR_BUNDLED_ON_GBA_FILENAME = `${DIR}/Phantasy Star-...
constant SMS_ADVANCE_PHANTASY_STAR_BUNDLED_ON_GBA_FILENAME (line 23) | const SMS_ADVANCE_PHANTASY_STAR_BUNDLED_ON_GBA_FILENAME = `${DIR}/Phanta...
constant RAW_PHANTASY_STAR_FROM_EMULATOR_FILENAME (line 25) | const RAW_PHANTASY_STAR_FROM_EMULATOR_FILENAME = `${DIR}/Phantasy Star (...
constant SMS_ADVANCE_PHANTASY_STAR_FROM_EMULATOR_FILENAME (line 26) | const SMS_ADVANCE_PHANTASY_STAR_FROM_EMULATOR_FILENAME = `${DIR}/Phantas...
constant PHANTASY_STAR_ROM_FILENAME (line 28) | const PHANTASY_STAR_ROM_FILENAME = `${DIR}/retail/Phantasy Star (USA, Eu...
constant PHANTASY_STAR_ROM_CHECKSUM (line 29) | const PHANTASY_STAR_ROM_CHECKSUM = 0xE48D79F0;
FILE: frontend/tests/unit/save-formats/FlashCarts/GameGear.spec.js
constant DIR (line 6) | const DIR = './tests/data/save-formats/flashcarts/gamegear';
constant GG_FILENAME (line 8) | const GG_FILENAME = `${DIR}/Crystalis.sav`;
FILE: frontend/tests/unit/save-formats/FlashCarts/Genesis/MegaEverdrivePro/32X.spec.js
constant DIR (line 6) | const DIR = './tests/data/save-formats/flashcarts/genesis/megaeverdrivep...
constant MEGA_EVERDRIVE_PRO_SRAM_FILENAME (line 8) | const MEGA_EVERDRIVE_PRO_SRAM_FILENAME = `${DIR}/36 Great Holes Starring...
constant MEGA_EVERDRIVE_PRO_FRAM_FILENAME (line 9) | const MEGA_EVERDRIVE_PRO_FRAM_FILENAME = `${DIR}/Knuckles' Chaotix (Japa...
FILE: frontend/tests/unit/save-formats/FlashCarts/Genesis/MegaEverdrivePro/Genesis.spec.js
constant DIR (line 6) | const DIR = './tests/data/save-formats/flashcarts/genesis/megaeverdrivep...
constant MEGA_EVERDRIVE_PRO_SRAM_FILENAME (line 8) | const MEGA_EVERDRIVE_PRO_SRAM_FILENAME = `${DIR}/Phantasy Star II (USA, ...
constant MEGA_EVERDRIVE_PRO_EEPROM_FILENAME (line 9) | const MEGA_EVERDRIVE_PRO_EEPROM_FILENAME = `${DIR}/Wonder Boy in Monster...
constant MEGA_EVERDRIVE_PRO_FRAM_FILENAME (line 10) | const MEGA_EVERDRIVE_PRO_FRAM_FILENAME = `${DIR}/Sonic The Hedgehog 3 (U...
constant EMULATOR_FRAM_FILENAME (line 12) | const EMULATOR_FRAM_FILENAME = `${DIR}/emulator/Sonic The Hedgehog 3 (US...
FILE: frontend/tests/unit/save-formats/FlashCarts/Genesis/MegaEverdrivePro/NES.spec.js
constant DIR (line 6) | const DIR = './tests/data/save-formats/flashcarts/genesis';
constant MEGA_EVERDRIVE_PRO_NES_FILENAME (line 8) | const MEGA_EVERDRIVE_PRO_NES_FILENAME = `${DIR}/megaeverdrivepro/Zelda I...
FILE: frontend/tests/unit/save-formats/FlashCarts/Genesis/MegaEverdrivePro/SMS.spec.js
constant DIR (line 6) | const DIR = './tests/data/save-formats/flashcarts/genesis';
constant MEGA_EVERDRIVE_PRO_SMS_FILENAME (line 8) | const MEGA_EVERDRIVE_PRO_SMS_FILENAME = `${DIR}/megaeverdrivepro/Phantas...
constant KNOCKOFF_EVERDRIVE_SMS_FILENAME (line 10) | const KNOCKOFF_EVERDRIVE_SMS_FILENAME = `${DIR}/megaeverdrivepro/Phantas...
constant RAW_SMS_FILENAME (line 11) | const RAW_SMS_FILENAME = `${DIR}/megaeverdrivepro/Phantasy_Star_USA_Euro...
FILE: frontend/tests/unit/save-formats/FlashCarts/Genesis/MegaEverdrivePro/SegaCd.spec.js
constant DIR (line 7) | const DIR = './tests/data/save-formats/flashcarts/genesis/megaeverdrivep...
constant MEGA_EVERDRIVE_PRO_RAM_CART_FILENAME (line 9) | const MEGA_EVERDRIVE_PRO_RAM_CART_FILENAME = `${DIR}/Popful Mail (USA) (...
constant CONVERTED_TO_RAW_RAM_CART_FILENAME (line 10) | const CONVERTED_TO_RAW_RAM_CART_FILENAME = `${DIR}/Popful Mail (USA) (RE...
constant EMULATOR_RAM_CART_FILENAME (line 12) | const EMULATOR_RAM_CART_FILENAME = `${DIR}/Popful Mail (USA) (RE)-from-e...
constant CONVERTED_TO_MEGA_EVERDRIVE_PRO_RAM_CART_FILENAME (line 13) | const CONVERTED_TO_MEGA_EVERDRIVE_PRO_RAM_CART_FILENAME = `${DIR}/Popful...
constant MEGA_EVERDRIVE_PRO_INTERNAL_MEMORY_FILENAME (line 15) | const MEGA_EVERDRIVE_PRO_INTERNAL_MEMORY_FILENAME = `${DIR}/Dark Wizard ...
constant EMPTY_INTERNAL_MEMORY_SAVE (line 17) | const EMPTY_INTERNAL_MEMORY_SAVE = SegaCdUtil.makeEmptySave(SegaCdUtil.I...
constant EMPTY_FLASH_CART_RAM_CART_SAVE (line 18) | const EMPTY_FLASH_CART_RAM_CART_SAVE = SegaCdUtil.makeEmptySave(GenesisM...
constant EMPTY_EMULATOR_RAM_CART_SAVE (line 19) | const EMPTY_EMULATOR_RAM_CART_SAVE = SegaCdUtil.makeEmptySave(GenesisMeg...
FILE: frontend/tests/unit/save-formats/FlashCarts/Genesis/MegaSD/32X.spec.js
constant DIR (line 6) | const DIR = './tests/data/save-formats/flashcarts/genesis/megasd';
constant MEGA_SD_NEW_SRAM_FILENAME (line 8) | const MEGA_SD_NEW_SRAM_FILENAME = `${DIR}/36 Great Holes Starring Fred C...
constant MEGA_SD_RAW_NEW_SRAM_FILENAME (line 9) | const MEGA_SD_RAW_NEW_SRAM_FILENAME = `${DIR}/36 Great Holes Starring Fr...
constant MEGA_SD_NEW_FRAM_FILENAME (line 11) | const MEGA_SD_NEW_FRAM_FILENAME = `${DIR}/Knuckles' Chaotix (Japan, USA)...
constant MEGA_SD_RAW_NEW_FRAM_FILENAME (line 12) | const MEGA_SD_RAW_NEW_FRAM_FILENAME = `${DIR}/Knuckles' Chaotix (Japan, ...
FILE: frontend/tests/unit/save-formats/FlashCarts/Genesis/MegaSD/Genesis.spec.js
constant DIR (line 6) | const DIR = './tests/data/save-formats/flashcarts/genesis/megasd';
constant MEGA_SD_NEW_SRAM_PADDED_00_FILENAME (line 9) | const MEGA_SD_NEW_SRAM_PADDED_00_FILENAME = `${DIR}/Phantasy Star II (US...
constant MEGA_SD_RAW_NEW_SRAM_PADDED_00_FILENAME (line 10) | const MEGA_SD_RAW_NEW_SRAM_PADDED_00_FILENAME = `${DIR}/Phantasy Star II...
constant MEGA_SD_NEW_SRAM_PADDED_00_2_FILENAME (line 12) | const MEGA_SD_NEW_SRAM_PADDED_00_2_FILENAME = `${DIR}/Sword of Vermilion...
constant MEGA_SD_RAW_NEW_SRAM_PADDED_00_2_FILENAME (line 13) | const MEGA_SD_RAW_NEW_SRAM_PADDED_00_2_FILENAME = `${DIR}/Sword of Vermi...
constant MEGA_SD_NEW_SRAM_PADDED_FF_3_FILENAME (line 15) | const MEGA_SD_NEW_SRAM_PADDED_FF_3_FILENAME = `${DIR}/Phantasy Star IV (...
constant MEGA_SD_RAW_NEW_SRAM_PADDED_FF_3_FILENAME (line 16) | const MEGA_SD_RAW_NEW_SRAM_PADDED_FF_3_FILENAME = `${DIR}/Phantasy Star ...
constant MEGA_SD_NEW_SRAM_PADDED_00_3_FILENAME (line 17) | const MEGA_SD_NEW_SRAM_PADDED_00_3_FILENAME = `${DIR}/Phantasy Star IV (...
constant MEGA_SD_NEW_EEPROM_FILENAME (line 19) | const MEGA_SD_NEW_EEPROM_FILENAME = `${DIR}/Wonder Boy in Monster World ...
constant MEGA_SD_RAW_NEW_EEPROM_FILENAME (line 20) | const MEGA_SD_RAW_NEW_EEPROM_FILENAME = `${DIR}/Wonder Boy in Monster Wo...
constant MEGA_SD_NEW_FRAM_FILENAME (line 22) | const MEGA_SD_NEW_FRAM_FILENAME = `${DIR}/Sonic the Hedgehog 3 (USA)-new...
constant MEGA_SD_RAW_NEW_FR
Condensed preview — 936 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,693K chars).
[
{
"path": ".gitattributes",
"chars": 37,
"preview": "terraform/* linguist-detectable=false"
},
{
"path": ".gitignore",
"chars": 506,
"preview": ".DS_Store\n/test\n/frontend/stats.json\n/frontend/tests/data/rom-formats/psp/retail/*\n/frontend/tests/data/rom-formats/psp/"
},
{
"path": ".vscode/settings.json",
"chars": 61,
"preview": "{\n \"vue.server.path\": \"node_modules/@vue/language-server\",\n}"
},
{
"path": "LICENSE",
"chars": 35149,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "README.md",
"chars": 18773,
"preview": "# Save File Converter\n\nWeb-based tool to convert save files from retro game consoles to different formats\n\n![Save file c"
},
{
"path": "frontend/.editorconfig",
"chars": 160,
"preview": "[*.{js,jsx,ts,tsx,vue}]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ntrim_trailing_whitespace = true\ninsert_fin"
},
{
"path": "frontend/.eslintignore",
"chars": 43,
"preview": "src/save-formats/PSP/psp-encryption/*\nlib/*"
},
{
"path": "frontend/.gitignore",
"chars": 230,
"preview": ".DS_Store\nnode_modules\n/dist\n\n# local env files\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug.log*\nyarn-debug.log*\nyarn"
},
{
"path": "frontend/.nvmrc",
"chars": 8,
"preview": "16.19.1\n"
},
{
"path": "frontend/README.md",
"chars": 206,
"preview": "# Vue 3 upgrade notes\n\nNeed to undo these changes made for vscode: https://github.com/vuejs/language-tools/wiki/Vue-2-Co"
},
{
"path": "frontend/babel.config.js",
"chars": 76,
"preview": "module.exports = {\n presets: [\n '@vue/cli-plugin-babel/preset',\n ],\n};\n"
},
{
"path": "frontend/buildspec.yml",
"chars": 408,
"preview": "version: 0.2\n\nphases:\n install:\n runtime-versions:\n nodejs: 16\n commands:\n - apt-get update -y\n - "
},
{
"path": "frontend/lib/minlzo-js/lzo1x.js",
"chars": 21241,
"preview": "// This file is copied from https://github.com/euan-forrester/minilzo-js\n// Which was forked from https://github.com/abr"
},
{
"path": "frontend/package.json",
"chars": 2965,
"preview": "{\n \"name\": \"save-file-converter\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"serve\": \"vue-cli-service"
},
{
"path": "frontend/public/browserconfig.xml",
"chars": 246,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n <msapplication>\n <tile>\n <square150x150logo"
},
{
"path": "frontend/public/index.html",
"chars": 1890,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "frontend/public/robots.txt",
"chars": 49,
"preview": "Sitemap: http://savefileconverter.com/sitemap.txt"
},
{
"path": "frontend/public/site.webmanifest",
"chars": 263,
"preview": "{\"name\":\"\",\"short_name\":\"\",\"icons\":[{\"src\":\"/android-chrome-192x192.png\",\"sizes\":\"192x192\",\"type\":\"image/png\"},{\"src\":\"/"
},
{
"path": "frontend/public/sitemap.txt",
"chars": 1316,
"preview": "https://savefileconverter.com/#/retron-5\nhttps://savefileconverter.com/#/retron-5/erase-save\nhttps://savefileconverter.c"
},
{
"path": "frontend/src/App.vue",
"chars": 4580,
"preview": "<template>\n <div id=\"app\">\n <div id=\"nav\">\n <b-row>\n <b-col class=\"nav-row\">\n <router-link to=\""
},
{
"path": "frontend/src/components/AdvancedUtils.vue",
"chars": 2703,
"preview": "<template>\n <div>\n <b-container>\n <b-tabs v-model=\"tabIndex\" content-class=\"mt-3\" justified>\n\n <b-tab ti"
},
{
"path": "frontend/src/components/ByteExpandContract.vue",
"chars": 1811,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n "
},
{
"path": "frontend/src/components/CompressionDecompression.vue",
"chars": 1266,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n "
},
{
"path": "frontend/src/components/CompressionType.vue",
"chars": 2153,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n "
},
{
"path": "frontend/src/components/ConversionDirection.vue",
"chars": 2225,
"preview": "<template>\n <div>\n <mq-layout :mq=\"this.horizontalLayout\">\n <b-form-group class=\"horizontal-arrangement\" v-slot"
},
{
"path": "frontend/src/components/ConvertDreamcast.vue",
"chars": 16540,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertFlashCarts.vue",
"chars": 24028,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertGameCube.vue",
"chars": 17749,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertGbaActionReplay.vue",
"chars": 6163,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertGbaGameShark.vue",
"chars": 8179,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertGbaGameSharkSP.vue",
"chars": 6939,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertMister.vue",
"chars": 15986,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertN64DexDrive.vue",
"chars": 11467,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertN64Mempack.vue",
"chars": 9095,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertNintendoSwitchOnline.vue",
"chars": 11368,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertOnlineEmulators.vue",
"chars": 11691,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertPs1DexDrive.vue",
"chars": 12195,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertPs1Emulator.vue",
"chars": 7570,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertPs1Ps3.vue",
"chars": 11067,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertPs1Psp.vue",
"chars": 12023,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertRetron5.vue",
"chars": 5126,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertSegaCd.vue",
"chars": 14811,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertSegaSaturnEmulator.vue",
"chars": 10082,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertSegaSaturnSaroo.vue",
"chars": 19702,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertSrmSav.vue",
"chars": 5984,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/ConvertWii.vue",
"chars": 10687,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/DecryptPsp.vue",
"chars": 10008,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/DreamcastIndividualSaveTypeSelector.vue",
"chars": 1189,
"preview": "<template>\n <b-form-group v-slot=\"{ ariaDescribedby }\">\n <b-form-radio-group\n v-model=\"valueLocal\"\n :optio"
},
{
"path": "frontend/src/components/EndiannessWordSize.vue",
"chars": 1322,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n "
},
{
"path": "frontend/src/components/EraseSave.vue",
"chars": 3211,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/FileInfo.vue",
"chars": 2729,
"preview": "<template>\n <b-collapse appear id=\"id\" :visible=\"display\">\n <b-list-group>\n <b-list-group-item :variant=\"fileNameVa"
},
{
"path": "frontend/src/components/FileList.vue",
"chars": 2079,
"preview": "<template>\n <b-collapse appear :visible=\"display\">\n <b-alert variant=\"info\" :show=\"(this.files !== null) && (this.fi"
},
{
"path": "frontend/src/components/FileReader.vue",
"chars": 1821,
"preview": "<template>\n <b-form-file\n @input=\"loadFile\"\n v-model=\"file\"\n class=\"text-left\"\n :placeholder=\"this.placehol"
},
{
"path": "frontend/src/components/FileSize.vue",
"chars": 636,
"preview": "<template>\n <b-collapse appear id=\"id\" :visible=\"display\">\n <b-list-group>\n <b-list-group-item :variant=\"this.v"
},
{
"path": "frontend/src/components/FlashCartType.vue",
"chars": 5475,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n "
},
{
"path": "frontend/src/components/GameCubeEncodingSelector.vue",
"chars": 1580,
"preview": "<template>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n <b-form-s"
},
{
"path": "frontend/src/components/HeaderFooter.vue",
"chars": 1219,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n "
},
{
"path": "frontend/src/components/HelpButton.vue",
"chars": 778,
"preview": "<template>\n <b-col cols=1>\n <!-- Note that we choose a button because we need to render out an <a> element in order "
},
{
"path": "frontend/src/components/IndividualSavesOrMemoryCardSelector.vue",
"chars": 1073,
"preview": "<template>\n <b-form-group v-slot=\"{ ariaDescribedby }\">\n <b-form-radio-group\n v-model=\"valueLocal\"\n :optio"
},
{
"path": "frontend/src/components/InputFile.vue",
"chars": 1645,
"preview": "<template>\n <div>\n <b-row no-gutters>\n <b-col :cols=\"this.leaveRoomForHelpIcon ? 11 : 12\" sm=\"12\">\n <div"
},
{
"path": "frontend/src/components/InputNumber.vue",
"chars": 2981,
"preview": "<template>\n <div>\n <b-row no-gutters>\n <b-col v-if=\"this.labelText !== null\" cols=\"5\" sm=\"4\" align-self=\"center"
},
{
"path": "frontend/src/components/MemoryCardSelector.vue",
"chars": 846,
"preview": "<template>\n <b-form-group v-slot=\"{ ariaDescribedby }\">\n <b-form-radio-group\n v-model=\"valueLocal\"\n :optio"
},
{
"path": "frontend/src/components/MisterPlatform.vue",
"chars": 2965,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n "
},
{
"path": "frontend/src/components/NintendoSwitchOnlinePlatform.vue",
"chars": 1441,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n "
},
{
"path": "frontend/src/components/OnlineEmulatorPlatform.vue",
"chars": 1366,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n "
},
{
"path": "frontend/src/components/OutputFilename.vue",
"chars": 1424,
"preview": "<template>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col :cols=\"this.leaveRoomForHelpIcon ? 11 : 12\" "
},
{
"path": "frontend/src/components/OutputFilesize.vue",
"chars": 2464,
"preview": "<template>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n <b-form-s"
},
{
"path": "frontend/src/components/PadFillByte.vue",
"chars": 1199,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n "
},
{
"path": "frontend/src/components/RegionViewer.vue",
"chars": 627,
"preview": "<template>\n <b-collapse appear id=\"id\" :visible=\"this.regionName !== null\">\n <b-list-group>\n <b-list-group-item cla"
},
{
"path": "frontend/src/components/Retron5EraseSave.vue",
"chars": 3919,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/SegaCdSaveTypeSelector.vue",
"chars": 1176,
"preview": "<template>\n <b-form-group v-slot=\"{ ariaDescribedby }\">\n <b-form-radio-group\n v-model=\"valueLocal\"\n :optio"
},
{
"path": "frontend/src/components/TabAddHeaderFooter.vue",
"chars": 4529,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=7 lg=5 xl=4 align-self="
},
{
"path": "frontend/src/components/TabByteExpansion.vue",
"chars": 4866,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=7 lg=5 xl=4 align-self="
},
{
"path": "frontend/src/components/TabCompression.vue",
"chars": 7389,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=7 lg=5 xl=4 align-self="
},
{
"path": "frontend/src/components/TabEndianSwap.vue",
"chars": 3448,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=7 lg=5 xl=4 align-self="
},
{
"path": "frontend/src/components/TabFileCompare.vue",
"chars": 2945,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=7 lg=5 xl=4 align-self="
},
{
"path": "frontend/src/components/TabRemoveHeaderFooter.vue",
"chars": 3718,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=7 lg=5 xl=4 align-self="
},
{
"path": "frontend/src/components/TabResize.vue",
"chars": 4507,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=7 lg=5 xl=4 align-self="
},
{
"path": "frontend/src/components/TabSlice.vue",
"chars": 5480,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=7 lg=5 xl=4 align-self="
},
{
"path": "frontend/src/components/TroubleshootingUtils.vue",
"chars": 6494,
"preview": "<template>\n <div>\n <b-container>\n <b-row no-gutters align-h=\"center\" align-v=\"start\">\n <b-col sm=12 md=5"
},
{
"path": "frontend/src/components/WiiVcPlatform.vue",
"chars": 2111,
"preview": "<template>\n <div>\n <b-row no-gutters align-h=\"start\" align-v=\"center\">\n <b-col cols=11 sm=12>\n <div>\n "
},
{
"path": "frontend/src/main.js",
"chars": 408,
"preview": "import Vue from 'vue';\nimport './plugins/bootstrap-vue';\nimport './plugins/fontawesome-vue';\nimport './plugins/mediaquer"
},
{
"path": "frontend/src/plugins/bootstrap-vue.js",
"chars": 1484,
"preview": "import Vue from 'vue';\n\n// Reduce bundle size by pulling in only what we need from bootstrap.\n// We could further optimi"
},
{
"path": "frontend/src/plugins/fontawesome-vue.js",
"chars": 822,
"preview": "import Vue from 'vue';\n\nimport { library, dom } from '@fortawesome/fontawesome-svg-core';\nimport {\n faArrowCircleLeft,\n"
},
{
"path": "frontend/src/plugins/google-tag-manager-vue.js",
"chars": 774,
"preview": "import Vue from 'vue';\nimport VueGtm from '@gtm-support/vue2-gtm';\nimport router from '../router/index';\n\nVue.use(VueGtm"
},
{
"path": "frontend/src/plugins/mediaquery-vue.js",
"chars": 289,
"preview": "import Vue from 'vue';\nimport VueMq from 'vue-mq';\n\nVue.use(VueMq, {\n breakpoints: { // Values copied from https://boot"
},
{
"path": "frontend/src/plugins/vue-async-computed.js",
"chars": 97,
"preview": "import Vue from 'vue';\n\nimport AsyncComputed from 'vue-async-computed';\n\nVue.use(AsyncComputed);\n"
},
{
"path": "frontend/src/rom-formats/PspIso.js",
"chars": 7135,
"preview": "// Extracts executables from a PSP .ISO image\n// This is based on https://github.com/hrydgard/ppsspp/blob/master/Core/PS"
},
{
"path": "frontend/src/rom-formats/SegaSaturnCueBin.js",
"chars": 798,
"preview": "// Extracts some information from a Sega Saturn .bin file for a game in .cue/.bin format\n// Note that it must be the fir"
},
{
"path": "frontend/src/rom-formats/gb.js",
"chars": 2276,
"preview": "// Extracts some information from a Game Boy ROM.\n// Information can be found here: https://gbdev.gg8.se/wiki/articles/T"
},
{
"path": "frontend/src/rom-formats/gba.js",
"chars": 1201,
"preview": "// Extracts some information from a Game Boy Advance ROM.\n// Based on https://github.com/visualboyadvance-m/visualboyadv"
},
{
"path": "frontend/src/rom-formats/nes.js",
"chars": 1351,
"preview": "/* eslint-disable no-bitwise */\n\n// Extracts some information from an NES ROM.\n//\n// There are 2 different formats: iNES"
},
{
"path": "frontend/src/rom-formats/sms.js",
"chars": 763,
"preview": "/* eslint-disable no-bitwise */\n\n// Extracts some information from an SMS ROM.\n//\n// More info at: https://www.smspower."
},
{
"path": "frontend/src/router/index.js",
"chars": 5923,
"preview": "import Vue from 'vue';\nimport VueRouter from 'vue-router';\n\nVue.use(VueRouter);\n\nconst routes = [\n {\n path: '/',\n "
},
{
"path": "frontend/src/save-formats/Dreamcast/Components/Basics.js",
"chars": 1587,
"preview": "export default class DreamcastBasics {\n static LITTLE_ENDIAN = true;\n\n static WORD_SIZE_IN_BYTES = 4;\n\n static BLOCK_"
},
{
"path": "frontend/src/save-formats/Dreamcast/Components/Directory.js",
"chars": 1596,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nFormat taken from https://mc.pp.se/dc/vms/flashmem.html\n\nThe directory is just a seq"
},
{
"path": "frontend/src/save-formats/Dreamcast/Components/DirectoryEntry.js",
"chars": 6735,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nFormat taken from\n - https://mc.pp.se/dc/vms/flashmem.html\n - https://github.com/gyr"
},
{
"path": "frontend/src/save-formats/Dreamcast/Components/FileAllocationTable.js",
"chars": 4210,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nDreamcast file allocation table block\n\nFormat taken from https://mc.pp.se/dc/vms/fla"
},
{
"path": "frontend/src/save-formats/Dreamcast/Components/SystemInfo.js",
"chars": 9789,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nDreamcast system info block\n\nFormat taken from:\n- https://vmu.falcogirgis.net/filesy"
},
{
"path": "frontend/src/save-formats/Dreamcast/Dreamcast.js",
"chars": 11841,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nThe format for a memory card image\n\nTaken from https://mc.pp.se/dc/vms/flashmem.html"
},
{
"path": "frontend/src/save-formats/Dreamcast/IndividualSaves/Dci.js",
"chars": 1850,
"preview": "/* eslint-disable no-bitwise */\n\n/*\n.DCI is a directory entry concatenated with the raw save data\n\nNote that the startin"
},
{
"path": "frontend/src/save-formats/Dreamcast/IndividualSaves/VmiVms.js",
"chars": 7916,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nThe standard format for individual saves on the Dreamcast appears to be the .VMI/.VM"
},
{
"path": "frontend/src/save-formats/Dreamcast/Util.js",
"chars": 6146,
"preview": "/* eslint-disable no-bitwise */\n\nimport DreamcastBasics from './Components/Basics';\n\nimport Util from '../../util/util';"
},
{
"path": "frontend/src/save-formats/FlashCarts/GB.js",
"chars": 1317,
"preview": "import SaveFilesUtil from '../../util/SaveFiles';\n\nexport default class GbFlashCartSaveData {\n static createFromFlashCa"
},
{
"path": "frontend/src/save-formats/FlashCarts/GBA/EmulatorBase.js",
"chars": 13066,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nBased on the Goomba Save Manager, specifically:\n- Ignore the first 4 bytes of the fi"
},
{
"path": "frontend/src/save-formats/FlashCarts/GBA/GBA.js",
"chars": 1325,
"preview": "import SaveFilesUtil from '../../../util/SaveFiles';\n\nexport default class GbaFlashCartSaveData {\n static createFromFla"
},
{
"path": "frontend/src/save-formats/FlashCarts/GBA/GoombaEmulator.js",
"chars": 3615,
"preview": "// Find it at https://github.com/Dwedit/goombacolor/releases\n\nimport EmulatorBase from './EmulatorBase';\nimport Util fro"
},
{
"path": "frontend/src/save-formats/FlashCarts/GBA/PocketNesEmulator.js",
"chars": 5837,
"preview": "/* eslint-disable no-bitwise */\n\n// Find it at https://github.com/Dwedit/PocketNES/releases\n\nimport EmulatorBase from '."
},
{
"path": "frontend/src/save-formats/FlashCarts/GBA/SmsAdvanceEmulator.js",
"chars": 5508,
"preview": "/* eslint-disable no-bitwise */\n\n// Find it at https://archive.org/details/smsadvance-25-bin\n\nimport EmulatorBase from '"
},
{
"path": "frontend/src/save-formats/FlashCarts/GameGear.js",
"chars": 1236,
"preview": "import SaveFilesUtil from '../../util/SaveFiles';\n\nexport default class GameGearFlashCartSaveData {\n static createFromF"
},
{
"path": "frontend/src/save-formats/FlashCarts/Genesis/MegaEverdrivePro/32X.js",
"chars": 200,
"preview": "import GenesisMegaEverdriveProGenesisFlashCartSaveData from './Genesis';\n\nexport default class GenesisMegaEverdrivePro32"
},
{
"path": "frontend/src/save-formats/FlashCarts/Genesis/MegaEverdrivePro/Genesis.js",
"chars": 1944,
"preview": "import SaveFilesUtil from '../../../../util/SaveFiles';\nimport GenesisUtil from '../../../../util/Genesis';\n\nconst FILL_"
},
{
"path": "frontend/src/save-formats/FlashCarts/Genesis/MegaEverdrivePro/NES.js",
"chars": 1310,
"preview": "import SaveFilesUtil from '../../../../util/SaveFiles';\n\nexport default class GenesisMegaEverdriveProNesFlashCartSaveDat"
},
{
"path": "frontend/src/save-formats/FlashCarts/Genesis/MegaEverdrivePro/SMS.js",
"chars": 2252,
"preview": "import SaveFilesUtil from '../../../../util/SaveFiles';\nimport GenesisUtil from '../../../../util/Genesis';\n\n// Some kno"
},
{
"path": "frontend/src/save-formats/FlashCarts/Genesis/MegaEverdrivePro/SegaCd.js",
"chars": 6069,
"preview": "import SegaCdUtil from '../../../../util/SegaCd';\n\nexport default class GenesisMegaEverdriveProSegaCdFlashCartSaveData {"
},
{
"path": "frontend/src/save-formats/FlashCarts/Genesis/MegaSD/32X.js",
"chars": 844,
"preview": "import GenesisBase from './GenesisBase';\n\nconst MEGA_SD_NEW_STYLE_PADDING_BYTE_SRAM = 0x00; // Smaller sample size with "
},
{
"path": "frontend/src/save-formats/FlashCarts/Genesis/MegaSD/Genesis.js",
"chars": 894,
"preview": "import GenesisBase from './GenesisBase';\n\nconst MEGA_SD_NEW_STYLE_PADDING_BYTE_SRAM = 0x00; // 3/4 of the new style file"
},
{
"path": "frontend/src/save-formats/FlashCarts/Genesis/MegaSD/GenesisBase.js",
"chars": 7390,
"preview": "// There are two \"styles\" of save files that can be generated by a Mega SD:\n// - The \"old style\" (from earlier firmware,"
},
{
"path": "frontend/src/save-formats/FlashCarts/Genesis/MegaSD/SMS.js",
"chars": 3101,
"preview": "// SMS files on the Mega SD appear to just have \"BUP2\" prepended to the start of the file.\n// This is the same as the \"n"
},
{
"path": "frontend/src/save-formats/FlashCarts/Genesis/MegaSD/SegaCd.js",
"chars": 6758,
"preview": "// The MegaSD produces a single file for Sega CD that's a concatenation of:\n//\n// - Magic\n// - Internal memory\n// - RAM "
},
{
"path": "frontend/src/save-formats/FlashCarts/N64/GB64Emulator.js",
"chars": 12492,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nGB64 is a GB/GBC emulator that runs on the N64\n\nThe save format has a header which i"
},
{
"path": "frontend/src/save-formats/FlashCarts/N64/N64.js",
"chars": 1849,
"preview": "/*\nSwaps the endianness of N64 save data for SRAM and FlashRAM files. EEPROM files do not need to be endian swapped\n*/\n\n"
},
{
"path": "frontend/src/save-formats/FlashCarts/N64/NES.js",
"chars": 2915,
"preview": "// Some N64 flash carts support an NES core that runs on the FPGA, as opposed to the Neon64 emulator supported by others"
},
{
"path": "frontend/src/save-formats/FlashCarts/N64/Neon64Emulator.js",
"chars": 3943,
"preview": "/*\nNeon64 is an NES emulator that runs on the N64\n\nDetails on the save format: https://github.com/hcs64/neon64v2/issues/"
},
{
"path": "frontend/src/save-formats/FlashCarts/NES.js",
"chars": 1218,
"preview": "import SaveFilesUtil from '../../util/SaveFiles';\n\nexport default class NesFlashCartSaveData {\n static createFromFlashC"
},
{
"path": "frontend/src/save-formats/FlashCarts/PcEngine.js",
"chars": 1099,
"preview": "import PcEngineUtil from '../../util/PcEngine';\n\nexport default class PcEngineFlashCartSaveData {\n static createFromFla"
},
{
"path": "frontend/src/save-formats/FlashCarts/SMS.js",
"chars": 1212,
"preview": "import SaveFilesUtil from '../../util/SaveFiles';\n\nexport default class SmsFlashCartSaveData {\n static createFromFlashC"
},
{
"path": "frontend/src/save-formats/FlashCarts/SNES/GB.js",
"chars": 1356,
"preview": "import SaveFilesUtil from '../../../util/SaveFiles';\n\nexport default class SuperGameboyFlashCartSaveData {\n static crea"
},
{
"path": "frontend/src/save-formats/FlashCarts/SNES/SNES.js",
"chars": 1229,
"preview": "import SaveFilesUtil from '../../../util/SaveFiles';\n\nexport default class SnesFlashCartSaveData {\n static createFromFl"
},
{
"path": "frontend/src/save-formats/GBA/ActionReplay.js",
"chars": 1551,
"preview": "/*\nThe Action Replay data format is just a raw file with no header or footer.\n*/\n\nimport SaveFilesUtil from '../../util/"
},
{
"path": "frontend/src/save-formats/GBA/GameShark.js",
"chars": 12649,
"preview": "/* eslint no-bitwise: [\"error\", { \"allow\": [\"&\", \">>>\", \"<<\"] }] */\n\n/*\nThe GameShark data format header contains a head"
},
{
"path": "frontend/src/save-formats/GBA/GameSharkSP.js",
"chars": 2634,
"preview": "/*\nThe GameShark SP data format header contains a header then the raw save.\nThe header is of fixed length. The full form"
},
{
"path": "frontend/src/save-formats/GameCube/Components/Basics.js",
"chars": 138,
"preview": "export default class GameCubeBasics {\n static LITTLE_ENDIAN = false;\n\n static BLOCK_SIZE = 0x2000;\n\n static NUM_RESER"
},
{
"path": "frontend/src/save-formats/GameCube/Components/BlockAllocationTable.js",
"chars": 5714,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nThe directory entry format is reused in a few different gamecube file type\n\nHere's t"
},
{
"path": "frontend/src/save-formats/GameCube/Components/Directory.js",
"chars": 4253,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nThe directory entry format is reused in a few different gamecube file type\n\nHere's t"
},
{
"path": "frontend/src/save-formats/GameCube/Components/DirectoryEntry.js",
"chars": 7348,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nThe directory entry format is reused in a few different gamecube file type\n\nHere's t"
},
{
"path": "frontend/src/save-formats/GameCube/Components/Header.js",
"chars": 8596,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nHeader: https://github.com/dolphin-emu/dolphin/blob/ee27f03a4387baca6371a06068274135"
},
{
"path": "frontend/src/save-formats/GameCube/GameCube.js",
"chars": 11558,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nThe format for a memory card image\n\nThe format is somewhat described here: https://w"
},
{
"path": "frontend/src/save-formats/GameCube/GameSpecificFixups/FZeroGx.js",
"chars": 2254,
"preview": "/* eslint-disable no-bitwise */\n\n// Taken from https://github.com/dolphin-emu/dolphin/blob/059282df6f5a0f1671611fbd72de6"
},
{
"path": "frontend/src/save-formats/GameCube/GameSpecificFixups/GameSpecificFixups.js",
"chars": 1881,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nThere are various games for the GameCube where the save data depends on specifics fr"
},
{
"path": "frontend/src/save-formats/GameCube/GameSpecificFixups/PhantasyStarOnline.js",
"chars": 2497,
"preview": "/* eslint-disable no-bitwise */\n\n// Taken from https://github.com/dolphin-emu/dolphin/blob/059282df6f5a0f1671611fbd72de6"
},
{
"path": "frontend/src/save-formats/GameCube/IndividualSaves/GameShark.js",
"chars": 1458,
"preview": "// A GameCube GameShark file is a .gci file with a 0x110 byte header prepended\n//\n// 0x00-0x05: Magic (\"GCSAVE\")\n// 0x1"
},
{
"path": "frontend/src/save-formats/GameCube/IndividualSaves/Gci.js",
"chars": 4060,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nThe standard format for individual saves on the GameCube appears to be the .GCI form"
},
{
"path": "frontend/src/save-formats/GameCube/IndividualSaves/IndividualSaves.js",
"chars": 1008,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nThere are various formats on GameFAQs for individual save files. Fortunately they ha"
},
{
"path": "frontend/src/save-formats/GameCube/IndividualSaves/MaxDrive.js",
"chars": 2012,
"preview": "// A GameCube MaxDrive file is a .gci file with a 0x80 byte header prepended\n//\n// Note that many, but not all, of the ."
},
{
"path": "frontend/src/save-formats/GameCube/Util.js",
"chars": 5754,
"preview": "/* eslint-disable no-bitwise */\n\nimport GameCubeBasics from './Components/Basics';\n\nconst {\n BLOCK_SIZE,\n NUM_RESERVED"
},
{
"path": "frontend/src/save-formats/Mister/GameGear.js",
"chars": 1491,
"preview": "/*\nThe MiSTer makes saves that are 64kB in size and the emulator I tried makes saves that are 32kB. Each seems able to l"
},
{
"path": "frontend/src/save-formats/Mister/Gameboy.js",
"chars": 1243,
"preview": "/*\nThe MiSTer saves GB/GBC data as just the raw data of the correct size: no transformation or padding required\n*/\n\nimpo"
},
{
"path": "frontend/src/save-formats/Mister/GameboyAdvance.js",
"chars": 2590,
"preview": "/*\nMiSTer GBA files are the same as emulator files with 2 exceptions:\n\n- 512B EEPROM files must be padded out to 8192B, "
},
{
"path": "frontend/src/save-formats/Mister/Genesis.js",
"chars": 4023,
"preview": "/*\nThe MiSTer saves Genesis data as bytes (similar to the internal Wii format) rather than shorts like some emulators\n\nB"
},
{
"path": "frontend/src/save-formats/Mister/N64Cart.js",
"chars": 1618,
"preview": "/*\nWe've split up the N64 into cart and mempack because a mempack image is the same size as an SRAM image,\nSo if the mem"
},
{
"path": "frontend/src/save-formats/Mister/N64Mempack.js",
"chars": 1549,
"preview": "/*\nThe MiSTer saves N64 mempack data as just a raw memory card image: no transformation requuired\n*/\n\nimport N64MempackS"
},
{
"path": "frontend/src/save-formats/Mister/Nes.js",
"chars": 2392,
"preview": "/*\nThe MiSTer saves NES data as a regular raw file. If the NES ROM has an iNES header, then the MiSTer core will make a "
},
{
"path": "frontend/src/save-formats/Mister/PcEngine.js",
"chars": 1353,
"preview": "/*\nThe MiSTer saves PC Engine data as just the raw data of the correct size: no transformation or padding required\n\nWe c"
},
{
"path": "frontend/src/save-formats/Mister/Ps1.js",
"chars": 1520,
"preview": "/*\nThe MiSTer saves PS1 data as just a raw memory card image: no transformation requuired\n*/\n\nimport Ps1MemcardSaveData "
},
{
"path": "frontend/src/save-formats/Mister/SegaCd.js",
"chars": 6954,
"preview": "/*\nThe Mister Sega CD save file is a single file with the internal backup RAM (8kB) concatenated with the cartridge back"
},
{
"path": "frontend/src/save-formats/Mister/SegaSaturn.js",
"chars": 7118,
"preview": "/*\nThe Saturn core on the MiSTer stores out regular Saturn BIOS files, except \"byte expanded\".\n\nThe cartridge memory is "
},
{
"path": "frontend/src/save-formats/Mister/Sms.js",
"chars": 1739,
"preview": "/*\nLooks to be similar to NES, as the MiSTer pads out the save to 32kB\n\nOpening one of these large MiSTerfiles in an emu"
},
{
"path": "frontend/src/save-formats/Mister/Snes.js",
"chars": 1231,
"preview": "/*\nThe MiSTer saves SNES data as just the raw data of the correct size: no transformation or padding required\n*/\n\nimport"
},
{
"path": "frontend/src/save-formats/Mister/WonderSwan.js",
"chars": 2145,
"preview": "/*\nThe MiSTer saves WonderSwan data with an extra sector of data at the end for realtime clock information\n\nSee https://"
},
{
"path": "frontend/src/save-formats/N64/Components/Basics.js",
"chars": 440,
"preview": "import Util from '../../../util/util';\n\nexport default class N64Basics {\n static LITTLE_ENDIAN = false;\n\n static NUM_N"
},
{
"path": "frontend/src/save-formats/N64/Components/GameSerialCodeUtil.js",
"chars": 2755,
"preview": "const GAME_SERIAL_CODE_MEDIA_INDEX = 0;\nconst GAME_SERIAL_CODE_REGION_INDEX = 3;\n\n// Taken from https://github.com/bryc/"
},
{
"path": "frontend/src/save-formats/N64/Components/IdArea.js",
"chars": 4297,
"preview": "/* eslint-disable no-bitwise */\n\nimport Util from '../../../util/util';\n\nimport N64Basics from './Basics';\n\nconst {\n LI"
},
{
"path": "frontend/src/save-formats/N64/Components/InodeTable.js",
"chars": 5718,
"preview": "/* eslint-disable no-bitwise */\n\nimport Util from '../../../util/util';\n\nimport N64Basics from './Basics';\n\nconst {\n LI"
},
{
"path": "frontend/src/save-formats/N64/Components/NoteTable.js",
"chars": 6734,
"preview": "/* eslint-disable no-bitwise */\n\nimport Util from '../../../util/util';\n\nimport N64Basics from './Basics';\nimport N64Ino"
},
{
"path": "frontend/src/save-formats/N64/Components/TextDecoder.js",
"chars": 2347,
"preview": "/* eslint-disable object-property-newline */\n\nimport { invert } from 'lodash-es';\n\n// The N64 uses a custom character en"
},
{
"path": "frontend/src/save-formats/N64/DexDrive.js",
"chars": 5363,
"preview": "/*\nThe DexDrive data format is described here:\nhttps://github.com/bryc/mempak/wiki/DexDrive-.N64-format\n\nIt is:\n- 4160 b"
},
{
"path": "frontend/src/save-formats/N64/IndividualSaveFilename.js",
"chars": 5740,
"preview": "import Util from '../../util/util';\nimport N64Util from '../../util/N64';\n\nimport N64GameSerialCodeUtil from './Componen"
},
{
"path": "frontend/src/save-formats/N64/Mempack.js",
"chars": 6965,
"preview": "/* eslint no-bitwise: ['error', { 'allow': ['&', '|', '^', '&=', '^=', '|='] }] */\n\n/*\nThe N64 mempack format is describ"
},
{
"path": "frontend/src/save-formats/NintendoSwitchOnline/Gameboy.js",
"chars": 6881,
"preview": "/*\nThe Nintendo Switch Online save format for Gameboy games is the similar to its format for NES except that there's 2 h"
},
{
"path": "frontend/src/save-formats/NintendoSwitchOnline/GameboyAdvance.js",
"chars": 1065,
"preview": "// GBA saves on NSO are just raw files\n\nimport SaveFilesUtil from '../../util/SaveFiles';\n\nexport default class GbaNsoSa"
},
{
"path": "frontend/src/save-formats/NintendoSwitchOnline/Genesis.js",
"chars": 1735,
"preview": "// Genesis files on NSO are not byte-expanded like other emulators\n\nimport SaveFilesUtil from '../../util/SaveFiles';\nim"
},
{
"path": "frontend/src/save-formats/NintendoSwitchOnline/N64.js",
"chars": 1515,
"preview": "// N64 saves on NSO have opposite endianness to emulator saves for SRAM and FlashRAM files. EEPROM files do not need to "
},
{
"path": "frontend/src/save-formats/NintendoSwitchOnline/Nes.js",
"chars": 2533,
"preview": "/*\nThe Nintendo Switch Online save format for NES games is the same as those on the NES Classic: the save is padded out "
},
{
"path": "frontend/src/save-formats/NintendoSwitchOnline/Snes.js",
"chars": 1076,
"preview": "// SNES saves on NSO are just raw save files\n\nimport SaveFilesUtil from '../../util/SaveFiles';\n\nexport default class Sn"
},
{
"path": "frontend/src/save-formats/OnlineEmulators/Emulators/EmulatorBase.js",
"chars": 1926,
"preview": "/*\nBase class for converting from save states for online emulators. Handles resizing multiple times without accidentally"
},
{
"path": "frontend/src/save-formats/OnlineEmulators/Emulators/Gambatte.js",
"chars": 2228,
"preview": "/*\nI'm not 100% sure which emulator GB games in emulator.js use.\n\nIt may be the Gambatte emulator: https://github.com/Em"
},
{
"path": "frontend/src/save-formats/OnlineEmulators/Emulators/Gb.js",
"chars": 1189,
"preview": "/*\nI have no idea which emulator GB/C games use\n*/\n\nimport EmulatorBase from './EmulatorBase';\n\nconst SRAM_OFFSET = 0x72"
},
{
"path": "frontend/src/save-formats/OnlineEmulators/Emulators/Snes9x.js",
"chars": 1903,
"preview": "/*\nSNES9x save states appear to store the game's SRAM data after the magic \"SRA:<size>:\"\n*/\n\nimport EmulatorBase from '."
},
{
"path": "frontend/src/save-formats/OnlineEmulators/Emulators/VBA-Next.js",
"chars": 2475,
"preview": "/*\nI'm not 100% sure which emulator GBA games use.\n\nIt may be the VBA-next emulator: https://github.com/libretro/vba-nex"
},
{
"path": "frontend/src/save-formats/OnlineEmulators/Emulators/mGba.js",
"chars": 2323,
"preview": "/*\nI'm not 100% sure which emulator GBA games in emulator.js use.\n\nIt may be the mGBA emulator: https://github.com/Emula"
},
{
"path": "frontend/src/save-formats/OnlineEmulators/OnlineEmulatorWrapper.js",
"chars": 5847,
"preview": "// At their core, many online emulator sites appear to use mostly the same underlying emulators, which appear to be\n// s"
},
{
"path": "frontend/src/save-formats/PS1/Components/Basics.js",
"chars": 628,
"preview": "export default class Ps1Basics {\n static NUM_RESERVED_BLOCKS = 1; // The header contains directory information\n\n stati"
},
{
"path": "frontend/src/save-formats/PS1/Components/DirectoryBlock.js",
"chars": 9847,
"preview": "/* eslint no-bitwise: [\"error\", { \"allow\": [\"&\", \"^\"] }] */\n\nimport Ps1Basics from './Basics';\n\nimport Util from '../../"
},
{
"path": "frontend/src/save-formats/PS1/Components/SaveBlocks.js",
"chars": 2662,
"preview": "import Ps1Basics from './Basics';\n\nimport Util from '../../../util/util';\n\nconst {\n BLOCK_SIZE,\n NUM_DATA_BLOCKS,\n MA"
},
{
"path": "frontend/src/save-formats/PS1/Components/SonyUtil.js",
"chars": 5308,
"preview": "/* eslint no-bitwise: [\"error\", { \"allow\": [\"^\"] }] */\n\n// Class for Sony-specific stuff, such as calculating the signat"
},
{
"path": "frontend/src/save-formats/PS1/DexDrive.js",
"chars": 7453,
"preview": "/*\nThe DexDrive data format is:\n- 3904 byte header:\n - Magic\n - Copy of the 'available' flags from the memcard header\n"
},
{
"path": "frontend/src/save-formats/PS1/Memcard.js",
"chars": 3022,
"preview": "/*\nThe PS1 memcard format is described here:\nhttps://www.psdevwiki.com/ps3/PS1_Savedata#Virtual_Memory_Card_PS1_.28.VM1."
},
{
"path": "frontend/src/save-formats/PS1/Ps3.js",
"chars": 9592,
"preview": "/* eslint no-bitwise: [\"error\", { \"allow\": [\"^\"] }] */\n\n/*\nPS3 files are a bit different from the PSP/DexDrive files. Th"
},
{
"path": "frontend/src/save-formats/PS1/Psp.js",
"chars": 4388,
"preview": "/*\nThe PSP data format for PS1 Classics is:\n- 128 byte header that contains a seed and a signature\n- Normal PS1 memory c"
},
{
"path": "frontend/src/save-formats/PSP/Executable.js",
"chars": 3929,
"preview": "/* eslint-disable no-bitwise */\n\nimport PspEncryptionUtil from './PspEncryptionUtil';\nimport Util from '../../util/util'"
},
{
"path": "frontend/src/save-formats/PSP/ParamSfo.js",
"chars": 4750,
"preview": "// Based on https://github.com/hrydgard/ppsspp/blob/master/Core/ELF/ParamSFO.cpp\n\n// The overall format is:\n// - Header\n"
},
{
"path": "frontend/src/save-formats/PSP/PspEncryptionUtil.js",
"chars": 3049,
"preview": "/* eslint-disable no-underscore-dangle */\n\nimport createModule from '@/save-formats/PSP/psp-encryption/psp-encryption';\n"
},
{
"path": "frontend/src/save-formats/PSP/Savefile.js",
"chars": 3366,
"preview": "import PspEncryptionUtil from './PspEncryptionUtil';\n\n// const INCORRECT_FORMAT_ERROR_MESSAGE = 'This does not appear to"
},
{
"path": "frontend/src/save-formats/PSP/psp-encryption/psp-encryption.js",
"chars": 13365,
"preview": "var createModule = (() => {\n var _scriptName = import.meta.url;\n \n return (\nasync function(moduleArg = {}) {\n var mo"
},
{
"path": "frontend/src/save-formats/PlatformSaveSizes.js",
"chars": 2998,
"preview": "// All values are in bytes\n// Not guaranteed to be correct: may have missing/estra values! Most of this is guesses\n\ncons"
},
{
"path": "frontend/src/save-formats/Retron5/Retron5.js",
"chars": 5361,
"preview": "/* eslint no-bitwise: [\"error\", { \"allow\": [\"&\", \">>>\"] }] */\n\n/*\nThe Retron5 data format is:\n\ntypedef struct\n{\n uint3"
},
{
"path": "frontend/src/save-formats/SegaCd/Crc16.js",
"chars": 1078,
"preview": "/* eslint-disable no-bitwise */\n\n// The Sega CD format uses a 16-bit CRC that I can't seem to find a JS implementation o"
},
{
"path": "frontend/src/save-formats/SegaCd/ReedSolomon.js",
"chars": 4755,
"preview": "/* eslint-disable no-bitwise */\n\n// The Sega CD format uses a version of Reed Solomon that I can't seem to find a JS imp"
},
{
"path": "frontend/src/save-formats/SegaCd/SegaCd.js",
"chars": 27535,
"preview": "/* eslint-disable no-bitwise */\n\n/*\nThis is based on https://github.com/superctr/buram/\n\nAll manipulation of Sega CD sav"
}
]
// ... and 736 more files (download for full content)
About this extraction
This page contains the full source code of the euan-forrester/save-file-converter GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 936 files (2.4 MB), approximately 673.7k tokens, and a symbol index with 2856 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.