pyffi.formats.kfm — NetImmerse/Gamebryo Keyframe Motion (.kfm)

Last Built: Mar 06, 2020

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.

get_global_display()[source]

Display the KFM file name.

inspect(stream)[source]

Quick heuristic check if stream contains KFM data, by looking at the first 64 bytes. Sets version and reads header string.

Parameters

stream (file) – The stream to inspect.

read(stream)[source]

Read a kfm file.

Parameters

stream (file) – The stream from which to read.

write(stream)[source]

Write a kfm file.

Parameters

stream (file) – The stream to which to write.

class FilePath(**kwargs)[source]

Bases: pyffi.object_models.common.SizedString

get_hash(data=None)[source]

Return a hash value for this value. For file paths, the hash value is case insensitive.

Returns

An immutable object that can be used as a hash.

class HeaderString(**kwargs)[source]

Bases: pyffi.object_models.xml.basic.BasicBase

The kfm header string.

get_detail_display()[source]

Return an object that can be used to display the instance.

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.

get_value()[source]

Return object value.

read(stream, data)[source]

Read header string from stream and check it.

Parameters
set_value(value)[source]

Set object value.

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'
write(stream, data)[source]

Write the header string to stream.

Parameters
  • stream (file) – The stream to write to.

  • data (Data) – The fileformat data to use

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.

set_value(value)

Set string to C{value}.

Parameters

value (str) – The value to assign.

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'

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