From 1375224a6e15fb22adae7607f8e38fc9bf5b8534 Mon Sep 17 00:00:00 2001 From: HTV04 <53527582+HTV04@users.noreply.github.com> Date: Sun, 2 May 2021 23:13:49 -0400 Subject: [PATCH] Post-review changes --- .gitignore | 1 - README.md | 49 +++++-------- resources/config.ini | 1 - resources/gba_db.bin | Bin 675108 -> 678984 bytes source/arm11/filebrowser.c | 23 +----- source/arm11/open_agb_firm.c | 38 +++------- tools/eeprom-fixer/eeprom-fixer.py | 21 ------ tools/gba-db-builder/addentries.csv | 21 ++++++ tools/gba-db-builder/gba-db-builder.py | 97 +++++++++++++++---------- 9 files changed, 109 insertions(+), 142 deletions(-) delete mode 100644 tools/eeprom-fixer/eeprom-fixer.py create mode 100644 tools/gba-db-builder/addentries.csv diff --git a/.gitignore b/.gitignore index 9a08579..1b7d35f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,6 @@ arm9/open_agb_firm9.bin arm11/open_agb_firm11.bin arm9/open_agb_firm9.elf arm11/open_agb_firm11.elf -tools/eeprom-fixer/*.sav tools/gba-db-builder/gba_db.bin tools/gba-db-builder/gba.dat tools/gba-db-builder/gba.xml diff --git a/README.md b/README.md index 5b22e21..92340f1 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,13 @@ open_agb_firm is also a complete and better alternative to GBA VC injects (AGB_F * And more to come! ## Disclaimer -open_agb_firm is currently in alpha. While open_agb_firm is relatively stable and safe to use, there are some quirks that have not been fixed. See [Known Issues](#known-issues) for more information. +open_agb_firm is currently in alpha. While open_agb_firm is relatively stable and safe to use, some quirks that have not been fixed. See [Known Issues](#known-issues) 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. ## Setup * 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 `open_agb_firm.firm` file to your 3DS's SD card at `/luma/payloads` if you're using Luma3DS or elsewhere 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. @@ -39,6 +39,7 @@ General settings. * Possible values: * Old 3DS: `20`-`117` * New 3DS: `16`-`142` +* Values ≤`64` are recommended. `bool biosIntro` - Show GBA BIOS intro at game startup * Default: `true` @@ -49,9 +50,6 @@ General settings. ### Video Video-related settings. -`bool adjustGamma` - Adjust screen gamma using values from `inGamma`, `outGamma`, `contrast`, and `brightness` -* Default: `true` - `float inGamma` - Screen input gamma * Default: `2.2` @@ -93,32 +91,19 @@ This section is reserved for a listing of known issues. At present only this rem 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. -* Games with extra hardware built into the cartridge (except RTC, or real-time clock). Patches are required. +open_agb_firm using the 3DS's built-in GBA hardware. Unfortunately, this comes with limitations compared to GBA emulators. This is a list of limitations we can't solve in software or are very hard to work around. +* \>32 MiB (>256 Mbit) games and homebrew. +* Games with extra hardware built into the cartridge (except real-time clocks). 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). +* \>32 KiB (>256 Kbit) SRAM (homebrew games/emulators). * Reboots are required for switching between games. * No save states. Very difficult to implement because no direct hardware access. ## EEPROM Fixer -Most emulators output EEPROM saves differently than what open_agb_firm expects, making them incompatible. To address this, we made a Python script that fixes them. +Most emulators output EEPROM saves differently than what open_agb_firm expects, making them incompatible. Fortunately, they are very easy to fix, using [this tool](https://exelotl.github.io/gba-eeprom-save-fix/) by exelotl. -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`. - -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. - -The steps for Linux may work on macOS with [Python 3](https://www.python.org/downloads/mac-osx/) installed, but have not been tested. - -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. +The tool also works vise versa, if you want to use a save generated by open_agb_firm with an emulator. ## FAQ **Q: Why isn't open_agb_firm a normal 3DS app?**\ @@ -130,11 +115,11 @@ A: Of course! While open_agb_firm does run with full hardware access, a lot of w **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: How can I increase the brightness?**\ +A: Increase the value of the `backlight` setting in `config.ini`. See [Configuration](#configuration) for more information. -**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 the colors look off?**\ +A: The default gamma settings are intended to make up for the washed out colors the 3DS LCD has. If they look weird to you, setting the `outGamma` setting to `2.2` might help. **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 data for official games), and it's a bit wonky for games that use EEPROM or misleading SDK save strings. @@ -146,14 +131,12 @@ A: There's a good chance that the save you're having issues with is an EEPROM sa 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/) checksums. 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). ## Compiling -If you're using Windows 10, you can 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://devkitpro.org/wiki/devkitPro_pacman) * [Corelink DMA-330 Assembler](https://github.com/profi200/dma330as) * [CTR Firm Builder](https://github.com/derrekr/ctr_firm_builder) -Additionally, `p7zip-full` 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. +Additionally, `p7zip` (or if available, `p7zip-full`) 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`. @@ -172,7 +155,9 @@ You may use this under the terms of the GNU General Public License GPL v3 or the * **ChaN** (fatfs) * **benhoyt** (inih) * **fastboot3DS project** -* **Wolfvak, Sono and all the other people in #GodMode9 on IRC/Discord** +* **MAME** +* **No-Intro** +* **Wolfvak, Sono and all the other people in #GodMode9 on freenode/Discord** * **endrift, Extrems and all the other people in #mgba on freenode** * ...everyone who contributed to **3dbrew.org** diff --git a/resources/config.ini b/resources/config.ini index 8e8b9d4..7b3d69c 100644 --- a/resources/config.ini +++ b/resources/config.ini @@ -4,7 +4,6 @@ biosIntro=true useGbaDb=true [video] -adjustGamma=true inGamma=2.2 outGamma=1.54 contrast=1.0 diff --git a/resources/gba_db.bin b/resources/gba_db.bin index 14f48f1f802ba7a3a5cfcaf5ca18cea725ce0785..e0a4b4910a32b56514fbc5775d330fd3058ca723 100644 GIT binary patch delta 1623 zcmZ`(eM}Q~815JS0D?MU+IixEsC2V>cP;&p)zH!_6sW1dCL_jq?cLzC?UA-1n+A=7 z=tL)}asz`FD<8w4M09n=Oho3;nTfiniSsM?5zL4)bL!@%``v9>vMGOE?sxZlp67ku z_kH%YsD_TJdJ~B^QH@Rut6>}ArQM7dcF;Z=M$pi3ZBlG{9#KK~RB$@ZqKr5M+lm}{ zKW~|_{LYL4dA#%Vvb~26HqIu-ngs$u7()?FsA5lgUluVjK`825%;apEh3YX4z|Qs% zfdK7>7vV*45#^_;064Vz=fMubPcxwue+05w9rzzcCgH$)=aqK@-PruX;yJfWhGGu7 z@AIb;yD%Zznk77ccov$0pyOgPzLnI+a6ZFsUmC-K=HuHkVIA@)9_y}dIyf4AK2`&5 zML5u?=T~9>+mkVa1_5ZCvVT+tnmXl2Ae-6h+%go5El+mnij~*Czpqoiu&OTm_^Wea z5jlN9HG=8D)&Cf$hVyBXsRUK}0_8MZ3g=Y%NWu$#%VmOak=svrT^@=}iI;DKY&oTQ zhfhXI=6~QdzR}kCK%M+$`LwDXxje;olPF9I1yOXbh>eqA1}(}~JP~KIJ>SYULzeu- zB|kkU75k$vEiFB#OIPkR9eZd}Tm?6eMu&PtKdO|d*2s1BRp+_JhEn}45NIae5Gf%K zXwKNwmpu<3{r*ko?s>5cPrvVqXzp@g`31dr*Vj?!Q?Y7Fyg|#AYh}tlfiV_o5N&F7 zY9NcrMUP=vbtm`>>uTvxt^hc``Bu9&80x8DVN&$yX!mV}?J}?69 zkj<&bYfW_vFMc}7Q`ercwq?iYls&qRVNOsd;*yw!q9_`XtgeY}PmP&60^Yuek*=;m zK_4;z)c^WmC1^FKUO~e}l@*j9E@WJw0mTFzpnRPDEU3RQ@3U}b^33};!qao{*30NIe(9h81-vu}d@eNzsX4LPVA9;D>w`GvG zv^dQ()y6xj-6!o50mSPaQbs)+ECx27C)q?G=%K0zAI+YOQ|#qN5zpxmCyiwVyUuL% zXYTAf6Epcz-%=j7;0Nhr0yN63lWCXF(;CM`EiR|v0;-JikudWSTuOOJ0*G#gY^4Qw zdiQ{vI$=Imdv7f}x;1IAtl_Ix-iBb4?82l>JvQ#b@i?&E4r<{D%w!ei3s(9mj-!C~ ztppSekgdRir#`Usv@~}dpYUCmAA0t<_DMtLQ=Y=wB^wliL05FkLUG{PdPKG=9{7|r zAUh{a(;B&%dv%Jzp@s3fD8H8<92# zRZ}#&SJo8)cCo!kY$9u4AlWrt00JZL$iY)9){6%Q>$JJbVH!y|`)AV<9_9F$EcZj8 zEXEctPhkmFMKhJ`?Q=1qM(1S6R`Nc6NM5&oUG2JCSK{5Bt9or& zt&5TddGK7R!mCcpK)5h^ZMk+g1wPPT7ke91fO_rOI5|pPo~E95_hwJ;OlEAui}vOv zX*}3rjiMiub1R7GjfSRn$@I|v#O6k4LNu#P@ysOw8>8oP;H`fHo=Yb_jNxp;TS3re zA@j&iE+X>Egu)4HluLhke&d?*j;lH&l2o5Nfm;#7S;e~`=%bZa6%i6lpwbi@H}Nl^ CP(Q-} delta 359 zcmX@HLvzV2%?%=nn|~zQ@GN@nYL+fzn$EplVKdVm&Fv5FGU+4$#dz(QXYXS%GBPlo?y!l; zdU`@Ud*}9^Kg_P;%q9lr(?2X=mYgg(dGW*mj_oy~EFXfF2V}B10`VyUj%{z9Gg z&to9(DK}en9gCrXp~-Zadu)>16T8{sWq{%bm$OY_-fp>uZ8;N=_i!CszV3FDyKG+) zfjmunc9Vqdjtkf?2yXwniTyAmP;BQG_Q~8p+V=o^IS-INdWQWB_8Wr{$h8J z2a453a@;or(y`qfDecS_Mn;n-+*jUyTA0&Km)Xd~eEJ(VE~)8Or`T6*-{Zvj!;piY yf#HCGxuwN)g*7a)lUIw(oEX5jy`hxzN7D9~o1CD4+&=R;=VDL*+4^vC3jhGlTZB;n diff --git a/source/arm11/filebrowser.c b/source/arm11/filebrowser.c index 992c18c..bc2d303 100644 --- a/source/arm11/filebrowser.c +++ b/source/arm11/filebrowser.c @@ -138,16 +138,7 @@ Result browseFiles(const char *const basePath, char selected[512]) if(dList == NULL) return RES_OUT_OF_MEM; Result res; - if((res = scanDir(curDir, dList, ".gba")) != RES_OK) - { - free(dList); - free(curDir); - - // Clear screen. - ee_printf("\x1b[2J"); - - return res; - } + if((res = scanDir(curDir, dList, ".gba")) != RES_OK) goto end; showDirList(dList, 0); s32 cursorPos = 0; // Within the entire list. @@ -164,16 +155,7 @@ Result browseFiles(const char *const basePath, char selected[512]) GFX_waitForVBlank0(); hidScanInput(); - if(hidGetExtraKeys(0) & (KEY_POWER_HELD | KEY_POWER)) - { - free(dList); - free(curDir); - - // Clear screen. - ee_printf("\x1b[2J"); - - return res; - } + if(hidGetExtraKeys(0) & (KEY_POWER_HELD | KEY_POWER)) goto end; kDown = hidKeysDown(); } while(kDown == 0); @@ -240,6 +222,7 @@ Result browseFiles(const char *const basePath, char selected[512]) } } +end: free(dList); free(curDir); diff --git a/source/arm11/open_agb_firm.c b/source/arm11/open_agb_firm.c index 51c0940..228662c 100644 --- a/source/arm11/open_agb_firm.c +++ b/source/arm11/open_agb_firm.c @@ -45,16 +45,15 @@ #define DEFAULT_CONFIG "[general]\n" \ "backlight=64\n" \ "biosIntro=true\n" \ - "useGbaDb=true\n\n" \ + "useGbaDb=true\n\n" \ "[video]\n" \ - "adjustGamma=true\n" \ - "inGamma=2.2\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" \ + "defaultSave=14\n" \ typedef struct @@ -66,7 +65,6 @@ typedef struct // Setting to separate save and config files from the ROMs? // [video] - bool adjustGamma; float inGamma; float outGamma; float contrast; @@ -99,7 +97,6 @@ static OafConfig g_oafConfig = 40, true, true, - true, 2.2f, 1.54f, 1.f, @@ -214,18 +211,8 @@ static u16 detectSaveType(u32 romSize) 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; @@ -403,14 +390,14 @@ static u16 getSaveType(u32 romSize, const char *const savePath) ee_printf("\x1b[%u;H ", oldCursor + 6); ee_printf("\x1b[%u;H>", cursor + 6); oldCursor = cursor; - + u32 kDown; do { GFX_waitForVBlank0(); - + hidScanInput(); - if(hidGetExtraKeys(0) & (KEY_POWER_HELD | KEY_POWER)) return saveType; + if(hidGetExtraKeys(0) & (KEY_POWER_HELD | KEY_POWER)) goto end; kDown = hidKeysDown(); } while(kDown == 0); @@ -433,6 +420,7 @@ static u16 getSaveType(u32 romSize, const char *const savePath) } } +end: return saveType; } @@ -535,9 +523,7 @@ static int confIniHandler(void* user, const char* section, const char* name, con } else if(strcmp(section, "video") == 0) { - if(strcmp(name, "adjustGamma") == 0) - config->adjustGamma = (strcmp(value, "true") == 0 ? true : false); - else if(strcmp(name, "inGamma") == 0) + if(strcmp(name, "inGamma") == 0) config->inGamma = str2float(value); else if(strcmp(name, "outGamma") == 0) config->outGamma = str2float(value); @@ -575,9 +561,7 @@ static int confIniHandler(void* user, const char* section, const char* name, con } else if(strcmp(section, "video") == 0) { - if(strcmp(name, "adjustGamma") == 0) - config->adjustGamma = (strcmp(value, "true") == 0 ? true : false); - else if(strcmp(name, "inGamma") == 0) + if(strcmp(name, "inGamma") == 0) config->inGamma = str2float(value); else if(strcmp(name, "outGamma") == 0) config->outGamma = str2float(value); @@ -724,7 +708,7 @@ Result oafInitAndRun(void) g_frameReadyEvent = frameReadyEvent; // Adjust gamma table and sync LgyFb start with LCD VBlank. - if(g_oafConfig.adjustGamma) adjustGammaTableForGba(); + adjustGammaTableForGba(); GFX_waitForVBlank0(); LGY_switchMode(); } diff --git a/tools/eeprom-fixer/eeprom-fixer.py b/tools/eeprom-fixer/eeprom-fixer.py deleted file mode 100644 index a478b3b..0000000 --- a/tools/eeprom-fixer/eeprom-fixer.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/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) diff --git a/tools/gba-db-builder/addentries.csv b/tools/gba-db-builder/addentries.csv new file mode 100644 index 0000000..dad28d5 --- /dev/null +++ b/tools/gba-db-builder/addentries.csv @@ -0,0 +1,21 @@ +Title,Serial,SHA-1,Size,Save Type +0246 - Kinniku Banzuke - Kimero! Kiseki no Kanzen Seiha (Japan),AK5J,CF0A6C1C473BA6C85027B6071AA1CF6E21336974,8388608,14 +1364 - Famicom Mini 01 - Super Mario Bros. (Japan) (En) (Rev 1),FSMJ,F08B1F60E41FC2080C50C65EA2B2AF912661ED99,1048576,0 +1366 - Famicom Mini 02 - Donkey Kong (Japan) (En),FDKJ,B5AFC36A8203C2C485344819D069300ECAFD9657,1048576,0 +"1492 - Classic NES Series - The Legend of Zelda (USA, Europe)",FZLE,28AAC26365BF41BA84E67F97E98D15C4678CB99D,1048576,2 +"1494 - Classic NES Series - Super Mario Bros. (USA, Europe)",FSME,8CA35864AE33C9462DD66CEFF1FAC5A79E2E0A6F,1048576,0 +"1496 - Classic NES Series - Bomberman (USA, Europe)",FBME,741EB2874C526CC014BF3E642B4EE37F18312735,1048576,0 +"1498 - Classic NES Series - Xevious (USA, Europe)",FXVE,B2088582808480E0D70C63A777B046409D4E15C4,1048576,0 +"1499 - Classic NES Series - Pac-Man (USA, Europe)",FP7E,843D853ED28A116C85A5357F9A94E9179F36A6D0,1048576,0 +"1500 - Classic NES Series - Ice Climber (USA, Europe)",FICE,64E965D61B2D1BE5DFADB0236FED83FEA5995724,1048576,0 +"1501 - Classic NES Series - Donkey Kong (USA, Europe)",FDKE,8E3B203630F10C32AA7896AFE9B7FBED7E1C8D30,1048576,0 +"1721 - Classic NES Series - Zelda II - The Adventure of Link (USA, Europe)",FLBE,22EA42AD9A99A6BC0FCBA8721CF8F484F68C3BF7,1048576,2 +1722 - Classic NES Series - Castlevania (USA),FADE,47A60315ED4074A8C986723B95B3C90513D3B35C,1048576,0 +"1723 - Classic NES Series - Dr. Mario (USA, Europe)",FDME,FC396F0EAE55CF19E573AA322F525427E03D3854,1048576,0 +"1724 - Classic NES Series - Metroid (USA, Europe)",FMRE,838DA11F879E2FA3FFDEF95E1C6D5A54246C1846,1048576,0 +2830 - NES Classics - Castlevania (Europe),FADP,8BC8740A681E4D365419DBCEE73619FE4429D66E,1048576,0 +"2841 - King Kong - The Official Game of the Movie (Europe) (En,Sv,No,Da,Fi)",BKQX,ECFB6409ABB7FF429AADC65A6B953DBAEF3D09D8,8388608,0 +2846 - Dogz 2 (USA) (Rev 1),BIME,FF2772E347212264D1A1C4D322A08685ADC1E6A7,16777216,2 +x025 - Famicom Mini - Dai-2-ji Super Robot Taisen (Japan) (Promo),FSRJ,8FA03B1E23E7DEA0DBC841D23046D03D246A1CDF,1048576,2 +x026 - Famicom Mini - Kidou Senshi Z Gundam - Hot Scramble (Japan) (Promo),FGZJ,B4C1A3582F596D3912A1A7EA2D1EB6681B769448,1048576,0 +x027 - Super Mario Bros. (Japan) (Hot Mario Campaign),FSMJ,6701010F7C195CF3FBDEDB19E4627835A3158748,1048576,15 diff --git a/tools/gba-db-builder/gba-db-builder.py b/tools/gba-db-builder/gba-db-builder.py index 5cdfac0..c59ef9f 100755 --- a/tools/gba-db-builder/gba-db-builder.py +++ b/tools/gba-db-builder/gba-db-builder.py @@ -1,13 +1,15 @@ #!/usr/bin/env python3 -# open_agb_firm gba_db.bin Builder v2.8 +# open_agb_firm gba_db.bin Builder v3.0 # 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. # No-Intro's GBA DAT (with scene numbers) is also used for filtering and naming (found here: https://datomatic.no-intro.org/). The DAT should be renamed to "gba.dat". +# Unless otherwise specified, entries from an addentries.csv file are also added. This file usually includes entries that cannot be not found or are wrong in MAME's gba.xml. # # This script should work with any updates to MAME's gba.xml and the No-Intro DAT, unless something this script expects is changed. +import csv import math import re import sys @@ -29,21 +31,19 @@ def gbadbentry(title, serial, sha, size, savetype): else: entry.append(serial.encode()) entry.append(shabytes) - entry.append((int(math.log(size, 2)) << 27 | savetype).to_bytes(4, 'little')) # Save type is stored weirdly + entry.append((int(math.log(size, 2)) << 27 | savetype).to_bytes(4, 'little')) return entry -# Prepare gba_db.bin binary string from gba_db list. -def preparegbadbbin(gbadb): - gbadbbin = b'' - - # Use sort key to sort the gba_db list and delete it from each entry +# Prepare gba_db list for gba_db.bin +def preparegbadb(gbadb): + # Use sort key to sort the gba_db list and delete it from each entry gbadb = sorted(gbadb, key=lambda l:l[0]) - length = len(gbadb) - for i in range(length): + for i in range(len(gbadb)): gbadb[i].pop(0) # Compile gba_db binary + gbadbbin = b'' for i in gbadb: for j in i: gbadbbin += j @@ -52,17 +52,16 @@ def preparegbadbbin(gbadb): if __name__ == '__main__': # 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 + noaddentries = False + if len(sys.argv) >= 2 and sys.argv[1] == 'noaddentries': # Don't include anything that isn't in gba.xml and gba.dat + noaddentries = True + # Start adding entries 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'): if part.get('name') == 'cart': @@ -77,17 +76,19 @@ if __name__ == '__main__': matchfound = False for game in nointro.findall('game'): for rom in game.findall('rom'): - if rom.get('sha1') == sha.upper(): - matchfound = True - + if rom.get('sha1').lower() == sha: title = game.get('name') serial = rom.get('serial') if serial == None: serial = '' size = int(rom.get('size')) + + matchfound = True + + break # If not in No-Intro DAT, skip entry - if matchfound == False: + if not matchfound: break # Obtain save type @@ -95,11 +96,11 @@ if __name__ == '__main__': for feature in part.findall('feature'): if feature.get('name') == 'slot': slottype = feature.get('value') - if slottype in ('gba_eeprom_4k', 'gba_eeprom'): + if slottype in ('gba_eeprom_4k', 'gba_yoshiug', 'gba_eeprom'): savetype = 0 # SAVE_TYPE_EEPROM_8k if size > 0x1000000: savetype += 1 # SAVE_TYPE_EEPROM_8k_2 - elif slottype == 'gba_eeprom_64k': + elif slottype in ('gba_eeprom_64k', 'gba_boktai'): savetype = 2 # SAVE_TYPE_EEPROM_64k if size > 0x1000000: savetype += 1 # SAVE_TYPE_EEPROM_64k_2 @@ -111,46 +112,62 @@ if __name__ == '__main__': savetype = 10 # SAVE_TYPE_FLASH_1m_MRX_RTC elif slottype == 'gba_flash_1m': savetype = 11 # SAVE_TYPE_FLASH_1m_MRX - elif slottype == 'gba_sram': + elif slottype in ('gba_sram', 'gba_drilldoz', 'gba_wariotws'): savetype = 14 # SAVE_TYPE_SRAM_256k break # If not in No-Intro DAT, skip entry - if matchfound == False: + if not matchfound: print ('Skipped "' + software.find('description').text + '"') skipcount += 1 continue - # Expand gba_db with entry - gbadb.append(gbadbentry(title, serial, sha, size, savetype)) + # Add entry to gba_db + entry = gbadbentry(title, serial, sha, size, savetype) + for i in range(len(gbadb)): + if gbadb[i][3].hex() == sha: + print('Duplicate entry "' + gbadb[i][1].decode() + '" replaced') + gbadb[i] = entry + skipcount += 1 + break + else: + gbadb.append(entry) + count += 1 - print('Added entry "' + software.find('description').text + '"') - count += 1 + print('Added entry "' + title + '"') - # Add additional entries if "puremode" is false - if not puremode: - # Title, serial, SHA-1, size, save type - gbadbentries = ([['0246 - Kinniku Banzuke - Kimero! Kiseki no Kanzen Seiha (Japan)', 'AK5J', 'CF0A6C1C473BA6C85027B6071AA1CF6E21336974', 0x800000, 14]]) + # Add additional entries from addentries.csv if "noaddentries" is false + if not noaddentries: + with open('addentries.csv') as f: + addentries = list(csv.reader(f)) + + addentries.pop(0) + for i in addentries: + i[3] = int(i[3]) + i[4] = int(i[4]) print() - for title, serial, sha, size, savetype in gbadbentries: - gbadb.append(gbadbentry(title, serial, sha, size, savetype)) + for title, serial, sha, size, savetype in addentries: + entry = gbadbentry(title, serial, sha, size, savetype) + for i in range(len(gbadb)): + if gbadb[i][3].hex().upper() == sha: + print('Duplicate entry "' + gbadb[i][1].decode() + '" replaced') + gbadb[i] = entry + skipcount += 1 + break + else: + gbadb.append(entry) + count += 1 print('Added additional entry "' + title + '"') - addcount += 1 - print('\nFinalizing...\n') - - gbadbbin = preparegbadbbin(gbadb) + gbadbbin = preparegbadb(gbadb) # Create and write to gba_db.bin with open('gba_db.bin', 'wb') as f: f.write(gbadbbin) - if puremode: - print(str(count) + ' entries added, ' + str(skipcount) + ' entries skipped') - else: - print(str(count) + ' entries added, ' + str(addcount) + ' additional entries added, ' + str(skipcount) + ' entries skipped') + print('\n' + str(count) + ' entries added, ' + str(skipcount) + ' entries skipped')