Skip to content

Commit

Permalink
Added more stuff. and rearranged the codes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Romarjosh Villamor committed Jan 8, 2016
1 parent e82bdca commit c951a8c
Showing 1 changed file with 175 additions and 5 deletions.
180 changes: 175 additions & 5 deletions pack/packer.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,10 @@ def create_archives(self):
real_path = os.path.join(archive["dir"], base_path)
out_path = os.path.join(temp_dir, archive["name"], base_path)

self.progress.setValue(self.progress.value() + 1)
self.progress.setLabelText("Reading...\n%s" % real_path)
self.file_count += 1
if self.file_count % 25 == 0:
self.progress.setLabelText("Reading...\n" + full_path)
self.progress.setValue(self.file_count)

# All items in the CPK list should be files.
# Therefore, if we have a directory, then it needs to be packed.
Expand Down Expand Up @@ -226,13 +228,91 @@ def create_archives(self):
eboot.overwrite(BitStream(uintle = file_size, length = 32), toc_info[entry][1] * 8)

del table_of_contents

def pack_dir(self, dir, handler, file_list = None, align_toc = 16, align_files = 16, eof = False):

table_of_contents = {}

if file_list == None:
file_list = sorted(os.listdir(dir))

num_files = len(file_list)

toc_length = (num_files + 1) * 4

if eof:
toc_length += 1

if toc_length % align_toc > 0:
toc_length += align_toc - (toc_length % align_toc)

handler.seek(0)
handler.write(struct.pack("<I", num_files))
handler.write(bytearray(toc_length - 4))

for file_num, item in enumerate(file_list):
full_path = os.path.join(dir, item)

if os.path.isfile(full_path):

basename = os.path.basename(item)
basename, ext = os.path.splitext(basename)

# Special handling for certain data types.
if ext == ".txt":
data = self.pack_txt(full_path)

# anagram_81.dat is not a valid anagram file. <_>
elif basename[:8] == "anagram_" and ext == ".dat" and not basename == "anagram_81":
anagram = AnagramFile(full_path)
data = anagram.pack(for_game = True).bytes

else:
with open(full_path, "rb") as f:
data = f.read()

else:

temp_align_toc = 16
temp_align_files = 4

if item in SPECIAL_ALIGN:
temp_align_toc = SPECIAL_ALIGN[item][0]
temp_align_files = SPECIAL_ALIGN[item][1]
elif os.path.basename(dir) in SPECIAL_ALIGN and len(SPECIAL_ALIGN[os.path.basename(dir)]) == 4:
temp_align_toc = SPECIAL_ALIGN[os.path.basename(dir)][2]
temp_align_files = SPECIAL_ALIGN[os.path.basename(dir)][3]

if os.path.splitext(full_path)[1].lower() == ".lin":
data = self.pack_lin(full_path)

else:
data = io.BytesIO()
with io.BufferedWriter(data) as fh:
self.pack_dir(full_path, fh, align_toc = temp_align_toc, align_files = temp_align_files, eof = eof)
fh.flush()
data = data.getvalue()

data = bytearray(data)
file_size = len(data)
padding = 0

if file_size % align_files > 0:
padding = align_files - (file_size % align_files)
data.extend(bytearray(padding))

handler.seek(0, io.SEEK_END)
file_pos = handler.tell()
handler.write(data)
handler.seek((file_num + 1) * 4)
handler.write(struct.pack("<I", file_pos))

del data

self.progress.setWindowTitle("Building...")
self.progress.setLabelText("Saving EBOOT.BIN...")
self.progress.setValue(self.progress.maximum())

with open(eboot_path, "wb") as f:
eboot.tofile(f)


# Text replacement
to_replace = eboot_text.get_eboot_text()
Expand Down Expand Up @@ -266,6 +346,96 @@ def create_archives(self):
# self.progress.setLabelText("Deleting temporary files...")
# shutil.rmtree(temp_dir)

# Re-center the dialog.
progress_w = self.progress.geometry().width()
progress_h = self.progress.geometry().height()

new_x = self.x + ((self.width - progress_w) / 2)
new_y = self.y + ((self.height - progress_h) / 2)

self.progress.move(new_x, new_y)

table_of_contents[item] = {}
table_of_contents[item]["size"] = file_size
table_of_contents[item]["pos"] = file_pos

if eof:
handler.seek(0, io.SEEK_END)
archive_len = handler.tell()
handler.seek((num_files + 1) * 4)
handler.write(struct.pack("<I", archive_len))

return table_of_contents

def pack_txt(self, filename):

if os.path.basename(os.path.dirname(filename)) in SCRIPT_NONSTOP:
is_nonstop = True
else:
is_nonstop = False

text = text_files.load_text(filename)
text = RE_SCRIPT.sub(u"\g<1>", text)

# Nonstop Debate lines need an extra newline at the end
# so they show up in the backlog properly.
if is_nonstop and not text[-1] == "\n":
text += "\n"

return SCRIPT_BOM.bytes + bytearray(text, encoding = "UTF-16LE") + SCRIPT_NULL.bytes

def pack_lin(self, dir):

# Collect our files.
file_list = sorted(list_all_files(dir))

txt = [filename for filename in file_list if os.path.splitext(filename)[1].lower() == ".txt"]
wrd = [filename for filename in file_list if os.path.splitext(filename)[1].lower() == ".wrd"]
py = [filename for filename in file_list if os.path.splitext(filename)[1].lower() == ".py"]

# If there are more than one for whatever reason, just take the first.
# We only have use for a single wrd or python file.
wrd = wrd[0] if wrd else None
py = py[0] if py else None

# Prepare our temporary output directory.
temp_dir = tempfile.mkdtemp(prefix = "sdse-")

# Where we're outputting our wrd file, regardless of whether it's a python
# file or a raw binary data file.
wrd_dst = os.path.join(temp_dir, "0.scp.wrd")

if py:
# _LOGGER.info("Compiling %s to binary." % py)
try:
wrd_file = WrdFile(py)
except:
_LOGGER.warning("%s failed to compile. Parsing wrd file instead. Exception info:\n%s" % (py, traceback.format_exc()))
shutil.copy(wrd, wrd_dst)
else:
# If we succeeded in loading the python file, compile it to binary.
# wrd_file.save_bin(wrd)
wrd_file.save_bin(wrd_dst)

else:
shutil.copy(wrd, wrd_dst)

# Pack the text files in-place to save us a bunch of copying
# and then move it to the tmp directory with the wrd file.
if txt:
with io.FileIO(os.path.join(temp_dir, "1.dat"), "w") as h:
self.pack_dir(dir, h, file_list = txt)

# Then pack it like normal.
data = io.BytesIO()
with io.BufferedWriter(data) as h:
self.pack_dir(temp_dir, h)
h.flush()
data = data.getvalue()

shutil.rmtree(temp_dir)

return data

if __name__ == "__main__":
pass
Expand Down

0 comments on commit c951a8c

Please sign in to comment.