mirror of
https://github.com/lesserkuma/GBA_MultiMenu.git
synced 2026-08-23 17:14:10 -05:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89b22c8205 | ||
|
|
39ab8936ec | ||
|
|
a2fa155e8e |
@@ -23,6 +23,7 @@ Set `type` to `1` or `2`:
|
|||||||
- `1` = MSP55LV100S (e.g. The Legend of Zelda Collection - Classic Edition 7-in-1, 64 MiB)
|
- `1` = MSP55LV100S (e.g. The Legend of Zelda Collection - Classic Edition 7-in-1, 64 MiB)
|
||||||
- `2` = 6600M0U0BE (e.g. 369IN1 2048M, 256 MiB)
|
- `2` = 6600M0U0BE (e.g. 369IN1 2048M, 256 MiB)
|
||||||
- `3` = MSP54LV100 (e.g. The Legend of Zelda Collection - Classic Edition 7-in-1, 128 MiB)
|
- `3` = MSP54LV100 (e.g. The Legend of Zelda Collection - Classic Edition 7-in-1, 128 MiB)
|
||||||
|
- `4` = F0095H0 (e.g. 53 in one 4G, 512 MiB)
|
||||||
|
|
||||||
Set `battery_present` to `true` or `false`. This will enable enhanced save data handling which will only be functional with a working battery.
|
Set `battery_present` to `true` or `false`. This will enable enhanced save data handling which will only be functional with a working battery.
|
||||||
|
|
||||||
@@ -51,7 +52,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" ]`.
|
- `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
|
||||||
|
|
||||||
@@ -62,6 +63,7 @@ No command line arguments are required for creating a compilation, however there
|
|||||||
--no-wait don't wait for user input when finished
|
--no-wait don't wait for user input when finished
|
||||||
--no-log don't write a log file
|
--no-log don't write a log file
|
||||||
--config config.json sets the config file to use
|
--config config.json sets the config file to use
|
||||||
|
--bg bg.png sets the background image to use
|
||||||
--output output.gba sets the file name of the compilation ROM
|
--output output.gba sets the file name of the compilation ROM
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -83,11 +85,12 @@ Tested repro cartridges:
|
|||||||
- 100SOP with MSP55LV100S
|
- 100SOP with MSP55LV100S
|
||||||
- 100BS6600_48BALL_V4 with 6600M0U0BE
|
- 100BS6600_48BALL_V4 with 6600M0U0BE
|
||||||
- SUN100S_MSP54_XXX_BGA48 with MSP54LV100
|
- SUN100S_MSP54_XXX_BGA48 with MSP54LV100
|
||||||
|
- F0095_4G_V1 with F0095H0
|
||||||
|
|
||||||
The generated compilation ROM can be written and read using a [GBxCart RW v1.4+](https://www.gbxcart.com/) device by insideGadgets and the [FlashGBX](https://github.com/lesserkuma/FlashGBX) software.
|
The generated compilation ROM can be written and read using a [GBxCart RW v1.4+](https://www.gbxcart.com/) device by insideGadgets and the [FlashGBX](https://github.com/lesserkuma/FlashGBX) software.
|
||||||
|
|
||||||
## Thanks
|
## Thanks
|
||||||
Thanks to FraX, Ausar, liuyunx, BennVenn, Jenetrix
|
Thanks to FraX, Ausar, liuyunx, BennVenn, Jenetrix, Matt
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
|
|||||||
BIN
graphics/bg.png
BIN
graphics/bg.png
Binary file not shown.
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 756 B |
BIN
rom_builder/bg.png
Normal file
BIN
rom_builder/bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 756 B |
@@ -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.10"
|
app_version = "1.0"
|
||||||
default_file = "LK_MULTIMENU_<CODE>.gba"
|
default_file = "LK_MULTIMENU_<CODE>.gba"
|
||||||
|
|
||||||
################################
|
################################
|
||||||
@@ -14,7 +14,6 @@ def UpdateSectorMap(start, length, c):
|
|||||||
sector_map[start + 1:start + length] = c * (length - 1)
|
sector_map[start + 1:start + length] = c * (length - 1)
|
||||||
sector_map[start] = c.upper()
|
sector_map[start] = c.upper()
|
||||||
|
|
||||||
|
|
||||||
def formatFileSize(size):
|
def formatFileSize(size):
|
||||||
if size == 1:
|
if size == 1:
|
||||||
return "{:d} Byte".format(size)
|
return "{:d} Byte".format(size)
|
||||||
@@ -57,6 +56,12 @@ cartridge_types = [
|
|||||||
"sector_size":0x20000,
|
"sector_size":0x20000,
|
||||||
"block_size":0x80000,
|
"block_size":0x80000,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name":"F0095H0",
|
||||||
|
"flash_size":0x20000000,
|
||||||
|
"sector_size":0x40000,
|
||||||
|
"block_size":0x80000,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
log = ""
|
log = ""
|
||||||
@@ -68,6 +73,7 @@ parser.add_argument("--split", help="splits output files into 32 MiB parts", act
|
|||||||
parser.add_argument("--no-wait", help="don’t wait for user input when finished", action="store_true", default=False)
|
parser.add_argument("--no-wait", help="don’t wait for user input when finished", action="store_true", default=False)
|
||||||
parser.add_argument("--no-log", help="don’t write a log file", action="store_true", default=False)
|
parser.add_argument("--no-log", help="don’t write a log file", action="store_true", default=False)
|
||||||
parser.add_argument("--config", type=str, default="config.json", help="sets the config file to use")
|
parser.add_argument("--config", type=str, default="config.json", help="sets the config file to use")
|
||||||
|
parser.add_argument("--bg", type=str, help="sets the background image to use")
|
||||||
parser.add_argument("--output", type=str, default=default_file, help="sets the file name of the compilation ROM")
|
parser.add_argument("--output", type=str, default=default_file, help="sets the file name of the compilation ROM")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
output_file = args.output
|
output_file = args.output
|
||||||
@@ -153,7 +159,36 @@ sector_map = list("." * sector_count)
|
|||||||
|
|
||||||
# Read menu ROM
|
# Read menu ROM
|
||||||
with open("lk_multimenu.gba", "rb") as f:
|
with open("lk_multimenu.gba", "rb") as f:
|
||||||
menu_rom = f.read()
|
menu_rom = bytearray(f.read())
|
||||||
|
menu_rom += bytearray([0xFF] * ((len(menu_rom) + 0x10 - (len(menu_rom) % 0x10)) - len(menu_rom)))
|
||||||
|
menu_rom += bytearray([0xFF] * 0x20)
|
||||||
|
build_timestamp_offset = len(menu_rom) - 0x20
|
||||||
|
build_timestamp = datetime.datetime.now().astimezone().replace(microsecond=0).isoformat().encode("ASCII")
|
||||||
|
menu_rom[build_timestamp_offset:build_timestamp_offset+len(build_timestamp)] = build_timestamp
|
||||||
|
|
||||||
|
# Change background image
|
||||||
|
if args.bg or os.path.exists("bg.png"):
|
||||||
|
try:
|
||||||
|
from PIL import Image
|
||||||
|
if args.bg:
|
||||||
|
img = Image.open(args.bg)
|
||||||
|
else:
|
||||||
|
img = Image.open("bg.png")
|
||||||
|
img = img.convert('P')
|
||||||
|
palette = img.getpalette()
|
||||||
|
palette_rgb555 = [((b >> 3) << 10) | ((g >> 3) << 5) | (r >> 3) for r, g, b in zip(palette[::3], palette[1::3], palette[2::3])]
|
||||||
|
raw_bitmap = bytearray(list(img.tobytes()))
|
||||||
|
raw_palette = bytearray(0x200)
|
||||||
|
pos = 0
|
||||||
|
for color in palette_rgb555:
|
||||||
|
raw_palette[pos:pos+2] = struct.pack("<H", color)
|
||||||
|
pos += 2
|
||||||
|
menu_rom_bg_offset = menu_rom.find(b"RTFN\xFF\xFE") - 0x9800
|
||||||
|
menu_rom[menu_rom_bg_offset:menu_rom_bg_offset+0x9600] = raw_bitmap
|
||||||
|
menu_rom[menu_rom_bg_offset+0x9600:menu_rom_bg_offset+0x9800] = raw_palette
|
||||||
|
except ImportError:
|
||||||
|
print("Error: Couldn’t update background image. Pillow library is not installed.")
|
||||||
|
|
||||||
menu_rom_size = menu_rom.find(b"dkARM\0\0\0") + 8
|
menu_rom_size = menu_rom.find(b"dkARM\0\0\0") + 8
|
||||||
compilation[0:len(menu_rom)] = menu_rom
|
compilation[0:len(menu_rom)] = menu_rom
|
||||||
UpdateSectorMap(start=0, length=math.ceil(len(menu_rom) / sector_size), c="m")
|
UpdateSectorMap(start=0, length=math.ceil(len(menu_rom) / sector_size), c="m")
|
||||||
@@ -225,6 +260,7 @@ for game in games:
|
|||||||
elif key.upper() == "L":
|
elif key.upper() == "L":
|
||||||
keys |= (1 << 9)
|
keys |= (1 << 9)
|
||||||
game["keys"] = keys
|
game["keys"] = keys
|
||||||
|
|
||||||
if keys > 0:
|
if keys > 0:
|
||||||
roms_keys.append(keys)
|
roms_keys.append(keys)
|
||||||
roms_keys = list(set(roms_keys))
|
roms_keys = list(set(roms_keys))
|
||||||
@@ -313,11 +349,11 @@ logp("{:.2f}% ({:d} of {:d} sectors) used\n".format(sectors_used / sector_count
|
|||||||
logp(f"Added {len(games)} ROM(s) to the compilation\n")
|
logp(f"Added {len(games)} ROM(s) to the compilation\n")
|
||||||
|
|
||||||
if battery_present:
|
if battery_present:
|
||||||
logp (" | Offset | Map Size | Save Slot | Title")
|
logp (" | Offset | Map Size | Save Slot | Title")
|
||||||
toc_sep = "----+-----------+-----------+----------------+---------------------------------"
|
toc_sep = "----+------------+-----------+----------------+--------------------------------"
|
||||||
else:
|
else:
|
||||||
logp (" | Offset | Map Size | Title")
|
logp (" | Offset | Map Size | Title")
|
||||||
toc_sep = "----+-----------+-----------+--------------------------------------------------"
|
toc_sep = "----+------------+-----------+-------------------------------------------------"
|
||||||
|
|
||||||
item_list = bytearray()
|
item_list = bytearray()
|
||||||
|
|
||||||
@@ -330,16 +366,21 @@ for key in roms_keys:
|
|||||||
if len(title) > 0x30: title = title[:0x2F] + "…"
|
if len(title) > 0x30: title = title[:0x2F] + "…"
|
||||||
|
|
||||||
table_line = \
|
table_line = \
|
||||||
f"{game['index'] + 1:3d} | " \
|
f"{game['index'] + 1:3d} | " + \
|
||||||
f"0x{game['block_offset'] * block_size:07X} | "\
|
f"0x{game['block_offset'] * block_size:X} | ".rjust(13, " ") + \
|
||||||
f"0x{game['block_count'] * block_size:07X} | "
|
f"0x{game['block_count'] * block_size:X} | ".rjust(12, " ")
|
||||||
if battery_present:
|
if battery_present:
|
||||||
if game['save_type'] > 0:
|
if game['save_type'] > 0:
|
||||||
table_line += f"{game['save_slot']+1:2d} (0x{(save_data_sector_offset + game['save_slot']) * sector_size:07X}) | "
|
table_line += f"{game['save_slot']+1:2d} (0x{(save_data_sector_offset + game['save_slot']) * sector_size:07X}) | "
|
||||||
else:
|
else:
|
||||||
table_line += " | "
|
table_line += " | "
|
||||||
table_line += f"{title}"
|
table_line += f"{title}"
|
||||||
if c % 8 == 0: logp(toc_sep)
|
if c % 8 == 0:
|
||||||
|
if game['keys'] != 0:
|
||||||
|
temp = toc_sep[:-9] + "[Hidden]-"
|
||||||
|
logp(temp)
|
||||||
|
else:
|
||||||
|
logp(toc_sep)
|
||||||
logp(table_line)
|
logp(table_line)
|
||||||
c += 1
|
c += 1
|
||||||
|
|
||||||
@@ -366,14 +407,15 @@ for i in range(0xA0, 0xBD):
|
|||||||
checksum = (checksum - 0x19) & 0xFF
|
checksum = (checksum - 0x19) & 0xFF
|
||||||
compilation[0xBD] = checksum
|
compilation[0xBD] = checksum
|
||||||
logp("")
|
logp("")
|
||||||
logp("Menu ROM: 0x{:07X}–0x{:07X}".format(0, len(menu_rom)))
|
logp("Menu ROM: 0x{:08X}–0x{:08X}".format(0, len(menu_rom)))
|
||||||
logp("Game List: 0x{:07X}–0x{:07X}".format(item_list_offset * sector_size, item_list_offset * sector_size + len(item_list)))
|
logp("Game List: 0x{:08X}–0x{:08X}".format(item_list_offset * sector_size, item_list_offset * sector_size + len(item_list)))
|
||||||
logp("Status Area: 0x{:07X}–0x{:07X}".format(status_offset * sector_size, status_offset * sector_size + 0x1000))
|
logp("Status Area: 0x{:08X}–0x{:08X}".format(status_offset * sector_size, status_offset * sector_size + 0x1000))
|
||||||
logp("")
|
logp("")
|
||||||
logp("Cartridge Type: {:d} ({:s}) {:s}".format(cartridge_type + 1, cartridge_types[cartridge_type]["name"], "with battery" if battery_present else "without battery"))
|
logp("Cartridge Type: {:d} ({:s}) {:s}".format(cartridge_type + 1, cartridge_types[cartridge_type]["name"], "with battery" if battery_present else "without battery"))
|
||||||
logp("Output ROM Size: {:.2f} MiB".format(rom_size / 1024 / 1024))
|
logp("Output ROM Size: {:.2f} MiB".format(rom_size / 1024 / 1024))
|
||||||
logp("Output ROM Code: {:s}".format(rom_code))
|
logp("Output ROM Code: {:s}".format(rom_code))
|
||||||
output_file = output_file.replace("<CODE>", rom_code)
|
output_file = output_file.replace("<CODE>", rom_code)
|
||||||
|
|
||||||
if args.split:
|
if args.split:
|
||||||
for i in range(0, math.ceil(flash_size / 0x2000000)):
|
for i in range(0, math.ceil(flash_size / 0x2000000)):
|
||||||
pos = i * 0x2000000
|
pos = i * 0x2000000
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ Author: Lesserkuma (github.com/lesserkuma)
|
|||||||
|
|
||||||
u8 flash_type;
|
u8 flash_type;
|
||||||
u8 *itemlist;
|
u8 *itemlist;
|
||||||
|
u16 itemlist_offset;
|
||||||
u32 flash_sector_size;
|
u32 flash_sector_size;
|
||||||
u32 flash_itemlist_sector_offset;
|
u32 flash_itemlist_sector_offset;
|
||||||
u32 flash_status_sector_offset;
|
u32 flash_status_sector_offset;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ extern s8 FontMarginBottom;
|
|||||||
extern const u8* font;
|
extern const u8* font;
|
||||||
extern u8 *itemlist;
|
extern u8 *itemlist;
|
||||||
extern u8 flash_type;
|
extern u8 flash_type;
|
||||||
|
extern u16 itemlist_offset;
|
||||||
extern u32 flash_sector_size;
|
extern u32 flash_sector_size;
|
||||||
extern u32 flash_itemlist_sector_offset;
|
extern u32 flash_itemlist_sector_offset;
|
||||||
extern u32 flash_status_sector_offset;
|
extern u32 flash_status_sector_offset;
|
||||||
@@ -101,20 +102,19 @@ int main(void) {
|
|||||||
show_debug = TRUE;
|
show_debug = TRUE;
|
||||||
}
|
}
|
||||||
if (kHeld) {
|
if (kHeld) {
|
||||||
u16 itemlist_offset = 0;
|
|
||||||
BOOL found_keys = FALSE;
|
BOOL found_keys = FALSE;
|
||||||
for (itemlist_offset = 0; itemlist_offset < 0x924; itemlist_offset += 0x70) {
|
for (itemlist_offset = 0; itemlist_offset < 0xE000; itemlist_offset += 0x70) {
|
||||||
memcpy(&sItemConfig, ((u8*)itemlist)+itemlist_offset, sizeof(sItemConfig));
|
memcpy(&sItemConfig, ((u8*)itemlist)+itemlist_offset, sizeof(sItemConfig));
|
||||||
if (sItemConfig.title_length == 0) break;
|
if (sItemConfig.title_length == 0) break;
|
||||||
if (sItemConfig.title_length == 0xFF) break;
|
if (sItemConfig.title_length == 0xFF) break;
|
||||||
if (sItemConfig.keys == kHeld) {
|
if (sItemConfig.keys == kHeld) {
|
||||||
itemlist += itemlist_offset;
|
|
||||||
found_keys = TRUE;
|
found_keys = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found_keys) {
|
if (!found_keys) {
|
||||||
kHeld = 0;
|
kHeld = 0;
|
||||||
|
itemlist_offset = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ int main(void) {
|
|||||||
|
|
||||||
// Count number of ROMs
|
// Count number of ROMs
|
||||||
for (roms_total = 0; roms_total < 512; roms_total++) {
|
for (roms_total = 0; roms_total < 512; roms_total++) {
|
||||||
memcpy(&sItemConfig, ((u8*)itemlist)+(0x70*roms_total), sizeof(sItemConfig));
|
memcpy(&sItemConfig, ((u8*)itemlist+itemlist_offset)+(0x70*roms_total), sizeof(sItemConfig));
|
||||||
if (sItemConfig.keys != kHeld) break;
|
if (sItemConfig.keys != kHeld) break;
|
||||||
if (sItemConfig.title_length == 0) break;
|
if (sItemConfig.title_length == 0) break;
|
||||||
if (sItemConfig.title_length == 0xFF) break;
|
if (sItemConfig.title_length == 0xFF) break;
|
||||||
@@ -148,7 +148,7 @@ int main(void) {
|
|||||||
REG_DISPCNT ^= 0x0010;
|
REG_DISPCNT ^= 0x0010;
|
||||||
while (1) { VBlankIntrWait(); }
|
while (1) { VBlankIntrWait(); }
|
||||||
} else if (roms_total == 1) {
|
} else if (roms_total == 1) {
|
||||||
memcpy(&sItemConfig, ((u8*)itemlist), sizeof(sItemConfig));
|
memcpy(&sItemConfig, ((u8*)itemlist+itemlist_offset), sizeof(sItemConfig));
|
||||||
u8 error_code = BootGame(sItemConfig, sFlashStatus);
|
u8 error_code = BootGame(sItemConfig, sFlashStatus);
|
||||||
boot_failed = error_code;
|
boot_failed = error_code;
|
||||||
}
|
}
|
||||||
@@ -169,9 +169,8 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
if (roms_page < 7) ClearList((void*)AGB_VRAM+0xA000, 26+(roms_page+1)*14, 14*(8-roms_page));
|
if (roms_page < 7) ClearList((void*)AGB_VRAM+0xA000, 26+(roms_page+1)*14, 14*(8-roms_page));
|
||||||
if (cursor_pos > roms_page) cursor_pos = roms_page;
|
if (cursor_pos > roms_page) cursor_pos = roms_page;
|
||||||
|
|
||||||
for (u8 i = 0; i <= roms_page; i++) {
|
for (u8 i = 0; i <= roms_page; i++) {
|
||||||
memcpy(&sItemConfig, ((u8*)itemlist)+0x70*(page_active*8+i), sizeof(sItemConfig));
|
memcpy(&sItemConfig, ((u8*)itemlist+itemlist_offset)+0x70*(page_active*8+i), sizeof(sItemConfig));
|
||||||
ClearList((void*)AGB_VRAM+0xA000, 27+i*14, 14);
|
ClearList((void*)AGB_VRAM+0xA000, 27+i*14, 14);
|
||||||
LoadFont(sItemConfig.font);
|
LoadFont(sItemConfig.font);
|
||||||
DrawText(28, 26+i*14, ALIGN_LEFT, sItemConfig.title, sItemConfig.title_length, font, (void*)AGB_VRAM+0xA000, i == cursor_pos);
|
DrawText(28, 26+i*14, ALIGN_LEFT, sItemConfig.title, sItemConfig.title_length, font, (void*)AGB_VRAM+0xA000, i == cursor_pos);
|
||||||
@@ -180,7 +179,7 @@ int main(void) {
|
|||||||
// Re-draw only changed list items (cursor moved up or down)
|
// Re-draw only changed list items (cursor moved up or down)
|
||||||
for (u8 i = 0; i < 8; i++) {
|
for (u8 i = 0; i < 8; i++) {
|
||||||
if ((redraw_items >> i) & 1) {
|
if ((redraw_items >> i) & 1) {
|
||||||
memcpy(&sItemConfig, ((u8*)itemlist)+0x70*(page_active*8+i), sizeof(sItemConfig));
|
memcpy(&sItemConfig, ((u8*)itemlist+itemlist_offset)+0x70*(page_active*8+i), sizeof(sItemConfig));
|
||||||
ClearList((void*)AGB_VRAM+0xA000, 27+i*14, 14);
|
ClearList((void*)AGB_VRAM+0xA000, 27+i*14, 14);
|
||||||
LoadFont(sItemConfig.font);
|
LoadFont(sItemConfig.font);
|
||||||
DrawText(28, 26+i*14, ALIGN_LEFT, sItemConfig.title, sItemConfig.title_length, font, (void*)AGB_VRAM+0xA000, i == cursor_pos);
|
DrawText(28, 26+i*14, ALIGN_LEFT, sItemConfig.title, sItemConfig.title_length, font, (void*)AGB_VRAM+0xA000, i == cursor_pos);
|
||||||
@@ -188,7 +187,7 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&sItemConfig, ((u8*)itemlist)+0x70*(page_active*8+cursor_pos), sizeof(sItemConfig));
|
memcpy(&sItemConfig, ((u8*)itemlist+itemlist_offset)+0x70*(page_active*8+cursor_pos), sizeof(sItemConfig));
|
||||||
|
|
||||||
// Draw cursor
|
// Draw cursor
|
||||||
LoadFont(1);
|
LoadFont(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user