|
@@ -5,7 +5,7 @@
|
|
# This is free and unencumbered software released into the public domain.
|
|
# This is free and unencumbered software released into the public domain.
|
|
# See the file COPYING for more details, or visit <http://unlicense.org>.
|
|
# See the file COPYING for more details, or visit <http://unlicense.org>.
|
|
|
|
|
|
-import struct
|
|
|
|
|
|
+import struct, functools
|
|
|
|
|
|
from greaseweazle import error
|
|
from greaseweazle import error
|
|
from greaseweazle.flux import Flux
|
|
from greaseweazle.flux import Flux
|
|
@@ -31,10 +31,22 @@ class SCP:
|
|
def from_file(cls, dat):
|
|
def from_file(cls, dat):
|
|
|
|
|
|
header = struct.unpack("<3s9BI", dat[0:16])
|
|
header = struct.unpack("<3s9BI", dat[0:16])
|
|
- (sig, _, _, nr_revs, _, _, flags, _, _, _, _) = header
|
|
|
|
|
|
+ (sig, _, _, nr_revs, _, _, flags, _, single_sided, _, _) = header
|
|
error.check(sig == b"SCP", "SCP: Bad signature")
|
|
error.check(sig == b"SCP", "SCP: Bad signature")
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ # Some tools generate a short TLUT. We handle this by truncating the
|
|
|
|
+ # TLUT at the first Track Data Header.
|
|
trk_offs = struct.unpack("<168I", dat[16:0x2b0])
|
|
trk_offs = struct.unpack("<168I", dat[16:0x2b0])
|
|
|
|
+ for i in range(168):
|
|
|
|
+ try:
|
|
|
|
+ off = trk_offs[i]
|
|
|
|
+ except IndexError:
|
|
|
|
+ break
|
|
|
|
+ if off == 0 or off >= 0x2b0:
|
|
|
|
+ continue
|
|
|
|
+ off = off//4 - 4
|
|
|
|
+ error.check(off >= 0, "SCP: Bad Track Table")
|
|
|
|
+ trk_offs = trk_offs[:off]
|
|
|
|
|
|
scp = cls(0, 2)
|
|
scp = cls(0, 2)
|
|
scp.nr_revs = nr_revs
|
|
scp.nr_revs = nr_revs
|
|
@@ -56,6 +68,25 @@ class SCP:
|
|
|
|
|
|
scp.track_list.append((thdr, tdat))
|
|
scp.track_list.append((thdr, tdat))
|
|
|
|
|
|
|
|
+ # s[side] is True iff there are non-empty tracks on @side
|
|
|
|
+ s = []
|
|
|
|
+ for i in range(2):
|
|
|
|
+ s.append(functools.reduce(lambda x, y: x or (y[1] is not None),
|
|
|
|
+ scp.track_list[i::2], False))
|
|
|
|
+
|
|
|
|
+ # Some tools produce (or used to produce) single-sided images using
|
|
|
|
+ # consecutive entries in the TLUT. This needs fixing up.
|
|
|
|
+ if single_sided and functools.reduce(lambda x, y: x and y, s):
|
|
|
|
+ new_list = []
|
|
|
|
+ for t in scp.track_list[:84]:
|
|
|
|
+ if single_sided != 1: # Side 1
|
|
|
|
+ new_list.append((None, None))
|
|
|
|
+ new_list.append(t)
|
|
|
|
+ if single_sided == 1: # Side 0
|
|
|
|
+ new_list.append((None, None))
|
|
|
|
+ scp.track_list = new_list
|
|
|
|
+ print('SCP: Imported old single-sided image')
|
|
|
|
+
|
|
return scp
|
|
return scp
|
|
|
|
|
|
|
|
|