mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-28 00:53:45 +08:00
a82935f326
Integrate onroad views, configurable widgets, local settings, steering-profile contracts, Bluetooth and Android Auto with their device and runtime services. Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> Co-authored-by: Daniel Koepping <elkoled@gmail.com> Co-authored-by: Danny <dannyirwin31@yahoo.com> Co-authored-by: DimitriChrysafis <Dimitri.chrysafis@gmail.com> Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com> Co-authored-by: Harald Schäfer <harald.the.engineer@gmail.com> Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu> Co-authored-by: Shane Smiskol <shane@smiskol.com> Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com> Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com> Co-authored-by: stef <19478336+stefpi@users.noreply.github.com> Co-authored-by: whoisdomi <dcantu83@gmail.com> Co-authored-by: Intelli <contact@intelli.software> Co-authored-by: pharmacomaniac <blittle65@gmail.com> Co-authored-by: prabhaavp <prabhaav@msu.edu>
97 lines
4.3 KiB
Python
97 lines
4.3 KiB
Python
"""Native, inert capture of the frozen large Device Settings viewport."""
|
|
|
|
import argparse
|
|
from dataclasses import asdict
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pyray as rl
|
|
import raylib
|
|
|
|
from openpilot.starpilot.ui.device import DeviceView
|
|
from openpilot.starpilot.ui.device_state import DeviceState
|
|
from openpilot.starpilot.ui.presentation import BitmapFonts, Profile
|
|
from openpilot.starpilot.ui.settings import SettingsView
|
|
from openpilot.starpilot.ui.settings_state import Destination, SettingsState
|
|
|
|
|
|
def digest(path: Path) -> str:
|
|
return hashlib.sha256(path.read_bytes()).hexdigest()
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--font-directory", type=Path, required=True)
|
|
parser.add_argument("--asset-directory", type=Path, required=True)
|
|
parser.add_argument("--output", type=Path, required=True)
|
|
args = parser.parse_args()
|
|
if args.output.exists():
|
|
raise ValueError("Refusing to overwrite Device evidence")
|
|
args.output.mkdir(parents=True)
|
|
width, height = Profile.LARGE.size
|
|
rl.set_config_flags(rl.ConfigFlags.FLAG_MSAA_4X_HINT | rl.ConfigFlags.FLAG_WINDOW_HIGHDPI | rl.ConfigFlags.FLAG_WINDOW_HIDDEN)
|
|
rl.init_window(960, 480, "Development preview — Device panel")
|
|
if not rl.is_window_ready():
|
|
raise RuntimeError("Unable to create native Device graphics context")
|
|
target = rl.load_render_texture(width, height)
|
|
try:
|
|
if not target.id or not target.texture.id:
|
|
raise RuntimeError("Unable to create Device framebuffer")
|
|
with BitmapFonts(Profile.LARGE, args.font_directory) as fonts:
|
|
settings = SettingsView(fonts, args.asset_directory)
|
|
try:
|
|
device = DeviceView(fonts)
|
|
state = DeviceState()
|
|
for _ in range(18):
|
|
rl.begin_texture_mode(target)
|
|
try:
|
|
rl.clear_background(rl.BLACK)
|
|
device.render(state)
|
|
settings.render_rail(SettingsState(), selected=Destination.DEVICE)
|
|
finally:
|
|
rl.end_texture_mode()
|
|
pixels = rl.load_image_from_texture(target.texture)
|
|
try:
|
|
if pixels.data == rl.ffi.NULL:
|
|
raise RuntimeError("Unable to read Device framebuffer")
|
|
rl.image_format(pixels, rl.PixelFormat.PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)
|
|
rl.image_flip_vertical(pixels)
|
|
if not rl.export_image(pixels, str(args.output / "large.png")):
|
|
raise RuntimeError("Unable to export Device framebuffer")
|
|
rgba_sha = hashlib.sha256(bytes(rl.ffi.buffer(pixels.data, width * height * 4))).hexdigest()
|
|
finally:
|
|
if pixels.data != rl.ffi.NULL:
|
|
rl.unload_image(pixels)
|
|
module = Path(__file__).parent
|
|
report = {
|
|
"profile": Profile.LARGE,
|
|
"dimensions": [width, height],
|
|
"development_only": True,
|
|
"state": asdict(state),
|
|
"rgba_sha256": rgba_sha,
|
|
"png_sha256": digest(args.output / "large.png"),
|
|
"native_raylib_sha256": digest(Path(raylib._cffi.__file__)),
|
|
"source_sha256": {name: digest(module / name) for name in (
|
|
"device.py", "device_state.py", "preview_device.py", "settings.py", "settings_assets.py", "presentation.py",
|
|
"settings-assets.json", "bitmap-fonts.json", "sora-brand-font.json", "dinish-speed-font.json")},
|
|
"asset_sha256": {"icons/backspace.png": digest(args.asset_directory / "icons/backspace.png")},
|
|
"font_sha256": {path.name: digest(path) for path in sorted(args.font_directory.glob("*"))
|
|
if path.name in {"Inter-Regular.fnt", "Inter-Regular.png", "Inter-Medium.fnt", "Inter-Medium.png",
|
|
"Inter-Bold.fnt", "Inter-Bold.png", "Inter-SemiBold.fnt", "Inter-SemiBold.png",
|
|
"unifont.fnt", "unifont.png"}} |
|
|
{name: digest(module / "assets/fonts" / name) for name in ("Sora-800.fnt", "Sora-800.png", "DINish-Speed.fnt", "DINish-Speed.png")},
|
|
"scope": "large captured viewport only; no compact Device scene, scrolling, services, or action execution",
|
|
}
|
|
(args.output / "large.json").write_text(json.dumps(report, indent=2) + "\n")
|
|
finally:
|
|
settings.close()
|
|
finally:
|
|
if target.id:
|
|
rl.unload_render_texture(target)
|
|
rl.close_window()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|