| Commit message (Collapse) | Author | Age |
|
|
|
|
|
|
|
| |
* Reorganize namespaces
- Most types are now moved into the `melonDS` namespace
- Only good chance to do this for a while, since a big refactor is next
* Fix the build
|
|
|
|
|
| |
Add support for exporting animated DSi icons as GIF using the
header-only gif.h library.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Refactor GPU3D to be an object
- Who has two thumbs and is the sworn enemy of global state? This guy!
* Refactor GPU itself to be an object
- Wow, it's used in a lot of places
- Also introduce a new `Melon` namespace for a few classes
- I expect other classes will be moved into `Melon` over time
* Change signature of Renderer3D::SetRenderSettings
- Make it noexcept, and its argument const
* Remove some stray whitespace
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Move NDSCart-related global state into objects
- RAII will now do the heavy lifting
- Mark some methods as const or noexcept
* Move GBACart-related global state into objects (#1870)
- RAII will now do the heavy lifting
- Mark some methods as const or noexcept
- Once the `NDS` object is finalized, most of these `assert`s can go away
* Make AREngine::RunCheat public (#1872)
- I use it directly in melonDS DS to apply single cheats without using ARCodeFile
- Before the AREngine refactor I could just redeclare the function in my code
- Now I can't
|
|
|
|
|
| |
- RAII will now do the heavy lifting
- Mark some methods as const or noexcept
- Once the `NDS` object is finalized, most of these `assert`s can go away
|
|
|
|
|
|
|
|
| |
The ExtractFileFromArchive function can sometimes return -1 on error,
however the function's return type was specified as u32, which would
mean that it would instead be represented as the maximum value.
Change the function's return type to the signed s32 instead, and
correct uses.
|
|
|
|
|
|
| |
Free some objects that were allocated with new but not deleted, and in
one case, do not set a pointer to nullptr before deleting, as this
results in a memory leak due to memory allocated not being freed.
|
|
|
|
|
|
|
|
|
| |
If a user manages to open a file as a ROM that is greater than 1 GiB,
it will cause a segmentation fault (a crash) in LoadROM due to a delete
being called on an uninitialised pointer, which is undefined behaviour.
Initialise filedata to nullptr to prevent this, as deleting a null
pointer is defined as a no-op.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In QCamera in Qt 5, the camera is required to have been loaded before
querying its settings and resolutions. Doing so without loading being
finished would result in the returned list being empty.
See https://doc.qt.io/qt-5.15/qcamera.html#supportedViewfinderSettings
Add a QEventLoop that waits for the state to change from Loading to
Loaded before supportedViewfinderSettings() is called to ensure that
valid information is returned.
(Fixes my camera being blank in preview, same issue also presumed
to occur when camera is needed in game, fix tested on a USB camera on
a Linux system and Qt 5.)
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* get this started
* implement DSi RTC commands
* set up RTC clock timer. lay down basic idea of a clock.
* make the date/time registers writable
* move RTC state to its own structure, to make it easier to deal with
* more RTC work
lay base for date/time dialog
* get the bulk of the RTC functionality going
* much simpler design for RTC stuff
* aha, that is what it is
* start working on the RTC IRQ
* implement all types of RTC IRQ
* start refining sleep mode. code still kinda sucks.
* implement keypad IRQ
* refine it some more
* shut the fuck uuuuuupppppppppppppp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Replace some standard I/O calls with Platform equivalents
- I missed a spot when I submitted that PR a few months ago
* Include <memory> in DSi_NAND.h
- Because it uses unique_ptr
* Split DSi_NAND::ReadHardwareInfo into ReadSerialData and ReadHardwareInfoN
* Add a RegionMask enum
* Move DSi NAND patching to the frontend
* Add DSiSupportedLanguageMask
- Not currently used by the frontend, but I use it in melonDS DS
* Remove some Platform::ConfigEntry values
- The core no longer needs to know about them
- The corresponding Config values are unchanged
* Mark NANDMount's destructor as noexcept
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* gdbstub beginnings
* gdbstub: finish gdb impl things, next up is integration with melonDS
* holy fuck the gdbstub works
* gdb breakpoints work, but there's a mysterious crash on continue
* fix memory corruption that sometimes happened, and make resetting the console thru gdb work
* remove some gdb debug printing
* fix things in gdbstub
* separate option for enabling gdbstub
* add mode-dependent CPU registers
* C++ize the GDBstub code
* add gdbstub config in emu settings dialog
* make sure gdb is disabled when jit is enabled
* Remove unnecessary compiler flags, mark ARMJIT assembly code as no-execute-stack
This hardens the binary a little bit against common exploitation methods
* add option to wait for debugger attach on startup
* only insert GNU stack notes on linux
* disable gdbstub enable checkbox when jit is enabled
* fix non-linux incompatibilities
* enable gdbstub by default
* fix issues with gdbstub settings disable stuff
* format stuff
* update gdb test code
* Fix segfault when calling StubCallbacks->GetCPU()
C++ overrides are hard. Please I'm just a lowly C programmer.
* fix packet size not being sent correctly
Thanks to @GlowingUmbreon on Github for troubleshooting this
* fix select(2) calls (i should read docs more properly)
* fix GDB command sequencing/parsing issue (hopefully)
* [GDB] implement no-ack mode
* fix sending ack on handshake
* get lldb to work
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Refactor diskio's contents
- Change ff_disk_read_cb/write_cb into a std::function instead of a raw pointer
- Add const specifiers as needed
* Refactor DSi_NAND to manage the file system's mounted lifetime with RAII
* Split NANDMount into NANDMount and NANDImage
- NANDImage is used for information about the NAND that doesn't require decryption or filesystem access
- NANDMount is used to actually access the file system
- Both classes manage their respective resources (the NAND file handle and the NAND's mount) with RAII
- Also split the file loading into another function that I will remove in a later PR
* Make NANDMount immovable
* Remove NAND-loading code that I had sectioned off into a function
- Incomplete copypasta
- I must have gotten distracted
* Tidy up NANDImage's initialization
- Don't unmount the disk image if the constructor fails (that's NANDMount's job now)
- Only assign CurFile if the constructor succeeds
* Add some const-correctness
* Move DSi NAND initialization to the frontend
- The NANDImage is now installed via a unique_ptr in DSi
* Remove Platform::DSi_NANDPath
- Not Config::DSiNANDPath; that can still be configured as usual
- The core no longer needs to care
|
|
|
| |
- It might have been changed in the settings
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
file system (#1826)
* Introduce firmware-related structs
* Fix some indents
* Move the generated firmware identifier to a constant
* Document the WifiAccessPoint constructors
* Add some constants
* Remove a stray comment
* Implement Firmware::UserData
* Add Firmware::Mask
* Document Firmware::Buffer
* Add a Firmware constructor that uses a FileHandle
* Set the default username in UserData
* Update the UserData checksum
* Forgot to include Platform.h
* Remove some redundant assignments in the default Firmware constructor
* const-ify CRC16
* Replace the plain Firmware buffer with a Firmware object
- Remove some functions that were reimplemented in the Firmware constructors
* Fix some crashes due to undefined behavior
* Fix the user data initialization
- Initialize both user data objects to default
- Set both user data objects to the same touch screen calibration
* Follow the DS logic in determining which user data section is current
* Remove an unneeded include
* Remove another unneeded include
* Initialize FirmwareMask in Firmware::Firmware
* Use the DEFAULT_SSID constant
* Add SPI_Firmware::InstallFirmware and SPI_Firmware::RemoveFirmware
* Move a logging call to after the file is written
* Add a SaveManager for the firmware
* Touch up the SPI_Firmware::Firmware declaration
* Move all firmware loading and customization to the frontend
* Call Platform::WriteFirmware when it's time to write the firmware back to disk
* Fix some missing stuff
* Remove the Get* functions from SPI_Firmware in favor of GetFirmware()
* Implement SPI_Firmware::DeInit in terms of RemoveFirmware
* Add Firmware::UpdateChecksums
* Fix an incorrect length
* Update all checksums in the firmware after setting touch screen calibration data
* Use the Firmware object's Position methods
* Remove register fields from the Firmware object
* Install the firmware before seeing if direct boot is necessary
* Install the firmware before calling NDS::Reset in LoadROM
* Slight cleanup in ROMManager
* Fix the default access point name
* Shorten the various getters in Firmware
* Add qualifiers for certain uses of firmware types
- GCC can get picky if -fpermissive isn't defined
* Add an InstallFirmware overload that takes a unique_ptr
* Log when firmware is added or removed
* Don't clear the firmware in SPI_Firmware::Init
- The original code didn't, it just set the pointer to nullptr
* Fix a typo
* Write back the full firmware if it's not generated
* Move the FreeBIOS to an external file
* Load wfcsettings.bin into the correct part of the generated firmware blob
* Load BIOS files in the frontend, not in the core
* Fix logging the firmware ID
* Add some utility functions
* Mark Firmware's constructors as explicit
* Remove obsolete ConfigEntry values
* Include <locale> explicitly in ROMManager
* Fix up some includes
* Add Firmware::IsBootable()
* Add a newline to a log entry
- Whoops
* Log the number of bytes written out in SaveManager
* Mark FirmwareHeader's constructor as explicit
* Clean up GenerateDefaultFirmware and LoadFirmwareFromFile
- Now they return a pair instead of two by-ref values
* Refactor SaveManager a little bit
- Manage its buffers as unique_ptrs to mitigate leaks
- Reallocate the internal buffer if SetPath is asked to reload the file (and the new length is different)
* Remove some stray parens
* Fix some firmware-related bugs I introduced
- Firmware settings are now properly saved to disk (beforehand I misunderstood when the firmware blob was written)
- Firmware is no longer overwritten by contents of wfcsettings.bin
* Slight cleanup
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Make cleanup a little more robust to mitigate undefined behavior
- Add some null checks before cleaning up the GPU3D renderer
- Make sure that all deleted objects are null
- Move cleanup logic out of an assert call
- Note that deleting a null pointer is a no-op, so there's no need to check for null beforehand
- Use RAII for GLCompositor instead of Init/DeInit methods
* Replace a DeInit call that I missed
* Make ARMJIT_Memory less likely to generate errors
- Set FastMem7/9Start to nullptr at the end
- Only close and unmap the file if it's initialized
* Make Renderer3D manage its resources with RAII
* Don't try to deallocate frontend resources that aren't loaded
* Make ARMJIT_Memory::DeInit more robust on the Switch
* Reset MemoryFile on Windows to INVALID_HANDLE_VALUE, not nullptr
- There is a difference
* Don't explicitly store a Valid state in GLCompositor or the 3D renderers
- Instead, create them with static methods while making the actual constructors private
* Make initialization of OpenGL resources fail if OpenGL isn't loaded
* assert that OpenGL is loaded instead of returning failure
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
CRC32.cpp:
Make table initialization compile time
DSi_NAND.cpp:
Fix file close / unmount / disk close on error
~L427: Remove redundant calls, as they are immediately rendered useless by `rem` being overwritten
NDS.cpp / FreeBIOS.h:
Remove unneeded size values in header
Remove unneeded memset's as they are initialized anyway
sha1.c / sha1.h:
Fix useless warning
Wifi.cpp:
Remove unneeded includes
DSi.cpp:
Reduce ugly casts
Deduplicate code
qt_sdl/main.cpp:
silence clang switch statement warning
qt_sdl/main.h:
fix override warnings
dolphin/BitSet.h:
use msvc extensions only when appropriate, fix broken bit set count under _WIN32
|
|
|
|
|
|
|
| |
* Add SVG icon
* Update macOS icon
* Don't force change the application icon at runtime on macOS
|
|
|
| |
Co-authored-by: Arisotura <thetotalworm@gmail.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Introduce some Platform calls for managing dynamic libraries
* Add Platform::WriteFATSectors
* Introduce some Platform calls for managing dynamic libraries
* Add Platform::WriteFATSectors
* Change includes of "../types.h" to "types.h"
- Makes it easier to directly include these headers in downstream projects
* Change an include of "../Wifi.h" to "Wifi.h"
* Allow CommonFuncs.cpp to compile on Android
* Tidy up some logging calls
- Use Platform::Log in LAN_Socket.cpp
- Soften some warnings to Debug logs (since they don't necessarily represent problems)
* Add Platform::EnterGBAMode
- Gracefully stop the emulator if trying to enter GBA mode
* Soften some logs that most players won't care about
* Soften some more logs
* Introduce Platform wrappers for file operations
* Fix pointer spacing
* Fix more style nits
* Log the errno when ftruncate fails
* Fix FileSeek offset argument
- With an s32 offset, we couldn't access files larger than 2GB
* Revise Platform::StopEmu to address feedback
- Remove Platform::EnterGBAMode in favor of adding a reason to Platform::StopEmu
- Also rename Platform::StopEmu to Platform::SignalStop
- Add an optional argument to NDS::Stop
- Use the new argument everywhere that the console stops itself
* Rename FileGetString to FileReadLine
- It conveys the meaning better
* Rename FileSeekOrigin::Set to Start
- It conveys the meaning better
* Change definition of FileGetString to FileReadLine
- Oops, almost forgot it
* Rename FlushFile to FileFlush
- To remain consistent with the other File functions
* Add a FileType usage
* Fix line break in FileSeekOrigin
* Document Platform::DeInit
* Clarify that StopReason::Unknown doesn't always mean an error
* Move and document FileType::HostFile
* Remove Platform::OpenDataFile
- Nothing currently uses it
* Refactor Platform::OpenFile and Platform::OpenLocalFile to accept a FileMode enum instead of a string
- The enum is converted to fopen flags under the hood
- The file type is used to decide whether to add the "b" flag
- Some helper functions are exposed for the benefit of consistent behavior among frontends
- Equivalent behavior is maintained
* Fix a tab that should be spaces
* Use Windows' 64-bit implementations of fseek/ftell
* Move Platform::IsBinaryFile to Platform.cpp
- It could vary by frontend
* Remove an unused FileType
* Rename an enum constant
* Document various Platform items
* Use Platform::DynamicLibrary to load libandroid
- And clean it up at the end
* Fix a typo
* Pass the correct filetype to FATStorage
- Since it can be used for DSI NAND images or for SD cards
* Remove Platform::FileType
|
| |
|
| |
|
|
|
|
|
|
|
| |
...but only with LTO enabled
...but only on some UNIX systems
...but only with some additional build options except when it breaks
without any as well
|
|
|
|
|
|
|
|
|
| |
* DSi: add option to boot the full boot ROMs
added a config option for this so that this can be enabled or disabled
also added IO regs for DSi GPIO, but those don't do anything yet.
* reset GPIO regs on reset
|
|
|
|
|
|
| |
Because of course some compression programs aren't nice enough to tell
you the decompressed size up front in the file, so the other approach
will fail. Things just can't ever be easy and straight forward, can they?
|
|
|
|
|
| |
Fixes the UI hanging up on Windows 11 when there are no mics, but the mic
input is set to external device as it is by default.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Add a definition for TMD files
* Wrap TitleMetadata in a namespace
* Add a comment
* Remove TitleMetadataCertificate
- melonDS ignores it anyway
* Refactor the use of title metadata
- Move bitwise operations on the title ID into helper methods
- Use TitleMetadata objects instead of pointers to raw data
* Slight cleanup in DSi_NAND
- Replace some constants with sizeof
- Use an NDSHeader object instead of a raw array of bytes
* Add a DSi_NAND::ImportFile overload that loads a file from memory
* Split most of ImportTitle into InitTitleFileStructure
- It will be reused in the next commit
* Add ability to import title from memory
* Fix another potential issue
* Fix broken DSiWare installation
- The bytes of the title ID/category were being swapped in most places, but not all
* Add some logging calls
* Declare array sizes in DSi_TMD in decimal, not hex
* Add a space after the #endif
- To adhere to the style guide
* Assert the size of TitleMetadataContent
* Change the type of SignatureName
* Don't mark the TMD structs as packed
* Remove extraneous comments
* Cut down some newlines
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Split ROMList into a .cpp file
- Its definition in ROMList.h was causing multiple-definition linker errors
- Introduce ROMListSize, since you can't take a sizeof() of an extern declaration
- Mark ROMList and ROMListSize as const
* Update ReadROMParams to accommodate ROMList changes
* Split parsing and loading of NDS ROMs
- Introduce an NDSCartData class for parsing a ROM file
- Introduce InsertROM for loading a NDS cart
- Refactor LoadROM to use NDSCartData and InsertROM under the hood
* Reset cart state and initialize save memory in the NDSCartData constructor
- Otherwise there's no way to know about SRAM-specific attributes before inserting the game
* Add a comment to NDSCartData
* First crack at splitting parsing and loading for GBACart
* Add some logging calls for encrypting the secure area
* Log the XXH64 hash of the inserted NDS ROM
* Log the XXH64 hash of the secure area after decryption
* Add some logging to Key1_LoadKeyBuf
* Re-encrypt the secure area when inserting the cart, not when parsing it
- This way, constructing a NDSCart doesn't imply a read from the filesystem (as is done in Key1_KeyBuf)
* Load Key1_KeyBuf from memory, not from the file system
- Now that the cart's secure area isn't re-encrypted until insertion, we can expect that the BIOS will be ready at this point
* Add some helper query methods to NDSHeader
* Query the DSi region directly from the header instead of checking the ROM again
* Introduce a CartType enum
- So CartCommon::Type doesn't have to return magic numbers
* Reset the cart in NDSCart::InsertROM instead of the NDSCartData constructor
- That way the constructor doesn't rely on the config or on file I/O when loading homebrew
- This keeps the use of global state closer to one place
* Add non-const getters for the carts
* Add InsertROM overloads that accept unique_ptrs
* Fix a comment
* Rename member functions on NDSCartData and GBACartData to adhere to the convention
* Rename members on NDSCartData and GBACartData to adhere to the convention
* Fix build errors on some platforms
* Add NDSHeader::IsDSiWare
* Add a ROMListEntry parameter to the cart constructors
- To allow for looking up details of SRAM or expected ROM size
* Add some new getters to CartCommon
* Use the Header/Banner members instead of globals
* Make CartCommon abstract
- It's not supposed to be instantiated anyway
* Change the signature of CartCommon::Checksum
- It's neither overridden nor mutating
* Add some clarifying comments to NDSHeader
* Delete CartCommon::ROM in its destructor
- ParseROM copies its input and gives that copy to the cart object, so it's okay
* Add some getters to CartCommon
* Refactor NDSCart
- Get rid of NDSCartData
- Get rid of cart-specific global state within NDSCart (so registers are untouched)
- Refactor uses of removed global variables to use the Cart pointer instead
- Refactor ROMInfoDialog's icon functions to accept const arguments
* Return the cart pointer
- So *that's* why it was crashing. Whoops
- Why is this even allowed?
* Refactor GBACart
- Delete CartGame::ROM in the destructor
- Get rid of GBACartData
- Remove some global state
* Mark NDSCart::CartCommon::Type as const
* Slightly refactor GBACart::CartCommon
- Mark Type as const
- Use enum constants
- Make CartCommon itself abstract
* Mark CRC32's data parameter as const
* Mark GBACart::CartCommon::Checksum as const
* Use assert.h instead of cassert
- As demanded by the style guide
* Fix some includes to adhere to the style guide
* Get the ARM9 entry address directly from the header object
* Use more Header fields directly
* Rename some parameters to match the style guide
* Remove some unused includes
* Slightly change NDS_Header::IsHomebrew for clarity
|
| |
|
| |
|
| |
|
|
|
|
|
| |
Explains that the settings only affect online play, not local
multiplayer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Refactor Savestate::Var{8,16,32,64}
- They now delegate to VarArray
- They're declared in the class header so they're likely to be inlined
* First crack at refactoring Savestate to work in-memory
- Well, third, but who's counting?
* Implement Savestate::Finish
* Remove the VersionMajor and VersionMinor fields
- Instead, pull their values directly from the savestate buffer
* Mark a new constructor as explicit
* Rename Reset to Rewind
* Fix a linebreak
* Implement Savestate::Rewind
* Add ROMManager::ClearBackupState
* Refactor ROMManager to use the refactored Savestate
* Capitalize "Least"
- It was driving me nuts
* Add a log call
* Increase default Savestate buffer length to 32MB
* Use C-style file I/O instead of C++-style
- Dumping bytes to a file with C++'s standard library is a MONSTROUS PAIN IN THE ASS
* Quote the savestate's file path for clarity
* Write the savestate's length into the header
* Add some extra logging calls
* Fix section-loading
* Remove the deprecated Savestate constructor
* Convert a char* to a u32 with memcpy, not a cast
* Fix section-handling in loads
* Include <cstring> in Savestate.h
- This was causing a build error on Linux
|
|
|
|
| |
it can bring everything to a crawl and OpenGL display can be used as an alternative
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
| |
This is different from the archive support in that the compressed ROMs
are standalone files, rather than archives, making it possible to use
them exactly as if they were regular ROMs, while saving a bunch of space
on disk. This is supported both for DS and GBA ROMs, though given GBA
ROMs' generally small size it's mostly useful for the former.
|