traxator.py 7.5 KB

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