From 4f4badfb1d6eb7ee370997dd117bd8642df42f4b Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Fri, 11 Aug 2023 23:00:36 -0400 Subject: [PATCH 01/26] add xbe title naming --- ciso.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/ciso.py b/ciso.py index bced6c3..d8d844c 100755 --- a/ciso.py +++ b/ciso.py @@ -221,9 +221,74 @@ def compress_iso(infile): pad_file_size(fout_2) fout_2.close() +# https://www.caustik.com/cxbx/download/xbe.htm +def get_xbe_title_offset(xbe): + base_addr_offset = 0x104 + cert_addr_offset = 0x118 + title_addr_offset = 0xc + + with open(xbe, 'rb') as xbe_file: + xbe_file.seek(base_addr_offset) + base_addr = struct.unpack(' Date: Sat, 12 Aug 2023 00:19:50 -0400 Subject: [PATCH 02/26] fix some pathing issues --- ciso.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ciso.py b/ciso.py index d8d844c..650f20f 100755 --- a/ciso.py +++ b/ciso.py @@ -249,10 +249,6 @@ def is_xbe_file(xbe): return True def gen_attach_xbe(argv): - title_len_max = 40 - in_file_name = 'attach_cso.xbe' - out_file_name = 'default.xbe' - try: if argv[1]: iso_file = argv[1] @@ -264,7 +260,11 @@ def gen_attach_xbe(argv): if argv[2]: title = argv[2] except IndexError: - title = os.path.splitext(iso_file)[0] + title = os.path.splitext(os.path.basename(iso_file))[0] + + title_len_max = 40 + in_file_name = os.path.dirname(os.path.abspath(__file__)) + '/attach_cso.xbe' + out_file_name = os.path.dirname(os.path.abspath(iso_file)) + '/default.xbe' if not is_xbe_file(in_file_name): return From b676814819d6b95fc250103a3568d8d34119a73a Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Sat, 12 Aug 2023 08:12:54 -0400 Subject: [PATCH 03/26] minor change to xbe detection --- ciso.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ciso.py b/ciso.py index 650f20f..d1e808a 100755 --- a/ciso.py +++ b/ciso.py @@ -241,9 +241,9 @@ def is_xbe_file(xbe): return False with open(xbe, 'rb') as xbe_file: - magic = xbe_file.read(4).decode("utf-8") + magic = xbe_file.read(4) - if magic != 'XBEH': + if magic != b'XBEH': return False return True From bd2db02676a300d50eb7b485139229ee5befd3ce Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Sat, 12 Aug 2023 08:53:44 -0400 Subject: [PATCH 04/26] remove optional title parameter --- ciso.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/ciso.py b/ciso.py index d1e808a..bda8d30 100755 --- a/ciso.py +++ b/ciso.py @@ -248,20 +248,8 @@ def is_xbe_file(xbe): return True -def gen_attach_xbe(argv): - try: - if argv[1]: - iso_file = argv[1] - except IndexError: - print("No ISO file provided") - sys.exit(2) - - try: - if argv[2]: - title = argv[2] - except IndexError: - title = os.path.splitext(os.path.basename(iso_file))[0] - +def gen_attach_xbe(iso_file): + title = os.path.splitext(os.path.basename(iso_file))[0] title_len_max = 40 in_file_name = os.path.dirname(os.path.abspath(__file__)) + '/attach_cso.xbe' out_file_name = os.path.dirname(os.path.abspath(iso_file)) + '/default.xbe' @@ -288,7 +276,7 @@ def gen_attach_xbe(argv): def main(argv): infile = argv[1] compress_iso(infile) - gen_attach_xbe(argv) + gen_attach_xbe(infile) if __name__ == '__main__': sys.exit(main(sys.argv)) From a6d9cbb69110813eb133a143fbb61eb3bdb40fef Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Sat, 12 Aug 2023 12:27:35 -0400 Subject: [PATCH 05/26] pull title from default.xbe inside iso --- ciso.py | 88 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 14 deletions(-) diff --git a/ciso.py b/ciso.py index bda8d30..a9eed2e 100755 --- a/ciso.py +++ b/ciso.py @@ -14,6 +14,8 @@ CISO_HEADER_FMT = ' Date: Sat, 12 Aug 2023 13:03:57 -0400 Subject: [PATCH 06/26] minor perf cleanup --- ciso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ciso.py b/ciso.py index a9eed2e..6ac6055 100755 --- a/ciso.py +++ b/ciso.py @@ -310,7 +310,6 @@ def read_default_xbe_title_from_iso(iso_file): return title_bytes def gen_attach_xbe(iso_file): - title = read_default_xbe_title_from_iso(iso_file) in_file_name = os.path.dirname(os.path.abspath(__file__)) + '/attach_cso.xbe' out_file_name = os.path.dirname(os.path.abspath(iso_file)) + '/default.xbe' @@ -318,6 +317,7 @@ def gen_attach_xbe(iso_file): return title_offset = get_xbe_title_offset(in_file_name) + title = read_default_xbe_title_from_iso(iso_file) title = title[0:TITLE_MAX_LENGTH] with open(in_file_name, 'rb') as in_xbe: From e58685f056f34869a1bf095e8b914423b1037f2b Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Sat, 12 Aug 2023 13:14:46 -0400 Subject: [PATCH 07/26] add a print message --- ciso.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ciso.py b/ciso.py index 6ac6055..8e22c3f 100755 --- a/ciso.py +++ b/ciso.py @@ -320,6 +320,8 @@ def gen_attach_xbe(iso_file): title = read_default_xbe_title_from_iso(iso_file) title = title[0:TITLE_MAX_LENGTH] + print("Generating default.xbe with title:", title) + with open(in_file_name, 'rb') as in_xbe: with open(out_file_name, 'wb') as out_xbe: before = in_xbe.read(title_offset) From 8e639e5644e43ccd48dcdd15dfb7efa941530fdd Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Sat, 12 Aug 2023 22:08:46 -0400 Subject: [PATCH 08/26] add fallback title --- ciso.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ciso.py b/ciso.py index 8e22c3f..b43209a 100755 --- a/ciso.py +++ b/ciso.py @@ -253,6 +253,7 @@ def is_xbe_file(xbe): def get_default_xbe_file_offset_in_iso(iso_file): return get_file_offset_in_iso(iso_file, 'default.xbe') +# only looks in root dir def get_file_offset_in_iso(iso_file, search_file): global image_offset @@ -289,7 +290,7 @@ def get_file_offset_in_iso(iso_file, search_file): #print("entry:", format(l_offset), format(r_offset), format(start_sector), format(file_size), format(attribs), format(filename_len), filename) - # entries are aligned 4 bytes + # entries are aligned on 4 byte bounderies next_offset = (dword - ((filename_offset + filename_len) % dword)) % dword f.seek(next_offset, os.SEEK_CUR) @@ -301,7 +302,11 @@ def get_file_offset_in_iso(iso_file, search_file): return 0 def read_default_xbe_title_from_iso(iso_file): - xbe_offset = get_default_xbe_file_offset_in_iso(iso_file) + xbe_offset = get_default_xbe_file_offset_in_iso(iso_file) + + if xbe_offset == 0: + return os.path.splitext(os.path.basename(iso_file))[0] + title_offset = get_xbe_title_offset(iso_file, xbe_offset) with open(iso_file, 'rb') as f: @@ -317,6 +322,7 @@ def gen_attach_xbe(iso_file): return title_offset = get_xbe_title_offset(in_file_name) + title = read_default_xbe_title_from_iso(iso_file) title = title[0:TITLE_MAX_LENGTH] From 9de62009cbfed862b1ef9fcddb0878c70e0ad57d Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Sun, 13 Aug 2023 13:50:07 -0400 Subject: [PATCH 09/26] some refactoring and improvements --- ciso.py | 91 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/ciso.py b/ciso.py index b43209a..d7e739d 100755 --- a/ciso.py +++ b/ciso.py @@ -14,8 +14,6 @@ CISO_HEADER_FMT = ' Date: Sun, 13 Aug 2023 19:03:30 -0400 Subject: [PATCH 10/26] title image patch --- ciso.py | 127 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 107 insertions(+), 20 deletions(-) diff --git a/ciso.py b/ciso.py index d7e739d..86236c3 100755 --- a/ciso.py +++ b/ciso.py @@ -222,7 +222,6 @@ def compress_iso(infile): fout_2.close() - def is_xbe_file(xbe): if not os.path.isfile(xbe): return False @@ -288,6 +287,13 @@ def get_file_offset_in_iso(iso_file, search_file): # entry wasn't found return 0 +# read C-style strings +def readcstr(bytes, start): + end = bytes.find(b'\0', start) + sub = bytes[start: end] + + return sub.decode() + def gen_attach_xbe(iso_file): in_file_name = os.path.dirname(os.path.abspath(__file__)) + '/attach_cso.xbe' out_file_name = os.path.dirname(os.path.abspath(iso_file)) + '/default.xbe' @@ -300,34 +306,75 @@ def gen_attach_xbe(iso_file): if xbe_offset == 0: return - title_max_length = 40 - title_img_sect_name = '$$XTIMAGE' - # https://www.caustik.com/cxbx/download/xbe.htm - base_addr_offset = 0x104 - cert_addr_offset = 0x118 - cert_title_id_offset = 0x8 - cert_title_offset = 0xc + title_max_length = 40 + title_img_sect_name = '$$XTIMAGE' + num_new_sections = 1 + xbe_header_size = 0x1000 + section_header_size = 0x38 + base_addr_offset = 0x104 + xbe_img_size_offset = 0x10c + cert_addr_offset = 0x118 + num_sections_offset = 0x11c + sect_headers_offset = 0x120 + sect_rv_addr_offset = 0x4 + sect_rv_size_offset = 0x8 + sect_raw_addr_offset = 0xc + sect_raw_size_offset = 0x10 + sect_name_addr_offset = 0x14 + sect_name_ref_offset = 0x18 + sect_head_ref_offset = 0x1c + sect_tail_ref_offset = 0x20 + sect_digest_offset = 0x24 + cert_title_id_offset = 0x8 + cert_title_offset = 0xc + + title_img_sect_header_bytes = None + title_img_sect_bytes = None # pull data from source xbe with open(iso_file, 'rb') as f: - f.seek(xbe_offset + base_addr_offset) - base_addr = struct.unpack(' Date: Sun, 13 Aug 2023 19:19:32 -0400 Subject: [PATCH 11/26] small edit --- ciso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ciso.py b/ciso.py index 86236c3..d3e3f69 100755 --- a/ciso.py +++ b/ciso.py @@ -425,7 +425,7 @@ def gen_attach_xbe(iso_file): out_bytes[new_sect_addr: new_sect_addr + new_sect_len] = ( old_section + title_img_sect_header_bytes + - bytearray(title_img_sect_name.encode('utf-8')) + + bytearray(title_img_sect_name.encode()) + b'\0' ) From 44ffbcb992a72b2a1a29e65c0a98fb5b1b1816b2 Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Mon, 14 Aug 2023 01:26:33 -0400 Subject: [PATCH 12/26] add folder sorting and title fallback --- ciso.py | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/ciso.py b/ciso.py index d3e3f69..7ed7da5 100755 --- a/ciso.py +++ b/ciso.py @@ -6,6 +6,7 @@ import os import struct import sys +import shutil import lz4.frame CISO_MAGIC = 0x4F534943 # CISO @@ -295,8 +296,10 @@ def readcstr(bytes, start): return sub.decode() def gen_attach_xbe(iso_file): + base_dir = os.path.dirname(os.path.abspath(iso_file)) in_file_name = os.path.dirname(os.path.abspath(__file__)) + '/attach_cso.xbe' - out_file_name = os.path.dirname(os.path.abspath(iso_file)) + '/default.xbe' + out_file_name = base_dir + '/default.xbe' + iso_base_name = os.path.splitext(iso_file)[0] if not is_xbe_file(in_file_name): return @@ -345,7 +348,6 @@ def gen_attach_xbe(iso_file): # title offset = cert_addr - base_addr + cert_title_offset title_bytes = header_bytes[offset: offset + title_max_length * 2] - title_bytes = title_bytes[0:title_max_length * 2] # title id offset = cert_addr - base_addr + cert_title_id_offset @@ -376,8 +378,16 @@ def gen_attach_xbe(iso_file): f.seek(xbe_offset + raw_addr) title_img_sect_bytes = f.read(raw_size) - title_id = '{:02X}'.format(struct.unpack(" Date: Mon, 14 Aug 2023 01:37:10 -0400 Subject: [PATCH 13/26] small pathing fix --- ciso.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ciso.py b/ciso.py index 7ed7da5..10f8fb4 100755 --- a/ciso.py +++ b/ciso.py @@ -299,7 +299,7 @@ def gen_attach_xbe(iso_file): base_dir = os.path.dirname(os.path.abspath(iso_file)) in_file_name = os.path.dirname(os.path.abspath(__file__)) + '/attach_cso.xbe' out_file_name = base_dir + '/default.xbe' - iso_base_name = os.path.splitext(iso_file)[0] + iso_base_name = os.path.splitext(os.path.basename(iso_file))[0] if not is_xbe_file(in_file_name): return @@ -463,7 +463,7 @@ def gen_attach_xbe(iso_file): os.makedirs(out_dir) if os.path.exists(out_file_name) and os.path.exists(new_file): os.remove(new_file) - if os.path.exists(ciso2) and os.path.exists(new_cios1): + if os.path.exists(ciso1) and os.path.exists(new_cios1): os.remove(new_cios1) if os.path.exists(ciso2) and os.path.exists(new_cios2): os.remove(new_cios2) From bb5a2a3cc0a14bc543aed9914d77be87f1aea7ef Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Mon, 14 Aug 2023 02:04:55 -0400 Subject: [PATCH 14/26] some default.xbe's apparently have really large headers... --- ciso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ciso.py b/ciso.py index 10f8fb4..ec9c3c0 100755 --- a/ciso.py +++ b/ciso.py @@ -338,7 +338,7 @@ def gen_attach_xbe(iso_file): # pull data from source xbe with open(iso_file, 'rb') as f: f.seek(xbe_offset) - header_bytes = f.read(xbe_header_size) + header_bytes = f.read(xbe_header_size * 10) base_addr = struct.unpack(' Date: Mon, 14 Aug 2023 02:30:54 -0400 Subject: [PATCH 15/26] add filename escaping --- ciso.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ciso.py b/ciso.py index ec9c3c0..7ed6def 100755 --- a/ciso.py +++ b/ciso.py @@ -450,9 +450,11 @@ def gen_attach_xbe(iso_file): f.write(out_bytes) # move output files to sub-folder + keepcharacters = (' ', '.', '_') + safe_title = "".join(c for c in title_decoded if c.isalnum() or c in keepcharacters).rstrip() cios1_file = iso_base_name + '.1.cso' cios2_file = iso_base_name + '.2.cso' - out_dir = base_dir + '/' + title_decoded + out_dir = base_dir + '/' + safe_title ciso1 = base_dir + '/' + cios1_file ciso2 = base_dir + '/' + cios2_file new_file = out_dir + '/' + os.path.basename(out_file_name) From a050f778a626057521391ce1ba2a451137b781d6 Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Mon, 14 Aug 2023 10:00:25 -0400 Subject: [PATCH 16/26] use game title for cso name --- ciso.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ciso.py b/ciso.py index 7ed6def..6c5de1b 100755 --- a/ciso.py +++ b/ciso.py @@ -458,8 +458,8 @@ def gen_attach_xbe(iso_file): ciso1 = base_dir + '/' + cios1_file ciso2 = base_dir + '/' + cios2_file new_file = out_dir + '/' + os.path.basename(out_file_name) - new_cios1 = out_dir + '/' + cios1_file - new_cios2 = out_dir + '/' + cios2_file + new_cios1 = out_dir + '/' + safe_title + '.1.cso' + new_cios2 = out_dir + '/' + safe_title + '.2.cso' if not os.path.isdir(out_dir): os.makedirs(out_dir) From 1754f5e3e9ea7b72cfd55f9c35fa4854b27c1c9a Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Mon, 14 Aug 2023 10:06:09 -0400 Subject: [PATCH 17/26] let's just make it a generic name instead --- ciso.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ciso.py b/ciso.py index 6c5de1b..92a36ed 100755 --- a/ciso.py +++ b/ciso.py @@ -452,14 +452,15 @@ def gen_attach_xbe(iso_file): # move output files to sub-folder keepcharacters = (' ', '.', '_') safe_title = "".join(c for c in title_decoded if c.isalnum() or c in keepcharacters).rstrip() + new_name = 'Game' cios1_file = iso_base_name + '.1.cso' cios2_file = iso_base_name + '.2.cso' out_dir = base_dir + '/' + safe_title ciso1 = base_dir + '/' + cios1_file ciso2 = base_dir + '/' + cios2_file new_file = out_dir + '/' + os.path.basename(out_file_name) - new_cios1 = out_dir + '/' + safe_title + '.1.cso' - new_cios2 = out_dir + '/' + safe_title + '.2.cso' + new_cios1 = out_dir + '/' + new_name + '.1.cso' + new_cios2 = out_dir + '/' + new_name + '.2.cso' if not os.path.isdir(out_dir): os.makedirs(out_dir) From 0e7ce15c96028d3667ecd3dbd67ebdfd8ecc21e7 Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Mon, 14 Aug 2023 11:19:09 -0400 Subject: [PATCH 18/26] nvm, let's go with truncated title names --- ciso.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ciso.py b/ciso.py index 92a36ed..6e2c873 100755 --- a/ciso.py +++ b/ciso.py @@ -300,6 +300,7 @@ def gen_attach_xbe(iso_file): in_file_name = os.path.dirname(os.path.abspath(__file__)) + '/attach_cso.xbe' out_file_name = base_dir + '/default.xbe' iso_base_name = os.path.splitext(os.path.basename(iso_file))[0] + filename_len_limit = 42 if not is_xbe_file(in_file_name): return @@ -450,17 +451,18 @@ def gen_attach_xbe(iso_file): f.write(out_bytes) # move output files to sub-folder - keepcharacters = (' ', '.', '_') - safe_title = "".join(c for c in title_decoded if c.isalnum() or c in keepcharacters).rstrip() - new_name = 'Game' + keepcharacters = (' ', '.', '_', '-') + safe_title = "".join(c for c in title_decoded if c.isalnum() or c in keepcharacters).rstrip() + safe_title_trunc = safe_title[0:filename_len_limit - 6] + cios1_file = iso_base_name + '.1.cso' cios2_file = iso_base_name + '.2.cso' out_dir = base_dir + '/' + safe_title ciso1 = base_dir + '/' + cios1_file ciso2 = base_dir + '/' + cios2_file new_file = out_dir + '/' + os.path.basename(out_file_name) - new_cios1 = out_dir + '/' + new_name + '.1.cso' - new_cios2 = out_dir + '/' + new_name + '.2.cso' + new_cios1 = out_dir + '/' + safe_title_trunc + '.1.cso' + new_cios2 = out_dir + '/' + safe_title_trunc + '.2.cso' if not os.path.isdir(out_dir): os.makedirs(out_dir) From db4a04f657c88614259ed2f50839bfc86b42568b Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Wed, 16 Aug 2023 04:23:13 -0400 Subject: [PATCH 19/26] multi-sector root dir fix & title fix --- ciso.py | 68 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/ciso.py b/ciso.py index 6e2c873..07caff7 100755 --- a/ciso.py +++ b/ciso.py @@ -7,6 +7,7 @@ import struct import sys import shutil +import math import lz4.frame CISO_MAGIC = 0x4F534943 # CISO @@ -223,11 +224,12 @@ def compress_iso(infile): fout_2.close() -def is_xbe_file(xbe): +def is_xbe_file(xbe, offset = 0): if not os.path.isfile(xbe): return False with open(xbe, 'rb') as xbe_file: + xbe_file.seek(offset) magic = xbe_file.read(4) if magic != b'XBEH': @@ -242,10 +244,11 @@ def get_default_xbe_file_offset_in_iso(iso_file): def get_file_offset_in_iso(iso_file, search_file): global image_offset + dir_ent_size = 0xe sector_size = 0x800 iso_header_offset = 0x10000 - iso_header_magic_len = 20 - filename_offset = 14 + root_dir_sect_offset = 0x14 + dword = 4 search_file = search_file.casefold() @@ -253,37 +256,49 @@ def get_file_offset_in_iso(iso_file, search_file): detect_iso_type(f) # seek to root dir - f.seek(image_offset + iso_header_offset + iso_header_magic_len) - root_dir_offset = image_offset + struct.unpack(' Date: Fri, 18 Aug 2023 17:59:42 -0400 Subject: [PATCH 20/26] some refactoring --- ciso.py | 129 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 84 insertions(+), 45 deletions(-) diff --git a/ciso.py b/ciso.py index 07caff7..59a52c6 100755 --- a/ciso.py +++ b/ciso.py @@ -303,6 +303,55 @@ def get_file_offset_in_iso(iso_file, search_file): # entry wasn't found return 0 +# returns array with section header and raw bytes +def get_xbe_section_bytes(xbe_file, search_section, xbe_offset = 0): + xbe_header_size = 0x1000 + section_header_size = 0x38 + base_addr_offset = 0x104 + cert_addr_offset = 0x118 + num_sections_offset = 0x11c + sect_headers_offset = 0x120 + + ret_header_bytes = None + ret_raw_bytes = None + + with open(xbe_file, 'rb') as f: + f.seek(xbe_offset) + header_bytes = f.read(xbe_header_size * 10) + + base_addr = struct.unpack(' Date: Sun, 20 Aug 2023 00:00:47 -0400 Subject: [PATCH 21/26] add Forza override --- ciso.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/ciso.py b/ciso.py index 59a52c6..dcd623f 100755 --- a/ciso.py +++ b/ciso.py @@ -237,9 +237,6 @@ def is_xbe_file(xbe, offset = 0): return True -def get_default_xbe_file_offset_in_iso(iso_file): - return get_file_offset_in_iso(iso_file, 'default.xbe') - # only looks in root dir def get_file_offset_in_iso(iso_file, search_file): global image_offset @@ -359,7 +356,7 @@ def readcstr(bytes, start): return sub.decode() -def gen_attach_xbe(iso_file): +def gen_attach_xbe(iso_file, iso_xbe = 'default.xbe'): base_dir = os.path.dirname(os.path.abspath(iso_file)) in_file_name = os.path.dirname(os.path.abspath(__file__)) + '/attach_cso.xbe' out_file_name = base_dir + '/default.xbe' @@ -367,7 +364,7 @@ def gen_attach_xbe(iso_file): if not is_xbe_file(in_file_name): return - xbe_offset = get_default_xbe_file_offset_in_iso(iso_file) + xbe_offset = get_file_offset_in_iso(iso_file, iso_xbe) if xbe_offset == 0: return @@ -428,8 +425,14 @@ def gen_attach_xbe(iso_file): title_decoded = title_bytes.decode('utf-16-le').replace('\0', '') title_bytes = title_bytes[0:title_max_length * 2] - title_id = '{:02X}'.format(struct.unpack(" Date: Mon, 21 Aug 2023 12:42:23 -0400 Subject: [PATCH 22/26] add more title overrides & add sub-folder iso search --- ciso.py | 127 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 99 insertions(+), 28 deletions(-) diff --git a/ciso.py b/ciso.py index dcd623f..05f1080 100755 --- a/ciso.py +++ b/ciso.py @@ -237,34 +237,55 @@ def is_xbe_file(xbe, offset = 0): return True -# only looks in root dir -def get_file_offset_in_iso(iso_file, search_file): +def get_iso_root_dir_offset_and_size(iso_file): global image_offset - dir_ent_size = 0xe - sector_size = 0x800 iso_header_offset = 0x10000 root_dir_sect_offset = 0x14 - dword = 4 - - search_file = search_file.casefold() + sector_size = 0x800 with open(iso_file, 'rb') as f: detect_iso_type(f) - # seek to root dir f.seek(image_offset + iso_header_offset + root_dir_sect_offset) root_dir_sect = struct.unpack(' Date: Tue, 22 Aug 2023 20:47:56 -0400 Subject: [PATCH 23/26] some title override fixes --- ciso.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ciso.py b/ciso.py index 05f1080..0ab87b6 100755 --- a/ciso.py +++ b/ciso.py @@ -391,39 +391,39 @@ def check_title_overrides(iso_file, title_id, title): default_xbe = 'default.xbe' # Forza Motorsport + XBLA - if title_id == 0x584C8014: # "CDX" + if title_id == 0x584C8014 and title == 'CDX': # "CDX" return gen_attach_xbe(iso_file, 'Forza.xbe') # NCAA Football 2005 + Top Spin - if title_id == 0x584C000F: # "CDX" + if title_id == 0x584C000F and title == 'CDX': # "CDX" return gen_attach_xbe(iso_file, 'NCAA\\DEFAULT.XBE') # Hitman 2: Silent Assassin (Rev 2) - if title_id == 0x45530009: # "CDX" + if title_id == 0x45530009 and title == 'CDX': # "CDX" return gen_attach_xbe(iso_file, 'hm2.xbe') # Star Wars: The Clone Wars + Tetris Worlds - if title_id == 0x584C000D: # "CDX" + if title_id == 0x584C000D and title == 'CDX': # "CDX" return gen_attach_xbe(iso_file, 'CW\\default.xbe') # Jade Empire (Bonus Disc) - if title_id == 0x4D530085: # "CDX" + if title_id == 0x4D530085 and title == 'CDX': # "CDX" return gen_attach_xbe(iso_file, default_xbe, 'Jade Empire (Bonus Disc)') # LucasArts Xbox Experience Volume 01 - if title_id == 0x4C410010: # "CDX" + if title_id == 0x4C410010 and title == 'CDX': # "CDX" return gen_attach_xbe(iso_file, default_xbe, 'LucasArts Xbox Experience Vol 01') # MechAssault 2: Lone Wolf (Bonus Disc) - if title_id == 0x4D530083: # "CDX" + if title_id == 0x4D530083 and title == 'CDX': # "CDX" return gen_attach_xbe(iso_file, default_xbe, 'MechAssault 2: Lone Wolf (Bonus Disc)') # Xbox Live Starter Kit Disc (Rev 1) - if title_id == 0x584C0007: # "CDX" + if title_id == 0x584C0007 and title == 'CDX': # "CDX" return gen_attach_xbe(iso_file, default_xbe, 'Xbox Live Starter Kit Disc (Rev 1)') # Xbox Live Starter Kit Disc (Rev 3) - if title_id == 0x584C8010: # "CDX" + if title_id == 0x584C8010 and title == 'CDX': # "CDX" return gen_attach_xbe(iso_file, default_xbe, 'Xbox Live Starter Kit Disc (Rev 3)') def gen_attach_xbe(iso_file, iso_xbe = 'default.xbe', alt_title = ''): From 6b966c334418823dea3763e40c1931b20632d9b0 Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Wed, 23 Aug 2023 00:05:11 -0400 Subject: [PATCH 24/26] add more title overrides --- ciso.py | 50 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/ciso.py b/ciso.py index 0ab87b6..52ef4aa 100755 --- a/ciso.py +++ b/ciso.py @@ -391,41 +391,69 @@ def check_title_overrides(iso_file, title_id, title): default_xbe = 'default.xbe' # Forza Motorsport + XBLA - if title_id == 0x584C8014 and title == 'CDX': # "CDX" + if title_id == 0x584C8014 and title == 'CDX': return gen_attach_xbe(iso_file, 'Forza.xbe') # NCAA Football 2005 + Top Spin - if title_id == 0x584C000F and title == 'CDX': # "CDX" - return gen_attach_xbe(iso_file, 'NCAA\\DEFAULT.XBE') + if title_id == 0x584C000F and title == 'CDX': + return gen_attach_xbe(iso_file, 'NCAA\\DEFAULT.XBE', 'NCAA Football 2005 + Top Spin') # Hitman 2: Silent Assassin (Rev 2) - if title_id == 0x45530009 and title == 'CDX': # "CDX" + if title_id == 0x45530009 and title == 'CDX': return gen_attach_xbe(iso_file, 'hm2.xbe') # Star Wars: The Clone Wars + Tetris Worlds - if title_id == 0x584C000D and title == 'CDX': # "CDX" - return gen_attach_xbe(iso_file, 'CW\\default.xbe') + if title_id == 0x584C000D and title == 'CDX': + return gen_attach_xbe(iso_file, 'CW\\default.xbe', 'StarWars: The Clone Wars + Tetris Worlds') # Jade Empire (Bonus Disc) - if title_id == 0x4D530085 and title == 'CDX': # "CDX" + if title_id == 0x4D530085 and title == 'CDX': return gen_attach_xbe(iso_file, default_xbe, 'Jade Empire (Bonus Disc)') # LucasArts Xbox Experience Volume 01 - if title_id == 0x4C410010 and title == 'CDX': # "CDX" + if title_id == 0x4C410010 and title == 'CDX': return gen_attach_xbe(iso_file, default_xbe, 'LucasArts Xbox Experience Vol 01') # MechAssault 2: Lone Wolf (Bonus Disc) - if title_id == 0x4D530083 and title == 'CDX': # "CDX" + if title_id == 0x4D530083 and title == 'CDX': return gen_attach_xbe(iso_file, default_xbe, 'MechAssault 2: Lone Wolf (Bonus Disc)') # Xbox Live Starter Kit Disc (Rev 1) - if title_id == 0x584C0007 and title == 'CDX': # "CDX" + if title_id == 0x584C0007 and title == 'CDX': return gen_attach_xbe(iso_file, default_xbe, 'Xbox Live Starter Kit Disc (Rev 1)') # Xbox Live Starter Kit Disc (Rev 3) - if title_id == 0x584C8010 and title == 'CDX': # "CDX" + if title_id == 0x584C8010 and title == 'CDX': return gen_attach_xbe(iso_file, default_xbe, 'Xbox Live Starter Kit Disc (Rev 3)') + # Ninja Gaiden Video + Dead or Alive X-Treme Beach Volleyball Video + DOA 3 Bonus Materials + if title_id == 0x54438005 and title == 'Xbox Demos': + return gen_attach_xbe(iso_file, 'Doa3\\doa3b.xbe', 'Dead or Alive 3 Booster - DEMO') + + # Outlaw Golf: 9 Holes of X-Mas + if title_id == 0x5655801B and title == 'Xbox Demos': + return gen_attach_xbe(iso_file, 'OGXmas\\OLGDemo.xbe', 'Outlaw Golf: 9 Holes of X-Mas - DEMO') + + # Outlaw Golf - 9 More Holes of X-Mas + if title_id == 0x53530006 and title == 'OUTLAW GOLF': + return gen_attach_xbe(iso_file, default_xbe, 'Outlaw Golf: 9 More Holes of X-Mas') + + # Outlaw Golf: Holiday Golf + if title_id == 0x53538005 and title == 'Xbox Demos': + return gen_attach_xbe(iso_file, 'OGXmas\\OLGDemo.xbe', 'Outlaw Golf: Holiday Golf - DEMO') + + # Sega GT 2002 + Jet Set Radio Future + if title_id == 0x4D53003D and title == 'Xbox Demos': + return gen_attach_xbe(iso_file, 'SegaGT.xbe', 'Sega GT 2002 + Jet Set Radio Future') + + # Xbox Live Beta Starter Kit Disc v1.0 + if title_id == 0x584C0004 and title == 'Xbox Demos': + return gen_attach_xbe(iso_file, default_xbe, 'Xbox Live Beta Starter Kit Disc v1.0') + + # Xbox Live Starter Kit Disc + if title_id == 0x584C0007 and title == 'Xbox Demos': + return gen_attach_xbe(iso_file, default_xbe, 'Xbox Live Starter Kit Disc') + def gen_attach_xbe(iso_file, iso_xbe = 'default.xbe', alt_title = ''): base_dir = os.path.dirname(os.path.abspath(iso_file)) in_file_name = os.path.dirname(os.path.abspath(__file__)) + '/attach_cso.xbe' From 1d9b0fd674ba925de97744971d94b97ea353630b Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Wed, 30 Aug 2023 15:03:06 -0400 Subject: [PATCH 25/26] Add files via upload add decompressor script --- unciso.py | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 unciso.py diff --git a/unciso.py b/unciso.py new file mode 100644 index 0000000..b45b505 --- /dev/null +++ b/unciso.py @@ -0,0 +1,156 @@ +#!/usr/bin/python3 + +import os +import struct +import sys +import lz4.frame + +CISO_MAGIC = 0x4F534943 # CISO +CISO_HEADER_SIZE = 0x18 # 24 +CISO_BLOCK_SIZE = 0x800 # 2048 +CISO_HEADER_FMT = ' CISO_SPLIT_SIZE: + is_last_blk = True + read_len = block_size + + raw_data = fin.read(read_len) + + if is_lz4_frame: + frame_size = struct.unpack(' percent_cnt: + update_progress((index / (total_blocks2))) + percent_cnt = percent + + if is_last_blk: + fin.close() + fin = open(infile2, 'rb') + + print("") + return True + + +def main(argv): + for i in range(1, len(argv)): + infile = argv[i] + decompress_cso(infile) + + input("Press Enter to continue...") + +if __name__ == '__main__': + sys.exit(main(sys.argv)) From a909da0a7cb775310d8e5ffa30b4f04935e81387 Mon Sep 17 00:00:00 2001 From: nerdspice <49222223+nerdspice@users.noreply.github.com> Date: Wed, 30 Aug 2023 15:05:04 -0400 Subject: [PATCH 26/26] Delete unciso.py delete unciso.py --- unciso.py | 156 ------------------------------------------------------ 1 file changed, 156 deletions(-) delete mode 100644 unciso.py diff --git a/unciso.py b/unciso.py deleted file mode 100644 index b45b505..0000000 --- a/unciso.py +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/python3 - -import os -import struct -import sys -import lz4.frame - -CISO_MAGIC = 0x4F534943 # CISO -CISO_HEADER_SIZE = 0x18 # 24 -CISO_BLOCK_SIZE = 0x800 # 2048 -CISO_HEADER_FMT = ' CISO_SPLIT_SIZE: - is_last_blk = True - read_len = block_size - - raw_data = fin.read(read_len) - - if is_lz4_frame: - frame_size = struct.unpack(' percent_cnt: - update_progress((index / (total_blocks2))) - percent_cnt = percent - - if is_last_blk: - fin.close() - fin = open(infile2, 'rb') - - print("") - return True - - -def main(argv): - for i in range(1, len(argv)): - infile = argv[i] - decompress_cso(infile) - - input("Press Enter to continue...") - -if __name__ == '__main__': - sys.exit(main(sys.argv))