engine-psx/tools/buildprl/buildprl.py

91 lines
2.2 KiB
Python
Raw Normal View History

#!/bin/env python
import sys
import toml
from os.path import realpath, dirname, basename
from dataclasses import dataclass, field
from ctypes import c_ubyte, c_byte, c_short, c_ushort, c_int
from pprint import pp
c_short = c_short.__ctype_be__
c_ushort = c_ushort.__ctype_be__
c_int = c_int.__ctype_be__
def tofixed(value: float, scale: int) -> int:
return int(value * (1 << scale))
def tofixed12(value: float) -> int:
return tofixed(value, 12)
@dataclass
class ParallaxStrip:
u0: int = 0
v0: int = 0
width: int = 0
height: int = 0
bg_index: int = 0
single: bool = False
scrollx: float = 0
2024-10-25 00:49:22 -03:00
speedx: float = 0
y0: int = 0
def write_to(self, f):
f.write(c_ubyte(self.u0))
f.write(c_ubyte(self.v0))
f.write(c_ushort(self.width))
f.write(c_ushort(self.height))
f.write(c_ubyte(self.bg_index))
f.write(c_ubyte(int(self.single)))
f.write(c_int(tofixed12(self.scrollx)))
2024-10-25 00:49:22 -03:00
f.write(c_int(tofixed12(self.speedx)))
f.write(c_short(self.y0))
@dataclass
class Parallax:
strips: [ParallaxStrip] = field(default_factory=list)
def write(self, out_path):
with open(out_path, "wb") as f:
f.write(c_ubyte(len(self.strips)))
for s in self.strips:
s.write_to(f)
def parse(data) -> Parallax:
p = Parallax()
for name, strip_data in data.items():
strip = ParallaxStrip()
strip.single = strip_data.get("single", False)
strip.scrollx = strip_data.get("scrollx", 0)
2024-10-25 00:49:22 -03:00
strip.speedx = strip_data.get("speedx", 0)
strip.y0 = strip_data.get("y0")
strip.width = strip_data.get("width")
strip.height = strip_data.get("height")
v0 = strip_data.get("v0")
strip.bg_index = int(v0 / 256)
strip.u0 = strip_data.get("u0")
strip.v0 = v0 % 256
p.strips.append(strip)
return p
def main():
toml_path = realpath(sys.argv[1])
data = toml.load(toml_path)
parallax = parse(data)
# /assets/levels/R2/parallax.toml -> /assets/levels/R2/PRL.PRL
toml_dir = dirname(toml_path)
out_path = toml_dir + "/PRL.PRL"
parallax.write(out_path)
if __name__ == "__main__":
main()