traxator.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. #!/usr/bin/python
  2. from pydrk import serial
  3. from collections import namedtuple
  4. from dataclasses import dataclass
  5. from typing import Union
  6. @dataclass
  7. class SetScale:
  8. scale: float
  9. @dataclass
  10. class Move:
  11. x: float
  12. y: float
  13. @dataclass
  14. class SetPos:
  15. x: float
  16. y: float
  17. @dataclass
  18. class ApplyView:
  19. x: float
  20. y: float
  21. w: float
  22. h: float
  23. @dataclass
  24. class Draw:
  25. vert_id: int
  26. vert_epoch: int
  27. vert_tag: str
  28. vert_buftype: int
  29. index_id: int
  30. index_epoch: int
  31. index_tag: str
  32. index_buftype: int
  33. tex: (int, int, str)
  34. num_elements: int
  35. Instr = Union[SetScale, Move, SetPos, ApplyView, Draw]
  36. def hex(dat):
  37. return " ".join(f"{b:02x}" for b in dat)
  38. def read_tag(cur):
  39. return serial.decode_str(cur)
  40. DrawCall = namedtuple("DrawCall", [
  41. "dc_id",
  42. "instrs",
  43. "dcs",
  44. "z_index",
  45. "debug_str"
  46. ])
  47. def read_dc(cur):
  48. dc_id = serial.read_u64(cur)
  49. instrs = serial.decode_arr(cur, read_instr)
  50. dcs = serial.decode_arr(cur, serial.read_u64)
  51. z_index = serial.read_u32(cur)
  52. debug_str = serial.decode_str(cur)
  53. return DrawCall(
  54. dc_id,
  55. instrs,
  56. dcs,
  57. z_index,
  58. debug_str
  59. )
  60. def read_instr(cur):
  61. enum = serial.read_u8(cur)
  62. match enum:
  63. case 0:
  64. scale = serial.read_f32(cur)
  65. return SetScale(scale)
  66. case 1:
  67. x = serial.read_f32(cur)
  68. y = serial.read_f32(cur)
  69. return Move(x, y)
  70. case 2:
  71. x = serial.read_f32(cur)
  72. y = serial.read_f32(cur)
  73. #print(f" set_pos x={x}, y={y}")
  74. return SetPos(x, y)
  75. case 3:
  76. x = serial.read_f32(cur)
  77. y = serial.read_f32(cur)
  78. w = serial.read_f32(cur)
  79. h = serial.read_f32(cur)
  80. #print(f" apply_view x={x}, y={y}, w={w}, h={h}")
  81. return ApplyView(x, y, w, h)
  82. case 4:
  83. vert_id = serial.read_u32(cur)
  84. vert_epoch = serial.read_u32(cur)
  85. vert_tag = serial.decode_opt(cur, read_tag)
  86. vert_buftype = serial.read_u8(cur)
  87. index_id = serial.read_u32(cur)
  88. index_epoch = serial.read_u32(cur)
  89. index_tag = serial.decode_opt(cur, read_tag)
  90. index_buftype = serial.read_u8(cur)
  91. def read_tex(cur):
  92. id = serial.read_u32(cur)
  93. epoch = serial.read_u32(cur)
  94. tag = serial.decode_opt(cur, read_tag)
  95. return (id, epoch, tag)
  96. tex = serial.decode_opt(cur, read_tex)
  97. num_elements = serial.read_i32(cur)
  98. return Draw(
  99. vert_id,
  100. vert_epoch,
  101. vert_tag,
  102. vert_buftype,
  103. index_id,
  104. index_epoch,
  105. index_tag,
  106. index_buftype,
  107. tex,
  108. num_elements
  109. )
  110. case _:
  111. raise NotImplementedError
  112. @dataclass
  113. class Vertex:
  114. x: float
  115. y: float
  116. r: float
  117. g: float
  118. b: float
  119. a: float
  120. u: float
  121. v: float
  122. @dataclass
  123. class PutDrawCall:
  124. epoch: int
  125. timest: int
  126. dcs: [DrawCall]
  127. stats: [int]
  128. @dataclass
  129. class PutTex:
  130. epoch: int
  131. tex: int
  132. tag: str
  133. stat: int
  134. @dataclass
  135. class PutVerts:
  136. epoch: int
  137. verts: [Vertex]
  138. buf: int
  139. tag: str
  140. buftype: int
  141. stat: int
  142. @dataclass
  143. class PutIdxs:
  144. epoch: int
  145. idxs: [int]
  146. buf: int
  147. tag: str
  148. buftype: int
  149. stat: int
  150. @dataclass
  151. class DelTex:
  152. epoch: int
  153. buf: int
  154. tag: str
  155. stat: int
  156. @dataclass
  157. class DelBuf:
  158. epoch: int
  159. buf: int
  160. tag: str
  161. buftype: int
  162. stat: int
  163. @dataclass
  164. class SetCurr:
  165. dc: int
  166. @dataclass
  167. class SetInstr:
  168. idx: int
  169. Section = Union[PutDrawCall, PutTex, PutVerts, PutIdxs, DelTex, DelBuf, SetCurr, SetInstr]
  170. def read_vert(cur):
  171. return Vertex(
  172. serial.read_f32(cur),
  173. serial.read_f32(cur),
  174. serial.read_f32(cur),
  175. serial.read_f32(cur),
  176. serial.read_f32(cur),
  177. serial.read_f32(cur),
  178. serial.read_f32(cur),
  179. serial.read_f32(cur),
  180. )
  181. def read_section(f):
  182. fpos = f.tell()
  183. buf = serial.decode_buf(f)
  184. if not buf:
  185. return None
  186. cur = serial.Cursor(buf)
  187. c = serial.read_u8(cur)
  188. #print(f"SECTION: {c} {len(buf)}B [{fpos}]")
  189. #print(hex(cur.by))
  190. match c:
  191. case 0:
  192. epoch = serial.read_u32(cur)
  193. timest = serial.read_u64(cur)
  194. dcs = serial.decode_arr(cur, read_dc)
  195. stats = []
  196. for _ in dcs:
  197. stat = serial.read_u8(cur)
  198. stats.append(stat)
  199. #print(f" stat={stat}")
  200. #print(f"put_dcs epoch={epoch}, timest={timest}, dcs={dcs}, stats={stats}")
  201. sect = PutDrawCall(epoch, timest, dcs, stats)
  202. case 1:
  203. epoch = serial.read_u32(cur)
  204. tex = serial.read_u32(cur)
  205. tag = serial.decode_opt(cur, read_tag)
  206. stat = serial.read_u8(cur)
  207. #print(f"put_tex epoch={epoch}, tex={tex}, tag='{tag}', stat={stat}")
  208. sect = PutTex(epoch, tex, tag, stat)
  209. case 2:
  210. epoch = serial.read_u32(cur)
  211. verts = serial.decode_arr(cur, read_vert)
  212. buf = serial.read_u32(cur)
  213. tag = serial.decode_opt(cur, read_tag)
  214. buftype = serial.read_u8(cur)
  215. stat = serial.read_u8(cur)
  216. #print(f"put_verts epoch={epoch}, buf={buf}, tag='{tag}', buftype={buftype}, stat={stat}")
  217. sect = PutVerts(epoch, verts, buf, tag, buftype, stat)
  218. case 3:
  219. epoch = serial.read_u32(cur)
  220. idxs = serial.decode_arr(cur, serial.read_u16)
  221. buf = serial.read_u32(cur)
  222. tag = serial.decode_opt(cur, read_tag)
  223. buftype = serial.read_u8(cur)
  224. stat = serial.read_u8(cur)
  225. #print(f"put_idxs epoch={epoch}, buf={buf}, tag='{tag}', buftype={buftype}, stat={stat}")
  226. sect = PutIdxs(epoch, idxs, buf, tag, buftype, stat)
  227. case 4:
  228. epoch = serial.read_u32(cur)
  229. buf = serial.read_u32(cur)
  230. tag = serial.decode_opt(cur, read_tag)
  231. stat = serial.read_u8(cur)
  232. #print(f"del_tex epoch={epoch}, buf={buf}, tag='{tag}', stat={stat}")
  233. sect = DelTex(epoch, buf, tag, stat)
  234. case 5:
  235. epoch = serial.read_u32(cur)
  236. buf = serial.read_u32(cur)
  237. tag = serial.decode_opt(cur, read_tag)
  238. buftype = serial.read_u8(cur)
  239. stat = serial.read_u8(cur)
  240. #print(f"del_buf epoch={epoch}, buf={buf}, tag='{tag}', buftype={buftype}, stat={stat}")
  241. sect = DelBuf(epoch, buf, tag, buftype, stat)
  242. case 6:
  243. dc = serial.read_u64(cur)
  244. #print(f"set_curr dc={dc}")
  245. sect = SetCurr(dc)
  246. case 7:
  247. idx = serial.read_u64(cur)
  248. #print(f"set_instr idx={idx}")
  249. sect = SetInstr(idx)
  250. case _:
  251. raise NotImplementedError
  252. # Crash out if we didn't fully consume the buffer
  253. if not cur.is_end():
  254. print(hex(cur.remain_data()))
  255. assert cur.is_end()
  256. return sect
  257. def read_trax():
  258. f = open("trax.dat", "rb")
  259. sections = []
  260. while True:
  261. if (sect := read_section(f)) is None:
  262. break
  263. sections.append(sect)
  264. return sections
  265. if __name__ == "__main__":
  266. sections = read_trax()
  267. for sect in sections:
  268. print(sect)