Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """This module provides a parser and writer for BZ2 .stb files and their plain text representations."""
- VERSION = 1.0
- import re
- from ctypes import Structure, c_char, c_uint32, c_uint16
- RE_TEXT_SPRITE = re.compile(r"^\s*\"(.*)\"\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+0x(\w+)")
- RE_TEXT_FILE = re.compile(r"^\s*\@include \"(.+)\"")
- ENCODING = "ascii"
- class Sprite(Structure):
- _fields_ = [
- ("name", c_char*32), # Name used in ODF to refer to sprite
- ("file", c_char*8), # Texture image game slices the sprite from
- ("u", c_uint16), # x offset of sprite slice
- ("v", c_uint16), # y offset of sprite slice
- ("w", c_uint16), # Width of sprite slice
- ("h", c_uint16), # Height of sprite slice
- ("tw", c_uint16), # Texture width
- ("th", c_uint16), # Texture height
- ("flags", c_uint32)
- ]
- def decoded(self):
- return "\"%s\"\t\"%s\"\t%d\t%d\t%d\t%d\t%d\t%d\t0x%x" % (
- self.name.decode(encoding=ENCODING),
- self.file.decode(encoding=ENCODING),
- self.u, self.v,
- self.w, self.h,
- self.tw, self.th,
- self.flags
- )
- class STB:
- def __init__(self, from_path=None):
- self.sprites = []
- if from_path:
- if from_path[-4::].casefold() == ".stb":
- self.read(from_path)
- else:
- self.read_text(from_path)
- def __bytes__(self):
- return b"".join(self.sprites)
- def read_text(self, path):
- with open(path, "r") as f:
- for line in f:
- match = RE_TEXT_FILE.match(line)
- if match:
- # TODO: Check name against bz2-esque context of file locality? (files discoverable in a bzone.cfg context)
- self.read_text(match.group(1)) # Will raise FileNotFoundError if not found.
- continue
- match = RE_TEXT_SPRITE.match(line)
- if match:
- sprite = Sprite()
- sprite.name = match.group(1).encode(encoding=ENCODING)
- sprite.file = match.group(2).encode(encoding=ENCODING)
- sprite.u = int(match.group(3))
- sprite.v = int(match.group(4))
- sprite.w = int(match.group(5))
- sprite.h = int(match.group(6))
- sprite.tw = int(match.group(7))
- sprite.th = int(match.group(8))
- sprite.flags = int(match.group(9), 16)
- self.sprites += [sprite]
- continue
- def write_text(self, path):
- with open(path, "w") as f:
- f.write("sprite_tabel\n\n")
- for sprite in self.sprites:
- f.write(sprite.decoded() + "\n")
- def read(self, path):
- with open(path, "rb") as f:
- while True:
- sprite = Sprite()
- if not f.readinto(sprite):
- break
- self.sprites += [sprite]
- def write(self, path):
- with open(path, "wb") as f:
- f.write(bytes(self))
- def show(self):
- print("sprite_tabel\n")
- for sprite in self.sprites:
- print(sprite.decoded())
- if __name__ == "__main__":
- import sys, os
- for sprite_file in sys.argv[1::]:
- if sprite_file[-4::].casefold() == ".stb":
- # Convert STB file to humanly readable text file
- output_file = sprite_file + ".txt"
- if not os.path.exists(output_file):
- STB(sprite_file).write_text(output_file)
- else:
- # Convert sprite text file to STB file
- output_file = sprite_file + ".stb"
- if not os.path.exists(output_file):
- STB(sprite_file).write(output_file)
Add Comment
Please, Sign In to add comment