Finishing touches

This commit is contained in:
Harrison 2021-03-06 21:41:25 -05:00 committed by profi200
parent 588eb08e20
commit 7cc20dd4b7
6 changed files with 124 additions and 43 deletions

5
.gitignore vendored
View File

@ -7,6 +7,9 @@ arm9/open_agb_firm9.bin
arm11/open_agb_firm11.bin
arm9/open_agb_firm9.elf
arm11/open_agb_firm11.elf
tools/gba_db_builder/gba_db.bin
tools/eeprom-fixer/*.sav
tools/gba-db-builder/gba_db.bin
tools/gba-db-builder/gba.dat
tools/gba-db-builder/gba.xml
open_agb_firm.firm
open_agb_firm*.7z

View File

@ -15,16 +15,17 @@ Additionally, we are not responsible for any damage that may occur to your syste
## Setup
The process to set up and launch open_agb_firm is similar to 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`.
* Download the [latest release](https://github.com/profi200/open_agb_firm/releases/latest) and extract it.
* Copy the `open_agb_firm.firm` file to your 3DS's SD card at `/luma/payloads` if you're using Luma3DS or `/gm9/payloads` if you're using fastboot3DS.
* Copy the `3ds` folder to the root of your 3DS's SD card. Merge folders if asked.
* Launch open_agb_firm using Luma3DS by holding START while booting your 3DS or assign it to a slot if you're using fastboot3DS.
* After open_agb_firm launches, use the file browser to navigate to a `.GBA` ROM to run.
## Controls
A/B/L/R/START/SELECT - GBA buttons, respectively
SELECT+Y - Dump screen output to `/3ds/open_agb_firm/texture_dump.bmp`*\
*If the screen output freezes, press HOME to fix it. This is a hard to track down bug that will be fixed.
SELECT+Y - Dump screen output to `/3ds/open_agb_firm/texture_dump.bmp`
* If the screen output freezes, press HOME to fix it. This is a hard to track down bug that will be fixed.
Hold the power button to turn off the 3DS.
@ -44,6 +45,7 @@ General settings.
* Default: `true`
`bool useGbaDb` - Use `gba_db.bin` to get save types
* Default: `true`
### Video
Video-related settings.
@ -66,43 +68,75 @@ Video-related settings.
### Advanced
Options for advanced users. No pun intended.
`bool saveOverride` - Open save type override menu after selecting a game.
`bool saveOverride` - Open save type override menu after selecting a game
* Default: `false`
`u16 defaultSave` - Change save type default when save type is not in `gba_db.bin` and cannot be autodetected
* Default: `14` (SRAM 256k)
* Possible values:
* `0`, `1`: EEPROM 8k
* `2`, `3`: EEPROM 64k
* `4`, `6`, `8`: Flash 512k RTC
* `5`, `7`, `9`: Flash 512k
* `10`, `12`: Flash 1m RTC
* `11`, `13`: Flash 1m
* `14`: SRAM 256k
* `15`: None
## Known Issues
This section is reserved for a listing of known issues. At present only this remains:
* Sleep mode is not fully implemented.
* Using SELECT+Y to dump screen output to a file can freeze the screen output sometimes.
* Save type autodetection may still fail for certain games using EEPROM.
* Lack of settings (including runtime brightness control).
* Lack of settings (including brightness control during gameplay).
* No cheats and 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.
## Hardware Limitations
open_agb_firm runs GBA games natively, as in using the 3DS's built-in GBA hardware. Unfortunately, this comes with limiations compared to GBA emulators. This is a list of limitations we can't solve in software or are very hard to work around.
* 64+ MiB (512+ Mbit) games and homebrew. Not possible to support at all, unfortunately.
* 64+ MiB (512+ Mbit) games and homebrew.
* Games with extra hardware built into the cartridge (except RTC, or real-time clock). Patches are required.
* Proper save autodetection (can't find save type during gameplay).
* GBA serial port (aka Link Cable).
* 64+ KiB (512+ Kbit) SRAM (homebrew games/emulators). Not possible to support.
* 64+ KiB (512+ Kbit) SRAM (homebrew games/emulators).
* Reboots are required for switching between games.
* No save states. Very difficult to implement because no direct hardware access.
## FAQ
**Q: Why isn't open_agb_firm a normal 3DS app?**\
A: To access the 3DS's GBA hardware, open_agb_firm needs to run with full hardware access, which can only be provided by running as a FIRM. Nintendo also runs DS(i) games and GBA VC in separate FIRMs for full hardware access.
A: To access the 3DS's GBA hardware, open_agb_firm needs to run with full hardware access, which can only be provided by running as a FIRM.
**Q: Is this safe to use?**\
A: Of course! While open_agb_firm does run with full hardware access, a lot of work has been put in by several people to ensure that nothing unexpected happens. Some backend code from open_agb_firm is actually used in [fastboot3ds](https://github.com/derrekr/fastboot3DS)!
**Q: What games will work with open_agb_firm?**\
A: All official games will work, except the ones that fall within the [hardware limitations](#hardware-limitations).
**Q: What games work with open_agb_firm?**\
A: In theory, all of them, except those that fall within the [hardware limitations](#hardware-limitations).
**Q: Why is the screen so dark?**\
A: The default backlight value is `64`. You can increase the brightness by increasing this value. Brightness control during gameplay is planned for a future update.
**Q: Why do the colors look darker?**\
A: You're probably used to the way GBA games look on emulators. No worries, just set the `adjustGamma` setting to `false` to get the color scheme you're expecting. Do note that a lot of games were designed with a darker gamma in mind, so some games may look weird with the brighter colors.
**Q: Why do some of my ROM hacks/homebrew games have saving issues?**\
A: open_agb_firm resorts to save autodetection when it can't find an entry for the game it's running in `gba_db.bin` (which only contains official games), and it's a bit wonky for games that use EEPROM.
A: open_agb_firm resorts to save autodetection when it can't find an entry for the game it's running in `gba_db.bin` (which only contains data for official games), and it's a bit wonky for games that use EEPROM or misleading SDK save strings.
**Q: Why doesn't my save from an emulator work?**\
A: There's a good chance that the save you're having issues with is an EEPROM save, which most emulators output differently. Use [this tool](https://gist.github.com/profi200/e06794d7561ed552c518b4b0b2f5f2f6) to fix them.
**Q: Why doesn't my save file from an emulator work?**\
A: There's a good chance that the save you're having issues with is an EEPROM save, which most emulators output differently. To address this, we made a Python script that fixes them.
Setup (Windows):
* Make sure [Python 3](https://www.python.org/downloads/) is installed.
* Download [the script](tools/eeprom-fixer/eeprom-fixer.py).
* Drag and drop the `.SAV` file you want to fix onto `eeprom-fixer.py`.
Setup (Linux):
* Make sure `python3` is installed (installed by default on most distros).
* Download [the script](tools/eeprom-fixer/eeprom-fixer.py).
* Open a terminal, and in the same directory as `eeprom-fixer.py`, run `chmod +x eeprom-fixer.py`.
* Type `./eeprom-fixer.py savefile.sav`, where `savefile.sav` is the path to your `.SAV` file.
Your save file should now be fixed and ready to use with open_agb_firm. The script also works vise versa, if you want to use a save generated by open_agb_firm with an emulator.
**Q: My game doesn't save properly!**\
A: First, please ensure that the `.GBA` ROM you are playing is not modified in any way, and matches its [No-Intro](https://datomatic.no-intro.org/) checksum. Second, make sure you aren't using an existing `.SAV` file, because some may have issues for various reasons. Third, make sure your [`gba_db.bin`](resources/gba_db.bin) is up-to-date. If everything seems to be in order but the game still doesn't save properly, please [open an issue](https://github.com/profi200/open_agb_firm/issues) so it can be fixed. In the meantime, the `useGbaDb` and `saveOverride` settings may be useful (see [Configuration](#configuration) for more information).
@ -129,13 +163,13 @@ You may use this under the terms of the GNU General Public License GPL v3 or the
* **Normmatt**
* **WinterMute**
* **ctrulib devs**
* **Luma3DS devs**
* **LumaTeam**
* **devkitPro**
* **ChaN** (fatfs)
* **benhoyt** (inih)
* **fastboot3DS project**
* **Wolfvak, Sono and all the other people in #GodMode9 on IRC/Discord**
* **endrift, Extrems and all the other people in #mgba on Freenode**
* **endrift, Extrems and all the other people in #mgba on freenode**
* ...everyone who contributed to **3dbrew.org**
Copyright (C) 2021 derrek, profi200, d0k3

View File

@ -12,3 +12,4 @@ brightness=0.0
[advanced]
saveOverride=false
defaultSave=14

View File

@ -42,18 +42,19 @@
#define OAF_WORK_DIR "sdmc:/3ds/open_agb_firm"
#define INI_BUF_SIZE (1024u)
#define DEFAULT_CONFIG "[general]\n" \
"backlight=64\n" \
"biosIntro=true\n" \
"useGbaDb=true\n\n" \
"[video]\n" \
"adjustGamma=true\n" \
"inGamma=2.2\n" \
"outGamma=1.54\n" \
"contrast=1.0\n" \
"brightness=0.0\n\n" \
"[advanced]\n" \
#define DEFAULT_CONFIG "[general]\n" \
"backlight=64\n" \
"biosIntro=true\n" \
"useGbaDb=true\n\n" \
"[video]\n" \
"adjustGamma=true\n" \
"inGamma=2.2\n" \
"outGamma=1.54\n" \
"contrast=1.0\n" \
"brightness=0.0\n\n" \
"[advanced]\n" \
"saveOverride=false\n" \
"defaultSave=14\n" \
typedef struct
@ -73,6 +74,7 @@ typedef struct
// [advanced]
bool saveOverride;
u16 defaultSave;
} OafConfig;
typedef struct
@ -102,7 +104,8 @@ static OafConfig g_oafConfig =
1.54f,
1.f,
0.f,
false
false,
14
};
static KHandle g_frameReadyEvent = 0;
@ -165,7 +168,8 @@ static Result loadGbaRom(const char *const path, u32 *const romSizeOut)
return res;
}
static u16 checkSaveOverride(u32 serial)
// Deprecated because of defaultSave.
/*static u16 checkSaveOverride(u32 serial)
{
static const struct
{
@ -190,22 +194,38 @@ static u16 checkSaveOverride(u32 serial)
}
return 0xFF;
}
}*/
static u16 detectSaveType(u32 romSize)
{
const u32 *romPtr = (u32*)ROM_LOC;
u16 saveType;
if((saveType = checkSaveOverride(romPtr[0xAC / 4])) != 0xFF)
// Deprecated because of defaultSave.
/*if((saveType = checkSaveOverride(romPtr[0xAC / 4])) != 0xFF)
{
debug_printf("Serial in override list.\n"
"saveType: %u\n", saveType);
return saveType;
}
}*/
// Code based on: https://github.com/Gericom/GBARunner2/blob/master/arm9/source/save/Save.vram.cpp
romPtr += 0xE4 / 4; // Skip headers.
saveType = SAVE_TYPE_NONE;
const u16 defaultSave = g_oafConfig.defaultSave;
if(defaultSave > SAVE_TYPE_NONE)
saveType = SAVE_TYPE_NONE;
else
{
saveType = defaultSave;
if(saveType == SAVE_TYPE_EEPROM_8k || saveType == SAVE_TYPE_EEPROM_64k)
{
if(romSize > 0x1000000) saveType++;
}
else if(saveType == SAVE_TYPE_EEPROM_8k_2 || saveType == SAVE_TYPE_EEPROM_64k_2)
{
if(romSize <= 0x1000000) saveType--;
}
}
for(; romPtr < (u32*)(ROM_LOC + romSize); romPtr++)
{
u32 tmp = *romPtr;
@ -358,7 +378,7 @@ static u16 getSaveType(u32 romSize, const char *const savePath)
ee_printf("%u\n", saveType);
ee_puts("\n"
"=Save Types=\n"
" EEPROM 4k/8k (0, 1)\n"
" EEPROM 8k (0, 1)\n"
" EEPROM 64k (2, 3)\n"
" Flash 512k RTC (4, 6, 8)\n"
" Flash 512k (5, 7, 9)\n"
@ -536,6 +556,8 @@ static int confIniHandler(void* user, const char* section, const char* name, con
{
if(strcmp(name, "saveOverride") == 0)
config->saveOverride = (strcmp(value, "true") == 0 ? true : false);
if(strcmp(name, "defaultSave") == 0)
config->defaultSave = (u16)strtoul(value, NULL, 10);
}
else return 0; // Error.

View File

@ -0,0 +1,21 @@
#!/usr/bin/env python3
# EEPROM Fixer v1.0
# By HTV04
import sys
with open(sys.argv[1], 'rb') as f:
save = f.read()
length = len(save)
if length < 32 or length & (length - 1) != 0:
print('Broken save file or incorrect size!')
exit()
swapsave = b''
for i in range(0, length, 8):
swapsave += save[i:i + 8][::-1]
with open(sys.argv[1], 'wb') as f:
f.write(swapsave)

View File

@ -1,4 +1,6 @@
# open_agb_firm gba_db.bin Builder v2.6
#!/usr/bin/env python3
# open_agb_firm gba_db.bin Builder v2.7
# 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.
@ -49,19 +51,17 @@ def preparegbadbbin(gbadb):
return gbadbbin
if __name__ == '__main__':
gbadb = []
skipcount = 0
count = 0
addcount = 0
gba = ET.parse('gba.xml').getroot() # MAME gba.xml
nointro = ET.parse('gba.dat').getroot() # No-Intro GBA DAT
# Arguments (could totally be done better but this will do for now)
puremode = False
if len(sys.argv) >= 2 and sys.argv[1] == 'pure': # Don't include anything that isn't in gba.xml and gba.dat
puremode = True
gbadb = []
skipcount = 0
count = 0
addcount = 0
gba = ET.parse('gba.xml').getroot() # MAME gba.xml
nointro = ET.parse('gba.dat').getroot() # No-Intro GBA DAT
# Start adding entries
for software in gba.findall('software'):
for part in software.findall('part'):