diff --git a/README.md b/README.md index 310ec8a..6b86c54 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ In the `games` section, you can edit the game-related stuff: - `6` = Pokémon Black & White condensed battle font - `save_slot` defines which save slot your game uses. Set it to `null` for no saving or a number starting from `1`. Multiple games can share a save slot. - `map_256m`, if set to `true`, can serve as a workaround for a glitch with the cartridge mapper that causes games to freeze with screeching noises upon launch. +- `keys` will let you specify a list of keys that must be held down at startup for this ROM to appear in the menu, e. g. `[ "L", "R", "DOWN" ]`. ### ROM Builder Command Line Arguments diff --git a/rom_builder/rom_builder.py b/rom_builder/rom_builder.py index cb38b39..d034415 100644 --- a/rom_builder/rom_builder.py +++ b/rom_builder/rom_builder.py @@ -5,7 +5,7 @@ import sys, os, glob, json, math, re, struct, hashlib, argparse, datetime # Configuration -app_version = "0.9" +app_version = "0.10" default_file = "LK_MULTIMENU_.gba" ################################ @@ -145,6 +145,7 @@ block_size = cartridge_types[cartridge_type]["block_size"] block_count = flash_size // block_size sectors_per_block = 0x80000 // sector_size compilation = bytearray() +roms_keys = [0] for i in range(flash_size // 0x2000000): chunk = bytearray([0xFF] * 0x2000000) compilation += chunk @@ -198,7 +199,36 @@ for game in games: else: game["title_font"] = 0 game["sector_count"] = int(size / sector_size) - + + # Hidden ROMs + keys = 0 + if "keys" in game: + for key in game["keys"]: + if key.upper() == "A": + keys |= (1 << 0) + elif key.upper() == "B": + keys |= (1 << 1) + elif key.upper() == "SELECT": + keys |= (1 << 2) + elif key.upper() == "START": + keys |= (1 << 3) + elif key.upper() == "RIGHT": + keys |= (1 << 4) + elif key.upper() == "LEFT": + keys |= (1 << 5) + elif key.upper() == "UP": + keys |= (1 << 6) + elif key.upper() == "DOWN": + keys |= (1 << 7) + elif key.upper() == "R": + keys |= (1 << 8) + elif key.upper() == "L": + keys |= (1 << 9) + game["keys"] = keys + if keys > 0: + roms_keys.append(keys) + roms_keys = list(set(roms_keys)) + if battery_present and game["save_slot"] is not None: game["save_type"] = 2 game["save_slot"] -= 1 @@ -240,7 +270,6 @@ for game in games: # Read ROM data games.sort(key=lambda game: game["size"], reverse=True) -c = 0 for game in games: found = False for i in range(save_end_offset, len(sector_map)): @@ -291,33 +320,39 @@ else: toc_sep = "----+-----------+-----------+--------------------------------------------------" item_list = bytearray() -for game in games: - title = game["title"] - if len(title) > 0x30: title = title[:0x2F] + "…" - table_line = \ - f"{game['index'] + 1:3d} | " \ - f"0x{game['block_offset'] * block_size:07X} | "\ - f"0x{game['block_count'] * block_size:07X} | " - if battery_present: - if game['save_type'] > 0: - table_line += f"{game['save_slot']+1:2d} (0x{(save_data_sector_offset + game['save_slot']) * sector_size:07X}) | " - else: - table_line += " | " - table_line += f"{title}" - if c % 8 == 0: logp(toc_sep) - logp(table_line) - c += 1 - - title = title.ljust(0x30, "\0") - item_list += bytearray(struct.pack("B", game["title_font"])) - item_list += bytearray(struct.pack("B", len(game["title"]))) - item_list += bytearray(struct.pack(" 0x30: title = title[:0x2F] + "…" + + table_line = \ + f"{game['index'] + 1:3d} | " \ + f"0x{game['block_offset'] * block_size:07X} | "\ + f"0x{game['block_count'] * block_size:07X} | " + if battery_present: + if game['save_type'] > 0: + table_line += f"{game['save_slot']+1:2d} (0x{(save_data_sector_offset + game['save_slot']) * sector_size:07X}) | " + else: + table_line += " | " + table_line += f"{title}" + if c % 8 == 0: logp(toc_sep) + logp(table_line) + c += 1 + + title = title.ljust(0x30, "\0") + item_list += bytearray(struct.pack("B", game["title_font"])) + item_list += bytearray(struct.pack("B", len(game["title"]))) + item_list += bytearray(struct.pack("= roms_total)) { @@ -119,15 +131,29 @@ int main(void) { page_active = sFlashStatus.last_boot_menu_index / 8; } - // Check on-boot keys - scanKeys(); - kHeld = keysHeld(); - if ((kHeld & KEY_SELECT) && (kHeld & KEY_R)) { - show_credits = TRUE; - } else if (kHeld & KEY_SELECT) { - show_debug = TRUE; + // Count number of ROMs + for (roms_total = 0; roms_total < 512; roms_total++) { + memcpy(&sItemConfig, ((u8*)itemlist)+(0x70*roms_total), sizeof(sItemConfig)); + if (sItemConfig.keys != kHeld) break; + if (sItemConfig.title_length == 0) break; + if (sItemConfig.title_length == 0xFF) break; } - + if (roms_total == 0) { + LoadFont(2); + DrawText(0, 64, ALIGN_CENTER, u"Please use the ROM Builder to", 48, font, (void*)AGB_VRAM+0xA000, FALSE); + DrawText(0, 64 + sFontSpecs.max_height, ALIGN_CENTER, u"create your own compilation.", 48, font, (void*)AGB_VRAM+0xA000, FALSE); + LoadFont(0); + DrawText(0, 127, ALIGN_CENTER, u"https://github.com/lesserkuma/GBA_MultiMenu", 48, font, (void*)AGB_VRAM+0xA000, FALSE); + DrawText(14, SCREEN_HEIGHT - sFontSpecs.max_height - 3 - FontMarginBottom, ALIGN_RIGHT, u"No ROMs", 10, font, (void*)AGB_VRAM+0xA000, FALSE); + REG_DISPCNT ^= 0x0010; + while (1) { VBlankIntrWait(); } + } else if (roms_total == 1) { + memcpy(&sItemConfig, ((u8*)itemlist), sizeof(sItemConfig)); + u8 error_code = BootGame(sItemConfig, sFlashStatus); + boot_failed = error_code; + } + page_total = (roms_total + 8.0 - 1) / 8.0; + s32 wait = 0; u8 f = 0; while (1) { @@ -212,6 +238,11 @@ int main(void) { // Check for menu keys scanKeys(); kHeld = keysHeld(); + if ((kHeld_boot == 0) || (kHeld != kHeld_boot)) { + kHeld_boot = 0; + } else { + kHeld = 0; + } if (kHeld != 0) { wait++; } else { diff --git a/source/main.h b/source/main.h index b25cd73..8a331b9 100644 --- a/source/main.h +++ b/source/main.h @@ -66,7 +66,7 @@ typedef struct ItemConfig_ u16 rom_size; SAVE_TYPE save_type; u8 save_index; - u16 index; + u16 keys; u8 reserved[6]; u16 title[0x30]; } ItemConfig;