| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- #!/usr/bin/python
- from pydrk import serial
- from collections import namedtuple
- from dataclasses import dataclass
- from typing import Union
- import sys
- @dataclass
- class SetScale:
- scale: float
- @dataclass
- class Move:
- x: float
- y: float
- @dataclass
- class SetPos:
- x: float
- y: float
- @dataclass
- class ApplyView:
- x: float
- y: float
- w: float
- h: float
- @dataclass
- class Draw:
- vert_id: int
- vert_epoch: int
- vert_tag: str
- vert_buftype: int
- index_id: int
- index_epoch: int
- index_tag: str
- index_buftype: int
- tex: (int, int, str)
- num_elements: int
- Instr = Union[SetScale, Move, SetPos, ApplyView, Draw]
- def hex(dat):
- return " ".join(f"{b:02x}" for b in dat)
- def read_tag(cur):
- return serial.decode_str(cur)
- DrawCall = namedtuple("DrawCall", [
- "dc_id",
- "instrs",
- "dcs",
- "z_index",
- "debug_str"
- ])
- def read_dc(cur):
- dc_id = serial.read_u64(cur)
- instrs = serial.decode_arr(cur, read_instr)
- dcs = serial.decode_arr(cur, serial.read_u64)
- z_index = serial.read_u32(cur)
- debug_str = serial.decode_str(cur)
- return DrawCall(
- dc_id,
- instrs,
- dcs,
- z_index,
- debug_str
- )
- def read_instr(cur):
- enum = serial.read_u8(cur)
- match enum:
- case 0:
- scale = serial.read_f32(cur)
- return SetScale(scale)
- case 1:
- x = serial.read_f32(cur)
- y = serial.read_f32(cur)
- return Move(x, y)
- case 2:
- x = serial.read_f32(cur)
- y = serial.read_f32(cur)
- #print(f" set_pos x={x}, y={y}")
- return SetPos(x, y)
- case 3:
- x = serial.read_f32(cur)
- y = serial.read_f32(cur)
- w = serial.read_f32(cur)
- h = serial.read_f32(cur)
- #print(f" apply_view x={x}, y={y}, w={w}, h={h}")
- return ApplyView(x, y, w, h)
- case 4:
- vert_id = serial.read_u32(cur)
- vert_epoch = serial.read_u32(cur)
- vert_tag = serial.decode_opt(cur, read_tag)
- vert_buftype = serial.read_u8(cur)
- index_id = serial.read_u32(cur)
- index_epoch = serial.read_u32(cur)
- index_tag = serial.decode_opt(cur, read_tag)
- index_buftype = serial.read_u8(cur)
- def read_tex(cur):
- id = serial.read_u32(cur)
- epoch = serial.read_u32(cur)
- tag = serial.decode_opt(cur, read_tag)
- return (id, epoch, tag)
- tex = serial.decode_opt(cur, read_tex)
- num_elements = serial.read_i32(cur)
- return Draw(
- vert_id,
- vert_epoch,
- vert_tag,
- vert_buftype,
- index_id,
- index_epoch,
- index_tag,
- index_buftype,
- tex,
- num_elements
- )
- case _:
- raise NotImplementedError
- @dataclass
- class Vertex:
- x: float
- y: float
- r: float
- g: float
- b: float
- a: float
- u: float
- v: float
- @dataclass
- class PutDrawCall:
- epoch: int
- timest: int
- dcs: [DrawCall]
- stats: [int]
- @dataclass
- class PutTex:
- epoch: int
- tex: int
- tag: str
- stat: int
- @dataclass
- class PutVerts:
- epoch: int
- verts: [Vertex]
- buf: int
- tag: str
- buftype: int
- stat: int
- @dataclass
- class PutIdxs:
- epoch: int
- idxs: [int]
- buf: int
- tag: str
- buftype: int
- stat: int
- @dataclass
- class DelTex:
- epoch: int
- buf: int
- tag: str
- stat: int
- @dataclass
- class DelBuf:
- epoch: int
- buf: int
- tag: str
- buftype: int
- stat: int
- @dataclass
- class SetCurr:
- dc: int
- @dataclass
- class SetInstr:
- idx: int
- Section = Union[PutDrawCall, PutTex, PutVerts, PutIdxs, DelTex, DelBuf, SetCurr, SetInstr]
- def read_vert(cur):
- return Vertex(
- serial.read_f32(cur),
- serial.read_f32(cur),
- serial.read_f32(cur),
- serial.read_f32(cur),
- serial.read_f32(cur),
- serial.read_f32(cur),
- serial.read_f32(cur),
- serial.read_f32(cur),
- )
- def read_section(f):
- fpos = f.tell()
- buf = serial.decode_buf(f)
- if not buf:
- return None
- cur = serial.Cursor(buf)
- c = serial.read_u8(cur)
- #print(f"SECTION: {c} {len(buf)}B [{fpos}]")
- #print(hex(cur.by))
- match c:
- case 0:
- epoch = serial.read_u32(cur)
- timest = serial.read_u64(cur)
- dcs = serial.decode_arr(cur, read_dc)
- stats = []
- for _ in dcs:
- stat = serial.read_u8(cur)
- stats.append(stat)
- #print(f" stat={stat}")
- #print(f"put_dcs epoch={epoch}, timest={timest}, dcs={dcs}, stats={stats}")
- sect = PutDrawCall(epoch, timest, dcs, stats)
- case 1:
- epoch = serial.read_u32(cur)
- tex = serial.read_u32(cur)
- tag = serial.decode_opt(cur, read_tag)
- stat = serial.read_u8(cur)
- #print(f"put_tex epoch={epoch}, tex={tex}, tag='{tag}', stat={stat}")
- sect = PutTex(epoch, tex, tag, stat)
- case 2:
- epoch = serial.read_u32(cur)
- verts = serial.decode_arr(cur, read_vert)
- buf = serial.read_u32(cur)
- tag = serial.decode_opt(cur, read_tag)
- buftype = serial.read_u8(cur)
- stat = serial.read_u8(cur)
- #print(f"put_verts epoch={epoch}, buf={buf}, tag='{tag}', buftype={buftype}, stat={stat}")
- sect = PutVerts(epoch, verts, buf, tag, buftype, stat)
- case 3:
- epoch = serial.read_u32(cur)
- idxs = serial.decode_arr(cur, serial.read_u16)
- buf = serial.read_u32(cur)
- tag = serial.decode_opt(cur, read_tag)
- buftype = serial.read_u8(cur)
- stat = serial.read_u8(cur)
- #print(f"put_idxs epoch={epoch}, buf={buf}, tag='{tag}', buftype={buftype}, stat={stat}")
- sect = PutIdxs(epoch, idxs, buf, tag, buftype, stat)
- case 4:
- epoch = serial.read_u32(cur)
- buf = serial.read_u32(cur)
- tag = serial.decode_opt(cur, read_tag)
- stat = serial.read_u8(cur)
- #print(f"del_tex epoch={epoch}, buf={buf}, tag='{tag}', stat={stat}")
- sect = DelTex(epoch, buf, tag, stat)
- case 5:
- epoch = serial.read_u32(cur)
- buf = serial.read_u32(cur)
- tag = serial.decode_opt(cur, read_tag)
- buftype = serial.read_u8(cur)
- stat = serial.read_u8(cur)
- #print(f"del_buf epoch={epoch}, buf={buf}, tag='{tag}', buftype={buftype}, stat={stat}")
- sect = DelBuf(epoch, buf, tag, buftype, stat)
- case 6:
- dc = serial.read_u64(cur)
- #print(f"set_curr dc={dc}")
- sect = SetCurr(dc)
- case 7:
- idx = serial.read_u64(cur)
- #print(f"set_instr idx={idx}")
- sect = SetInstr(idx)
- case _:
- raise NotImplementedError
- # Crash out if we didn't fully consume the buffer
- if not cur.is_end():
- print(hex(cur.remain_data()))
- assert cur.is_end()
- return sect
- def read_trax(fname):
- f = open(fname, "rb")
- sections = []
- while True:
- if (sect := read_section(f)) is None:
- break
- sections.append(sect)
- return sections
- if __name__ == "__main__":
- if len(sys.argv) != 2:
- print("wrong args", file=sys.stderr)
- sys.exit(-1)
- fname = sys.argv[1]
- sections = read_trax(fname)
- for sect in sections:
- print(sect)
|