Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate project to Python3 #8

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
74 changes: 37 additions & 37 deletions gui.py
Original file line number Diff line number Diff line change
@@ -7,12 +7,12 @@

"""Graphical user-interface for mymc."""

_SCCS_ID = "@(#) mymc gui.py 1.8 22/02/05 19:20:59\n"
_SCCS_ID = "@(#) mymc gui.py 1.9 23/07/06 19:35:21\n"

import os
import sys
import struct
import cStringIO
from io import BytesIO
import time
from functools import partial

@@ -101,7 +101,7 @@ def single_title(title):
def _get_icon_resource_as_images(name):
ico = guires.resources[name]
images = []
f = cStringIO.StringIO(ico)
f = BytesIO(ico)
count = struct.unpack("<HHH", ico[0:6])[2]
# count = wx.Image_GetImageCount(f, wx.BITMAP_TYPE_ICO)
for i in range(count):
@@ -159,7 +159,7 @@ def __init__(self, parent, evt_focus, evt_select, config):

def _update_dirtable(self, mc, dir):
self.dirtable = table = []
enc = "unicode"
enc = "utf-8"
if self.config.get_ascii():
enc = "ascii"
for ent in dir:
@@ -347,7 +347,7 @@ def __init__(self, parent, focus):
r = mymcicon.init_icon_renderer(focus.GetHandle(),
self.GetHandle())
if r == -1:
print "init_icon_renderer failed"
print("init_icon_renderer failed")
self.failed = True
return

@@ -384,7 +384,7 @@ def load_icon(self, icon_sys, icon):
r = mymcicon.load_icon(icon_sys, len(icon_sys),
icon, len(icon))
if r != 0:
print "load_icon", r
print("load_icon", r)
self.failed = True

def _set_lighting(self, lighting, vertex_diffuse, alt_lighting,
@@ -634,22 +634,22 @@ def _close_mc(self):
if self.mc != None:
try:
self.mc.close()
except EnvironmentError, value:
self.mc_error(value)
except EnvironmentError as e:
self.mc_error(e)
self.mc = None
if self.f != None:
try:
self.f.close()
except EnvironmentError, value:
self.mc_error(value)
except EnvironmentError as e:
self.mc_error(e)
self.f = None
self.mcname = None

def refresh(self):
try:
self.dirlist.update(self.mc)
except EnvironmentError, value:
self.mc_error(value)
except EnvironmentError as e:
self.mc_error(e)
self._close_mc()
self.dirlist.update(None)

@@ -674,12 +674,12 @@ def open_mc(self, filename):

f = None
try:
f = file(filename, "r+b")
f = open(filename, "r+b")
mc = ps2mc.ps2mc(f)
except EnvironmentError, value:
except EnvironmentError as e:
if f != None:
f.close()
self.mc_error(value, filename)
self.mc_error(e, filename)
self.SetTitle(self.title)
self.refresh()
return
@@ -718,8 +718,8 @@ def evt_dirlist_item_focused(self, event):
icon = f.read()
finally:
f.close()
except EnvironmentError, value:
print "icon failed to load", value
except EnvironmentError as e:
print("icon failed to load", e)
self.icon_win.load_icon(None, None)
return

@@ -758,8 +758,8 @@ def evt_cmd_export(self, event):
sf = mc.export_save_file("/" + dirname)
longname = ps2save.make_longname(dirname, sf)
sfiles.append((dirname, sf, longname))
except EnvironmentError, value:
self.mc_error(value. dirname)
except EnvironmentError as e:
self.mc_error(e.dirname)

if len(sfiles) == 0:
return
@@ -778,16 +778,16 @@ def evt_cmd_export(self, event):
if fn == "":
return
try:
f = file(fn, "wb")
f = open(fn, "wb")
try:
if fn.endswith(".max"):
sf.save_max_drive(f)
else:
sf.save_ems(f)
finally:
f.close()
except EnvironmentError, value:
self.mc_error(value, fn)
except EnvironmentError as e:
self.mc_error(e, fn)
return

dir = os.path.dirname(fn)
@@ -804,12 +804,12 @@ def evt_cmd_export(self, event):
for (dirname, sf, longname) in sfiles:
fn = os.path.join(dir, longname) + ".psu"
try:
f = file(fn, "wb")
f = open(fn, "wb")
sf.save_ems(f)
f.close()
count += 1
except EnvironmentError, value:
self.mc_error(value, fn)
except EnvironmentError as e:
self.mc_error(e, fn)
if count > 0:
if os.path.isabs(dir):
self.config.set_savefile_dir(dir)
@@ -819,7 +819,7 @@ def evt_cmd_export(self, event):

def _do_import(self, fn):
sf = ps2save.ps2_save_file()
f = file(fn, "rb")
f = open(fn, "rb")
try:
ft = ps2save.detect_file_type(f)
f.seek(0)
@@ -868,8 +868,8 @@ def evt_cmd_import(self, event):
try:
self._do_import(fn)
success = fn
except EnvironmentError, value:
self.mc_error(value, fn)
except EnvironmentError as e:
self.mc_error(e, fn)

if success != None:
dir = os.path.dirname(success)
@@ -904,8 +904,8 @@ def evt_cmd_delete(self, event):
for dn in dirnames:
try:
mc.rmdir("/" + dn)
except EnvironmentError, value:
self.mc_error(value, dn)
except EnvironmentError as e:
self.mc_error(e, dn)

mc.check()
self.refresh()
@@ -934,13 +934,13 @@ def run(filename = None):

run("test.ps2")

gc.collect()
for o in gc.garbage:
print
print o
if type(o) == ps2mc.ps2mc_file:
gc.collect()
for o in gc.garbage:
print()
print(o)
if type(o) == ps2mc.ps2mc_file:
for m in dir(o):
print m, getattr(o, m)
print(m, getattr(o, m))


# while True:
@@ -954,7 +954,7 @@ def run(filename = None):
# or m == "__dict__"
# or m == "__weakref__"):
# continue
# print m
# print(m)
# setattr(o, m, None)
# o = None
# break
368 changes: 185 additions & 183 deletions guires.py

Large diffs are not rendered by default.

92 changes: 46 additions & 46 deletions lzari.py
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
LZARI.C's binary search tree.
"""

_SCCS_ID = "@(#) mymc lzari.py 1.6 12/10/04 19:07:53\n"
_SCCS_ID = "@(#) mymc lzari.py 1.7 23/07/06 16:03:53\n"

import sys
import array
@@ -56,18 +56,18 @@
MAX_SUFFIX_CHAIN = 50 # limit on how many identical suffixes to try to match

#def debug(value, msg):
# print "@@@ %s %04x" % (msg, value)
# print("@@@ %s %04x" % (msg, value))
debug = lambda value, msg: None

_tr_16 = string.maketrans("0123456789abcdef",
"\x00\x01\x02\x03"
"\x10\x11\x12\x13"
"\x20\x21\x22\x23"
"\x30\x31\x32\x33")
_tr_4 = string.maketrans("0123",
"\x00\x01"
"\x10\x11")
_tr_2 = string.maketrans("01", "\x00\x01")
_tr_16 = bytes.maketrans(b"0123456789abcdef",
b"\x00\x01\x02\x03"
b"\x10\x11\x12\x13"
b"\x20\x21\x22\x23"
b"\x30\x31\x32\x33")
_tr_4 = bytes.maketrans(b"0123",
b"\x00\x01"
b"\x10\x11")
_tr_2 = bytes.maketrans(b"01", b"\x00\x01")

def string_to_bit_array(s):
"""Convert a string to an array containing a sequence of bits."""
@@ -77,15 +77,15 @@ def string_to_bit_array(s):
a = array.array('B', s)
return a

_tr_rev_2 = string.maketrans("\x00\x01", "01")
_tr_rev_4 = string.maketrans("\x00\x01"
"\x10\x11",
"0123")
_tr_rev_16 = string.maketrans("\x00\x01\x02\x03"
"\x10\x11\x12\x13"
"\x20\x21\x22\x23"
"\x30\x31\x32\x33",
"0123456789abcdef")
_tr_rev_2 = bytes.maketrans(b"\x00\x01", b"01")
_tr_rev_4 = bytes.maketrans(b"\x00\x01"
b"\x10\x11",
b"0123")
_tr_rev_16 = bytes.maketrans(b"\x00\x01\x02\x03"
b"\x10\x11\x12\x13"
b"\x20\x21\x22\x23"
b"\x30\x31\x32\x33",
b"0123456789abcdef")
def bit_array_to_string(a):
"""Convert an array containing a sequence of bits to a string."""
remainder = len(a) % 8
@@ -151,7 +151,7 @@ def init(self, decode):

def search(self, table, x):
c = 1
s = len(table) - 1
s = len(table) - 1
while True:
a = (s + c) / 2
if table[a] <= x:
@@ -179,11 +179,11 @@ def update_model_decode(self, symbol):
freq = sym_freq[symbol]
new_symbol = symbol
while self.sym_freq[new_symbol - 1] == freq:
new_symbol -= 1
new_symbol -= 1
# new_symbol = sym_freq.index(freq)
if new_symbol != symbol:
symbol_to_char = self.symbol_to_char
swap_char = symbol_to_char[new_symbol]
swap_char = symbol_to_char[new_symbol]
char = symbol_to_char[symbol]
symbol_to_char[new_symbol] = char
symbol_to_char[symbol] = swap_char
@@ -195,7 +195,7 @@ def update_model_encode(self, symbol):
sym_freq = self.sym_freq
sym_cum = self.sym_cum

if sym_cum[0] >= MAX_CUM:
if sym_cum[0] >= MAX_CUM:
c = 0
for i in range(MAX_CHAR, 0, -1):
sym_cum[i] = c
@@ -206,10 +206,10 @@ def update_model_encode(self, symbol):
freq = sym_freq[symbol]
new_symbol = symbol
while sym_freq[new_symbol - 1] == freq:
new_symbol -= 1
new_symbol -= 1
if new_symbol != symbol:
debug(new_symbol, "a")
swap_char = self.symbol_to_char[new_symbol]
swap_char = self.symbol_to_char[new_symbol]
char = self.symbol_to_char[symbol]
self.symbol_to_char[new_symbol] = char
self.symbol_to_char[symbol] = swap_char
@@ -272,7 +272,7 @@ def decode_position(self):
or self.high > QUADRANT3):
if self.high > QUADRANT2:
return pos
else:
else:
self.low -= QUADRANT1
self.code -= QUADRANT1
self.high -= QUADRANT1
@@ -437,11 +437,11 @@ def _add_suffix(self, pos, find):
r = self.add_suffix_2(pos, find)
start_pos = self.start_pos
if find and r[0] != None:
print ("%4d %02x %4d %2d"
print("%4d %02x %4d %2d"
% (pos - start_pos, ord(self.src[pos]),
r[0] - start_pos, r[1]))
else:
print ("%4d %02x"
print("%4d %02x"
% (pos - start_pos, ord(self.src[pos])))
return r

@@ -570,7 +570,7 @@ def encode(self, src, progress = None):

#for k, v in sorted(self.suffix_table.items()):
# count, head, table2, chars = v
# print hexlify(k), count, head, len(table2), chars
# print(hexlify(k), count, head, len(table2), chars)

if progress:
sys.stderr.write("%s100%%\n" % progress)
@@ -584,7 +584,7 @@ def decode(self, src, out_length, progress = None):
a.fromlist([0] * 32) # add some extra bits
self.in_iter = iter(a).next

out = array.array('B', "\0") * out_length
out = array.array('B', b"\0") * out_length
outpos = 0

self.init(True)
@@ -646,15 +646,15 @@ def decode(src, out_length, progress = None):
out = ctypes.create_string_buffer(out_length)
if (mylzari_decode(src, len(src), out, out_length, progress)
== -1):
raise ValueError, "compressed input is corrupt"
raise ValueError("compressed input is corrupt")
return ctypes.string_at(out, out_length)

def encode(src, progress = None):
(r, compressed, comp_len) = mylzari_encode(src, len(src),
progress)
# print r, compressed.value, comp_len
# print(r, compressed.value, comp_len)
if r == -1:
raise MemoryError, "out of memory during compression"
raise MemoryError("out of memory during compression")
if compressed.value == None:
return ""
ret = ctypes.string_at(compressed.value, comp_len.value)
@@ -665,9 +665,9 @@ def main2(args):
import struct
import os

src = file(args[2], "rb").read()
src = open(args[2], "rb").read()
lzari = lzari_codec()
out = file(args[3], "wb")
out = open(args[3], "wb")
start = os.times()
if args[1] == "c":
dest = lzari.encode(src)
@@ -679,7 +679,7 @@ def main2(args):
now = os.times()
out.write(dest)
out.close()
print "time:", now[0] - start[0], now[1] - start[1], now[4] - start[4]
print("time:", now[0] - start[0], now[1] - start[1], now[4] - start[4])


def _get_hotshot_lineinfo(filename):
@@ -703,10 +703,10 @@ def _dump_hotshot_lineinfo(log):
total_time = sum((time[1]
for (loc, time) in a))
for (loc, [count, time]) in a:
print ("%8d %6.3f%% %8d %6.3f%%"
print("%8d %6.3f%% %8d %6.3f%%"
% (time, time * 100.0 / total_time,
count, count * 100.0 / total_count)),
print "%s:%d(%s)" % loc
print("%s:%d(%s)" % loc)

def _dump_hotshot_lineinfo2(log):
cur = None
@@ -719,25 +719,25 @@ def _dump_hotshot_lineinfo2(log):
if cur != filename:
if cur != None and f != None:
for line in f:
print line[:-1]
print(line[:-1])
f.close()
try:
f = file(filename, "r")
f = open(filename, "r")
except OSError:
f = None
cur = filename
l = 0
print "#", filename
print("#", filename)
if f != None:
while l < lineno:
print f.readline()[:-1]
print(f.readline()[:-1])
l += 1
print ("# %8d %6.3f%% %8d %6.3f%%"
print("# %8d %6.3f%% %8d %6.3f%%"
% (time, time * 100.0 / total_time,
count, count * 100.0 / total_count))
if cur != None and f != None:
for line in f:
print line[:-1]
print(line[:-1])
f.close()

def main(args):
@@ -747,7 +747,7 @@ def main(args):
import profile
pr = profile.Profile()
for i in range(5):
print pr.calibrate(100000)
print(pr.calibrate(100000))
return
elif args[1] == "p":
import profile
94 changes: 47 additions & 47 deletions mymc.py
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@

"""A utility for manipulating PS2 memory card images."""

_SCCS_ID = "@(#) mymc mymc.py 1.13 22/01/15 01:04:45\n"[:-1]
_SCCS_ID = "@(#) mymc mymc.py 1.14 23/07/06 15:51:52\n"[:-1]

import sys
import os
@@ -50,7 +50,7 @@ def __getattribute__(self, name):

def __setattr__(self, name, value):
if name == "encoding":
raise TypeError, "readonly attribute"
raise TypeError("readonly attribute")
return setattr(object.__getattribute__(self, "_f"),
name, value)

@@ -89,7 +89,7 @@ def _copy(fout, fin):

while True:
s = fin.read(1024)
if s == "":
if s == b"":
break
fout.write(s)

@@ -157,7 +157,7 @@ def do_extract(cmd, mc, opts, args, opterr):
if opts.use_stdout:
opterr("The -o and -p options are mutually exclusive.")
dont_close_out = True
out = file(opts.output, "wb")
out = open(opts.output, "wb")
elif opts.use_stdout:
out = sys.stdout

@@ -169,7 +169,7 @@ def do_extract(cmd, mc, opts, args, opterr):
_copy(out, f)
continue
a = filename.split("/")
o = file(a[-1], "wb")
o = open(a[-1], "wb")
try:
_copy(o, f)
finally:
@@ -205,7 +205,7 @@ def do_import(cmd, mc, opts, args, opterr):

for filename in args:
sf = ps2save.ps2_save_file()
f = file(filename, "rb")
f = open(filename, "rb")
try:
ftype = ps2save.detect_file_type(f)
f.seek(0)
@@ -218,21 +218,21 @@ def do_import(cmd, mc, opts, args, opterr):
elif ftype == "sps":
sf.load_sharkport(f)
elif ftype == "npo":
raise io_error, (EIO, "nPort saves"
raise io_error((EIO, "nPort saves"
" are not supported.",
filename)
filename))
else:
raise io_error, (EIO, "Save file format not"
" recognized", filename)
raise io_error((EIO, "Save file format not"
" recognized", filename))
finally:
f.close()
dirname = opts.directory
if dirname == None:
dirname = sf.get_directory()[8]
print "Importing", filename, "to", dirname
print("Importing", filename, "to", dirname)
if not mc.import_save_file(sf, opts.ignore_existing,
opts.directory):
print (filename + ": already in memory card image,"
print(filename + ": already in memory card image,"
" ignored.")

#re_num = re.compile("[0-9]+")
@@ -275,9 +275,9 @@ def do_export(cmd, mc, opts, args, opterr):
continue
raise io_error(EEXIST, "File exists", filename)

f = file(filename, "wb")
f = open(filename, "wb")
try:
print "Exporing", dirname, "to", filename
print("Exporing", dirname, "to", filename)

if opts.type == "max":
sf.save_max_drive(f)
@@ -326,7 +326,7 @@ def do_setmode(cmd, mc, opts, args, opterr):
ent = mc.get_dirent(arg)
if value == None:
ent[0] = (ent[0] & clear_mask) | set_mask
# print "new %04x" % ent[0]
# print("new %04x" % ent[0])
else:
ent[0] = value
mc.set_dirent(arg, ent)
@@ -337,7 +337,7 @@ def do_rename(cmd, mc, opts, args, opterr):
mc.rename(args[0], args[1])

def _get_ps2_title(mc, enc):
s = mc.get_icon_sys(".");
s = mc.get_icon_sys(".")
if s == None:
return None
a = ps2save.unpack_icon_sys(s)
@@ -394,10 +394,10 @@ def do_dir(cmd, mc, opts, args, opterr):
if type != None:
protection = type

print "%-32s %s" % (ent[8], title[0])
print ("%4dKB %-25s %s"
print("%-32s %s" % (ent[8], title[0]))
print("%4dKB %-25s %s"
% (length / 1024, protection, title[1]))
print
print()
finally:
if f != None:
f.close()
@@ -412,18 +412,18 @@ def do_dir(cmd, mc, opts, args, opterr):
else:
free = "%d" % free

print free + " KB Free"
print(free + " KB Free")

def do_df(cmd, mc, opts, args, opterr):
if len(args) != 0:
opterr("Incorrect number of arguments.")
print mc.f.name + ":", mc.get_free_space(), "bytes free."
print(mc.f.name + ":", mc.get_free_space(), "bytes free.")

def do_check(cmd, mc, opts, args, opterr):
if len(args) != 0:
opterr("Incorrect number of arguments.")
if mc.check():
print "No errors found."
print("No errors found.")
return 0
return 1

@@ -443,13 +443,13 @@ def do_format(cmd, mcname, opts, args, opterr):
if not opts.overwrite_existing:
exists = True
try:
file(mcname, "rb").close()
open(mcname, "rb").close()
except EnvironmentError:
exists = False
if exists:
raise io_error, (EEXIST, "file exists", mcname)
raise io_error(EEXIST, "file exists", mcname)

f = file(mcname, "w+b")
f = open(mcname, "w+b")
try:
ps2mc.ps2mc(f, True, params).close()
finally:
@@ -472,10 +472,10 @@ def do_create_pad(cmd, mc, opts, args, opterr):
length = mc.clusters_per_card
if len(args) > 1:
length = int(args[1])
pad = "\0" * mc.cluster_size
pad = b"\0" * mc.cluster_size
f = mc.open(args[0], "wb")
try:
for i in xrange(length):
for i in range(length):
f.write(pad)
finally:
f.close()
@@ -484,15 +484,15 @@ def do_create_pad(cmd, mc, opts, args, opterr):
def do_frob(cmd, mc, opts, args, opterr):
mc.write_superblock()

_trans = string.maketrans("".join(map(chr, range(32))), " " * 32)
_trans = str.maketrans("".join(map(chr, range(32))), " " * 32)

def _print_bin(base, s):
for off in range(0, len(s), 16):
print "%04X" % (base + off),
print("%04X" % (base + off))
a = s[off : off + 16]
for b in a:
print "%02X" % ord(b),
print "", a.translate(_trans)
print("%02X" % ord(b))
print("", a.translate(_trans))

def _print_erase_block(mc, n):
ppb = mc.pages_per_erase_block
@@ -503,17 +503,17 @@ def _print_erase_block(mc, n):
print

def do_print_good_blocks(cmd, mc, opts, args, opterr):
print "good_block2:"
print("good_block2:")
_print_erase_block(mc, mc.good_block2)
print "good_block1:"
print("good_block1:")
_print_erase_block(mc, mc.good_block1)

def do_ecc_check(cmd, mc, opts, args, opterr):
for i in range(mc.clusters_per_card * mc.pages_per_cluster):
try:
mc.read_page(i)
except ps2mc.ecc_error:
print "bad: %05x" % i
print("bad: %05x" % i)

opt = optparse.make_option

@@ -688,7 +688,7 @@ class suboption_parser(optparse.OptionParser):
def exit(self, status = 0, msg = None):
if msg:
sys.stderr.write(msg)
raise subopt_error, status
raise subopt_error(status)

class my_help_formatter(optparse.IndentedHelpFormatter):
"""A better formatter for optparser's help message"""
@@ -713,7 +713,7 @@ def format_description(self, description):
return "\n".join(lines) + "\n"

def main():
prog = sys.argv[0].decode(sys.getdefaultencoding(), "replace")
prog = sys.argv[0]
usage = "usage: %prog [-ih] memcard.ps2 command [...]"
description = ("Manipulate PS2 memory card images.\n\n"
"Supported commands: ")
@@ -780,38 +780,38 @@ def main():
ret = fn(cmd, mcname, subopts, subargs,
subopt_parser.error)
else:
f = file(mcname, mode)
f = open(mcname, mode)
mc = ps2mc.ps2mc(f, opts.ignore_ecc)
ret = fn(cmd, mc, subopts, subargs,
subopt_parser.error)
finally:
if mc != None:
mc.close()
if f != None:
# print "f.close()"
# print("f.close()")
f.close()

except EnvironmentError, value:
if getattr(value, "filename", None) != None:
write_error(value.filename, value.strerror)
except EnvironmentError as e:
if getattr(e, "filename", None) != None:
write_error(e.filename, e.strerror)
ret = 1
elif getattr(value, "strerror", None) != None:
write_error(mcname, value.strerror)
elif getattr(e, "strerror", None) != None:
write_error(mcname, e.strerror)
ret = 1
else:
# something weird
raise
if opts.debug:
raise

except subopt_error, (ret,):
except subopt_error:
pass

except (ps2mc.error, ps2save.error), value:
fn = getattr(value, "filename", None)
except (ps2mc.error, ps2save.error) as e:
fn = getattr(e, "filename", None)
if fn == None:
fn = mcname
write_error(fn, str(value))
write_error(fn, str(e))
if opts.debug:
raise
ret = 1
362 changes: 181 additions & 181 deletions ps2mc.py

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions ps2mc_dir.py
Original file line number Diff line number Diff line change
@@ -7,11 +7,12 @@

"""Functions for working with PS2 memory card directory entries."""

_SCCS_ID = "@(#) mymc ps2mc_dir.py 1.4 12/10/04 19:11:08\n"
_SCCS_ID = "@(#) mymc ps2mc_dir.py 1.5 23/07/06 06:30:13\n"

import struct
import time
import calendar
import os

PS2MC_DIRENT_LENGTH = 512

@@ -36,7 +37,7 @@
def zero_terminate(s):
"""Truncate a string at the first NUL ('\0') character, if any."""

i = s.find('\0')
i = s.find(b'\0')
if i == -1:
return s
return s[:i]
@@ -67,13 +68,14 @@ def unpack_dirent(s):
ent = list(ent)
ent[3] = _tod_struct.unpack(ent[3])
ent[6] = _tod_struct.unpack(ent[6])
ent[8] = zero_terminate(ent[8])
ent[8] = zero_terminate(ent[8]).decode("utf-8")
return ent

def pack_dirent(ent):
ent = list(ent)
ent[3] = _tod_struct.pack(*ent[3])
ent[6] = _tod_struct.pack(*ent[6])
ent[8] = ent[8].encode("utf-8")
return _dirent_struct.pack(*ent)
else:
def unpack_tod(s):
@@ -97,6 +99,7 @@ def pack_dirent(ent):
ent = list(ent)
ent[3] = struct.pack(_tod_fmt, *ent[3])
ent[6] = struct.pack(_tod_fmt, *ent[6])
ent[8] = ent[8].encode("utf-8")
return struct.pack(_dirent_fmt, *ent)

def time_to_tod(when):
28 changes: 14 additions & 14 deletions ps2mc_ecc.py
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
correcting codes (ECC), as used on PS2 memory cards.
"""

_SCCS_ID = "@(#) mymc ps2mc_ecc.py 1.4 07/12/17 02:34:04\n"
_SCCS_ID = "@(#) mymc ps2mc_ecc.py 1.5 23/07/06 16:03:58\n"

import array

@@ -64,7 +64,7 @@ def _ecc_calculate(s):

if not isinstance(s, array.array):
a = array.array('B')
a.fromstring(s)
a.frombytes(s)
s = a
column_parity = 0x77
line_parity_0 = 0x7F
@@ -88,10 +88,10 @@ def _ecc_check(s, ecc):
if computed == ecc:
return ECC_CHECK_OK

#print
#print()
#_print_bin(0, s.tostring())
#print "computed %02x %02x %02x" % tuple(computed)
#print "actual %02x %02x %02x" % tuple(ecc)
#print("computed %02x %02x %02x" % tuple(computed))
#print("actual %02x %02x %02x" % tuple(ecc))

# ECC mismatch

@@ -101,17 +101,17 @@ def _ecc_check(s, ecc):
lp_comp = lp0_diff ^ lp1_diff
cp_comp = (cp_diff >> 4) ^ (cp_diff & 0x07)

#print "%02x %02x %02x %02x %02x" % (cp_diff, lp0_diff, lp1_diff,
# lp_comp, cp_comp)
#print("%02x %02x %02x %02x %02x" % (cp_diff, lp0_diff, lp1_diff,
# lp_comp, cp_comp))

if lp_comp == 0x7F and cp_comp == 0x07:
print "corrected 1"
print("corrected 1")
# correctable 1 bit error in data
s[lp1_diff] ^= 1 << (cp_diff >> 4)
return ECC_CHECK_CORRECTED
if ((cp_diff == 0 and lp0_diff == 0 and lp1_diff == 0)
or _popcount(lp_comp) + _popcount(cp_comp) == 1):
print "corrected 2"
print("corrected 2")
# correctable 1 bit error in ECC
# (and/or one of the unused bits was set)
ecc[0] = computed[0]
@@ -140,15 +140,15 @@ def ecc_check_page(page, spare):
chunks = []
for i in range(div_round_up(len(page), 128)):
a = array.array('B')
a.fromstring(page[i * 128 : i * 128 + 128])
chunks.append((a, map(ord, spare[i * 3 : i * 3 + 3])))
a.frombytes(page[i * 128 : i * 128 + 128])
chunks.append((a, list(spare[i * 3 : i * 3 + 3])))

r = [ecc_check(s, ecc)
for (s, ecc) in chunks]
ret = ECC_CHECK_OK
if ECC_CHECK_CORRECTED in r:
# rebuild sector and spare from the corrected versions
page = "".join([a[0].tostring()
page = "".join([a[0].tobytes()
for a in chunks])
spare = "".join([chr(a[1][i])
for a in chunks
@@ -164,14 +164,14 @@ def ecc_check_page(page, spare):
else:
# _c_ubyte_p = ctypes.POINTER(ctypes.c_ubyte)
def ecc_calculate(s):
aecc = array.array('B', "\0\0\0")
aecc = array.array('B', b"\0\0\0")
cecc = ctypes.c_ubyte.from_address(aecc.buffer_info()[0])
mymcsup.ecc_calculate(s, len(s), cecc)
return list(aecc)

def ecc_check(s, ecc):
cs = ctypes.c_ubyte.from_address(s.buffer_info()[0])
# print "%08X" % s.buffer_info()[0]
# print("%08X" % s.buffer_info()[0])
aecc = array.array('B', ecc)
cecc = ctypes.c_ubyte.from_address(aecc.buffer_info()[0])
ret = mymcsup.ecc_check(cs, len(s), cecc)
77 changes: 39 additions & 38 deletions ps2save.py
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
# A simple interface for working with various PS2 save file formats.
#

_SCCS_ID = "@(#) mymc ps2save.py 1.8 22/01/15 01:25:25\n"
_SCCS_ID = "@(#) mymc ps2save.py 1.9 23/07/06 19:46:30\n"

import sys
import os
@@ -26,10 +26,10 @@
except ImportError:
lzari = None

PS2SAVE_MAX_MAGIC = "Ps2PowerSave"
PS2SAVE_SPS_MAGIC = "\x0d\0\0\0SharkPortSave"
PS2SAVE_CBS_MAGIC = "CFU\0"
PS2SAVE_NPO_MAGIC = "nPort"
PS2SAVE_MAX_MAGIC = b"Ps2PowerSave"
PS2SAVE_SPS_MAGIC = b"\x0d\0\0\0SharkPortSave"
PS2SAVE_CBS_MAGIC = b"CFU\0"
PS2SAVE_NPO_MAGIC = b"nPort"

# This is the initial permutation state ("S") for the RC4 stream cipher
# algorithm used to encrpyt and decrypt Codebreaker saves.
@@ -180,8 +180,8 @@ def shift_jis_conv(src, encoding = None):
if encoding == "shift_jis":
return src
u = src.decode("shift_jis", "replace")
if encoding == "unicode":
return u
if encoding == "utf-8":
return u.encode("utf-8")
a = []
for uc in u:
try:
@@ -242,16 +242,17 @@ def icon_sys_title(icon_sys, encoding = None):

offset = icon_sys[1]
title = icon_sys[14]
title2 = shift_jis_conv(title[offset:], encoding)
title1 = shift_jis_conv(title[:offset], encoding)
encoding = sys.getdefaultencoding() if not encoding else encoding
title2 = shift_jis_conv(title[offset:], encoding).decode(encoding)
title1 = shift_jis_conv(title[:offset], encoding).decode(encoding)
return (title1, title2)

def _read_fixed(f, n):
"""Read a string of a fixed length from a file."""

s = f.read(n)
if len(s) != n:
raise eof, f
raise eof(f)
return s

def _read_long_string(f):
@@ -314,7 +315,7 @@ def load_ems(self, f):
or not mode_is_dir(dotent[0])
or not mode_is_dir(dotdotent[0])
or dirent[2] < 2):
raise corrupt, ("Not a EMS (.psu) save file.", f)
raise corrupt("Not a EMS (.psu) save file.", f)

dirent[2] -= 2
self.set_directory(dirent)
@@ -323,7 +324,7 @@ def load_ems(self, f):
ent = unpack_dirent(_read_fixed(f,
PS2MC_DIRENT_LENGTH))
if not mode_is_file(ent[0]):
raise subdir, f
raise subdir(f)
flen = ent[2]
self.set_file(i, ent, _read_fixed(f, flen))
_read_fixed(f, round_up(flen, cluster_size) - flen)
@@ -346,11 +347,11 @@ def save_ems(self, f):
(ent, data) = self.get_file(i)
f.write(pack_dirent(ent))
if not mode_is_file(ent[0]):
# print ent
# print hex(ent[0])
raise error, "Directory has a subdirectory."
# print(ent)
# print(hex(ent[0]))
raise error("Directory has a subdirectory.")
f.write(data)
f.write("\0" * (round_up(len(data), cluster_size)
f.write(b"\0" * (round_up(len(data), cluster_size)
- len(data)))
f.flush()

@@ -359,7 +360,7 @@ def _load_max_drive_2(self):
self._compressed = None

if lzari == None:
raise error, ("The lzari module is needed to "
raise error("The lzari module is needed to "
" decompress MAX Drive saves.")
s = lzari.decode(s, length,
"decompressing " + self.dirent[8] + ": ")
@@ -368,14 +369,14 @@ def _load_max_drive_2(self):
off = 0
for i in range(dirlen):
if len(s) - off < 36:
raise eof, f
raise eof(self.f)
(l, name) = struct.unpack("<L32s", s[off : off + 36])
name = zero_terminate(name)
# print "%08x %08x %s" % (off, l, name)
# print("%08x %08x %s" % (off, l, name))
off += 36
data = s[off : off + l]
if len(data) != l:
raise eof, f
raise eof(self.f)
self.set_file(i,
(DF_RWX | DF_FILE | DF_0400 | DF_EXISTS,
0, l, timestamp, 0, 0, timestamp, 0,
@@ -391,7 +392,7 @@ def load_max_drive(self, f, timestamp = None):
(magic, crc, dirname, iconsysname, clen, dirlen,
length) = struct.unpack("<12sL32s32sLLL", s)
if magic != PS2SAVE_MAX_MAGIC:
raise corrupt, ("Not a MAX Drive save file", f)
raise corrupt("Not a MAX Drive save file", f)
if clen == length:
# some saves have the uncompressed size here
# instead of the compressed size
@@ -409,7 +410,7 @@ def load_max_drive(self, f, timestamp = None):

def save_max_drive(self, f):
if lzari == None:
raise error, ("The lzari module is needed to "
raise error("The lzari module is needed to "
" decompress MAX Drive saves.")
iconsysname = ""
icon_sys = self.get_icon_sys()
@@ -424,10 +425,10 @@ def save_max_drive(self, f):
for i in range(dirent[2]):
(ent, data) = self.get_file(i)
if not mode_is_file(ent[0]):
raise error, "Non-file in save file."
raise error("Non-file in save file.")
s += struct.pack("<L32s", ent[2], ent[8])
s += data
s += "\0" * (round_up(len(s) + 8, 16) - 8 - len(s))
s += b"\0" * (round_up(len(s) + 8, 16) - 8 - len(s))
length = len(s)
progress = "compressing " + dirent[8] + ": "
compressed = lzari.encode(s, progress)
@@ -445,10 +446,10 @@ def save_max_drive(self, f):
def load_codebreaker(self, f):
magic = f.read(4)
if magic != PS2SAVE_CBS_MAGIC:
raise corrupt, ("Not a Codebreaker save file.", f)
raise corrupt("Not a Codebreaker save file.", f)
(d04, hlen) = struct.unpack("<LL", _read_fixed(f, 8))
if hlen < 92 + 32:
raise corrupt, ("Header lengh too short.", f)
raise corrupt("Header lengh too short.", f)
(dlen, flen, dirname, created, modified, d44, d48, dirmode,
d50, d54, d58, title) \
= struct.unpack("<LL32s8s8sLLLLLL%ds" % (hlen - 92),
@@ -471,20 +472,20 @@ def load_codebreaker(self, f):
body = f.read(flen)
clen = len(body)
if clen != flen and clen != flen - hlen:
raise eof, f
raise eof(f)
body = rc4_crypt(PS2SAVE_CBS_RC4S, body)
dcobj = zlib.decompressobj()
body = dcobj.decompress(body, dlen)

files = []
while body != "":
if len(body) < 64:
raise eof, f
raise eof(f)
header = struct.unpack("<8s8sLHHLL32s", body[:64])
size = header[2]
data = body[64 : 64 + size]
if len(data) != size:
raise eof, f
raise eof(f)
body = body[64 + size:]
files.append((header, data))

@@ -498,7 +499,7 @@ def load_codebreaker(self, f):
created = unpack_tod(created)
modified = unpack_tod(modified)
if not mode_is_file(mode):
raise subdir, f
raise subdir(f)
if tod_to_time(created) == 0:
created = tod_now()
if tod_to_time(modified) == 0:
@@ -509,7 +510,7 @@ def load_codebreaker(self, f):
def load_sharkport(self, f):
magic = f.read(17)
if magic != PS2SAVE_SPS_MAGIC:
raise corrupt, ("Not a SharkPort/X-Port save file.", f)
raise corrupt("Not a SharkPort/X-Port save file.", f)
(savetype,) = struct.unpack("<L", _read_fixed(f, 4))
dirname = _read_long_string(f)
datestamp = _read_long_string(f)
@@ -529,7 +530,7 @@ def load_sharkport(self, f):
dirmode = dirmode / 256 % 256 + dirmode % 256 * 256
dirlen -= 2
if not mode_is_dir(dirmode) or dirlen < 0:
raise corrupt, ("Bad values in directory entry.", f)
raise corrupt("Bad values in directory entry.", f)
self.set_directory((dirmode, 0, dirlen, created, 0, 0,
modified, 0, dirname))

@@ -538,14 +539,14 @@ def load_sharkport(self, f):
= struct.unpack("<H64sL8xH2x8s8s",
_read_fixed(f, 98))
if hlen < 98:
raise corrupt, ("Header length too short.", f)
raise corrupt("Header length too short.", f)
_read_fixed(f, hlen - 98)
name = zero_terminate(name)
created = unpack_tod(created)
modified = unpack_tod(modified)
mode = mode / 256 % 256 + mode % 256 * 256
if not mode_is_file(mode):
raise subdir, f
raise subdir(f)
self.set_file(i, (mode, 0, flen, created, 0, 0,
modified, 0, name),
_read_fixed(f, flen))
@@ -601,8 +602,8 @@ def detect_file_type(f):
_bad_filename_chars2 = _bad_filename_chars + "?*'&|:[<>] \\\""
_bad_filename_repl2 = _bad_filename_repl + "______(())___"

_filename_trans = string.maketrans(_bad_filename_chars, _bad_filename_repl);
_filename_trans2 = string.maketrans(_bad_filename_chars2, _bad_filename_repl2);
_filename_trans = str.maketrans(_bad_filename_chars, _bad_filename_repl);
_filename_trans2 = str.maketrans(_bad_filename_chars2, _bad_filename_repl2);

def fix_filename(filename):
"""Replace illegal or problematic characters from a filename."""
@@ -617,10 +618,10 @@ def make_longname(dirname, sf):
title = icon_sys_title(icon_sys, "ascii")
title = title[0] + " " + title[1]
title = " ".join(title.split())
crc = binascii.crc32("")
crc = binascii.crc32(b"")
for (ent, data) in sf:
crc = binascii.crc32(data, crc)
if len(dirname) >= 12 and (dirname[0:2] in ("BA", "BJ", "BE", "BK")):
if len(dirname) >= 12 and (dirname[0:2] in ("BA", "BJ", "BE", "BK")):
if dirname[2:6] == "DATA":
title = ""
else:
8 changes: 4 additions & 4 deletions round.py
Original file line number Diff line number Diff line change
@@ -7,15 +7,15 @@
# Simple rounding functions.
#

_SCCS_ID = "@(#) mymc round.py 1.3 07/04/17 02:10:27\n"
_SCCS_ID = "@(#) mymc round.py 1.4 23/07/06 02:44:14\n"

def div_round_up(a, b):
return (a + b - 1) / b
return int((a + b - 1) / b)

def round_up(a, b):
return (a + b - 1) / b * b
return int((a + b - 1) / b * b)

def round_down(a, b):
return a / b * b
return int(a / b * b)


4 changes: 2 additions & 2 deletions verbuild.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
MYMC_VERSION_BUILD = r'''7'''
MYMC_VERSION_MAJOR = r'''2'''
MYMC_VERSION_BUILD = r'''0'''
MYMC_VERSION_MAJOR = r'''3'''