summaryrefslogtreecommitdiff
path: root/lib9p_util/nut_gen/__init__.py
blob: dd0a8add48d7c038aeafe8bf75dbf6023d16f2eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# lib9p_util/nut_gen/__init__.py - Generate NUT file headers
#
# Copyright (C) 2025  Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later

import sys
import typing

from . import app, nut

# pylint: disable=unused-variable
__all__ = ["main"]


def main() -> None:
    outfile = sys.argv[1]
    with open(outfile, "w", encoding="utf-8") as fh:
        fh.write(
            f"/* {outfile} - Generated by `{' '.join(sys.argv)}`.  DO NOT EDIT!  */\n"
        )

        fh.write("\n")
        fh.write(f"#define NUT_FB_W {app.fb_w}\n")
        fh.write(f"#define NUT_FB_H {app.fb_h}\n")

        fh.write("\n")
        buf = bytearray()
        app.append_intro(buf)
        fh.write(f"#define NUT_FILE_INTRO_LEN {len(buf)}\n")
        fh.write("#define NUT_FILE_INTRO ")
        for i, b in enumerate(buf):
            if i > 0:
                fh.write(", ")
            if i % 8 == 0:
                fh.write("\\\n\t")

            fh.write(f"0x{b:02x}")
        fh.write("\n")

        fh.write("\n")
        state = app.State()
        buf0 = bytearray()
        state.append_frame_intro(buf0, 0)
        buf1 = bytearray()
        state.append_frame_intro(buf1, (1 << 64) - 1)
        assert len(buf0) == len(buf1)
        fh.write(f"#define NUT_FRAME_INTRO_LEN {len(buf0)}\n")
        fh.write("#define NUT_FRAME_INTRO(prev_len, time_ns) ")
        runs = [
            (10, "NUT_VU10(time_ns)"),
            (2, "NUT_VU2((prev_len)/16)"),
            (4, "NUT_CHECKSUM"),
            (10, "NUT_VU10(time_ns)"),
            (4, "NUT_CHECKSUM"),
        ]
        run_idx = 0
        run_var = ""
        run_len = 0
        csum_beg = len(nut.StartCode.syncpoint.value) + 1
        extra: dict[str, typing.Any] = {}
        for i, b0 in enumerate(buf0):
            b1 = buf1[i]

            if run_len > 0:
                assert b0 != b1
                run_len -= 1
                continue

            if i > 0:
                fh.write(", ")
            if i % 8 == 0:
                fh.write("\\\n\t")

            if b0 == b1:
                fh.write(f"0x{b0:02x}")
            else:
                run_len, run_expr = runs[run_idx]
                if run_expr == "NUT_CHECKSUM":
                    n = len(extra) // 2
                    extra[f"NUT_FRAME_INTRO_CSUM{n}_BEG"] = csum_beg
                    extra[f"NUT_FRAME_INTRO_CSUM{n}_END"] = i
                    csum_beg = i + 4
                pseudo_expr = ""
                for j in range(run_len):
                    if j > 0:
                        pseudo_expr += ", "
                    if (i + j) % 8 == 0:
                        pseudo_expr += "\\\n\t"
                    pseudo_expr += "0x__"
                if len(run_expr) + 4 < len(pseudo_expr):
                    run_expr += "/*" + pseudo_expr[len(run_expr) + 2 : -2] + "*/"
                fh.write(run_expr)
                run_idx += 1
                run_len -= 1
        fh.write("\n")
        for k, v in extra.items():
            fh.write(f"#define {k} {v}\n")

        fh.write("\n")
        fh.write("#define NUT_CRC32_TABLE ")
        for i, v in enumerate(nut.crc32_table(4)):
            if i > 0:
                fh.write(", ")
            if i % 4 == 0:
                fh.write("\\\n\t")

            fh.write(f"0x{v:08x}")
        fh.write("\n")