Add rudimentary iso creation to Rebirth

This commit is contained in:
Mc-muffin
2023-08-22 17:42:30 -05:00
parent 0b5e57c67a
commit bf0ae1ebb6
2 changed files with 96 additions and 1 deletions

View File

@@ -6,6 +6,7 @@ import struct
from dataclasses import dataclass
from itertools import tee
from pathlib import Path
from time import time
import lxml.etree as etree
import pandas as pd
@@ -910,6 +911,90 @@ class ToolsTOR(ToolsTales):
pbar.update(len(data))
iso.close()
def make_iso(self, umd_iso: Path) -> None:
print("Creating new iso...")
# We now pack the iso using every shortcut imaginable
# because realistically we won't really touch anything
# apart from the DAT.BIN and SLPS files
# The logic was basically taken from PS2 Iso Rebuilder
# Let's clean old build (if they exists)
self.clean_builds(self.paths["game_builds"])
# Set up new iso name
new_iso = self.paths["game_builds"] / f"TalesOfRebirth_{int(time())}.iso"
with FileIO(new_iso, "wb+") as new:
# 1st copy the relevant contents from the original iso
# as we don't touch anything before the DAT.BIN that means
# copying the first 847549 LBAs from the original iso
with open(umd_iso, "rb") as og:
og_sz = 847549 * 0x800
with tqdm(total=og_sz, desc=f"Copying unchanged data", unit="B", unit_divisor=1024, unit_scale=True) as pbar:
for _ in range(og_sz // 0xCEEBD):
new.write(og.read(0xCEEBD))
pbar.update(0xCEEBD)
# Now we grab the 2nd Anchor from the original iso too
# it's at the end of the image, so just grab the last LBA
og.seek(-0x800, 2)
anchor_save = og.read(0x800)
# Now we plop the new DAT.BIN in its legitimate spot
with open(self.paths["final_files"] / "DAT.BIN", "rb") as dt:
dt.seek(0, 2)
dat_sz = dt.tell()
dt.seek(0)
with tqdm(total=dat_sz, desc=f"Inserting DAT.BIN", unit="B", unit_divisor=1024, unit_scale=True) as pbar:
while data := dt.read(0x8000):
new.write(data)
pbar.update(len(data))
# Align to nearest LBA
new.write_padding(0x800)
# get FIELD.BIN LBA
fld_lba = new.tell() // 0x800
# Now we plop FIELD.BIN in its legitimate spot
with open(self.paths["original_files"] / "FLD.BIN", "rb") as dt:
dt.seek(0, 2)
fld_sz = dt.tell()
dt.seek(0)
with tqdm(total=fld_sz, desc=f"Inserting FLD.BIN", unit="B", unit_divisor=1024, unit_scale=True) as pbar:
while data := dt.read(0x8000):
new.write(data)
pbar.update(len(data))
# Align
new.write_padding(0x8000)
# get end of volume spot
end_lba = new.tell() // 0x800
# Put the Anchor in place
new.write(anchor_save)
# Now we update the file entries, DAT.BIN only need updated
# size, FLD.BIN size and LBA, also update the PVD size
new.write_int32_at(dat_sz, 0x82992)
new.write_int32_at(fld_lba, 0x829C2)
new.write_int32_at(end_lba, 0x8050)
new.write_int32_at(end_lba - 1, end_lba - 0x7F4)
new.set_endian("big")
new.write_int32_at(dat_sz, 0x82996)
new.write_int32_at(fld_lba, 0x829C6)
new.write_int32_at(end_lba, 0x8054)
new.set_endian("little")
# Finally, the SLPS, it's at the same location and size
# so no problems for us
with open(self.paths["final_files"] / "SLPS_254.50", "rb") as sl:
new.seek(0x89000)
new.write(sl.read())
def clean_folder(self, path: Path) -> None:
@@ -920,4 +1005,13 @@ class ToolsTOR(ToolsTales):
if file.is_dir():
shutil.rmtree(file)
elif file.name.lower() != ".gitignore":
file.unlink(missing_ok=False)
file.unlink(missing_ok=False)
def clean_builds(self, path: Path) -> None:
target_files = sorted(list(path.glob("*.iso")))[5:]
if len(target_files) != 0:
print("Cleaning builds folder...")
for file in target_files:
print(f"deleting {str(file)}...")
file.unlink()