Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit b3cbc3b

Browse files
committed
PyCod 0.2.1
1 parent 575871e commit b3cbc3b

6 files changed

Lines changed: 284 additions & 124 deletions

File tree

pycod/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
# <pep8 compliant>
2+
13
from .xmodel import Model
24
from .xanim import Anim
35
from .sanim import SiegeAnim
46

5-
version = (0, 1, 5) # Version specifier for PyCoD
7+
version = (0, 2, 1) # Version specifier for PyCoD

pycod/_lz4.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
try:
22
# Try to import the python-lz4 package
3-
import lz4
3+
import lz4.block
44

5-
except:
5+
except ImportError:
66
# If python-lz4 isn't present, fallback to using pure python
7-
import sys
87
from io import BytesIO
98

109
try:
1110
from six import byte2int
1211
from six.moves import xrange
13-
except:
12+
except ImportError:
1413
xrange = range
1514

16-
def byte2int(bytes):
17-
return int(bytes[0])
15+
# If we're running Python 3 or newer, we must
16+
# define byte2int differently than with Python 2
17+
import sys
18+
if sys.version_info[0] >= 3:
19+
import operator
20+
byte2int = operator.itemgetter(0)
21+
else:
22+
def byte2int(_bytes):
23+
return ord(_bytes[0])
1824

1925
class CorruptError(Exception):
2026
pass
@@ -123,7 +129,10 @@ def compress(data):
123129
else:
124130
# Use python-lz4 if present
125131
__support_mode__ = 'python-lz4'
126-
compress = lz4.block.compress
132+
133+
def compress(data):
134+
return lz4.block.compress(data, store_size=False)
135+
127136
uncompress = lz4.block.decompress
128137

129138
support_info = 'LZ4: Using %s' % __support_mode__

pycod/sanim.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
1+
# <pep8 compliant>
2+
13
import json
24
import zipfile
35
import struct
46

57
'''
6-
-------------------
8+
---------------------------
79
---< SIEGE_ANIM_SOURCE >---
8-
-------------------
10+
---------------------------
911
'''
1012

13+
# buffer() is required for file.writestr in Python 2.x but
14+
# is no longer required (and doesn't exist) in Python 3.x
15+
try:
16+
buffer
17+
except NameError:
18+
def buffer(data):
19+
return data
20+
1121

1222
class Frame(object):
1323
__slots__ = ('index', 'position', 'rotation')

pycod/xanim.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
# <pep8 compliant>
2+
13
from time import strftime
24
import os
35

4-
from .xbin import XBinIO
6+
from .xbin import XBinIO, validate_version
57

68
# Can be int or float
79
# Changes the internal type for frames indices
@@ -75,6 +77,7 @@ def WriteFile_Raw(self, filepath):
7577
The following are just accessors for various properties of the notetrack
7678
file
7779
"""
80+
7881
# Literally the first keyed frame in the XANIM_EXPORT file
7982
def FirstFrame(self):
8083
return self.first_frame
@@ -95,12 +98,12 @@ def NumKeys(self):
9598
'''
9699

97100

98-
def __clamp_float__(value, clamp=(-1.0, 1.0)):
99-
return max(min(value, clamp[1]), clamp[0])
101+
def __clamp_float__(value, clamp_range=(-1.0, 1.0)):
102+
return max(min(value, clamp_range[1]), clamp_range[0])
100103

101104

102-
def __clamp_multi__(value, clamp=(-1.0, 1.0)):
103-
return tuple([max(min(v, clamp[1]), clamp[0]) for v in value])
105+
def __clamp_multi__(value, clamp_range=(-1.0, 1.0)):
106+
return tuple([max(min(v, clamp_range[1]), clamp_range[0]) for v in value])
104107

105108

106109
def __clean_float2str__(value):
@@ -110,7 +113,7 @@ def __clean_float2str__(value):
110113
class PartInfo(object):
111114
'''In the context of an XANIM_EXPORT file, a 'part' is essentially a
112115
bone'''
113-
__slots__ = ('name')
116+
__slots__ = ('name',)
114117

115118
def __init__(self, name):
116119
self.name = name
@@ -170,7 +173,9 @@ def __load_part__(self, file, part_count):
170173
part = self.parts[part_index]
171174
state = 2
172175
elif state == 2 and line_split[0] == "SCALE":
173-
# Scales are not required and not used anymore, so we share state 2
176+
# Scales are now deprecated and, in some cases
177+
# aren't actually required; so we reuse state 2
178+
# to do soft check for the SCALE block
174179
scale = (float(line_split[1]),
175180
float(line_split[2]),
176181
float(line_split[3]))
@@ -201,17 +206,16 @@ def _load_parts_(self, file, part_count):
201206
self.parts = [FramePart()] * part_count
202207

203208
lines_read = 0
204-
for part in range(part_count):
209+
for _ in range(part_count):
205210
lines_read += self.__load_part__(file, part_count)
206211
return lines_read
207212

208213

209214
class Anim(XBinIO, object):
210-
__slots__ = ('version', 'framerate', 'parts', 'frames', 'notes')
215+
__slots__ = ('framerate', 'parts', 'frames', 'notes')
211216

212217
def __init__(self):
213-
super(Anim, self).__init__()
214-
self.version = None
218+
super(XBinIO, self).__init__()
215219
self.framerate = None
216220
self.parts = []
217221
self.frames = []
@@ -278,6 +282,13 @@ def __load_frames__(self, file):
278282
elif line_split[0] == "FRAME":
279283
frame_number = FRAME_TYPE(line_split[1])
280284

285+
# Don't enable this until anims that don't start on frame 0 are
286+
# sorted out
287+
# if frame_number >= frame_count:
288+
# fmt = ("frame_count does not index frame_number -- "
289+
# "%d not in [0, %d)")
290+
# raise ValueError(fmt % (frame_number, frame_count))
291+
281292
lines_read += self.__load_frame__(file,
282293
frame_index, frame_number)
283294
frame_index += 1
@@ -376,16 +387,15 @@ def WriteFile_Raw(self, path, version=3,
376387
if last_frame - first_frame != len(self.frames):
377388
fmt = ("The keyed frame count and number of frames do not match"
378389
" (%d != %d)")
379-
err = ( fmt % (last_frame - first_frame, len(self.frames)))
390+
err = (fmt % (last_frame - first_frame, len(self.frames)))
380391
raise ValueError(err)
381392

382393
file = open(path, "w")
383394
file.write(header_message)
384395
file.write("// Export time: %s\n\n" % strftime("%a %b %d %H:%M:%S %Y"))
385396

386397
# If there is no current version, fallback to the argument
387-
if self.version is None:
388-
self.version = version
398+
version = validate_version(self, version)
389399

390400
file.write("ANIMATION\n")
391401
file.write("VERSION %d\n\n" % self.version)
@@ -401,7 +411,7 @@ def WriteFile_Raw(self, path, version=3,
401411
file.write("FRAME %s\n" % __clean_float2str__(frame.frame))
402412
for part_index, part in enumerate(frame.parts):
403413
file.write("PART %d\n" % part_index)
404-
# Investigate precision options?
414+
# TODO: Investigate precision options?
405415
offset = (part.offset[0], part.offset[1], part.offset[2])
406416
scale = (part.scale[0], part.scale[1], part.scale[2])
407417
file.write("OFFSET %f %f %f\n" % offset)
@@ -474,8 +484,7 @@ def LoadFile_Bin(self, path, is_compressed=True, dump=False):
474484

475485
def WriteFile_Bin(self, path, version=3, header_message=""):
476486
# If there is no current version, fallback to the argument
477-
if self.version is None:
478-
self.version = version
487+
version = validate_version(self, version)
479488
return self.__xbin_writefile_anim_internal__(path,
480489
self.version,
481490
header_message)

0 commit comments

Comments
 (0)