A ton of changes

* Updated gba_db.bin Builder to v2.1, adding some important fail-safes and fixing some nasty bugs.
* Updated Makefile to create releases as ZIPs instead of 7Zs and include the gba_db.bin file in releases.
* Updated gitignore to allow necessary files for gba_db.bin Builder to be added to the repo, among other changes.
* Moved script and necessary files to a new "tools" folder. The resources folder is now used for files that facilitate releases, such as "safe" versions of gba_db.bin.
* Made a few changes to open_agb_firm.c to prepare for full gba_db.bin integration.
* Updated README to reflect the new changes, among other changes.
This commit is contained in:
Harrison 2021-02-24 19:56:21 -05:00 committed by profi200
parent e2b527b35b
commit 1b0cdbbf9d
8 changed files with 54817 additions and 60 deletions

4
.gitignore vendored
View File

@ -1,13 +1,13 @@
arm9/build/
arm11/build/
eclipse_project/
open_agb_firm/
*.sublime-project
*.sublime-workspace
arm9/open_agb_firm9.bin
arm11/open_agb_firm11.bin
arm9/open_agb_firm9.elf
arm11/open_agb_firm11.elf
resources/gba.dat
resources/gba.xml
tools/gba_db_builder/gba_db.bin
open_agb_firm.firm
open_agb_firm*.7z

View File

@ -53,13 +53,17 @@ arm11/$(TARGET)11.bin:
clean:
@$(MAKE) --no-print-directory -C arm9 clean
@$(MAKE) --no-print-directory -C arm11 clean
rm -f $(TARGET).firm *.7z
rm -rf open_agb_firm $(TARGET).firm *.zip
release: clean
@$(MAKE) -j4 --no-print-directory -C arm9 NO_DEBUG=1
@$(MAKE) -j4 --no-print-directory -C arm11 NO_DEBUG=1
firm_builder $(TARGET).firm $(ENTRY9) $(ENTRY11) $(SECTION0_ADR) $(SECTION0_TYPE) \
$(SECTION0_FILE) $(SECTION1_ADR) $(SECTION1_TYPE) $(SECTION1_FILE)
@7z a -mx -m0=ARM -m1=LZMA $(TARGET)$(VERS_STRING).7z $(TARGET).firm
@7z u -mx -m0=PPMD $(TARGET)$(VERS_STRING).7z LICENSE.txt thirdparty/fatfs/LICENSE.txt thirdparty/inih/LICENSE.txt README.md
@7z rn $(TARGET)$(VERS_STRING).7z thirdparty/fatfs/LICENSE.txt LICENSE_fatfs.txt thirdparty/inih/LICENSE.txt LICENSE_inih.txt
@mkdir open_agb_firm
@mkdir open_agb_firm/3ds
@cp LICENSE.txt open_agb_firm.firm README.md open_agb_firm
@cp resources/gba_db.bin open_agb_firm/3ds
@cp thirdparty/fatfs/LICENSE.txt open_agb_firm/LICENSE_fatfs.txt
@cp thirdparty/inih/LICENSE.txt open_agb_firm/LICENSE_inih.txt
@zip -r $(TARGET)$(VERS_STRING).zip open_agb_firm

View File

@ -1,21 +1,20 @@
# open_agb_firm
open_agb_firm is a bare metal interface for natively running GBA games and homebrew using the 3DS built-in GBA hardware.
open_agb_firm is a bare metal app for running GBA games and homebrew using the 3DS builtin GBA hardware.
open_gba_firm is a complete and better alternative to GBA VC injects, allowing for:
* Launching GBA files directly from the SD card
* Writing save files directly to the SD card
* Automatic save file configuration using an included database
* Screenshots via pressing SELECT+Y
* User configuration, such as gamma settings
* And more to come!
## Disclaimer
open_agb_firm is currently in alpha. While open_agb_firm is relatively stable, there are few quirks that have yet to be fixed. See [Known issues](#known-issues) and [Troubleshooting](#troubleshooting) for more information.
open_agb_firm is currently in alpha. While open_agb_firm is relatively stable and safe to use, there are few quirks that have yet to be fixed. See [Known issues](#known-issues) and [Troubleshooting](#troubleshooting) for more information.
Additionally, we are not responsible for any damage that may occur to your system as a direct or indirect result of you using open_agb_firm.
## How to build
To compile open_agb_firm, the following needs to be installed:
* [devkitARM](https://sourceforge.net/projects/devkitpro/)
* [Corelink DMA-330 assembler](https://github.com/profi200/dma330as)
* [CTR firm builder](https://github.com/derrekr/ctr_firm_builder)
Additionally, 7-Zip (or on Linux, p7zip) needs to be installed to make release builds. Also, make sure that the dma330as and CTR firm builder binaries are in the $PATH environment variable and accessible to the Makefile. Build open_agb_firm as a debug build via `make` or as a release build via `make release`.
## How to use
## How to Use
The process to set up and launch open_agb_firm is similar that of [GodMode9](https://github.com/d0k3/GodMode9).
* Download the [latest release](https://github.com/profi200/open_agb_firm/releases/latest) and extract it to obtain `open_agb_firm.firm`.
* Copy the `open_agb_firm.firm` file to your 3DS's SD card at `/luma/payloads` if using Luma3DS or elsewhere if using fastboot3DS.
@ -31,7 +30,6 @@ SELECT+Y - Dump screen output to `/3ds/open_agb_firm/texture_dump.bmp`*\
Hold the power button to turn off the 3DS.
## Configuration
Settings are stored in `/3ds/open_agb_firm/config.ini`.
### General
@ -40,38 +38,48 @@ Settings are stored in `/3ds/open_agb_firm/config.ini`.
`bool biosIntro` - Show GBA BIOS intro at game startup (default: `true`)
### Video
`float inGamma` - Set gamma (default: `2.2`)
`float inGamma` - Screen input gamma (default: `2.2`)
`float outGamma` - Specify screen gamma (default: `1.54`)*\
*Default setting based on o3DS LCD. For raw GBA colors, set to `2.2`.
`float outGamma` - Screen output gamma (default: `1.54`)*\
*Default setting based on o3DS LCD. For raw GBA colors, set to the same value as `inGamma`.
`float contrast` - Set gain (default: `1.0`)
`float contrast` - Screen gain (default: `1.0`)
`float brightness` - Set lift (default: `0.0`)
`float brightness` - Screen lift (default: `0.0`)
## Known issues
## How to Compile
If you are using Windows 10, install and perform the following steps using [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/install-win10).
To compile open_agb_firm, the following needs to be installed:
* [devkitARM](https://sourceforge.net/projects/devkitpro/)
* [Corelink DMA-330 Assembler](https://github.com/profi200/dma330as)
* [CTR Firm Builder](https://github.com/derrekr/ctr_firm_builder)
Additionally, `zip` needs to be installed to make release builds. Also, make sure that the `dma330as` and `firmbuilder` binaries are in the PATH environment variable and accessible to the Makefile. Build open_agb_firm as a debug build via `make`, or as a release build via `make release`.
## Known Issues
This section is reserved for a listing of known issues. At present only this remains:
* Sleep mode is not fully implemented.
* Save type detection may still fail for certain games using EEPROM.
* Lack of settings (including brightness control).
* Lack of settings (including runtime brightness control).
* No cheats or other enhancements.
If you happen to stumble over another bug, please [open an issue](https://github.com/profi200/open_agb_firm/issues) or contact profi200 via other platforms.
## Troubleshooting
Known problems and their solutions.
Known problems and their solutions:
Problem: The game crashes/shows white or blackscreens or shows a savegame corrupt message.\
Solution: Try to delete the savegame file. If this doesn't help, [report the issue](https://github.com/profi200/open_agb_firm/issues).\
Note: EEPROM saves made by some emulators are incompatible because they have every 8 byte block endian swapped. [This tool](https://gist.github.com/profi200/e06794d7561ed552c518b4b0b2f5f2f6) can fix affected saves.
## Hardware limitations
## Hardware Limitations
This is a list of limitations we can't solve in software or are very hard to work around. This doesn't mean it will never happen (unless stated otherwise).
* 64 MiB (512 mbit) games. Not possible to support.
* 64+ MiB (512+ Mbit) games and homebrew. Not possible to support at all, unfortunately.
* Games with extra hardware built into the cartridge (except Real-Time Clock). Patches are required.
* GBA Serial port (aka Link Cable).
* 64 KiB (512 kbit) SRAM (homebrew games/emulators). Not possible to support.
* Can't switch back to 3DS mode from GBA mode, requiring a reboot for booting a different game.
* GBA serial port (aka Link Cable).
* 64+ KiB (512+ Kbit) SRAM (homebrew games/emulators). Not possible to support.
* Reboots are required for switching between games.
* Savestates. Very difficult to implement because no direct hardware access.
## License

Binary file not shown.

View File

@ -197,16 +197,6 @@ static Result searchGameDb(u64 x, GameDbEntry *const db, s32 *const entryPos)
static u16 checkSaveOverride(u32 gameCode)
{
switch (gameCode & 0xFFu)
{
case '1': return SAVE_TYPE_EEPROM_64k; // Homebrew using EEPROM.
case '2': return SAVE_TYPE_SRAM_256k; // Homebrew using SRAM.
case '3': return SAVE_TYPE_FLASH_512k_PSC_RTC; // Homebrew using FLASH-64.
case '4': return SAVE_TYPE_FLASH_1m_MRX_RTC; // Homebrew using FLASH-128.
case 'F': return SAVE_TYPE_EEPROM_8k; // Classic NES Series.
case 'S': return SAVE_TYPE_SRAM_256k; // Homebrew using SRAM (Butano games).
}
static const struct
{
alignas(4) char gameCode[4];
@ -215,7 +205,7 @@ static u16 checkSaveOverride(u32 gameCode)
{
// Generalizations
{"\0\0\0\0", SAVE_TYPE_SRAM_256k}, // Homebrew (TODO: Set WAITCNT to 0x4014?)
// Homebrew
{"GMB\0", SAVE_TYPE_SRAM_256k}, // Goomba Color
};

13075
tools/gba_db_builder/gba.dat Normal file

File diff suppressed because it is too large Load Diff

41678
tools/gba_db_builder/gba.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
# open_agb_firm gba_db.bin Builder v2.0
# open_agb_firm gba_db.bin Builder v2.1
# By HTV04
#
# This script parses MAME's gba.xml (found here: https://github.com/mamedev/mame/blob/master/hash/gba.xml) and converts it to a gba_db.bin file for open_agb_firm.
@ -14,12 +14,12 @@ import xml.etree.ElementTree as ET
def gbadbentry(title, serial, sha, size, savetype):
entry = b''
entry += title.encode().ljust(200, b'\x00')
entry += serial.encode().ljust(4, b'\x00')
entry += bytes.fromhex(sha).ljust(20, b'\x00')
entry += title.encode().ljust(200, b'\x00')[0:200]
entry += serial.encode().ljust(4, b'\x00')[0:4]
entry += bytes.fromhex(sha).ljust(20, b'\x00')[0:20]
entry += (int(math.log(size, 2)) << 27 | savetype).to_bytes(4, 'little') # Save type is stored weirdly
return entry # Entry size is 228 bytes total
return entry
if __name__ == '__main__':
gbadb = b''
@ -36,10 +36,10 @@ if __name__ == '__main__':
for software in gba.findall('software'):
for part in software.findall('part'):
if part.get('name') == 'cart':
# Obtain CRC32 for No-Intro DAT matching
# Obtain SHA-1
for dataarea in part.findall('dataarea'):
if dataarea.get('name') == 'rom':
crc = dataarea.find('rom').get('crc')
sha = dataarea.find('rom').get('sha1')
break
@ -47,14 +47,13 @@ if __name__ == '__main__':
matchfound = False
for game in nointro.findall('game'):
for rom in game.findall('rom'):
if rom.get('crc') == crc.upper():
if rom.get('sha1') == sha.upper():
matchfound = True
title = game.get('name')
serial = rom.get('serial')
if serial in (None, 'N/A'):
serial = '\x00\x00\x00\x00' # If a serial can't be found, default to null bytes
sha = rom.get('sha1')
size = int(rom.get('size'))
# If not in No-Intro DAT, skip entry
@ -62,17 +61,17 @@ if __name__ == '__main__':
break
# Obtain save type
savetype = 15 # If a save type can't be found or is unknown, set to "SAVE_TYPE_NONE"
savetype = 15 # SAVE_TYPE_NONE
for feature in part.findall('feature'):
if feature.get('name') == 'slot':
slottype = feature.get('value')
if slottype in ('gba_eeprom', 'gba_eeprom_4k'):
savetype = 0 # SAVE_TYPE_EEPROM_8k
if size > 0x1000000: # If greater than 16 MB, change save type
if size > 0x1000000:
savetype += 1 # SAVE_TYPE_EEPROM_8k_2
elif slottype == 'gba_eeprom_64k':
savetype = 2 # SAVE_TYPE_EEPROM_64k
if size > 0x1000000: # If greater than 16 MB, change save type
if size > 0x1000000:
savetype += 1 # SAVE_TYPE_EEPROM_64k_2
elif slottype == 'gba_flash_rtc':
savetype = 8 # SAVE_TYPE_FLASH_512k_PSC_RTC
@ -102,7 +101,10 @@ if __name__ == '__main__':
# Add additional entries
if addentries == True:
gbadbentries = ([['Example Game', 'WIP', '', 0x1000000, 14]])
# Example entries for demonstration purposes (to do: replace with valid entries)
gbadbentries = ([['AAAA - A', 'AAAA', 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', 0x1000000, 0],
['BBBB - B', 'BBBB', 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', 0x1000000, 14],
['CCCC - C', 'CCCC', 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC', 0x1000000, 15]])
print()
@ -115,8 +117,8 @@ if __name__ == '__main__':
# Create and write to gba_db.bin
with open('gba_db.bin', 'wb') as f:
f.write(gbadb)
if addentries == True:
print('\n' + str(count) + ' entries added, ' + str(addcount) + ' additional entries added, ' + str(skipcount) + ' entries skipped')
else:
print('\n' + str(count) + ' entries added, ' + str(skipcount) + ' entries skipped')
if addentries == True:
print('\n' + str(count) + ' entries added, ' + str(addcount) + ' additional entries added, ' + str(skipcount) + ' entries skipped')
else:
print('\n' + str(count) + ' entries added, ' + str(skipcount) + ' entries skipped')