1 Commits
0.9 ... 0.10

Author SHA1 Message Date
Lesserkuma
f756a705ae New config option + autoboot if there is only one game in the list 2024-01-06 11:47:03 +01:00
4 changed files with 118 additions and 51 deletions

View File

@@ -51,6 +51,7 @@ In the `games` section, you can edit the game-related stuff:
- `6` = Pokémon Black & White condensed battle font - `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. - `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. - `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 ### ROM Builder Command Line Arguments

View File

@@ -5,7 +5,7 @@
import sys, os, glob, json, math, re, struct, hashlib, argparse, datetime import sys, os, glob, json, math, re, struct, hashlib, argparse, datetime
# Configuration # Configuration
app_version = "0.9" app_version = "0.10"
default_file = "LK_MULTIMENU_<CODE>.gba" default_file = "LK_MULTIMENU_<CODE>.gba"
################################ ################################
@@ -145,6 +145,7 @@ block_size = cartridge_types[cartridge_type]["block_size"]
block_count = flash_size // block_size block_count = flash_size // block_size
sectors_per_block = 0x80000 // sector_size sectors_per_block = 0x80000 // sector_size
compilation = bytearray() compilation = bytearray()
roms_keys = [0]
for i in range(flash_size // 0x2000000): for i in range(flash_size // 0x2000000):
chunk = bytearray([0xFF] * 0x2000000) chunk = bytearray([0xFF] * 0x2000000)
compilation += chunk compilation += chunk
@@ -199,6 +200,35 @@ for game in games:
game["title_font"] = 0 game["title_font"] = 0
game["sector_count"] = int(size / sector_size) 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: if battery_present and game["save_slot"] is not None:
game["save_type"] = 2 game["save_type"] = 2
game["save_slot"] -= 1 game["save_slot"] -= 1
@@ -240,7 +270,6 @@ for game in games:
# Read ROM data # Read ROM data
games.sort(key=lambda game: game["size"], reverse=True) games.sort(key=lambda game: game["size"], reverse=True)
c = 0
for game in games: for game in games:
found = False found = False
for i in range(save_end_offset, len(sector_map)): for i in range(save_end_offset, len(sector_map)):
@@ -291,7 +320,12 @@ else:
toc_sep = "----+-----------+-----------+--------------------------------------------------" toc_sep = "----+-----------+-----------+--------------------------------------------------"
item_list = bytearray() item_list = bytearray()
for key in roms_keys:
c = 0
for game in games: for game in games:
if game["keys"] != key: continue
title = game["title"] title = game["title"]
if len(title) > 0x30: title = title[:0x2F] + "" if len(title) > 0x30: title = title[:0x2F] + ""
@@ -316,7 +350,8 @@ for game in games:
item_list += bytearray(struct.pack("<H", game["block_count"])) item_list += bytearray(struct.pack("<H", game["block_count"]))
item_list += bytearray(struct.pack("B", game["save_type"])) item_list += bytearray(struct.pack("B", game["save_type"]))
item_list += bytearray(struct.pack("B", game["save_slot"])) item_list += bytearray(struct.pack("B", game["save_slot"]))
item_list += bytearray([0] * 8) item_list += bytearray(struct.pack("<H", game["keys"]))
item_list += bytearray([0] * 6)
item_list += bytearray(title.encode("UTF-16LE")) item_list += bytearray(title.encode("UTF-16LE"))
compilation[item_list_offset * sector_size:item_list_offset * sector_size + len(item_list)] = item_list compilation[item_list_offset * sector_size:item_list_offset * sector_size + len(item_list)] = item_list

View File

@@ -60,6 +60,7 @@ int main(void) {
u8 redraw_items = 0xFF; u8 redraw_items = 0xFF;
u8 roms_page = 7; u8 roms_page = 7;
u16 kHeld = 0; u16 kHeld = 0;
u16 kHeld_boot = 0;
BOOL show_debug = FALSE; BOOL show_debug = FALSE;
BOOL show_credits = FALSE; BOOL show_credits = FALSE;
BOOL boot_failed = FALSE; BOOL boot_failed = FALSE;
@@ -90,21 +91,32 @@ int main(void) {
SetMode(MODE_4 | BG2_ENABLE); SetMode(MODE_4 | BG2_ENABLE);
dmaCopy(bgBitmap, (void*)AGB_VRAM+0xA000, SCREEN_WIDTH * SCREEN_HEIGHT); dmaCopy(bgBitmap, (void*)AGB_VRAM+0xA000, SCREEN_WIDTH * SCREEN_HEIGHT);
// Count number of ROMs // Check on-boot keys
for (roms_total = 0; roms_total < 512; roms_total++) { scanKeys();
if ((itemlist[(0x70*roms_total+1)] == 0) || (itemlist[(0x70*roms_total+1)] == 0xFF)) break; kHeld = keysHeld();
kHeld_boot = kHeld;
if ((kHeld & KEY_SELECT) && (kHeld & KEY_R)) {
show_credits = TRUE;
} else if (kHeld & KEY_SELECT) {
show_debug = TRUE;
}
if (kHeld) {
u16 itemlist_offset = 0;
BOOL found_keys = FALSE;
for (itemlist_offset = 0; itemlist_offset < 0x924; itemlist_offset += 0x70) {
memcpy(&sItemConfig, ((u8*)itemlist)+itemlist_offset, sizeof(sItemConfig));
if (sItemConfig.title_length == 0) break;
if (sItemConfig.title_length == 0xFF) break;
if (sItemConfig.keys == kHeld) {
itemlist += itemlist_offset;
found_keys = TRUE;
break;
}
}
if (!found_keys) {
kHeld = 0;
} }
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(); }
} }
page_total = (roms_total + 8.0 - 1) / 8.0;
memcpy(&sFlashStatus, (void *)(AGB_ROM + flash_status_sector_offset * flash_sector_size), sizeof(sFlashStatus)); memcpy(&sFlashStatus, (void *)(AGB_ROM + flash_status_sector_offset * flash_sector_size), sizeof(sFlashStatus));
if ((sFlashStatus.magic != MAGIC_FLASH_STATUS) || (sFlashStatus.last_boot_menu_index >= roms_total)) { if ((sFlashStatus.magic != MAGIC_FLASH_STATUS) || (sFlashStatus.last_boot_menu_index >= roms_total)) {
@@ -119,14 +131,28 @@ int main(void) {
page_active = sFlashStatus.last_boot_menu_index / 8; page_active = sFlashStatus.last_boot_menu_index / 8;
} }
// Check on-boot keys // Count number of ROMs
scanKeys(); for (roms_total = 0; roms_total < 512; roms_total++) {
kHeld = keysHeld(); memcpy(&sItemConfig, ((u8*)itemlist)+(0x70*roms_total), sizeof(sItemConfig));
if ((kHeld & KEY_SELECT) && (kHeld & KEY_R)) { if (sItemConfig.keys != kHeld) break;
show_credits = TRUE; if (sItemConfig.title_length == 0) break;
} else if (kHeld & KEY_SELECT) { if (sItemConfig.title_length == 0xFF) break;
show_debug = TRUE;
} }
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; s32 wait = 0;
u8 f = 0; u8 f = 0;
@@ -212,6 +238,11 @@ int main(void) {
// Check for menu keys // Check for menu keys
scanKeys(); scanKeys();
kHeld = keysHeld(); kHeld = keysHeld();
if ((kHeld_boot == 0) || (kHeld != kHeld_boot)) {
kHeld_boot = 0;
} else {
kHeld = 0;
}
if (kHeld != 0) { if (kHeld != 0) {
wait++; wait++;
} else { } else {

View File

@@ -66,7 +66,7 @@ typedef struct ItemConfig_
u16 rom_size; u16 rom_size;
SAVE_TYPE save_type; SAVE_TYPE save_type;
u8 save_index; u8 save_index;
u16 index; u16 keys;
u8 reserved[6]; u8 reserved[6];
u16 title[0x30]; u16 title[0x30];
} ItemConfig; } ItemConfig;