pyffi.formats.kfm
— NetImmerse/Gamebryo Keyframe Motion (.kfm)¶
Implementation¶
-
class
pyffi.formats.kfm.
KfmFormat
[source]¶ Bases:
pyffi.object_models.xml.FileFormat
This class implements the kfm file format.
-
class
Data
(version=33685515)[source]¶ Bases:
pyffi.object_models.Data
A class to contain the actual kfm data.
-
get_global_child_nodes
(edge_filter=(True, True))[source]¶ Generator which yields all children of this item in the global view, of given edge type (default is edges of type 0).
Override this method.
- Returns
Generator for global node children.
-
-
class
HeaderString
(**kwargs)[source]¶ Bases:
pyffi.object_models.xml.basic.BasicBase
The kfm header string.
-
get_hash
(data=None)[source]¶ Return a hash value for this value.
- Returns
An immutable object that can be used as a hash.
-
get_size
(data=None)[source]¶ Return number of bytes the header string occupies in a file.
- Returns
Number of bytes.
-
read
(stream, data)[source]¶ Read header string from stream and check it.
- Parameters
stream (file) – The stream to read from.
data (pyffi.formats.kfm.KfmFormat.Data) – The KfmFormat.Data()
-
static
version_string
(version)[source]¶ Transforms version number into a version string.
- Parameters
version (int) – The version number.
- Returns
A version string.
>>> KfmFormat.HeaderString.version_string(0x0202000b) ';Gamebryo KFM File Version 2.2.0.0b' >>> KfmFormat.HeaderString.version_string(0x01024b00) ';Gamebryo KFM File Version 1.2.4b'
-
-
class
SizedString
(**kwargs)¶ Bases:
pyffi.object_models.xml.basic.BasicBase
,pyffi.object_models.editable.EditableLineEdit
Basic type for strings. The type starts with an unsigned int which describes the length of the string.
>>> from tempfile import TemporaryFile >>> f = TemporaryFile() >>> from pyffi.object_models import FileFormat >>> data = FileFormat.Data() >>> s = SizedString() >>> if f.write('\x07\x00\x00\x00abcdefg'.encode("ascii")): pass # ignore result for py3k >>> if f.seek(0): pass # ignore result for py3k >>> s.read(f, data) >>> str(s) 'abcdefg' >>> if f.seek(0): pass # ignore result for py3k >>> s.set_value('Hi There') >>> s.write(f, data) >>> if f.seek(0): pass # ignore result for py3k >>> m = SizedString() >>> m.read(f, data) >>> str(m) 'Hi There'
-
get_hash
(data=None)¶ Return a hash value for this string.
- Returns
An immutable object that can be used as a hash.
-
get_size
(data=None)¶ Return number of bytes this type occupies in a file.
- Returns
Number of bytes.
-
get_value
()¶ Return the string.
- Returns
The stored string.
-
read
(stream, data)¶ Read string from stream.
- Parameters
stream (file) – The stream to read from.
-
write
(stream, data)¶ Write string to stream.
- Parameters
stream (file) – The stream to write to.
-
-
TextString
¶ alias of
pyffi.object_models.common.UndecodedData
-
byte
¶ alias of
pyffi.object_models.common.UByte
-
char
¶ alias of
pyffi.object_models.common.Char
-
float
¶ alias of
pyffi.object_models.common.Float
-
int
¶ alias of
pyffi.object_models.common.Int
-
short
¶ alias of
pyffi.object_models.common.Short
-
uint
¶ alias of
pyffi.object_models.common.UInt
-
ushort
¶ alias of
pyffi.object_models.common.UShort
-
static
version_number
(version_str)[source]¶ Converts version string into an integer.
- Parameters
version_str (str) – The version string.
- Returns
A version integer.
>>> hex(KfmFormat.version_number('1.0')) '0x1000000' >>> hex(KfmFormat.version_number('1.2.4b')) '0x1024b00' >>> hex(KfmFormat.version_number('2.2.0.0b')) '0x202000b'
-
class
Regression tests¶
Read a KFM file¶
>>> # read kfm file
>>> from os.path import dirname
>>> dirpath = __file__
>>> for i in range(4): #recurse up to root repo dir
... dirpath = dirname(dirpath)
>>> repo_root = dirpath
>>> files_dir = os.path.join(repo_root, 'tests', 'spells', 'kfm', 'files')
>>> file = os.path.join(files_dir, 'test.kfm')
>>> stream = open(file, 'rb')
>>> data = KfmFormat.Data()
>>> data.inspect(stream)
>>> data.read(stream)
>>> stream.close()
>>> print(data.nif_file_name.decode("ascii"))
Test.nif
>>> # get all animation file names
>>> for anim in data.animations:
... print(anim.kf_file_name.decode("ascii"))
Test_MD_Idle.kf
Test_MD_Run.kf
Test_MD_Walk.kf
Test_MD_Die.kf
Parse all KFM files in a directory tree¶
>>> for stream, data in KfmFormat.walkData(files_dir):
... try:
... # the replace call makes the doctest also pass on windows
... os_path = stream.name
... split = (os_path.split(os.sep))[-5:]
... rejoin = os.path.join(*split).replace("\\", "/")
... print("reading %s" % rejoin)
... except Exception:
... print(
... "Warning: read failed due corrupt file,"
... " corrupt format description, or bug.")
reading tests/spells/kfm/files/invalid.kfm
reading tests/spells/kfm/files/test.kfm
Create a KFM model from scratch and write to file¶
>>> data = KfmFormat.Data()
>>> data.nif_file_name = "Test.nif"
>>> data.num_animations = 4
>>> data.animations.update_size()
>>> data.animations[0].kf_file_name = "Test_MD_Idle.kf"
>>> data.animations[1].kf_file_name = "Test_MD_Run.kf"
>>> data.animations[2].kf_file_name = "Test_MD_Walk.kf"
>>> data.animations[3].kf_file_name = "Test_MD_Die.kf"
>>> from tempfile import TemporaryFile
>>> stream = TemporaryFile()
>>> data.write(stream)
>>> stream.close()
Get list of versions and games¶
>>> for vnum in sorted(KfmFormat.versions.values()):
... print('0x%08X' % vnum)
0x01000000
0x01024B00
0x0200000B
0x0201000B
0x0202000B
0x0202001B
>>> for game, versions in sorted(KfmFormat.games.items(),
... key=lambda x: x[0]):
... print("%s " % game + " ".join('0x%08X' % vnum for vnum in versions))
Civilization IV 0x01000000 0x01024B00 0x0200000B
Dragonica 0x0202001B
Emerge 0x0201000B 0x0202000B
Loki 0x01024B00
Megami Tensei: Imagine 0x0201000B
Oblivion 0x01024B00
Prison Tycoon 0x01024B00
Pro Cycling Manager 0x01024B00
Red Ocean 0x01024B00
Sid Meier's Railroads 0x0200000B
The Guild 2 0x01024B00