Files
PSBBN-Definitive-English-Patch/helper/txt_to_icon_sys.py
CosmicScale 3c4f6ba39b PSBBN v2.11: Button swap, VMC groups, icon generator, improved updates & more
- Bypass boot ELF security check; custom kernels now supported
- Swap X/O buttons (X=Enter, O=Back)
- Add DVD remote support in Music and Movie channels
- Update BB Guide: reflect button swap, game collection changes, and more
- Improve update process: no USB keyboard required after this version
- Allow custom POPS partition size in installer
- Add support for multi-disc PS1 games with auto-generated DISCS.TXT and shared VMCs
- Add VMC Groups (shared saves for compatible PS1 games)
- Improve VMC display: custom icons and clearer titles in Browser 2.0
- Generate HDD-OSD icons automatically using OPL art or game logos
- Contribute new icons to HDD-OSD icon database and report missing ones
- Improve Game ID detection in list-builder.py for non-standard PS1/PS2 titles
- Update Neutrino to v1.7.0
- Update OPL to v1.2.0 Beta-2210-6b300b0 (adds VMC Group support)
- Upgrade wLaunchELF to v4.43x_isr (adds exFAT + MMCE support)
2025-07-17 14:55:02 +01:00

103 lines
2.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sys
import os
import unicodedata
# Mapping for unsupported or problematic characters
REPLACEMENTS = {
"'": "",
"-": "",
# Subscript numbers
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
}
def ascii_to_fullwidth(text):
result = []
for c in text:
# Replace mapped characters
if c in REPLACEMENTS:
c = REPLACEMENTS[c]
# Decompose accented characters to base (e.g., é → e)
c = unicodedata.normalize('NFD', c)[0]
code = ord(c)
if 0x21 <= code <= 0x7E:
fullwidth_char = chr(code + 0xFEE0)
elif c == ' ':
fullwidth_char = '\u3000'
else:
fullwidth_char = c
result.append(fullwidth_char)
return ''.join(result)
def sanitize_for_shift_jis(text):
return ''.join(c for c in text if can_encode_shift_jis(c))
def can_encode_shift_jis(char):
try:
char.encode("shift_jis")
return True
except UnicodeEncodeError:
return False
def update_icon_sys(path, title0, title1):
if len(title0) > 16 or len(title1) > 16:
print("[!] Error: Both title0 and title1 must be 16 characters or fewer.")
sys.exit(1)
try:
with open(path, "rb") as f:
data = bytearray(f.read())
title_block_offset = 0xC0
title_block_length = 68
# Convert to full-width, replace unsupported, and sanitize
title0_fw = sanitize_for_shift_jis(ascii_to_fullwidth(title0))
title1_fw = sanitize_for_shift_jis(ascii_to_fullwidth(title1))
title0_encoded = title0_fw.encode("shift_jis")
title1_encoded = title1_fw.encode("shift_jis")
split_offset = len(title0_encoded)
if split_offset > 68:
print("[!] Error: title0 too long after encoding.")
sys.exit(1)
title_combined = title0_encoded + title1_encoded
title_block = title_combined[:title_block_length].ljust(title_block_length, b'\x00')
# Set split offset at byte 0x06
data[0x06] = split_offset
data[title_block_offset:title_block_offset + title_block_length] = title_block
with open("icon.sys", "wb") as f:
f.write(data)
# print(f"[✓] Updated icon.sys with dynamic split offset ({split_offset:#04x}): {path}")
except Exception as e:
print(f"[!] Failed to update icon.sys: {e}")
sys.exit(1)
if __name__ == "__main__":
if len(sys.argv) != 4:
print("Usage: python3 txt_to_icon_sys.py path/to/icon.sys title0 title1")
sys.exit(1)
_, icon_path, title0, title1 = sys.argv
if not os.path.isfile(icon_path):
print(f"[!] File not found: {icon_path}")
sys.exit(1)
update_icon_sys(icon_path, title0, title1)