Skip to content

RangeyRover/AMS2-SDF-File-Editor

Repository files navigation

# SDF File Editor & Hex Viewer

A small, Windows-friendly Tkinter GUI for inspecting and editing **binary `.sdf` suspension files**.

It scans a file for known element “signatures”, decodes fields using embedded encoding markers, presents everything in a tree view, and shows a synchronized **hex dump** with highlighting for the selected element/field/value. You can edit values inline and save a modified binary back to disk.

---

## Features

- **Open / view / edit `.sdf` (or any binary file)**
- **Tree view of decoded elements**
  - Body elements: `BODY`, `GENERIC`
  - Suspension elements: `JOINT&HINGE`, `BAR`
- **Inline editing**
  - Click a value → edit in place (bytes, ints, floats)
  - Modified values are shown in **blue**
- **Hex viewer**
  - Full hex dump with ASCII side
  - Selecting an element/field/value highlights the corresponding bytes
- **Auto-naming**
  - Attempts to infer human-meaningful names for body parts from mass/inertia/position patterns
  - Suspension parts are auto-named by detected order (corners and arms)
- **Persistent labels**
  - Rename elements and store labels in `yourfile.sdf.labels.json`
  - Import labels from another `.labels.json`
- **Reporting / Export**
  - View a structured report (body + suspension)
  - Copy report to clipboard
  - Save report to a `.txt`

---

## Requirements

- Python **3.10+** recommended (uses modern typing like `X | None`)
- Standard library only:
  - `tkinter`, `ttk`
  - `struct`, `json`, `dataclasses`, `pathlib`

> On Windows the app also attempts to set DPI awareness via `ctypes` for sharper UI.

---

## Install / Run

### Run directly
```bash
python sdf_viewer_final.py

Make executable (optional)

You can package with PyInstaller if you want a single EXE:

pyinstaller --onefile --windowed sdf_viewer_final.py

Usage

  1. File → Open… and pick an .sdf file

  2. Browse elements in the tree

  3. Click a value in the right-most column to edit it

    • Press Enter to confirm
    • Esc cancels
  4. Use the hex panel to verify byte-level alignment:

    • Selecting an element highlights its full byte range
    • Selecting a field/value highlights only the relevant bytes
  5. File → Save or Save As… to write the updated binary


SDF Editor screenshot

Data Model

The scanner produces Element objects, each containing one or more Fields:

  • Element

    • kind: e.g. BODY, GENERIC, JOINT&HINGE, BAR
    • start, end: byte offsets in the file
    • fields: list of decoded fields
    • display_name: user-visible name (editable)
    • auto_name: best-guess name (body elements)
    • identifier: raw bytes used to identify certain suspension elements
  • Field

    • name: e.g. mass, inertia, position, orientation, axis, pos, neg
    • at: byte offset of the field’s data
    • fmt: tuple of type codes (b, i, f)
    • values: decoded values
    • encoding_suffix: the encoding marker bytes found in the file (when applicable)

How Parsing Works (High Level)

Encoding markers

The file uses small byte sequences (1–2 bytes) to indicate how the next values are encoded. These are mapped in ENCODING_RULES, e.g.:

  • 0xA3 0x02Float, Float, Float
  • 0x03 0x00Byte×3
  • 0x21Float×1

The parser:

  1. Finds a known signature (sequence of bytes)
  2. Looks immediately after the signature for an encoding suffix
  3. Uses that suffix to decide the struct format (byte/int/float)
  4. Reads values and records offsets

Body elements

Body elements are parsed in sequence across the file:

  • BODY

    • mass is read as a byte (after SIG_BODY_MASS)
    • inertia/position/orientation are found by scanning ahead for signatures (SIG_INERT, SIG_POS, SIG_ORI)
  • GENERIC

    • mass is a float (after SIG_GEN_MASS)
    • then inertia/position/orientation similarly

Auto-naming (auto_name_element) uses patterns like:

  • mass ranges
  • encoding types used for inertia/position
  • wheel vs spindle guess from inertia magnitude and Z position

Suspension elements

Suspension scanning starts after the last body element.

  • JOINT&HINGE

    • signature match SIG_JOINT_HINGE
    • includes a 1-byte identifier immediately before the signature
    • reads ('f','b','b') as axis info
    • first four are auto-named by order: fl, fr, rl, rr*_wheel_hinge?
  • BAR

    • position signature SIG_BAR_POS
    • includes a 2-byte identifier immediately before the signature
    • reads pos triple-float then searches for SIG_BAR_NEG and reads neg
    • auto-named by order (5 per corner): forward_upper, rearward_upper, forward_lower, rearward_lower, tie_rod

Labels (Renaming) Persistence

When you rename an element (double-click an element row), the name is stored in:

  • yourfile.sdf.labels.json

Keys are:

  • body:<index> for body elements
  • susp:<index> for suspension elements

You can also import labels from another labels file via Tools → Import labels…


Export / Report

The Export menu generates a text report including:

  • Element number, kind, name, offsets

  • Field details:

    • encoding marker bytes
    • type tuple
    • formatted values

Options:

  • View Report…
  • Copy to Clipboard
  • Save Report…

Notes / Limitations

  • This tool is signature-based: it only parses elements it recognizes via hard-coded signatures.
  • Parsing uses a bounded lookahead (MAX_LOOKAHEAD = 16384) when searching for the next signature.
  • No checksum/CRC validation is performed—changes are written directly at recorded offsets.
  • The “auto names” include ? intentionally to indicate best-guess, not certainty.

Customising / Extending

If you want to support additional structures:

  1. Add new encoding suffixes to ENCODING_RULES

  2. Add new signatures (SIG_*)

  3. Write a new parse_*_at() function that:

    • matches the signature
    • detects encoding
    • reads values
    • returns an Element
  4. Hook it into scan() (phase 1 or 2 depending on where it appears)

About

AMS2 SDF File Editor

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages