123 Commits

Author SHA1 Message Date
eac92c3e44 re(flight): withdraw the roll result — the probe was measuring pitch as much as roll
Re-running roll with 5 s settles and in-run clock brackets:

  this run's clock: TIME 00:34.93 -> 00:45.97 = 11.04 s game in 7.98 s wall = 1.383
  min speed: 90.6 deg/wall-s /1.383 -> 65.5 deg/game-s  (AV_Roll_Min 200)
  max speed: 59.1            /1.383 -> 42.7             (AV_Roll_Max 125)

The corrected numbers are within a few per cent of the PITCH run's 67.8 and 40.9 —
two different stick axes cannot produce the same rates, so the probe is not
separating them. Cause: watching a non-forward matrix row sees any rotation that
moves that row, and pitch moves it as much as roll. The correct measure is rotation
ABOUT the forward axis (project the row onto the plane perpendicular to forward and
track that angle).

So "roll shows no speed dependence, unlike pitch" is withdrawn: it rested on 2 s
settles and a row that mixes axes, and the two runs disagree with each other
(144/150 then, 90.6/59.1 now). AV_Roll_{Min,Max} are not confirmed and the axis
question is open.

The clock ratio is now measured three times in three flights: 1.260, 1.311, 1.383 —
a property of the moment, not the machine, so every rate probe must bracket its own
phases.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 18:12:20 +00:00
8b10c0451f re(flight): the clock factor is universal — angular matches too once corrected in-run
pitch_gametime.py brackets each turn phase with HUD screenshots, so the mission
clock's own advance converts wall seconds to game seconds within the same run:

  this run's clock: TIME 00:33.68 -> 00:44.12 = 10.44 s game in 7.96 s wall = 1.311

  pitch @ min speed  88.9 deg/wall-s  /1.311 -> 67.8 deg/game-s  vs AV_PitchMinus_Min 75
  pitch @ max speed  53.6            /1.311 -> 40.9             vs AV_PitchMinus_Max 40

Both land on the definition (the slow phase 10% low, consistent with including the
AA_* ramp in an 8 s window), so the clock explanation covers angular motion as well:
every stated rate is per GAME second.

The ratio is not a machine constant — 1.260 in the earlier flight, 1.311 here — so it
must be measured in the same run as whatever it corrects. Bonus: the same shots show
the HUD reading 102 at full LT against MinimumVelocity 100.

Also documents the trap that cost three runs: a killed Canary leaves both its shm
image and its last frame on screen, so a dead emulator looks alive and the scans
report "0 moving triples" like a tooling bug. pgrep -x matches zombies, so
speed_law.require_live_emulator() checks the process state letter and refuses to
measure a corpse.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 17:56:16 +00:00
ae5f322c03 re(flight): the linear factor is the CLOCK — 1.260 measured against 1.267
Cleanest linear measurement: neutral throttle (HUD = CruisingVelocity 350), sticks
centred, 20 s of perfectly straight flight (displacement/path = 1.000):

  8 900 world units in 20.1 s -> 443.6 /s -> 1.267x the HUD's 350

And the game's own mission timer across a wall-clock interval:

  TIME 00:08.79 -> 00:46.97 = 38.18 s of game time in 30.29 s wall = 1.260

Same number. So the linear discrepancy is not a unit difference: the mission clock
runs ~1.26x faster than wall time under this emulator, and dividing world
displacement by WALL seconds inflates speed by exactly that. World units and
displayed speed share one unit; the definition velocities are per GAME second.

This supersedes the previous "world-unit vs displayed-speed" reading.

Left open (): settled turn rates measured 74.9/41.1 deg/s in wall time against
AV_PitchMinus_Min/Max 75/40, but the clock argument predicts ~94 for the first.
Either that agreement was luck inside a noisy sample (per-window rates spanned
61-96) or angular integration is frame-based where linear is time-based. The check
is to re-measure pitch and convert wall->game seconds with the clock ratio.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 17:26:27 +00:00
0cb81b6200 re(flight): the linear discrepancy is a world-unit vs displayed-speed difference
Screenshotting the HUD speed readout at each throttle step, beside the
position-derived measurement of the same moment:

  RT 0.00   HUD 350 (= CruisingVelocity)   position ~447   ratio 1.28
  RT 0.25   HUD 507                        position ~652   ratio 1.29
  RT 0.75   HUD 963                        position ~1141  ratio 1.19

So (a) the HUD speaks the definition's units — exactly CruisingVelocity at neutral,
963 at three-quarters against the 987 the interpolation predicts — confirming the
throttle law in the game's own numbers without any position sampling; and (b) world
displacement runs ~1.2x the displayed speed. Since settled angular rates need no such
factor, this is a unit difference between the position triple and the velocity
fields, not a clock effect: a reimplementation moving entities at MaximumVelocity in
world coordinates will be ~20% slow.

Also fixes speed_law.find_player: a mission holds more than one *_Player object and
at least one never moves, so the finder now samples each candidate twice and keeps
the one that displaces. Locking onto the static one is what produced a run of exact
zeros while the game was visibly flying.

🟡 The ratio is 1.19-1.29 rather than a clean constant and every sample was taken in
a firefight; pinning it wants a quiet map.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 17:06:35 +00:00
f6974ff3f0 re(flight): settled turn rates match the definition exactly — withdraw the time-base claim
Re-measured with 5 s of settle per phase and the speed recorded at the moment the
turn starts (flight_law3.py):

  pitch @ 130/s    74.9 deg/s   vs AV_PitchMinus_Min 75
  pitch @ 1821/s   41.1         vs AV_PitchMinus_Max 40
  roll  @ 110/s   129.5         vs AV_Roll_Min 200
  roll  @ 1722/s  149.3         vs AV_Roll_Max 125

Pitch lands on the definition's own numbers with NO scale factor, so the ~1.2x I
attributed to the emulated time base two iterations ago was an artefact of
differentiating during the AA_* acceleration ramp with too little settle. That
explanation is withdrawn: AV_* can be used verbatim.

What remains is only on the linear side — settled speeds still read high and vary
between runs (RT full: 1342 in one flight, 1821 in another, vs MaximumVelocity 1200),
consistent with a craft being shoved around in a firefight. The HUD reads exactly
CruisingVelocity at neutral. A clean linear measurement needs a quiet map; no cause
is claimed until then.

Roll re-measured with proper settles confirms the axis difference: no speed
dependence, both regimes near AV_Roll_Max, where pitch moved 75 -> 40.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 16:46:33 +00:00
6ebbbeff65 re(flight): LT mirrors RT, and roll does not depend on speed
One flight, two measurements (flight_law2.py, binding early so the moving-craft scan
can see the player).

LT curve: 436, 379, 289, 209, 126 units/s across LT 0.00 -> 1.00 — a straight ramp,
whose endpoints after the ~1.2 time-base factor are CruisingVelocity 350 and
MinimumVelocity 100. So the law is symmetric:

  RT: target = Cruising + RT * (Maximum - Cruising)
  LT: target = Cruising - LT * (Cruising - Minimum)

Roll (measured on a non-forward matrix row, since roll turns about the forward axis):
~144 deg/s at minimum speed and ~150 at maximum — no speed dependence, where pitch
dropped by a third to a half between the same regimes. After the time-base factor
that is ~121, i.e. AV_Roll_Max 125 in BOTH regimes.

So _Min/_Max does not mean the same thing for every axis: pitch interpolates with
speed, roll appears pinned at Max. A reimplementation applying one rule to all axes
would get low-speed roll wrong by ~60%.

Caveat recorded: the two roll phases were 2 s of settling apart, marginal for a
126 -> 1342 speed change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 16:30:19 +00:00
4dbd4f6cef re(flight): the throttle is analogue — target speed interpolates cruise -> maximum
RT is an analogue trigger, so "held" was one point on a curve. Walking it 0.00 ->
1.00 (throttle_curve.py) gives a straight ramp: 438, 626, 879, 1094, 1342 units/s.
Dividing by the ~1.2 time-base factor, the endpoints land on the definition's own
numbers (365 vs CruisingVelocity 350; 1118 vs MaximumVelocity 1200) and the midpoint
follows, so

  target speed = CruisingVelocity + RT * (MaximumVelocity - CruisingVelocity)

which refines the earlier "selects one of three targets" reading: those three are the
curve's endpoints.

It also refutes the standing afterburner hypothesis that full RT is the burner: the
curve is smooth through full deflection with no step, and the shield does not move.

The LT half is not measured yet — the entity scan needs the craft moving when it
runs, so a mission left idling drops out of it. Bind early.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 16:14:47 +00:00
fb1405b13f re(flight): the afterburner is not on A/B/X/LB/LS/RS — bounded negative, with a cheap HUD oracle
The definition describes the burner (AB_ConsumeShield_Begin 50, AB_ConsumeShield 10,
AB_AV_* turn caps well below normal) but names no input, and carries no AB velocity
field.

Three probes, all negative for A, B, X, LB (plus LS/RS on the first):
- ab_probe.py: hold RT for a max-speed baseline, then each candidate — speed stayed
  inside the baseline's own noise band every time.
- ab_state_probe.py: sample a window of the player object during each hold and
  report any float that falls — nothing fell.
- HUD oracle needing no offsets: count green pixels of the SHIELD bar on a freshly
  spawned craft. AB_ConsumeShield_Begin 50 should take a visible bite; the bar read
  156/156/156/157/157 across baseline and all four buttons.

So the burner needs a chord, an input this pad cannot reach, or belongs to another
craft/the AI. Recorded so the obvious buttons are not re-probed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 15:51:32 +00:00
86fcfcc8b0 re(flight): turn rates confirm AV_* are rate caps and _Min/_Max mean at min/max speed
turn_law.py pins the speed regime with a throttle, holds a stick axis and
differentiates the craft's own forward vector over 1-second windows.

  slow + nose down  ~87 deg/s   (AV_PitchMinus_Min 75)
  fast + nose down  ~54         (AV_PitchMinus_Max 40)
  slow + nose up   ~175         (AV_PitchPlus_Min 150)
  fast + nose up   ~136         (AV_PitchPlus_Max 70)

So agility falls with speed (_Min/_Max are at minimum/maximum speed, not rate
bounds) and pitching up is ~2x pitching down, exactly as the field pairs say.

Control mapping measured: LX is roll (forward vector barely moves, 3-5 deg/s), LY is
pitch (+1 = nose down per vgamepad's LY: -1 = up), and the right stick does not steer
at all.

The ~1.2x overshoot seen in the speed law appears again here (1.16-1.35x), and a
unit scale cannot explain both m/s and deg/s — a TIME BASE can: if the guest's
simulated second is shorter than the wall-clock second the probe measures against,
every rate reads high by the same factor. So the definition numbers are
self-consistent and these measurements confirm the shape of the law, not a scale.

Recorded 🟡: no yaw input found (AV_Yaw_* exists but neither stick yaws), which with
roll on LX and MaximumBank_Normal points at a bank-to-turn model.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 15:30:00 +00:00
1efc3f567d re(flight): the throttle is a target-speed selector, measured against the definition
speed_law.py locks onto the player entity once and samples its position while
holding each throttle input, differentiating over 1-second windows.

  no throttle  -> ~420   (CruisingVelocity 350)
  RT held      -> ~1 530 (MaximumVelocity 1200)
  LT held      -> ~125   (MinimumVelocity 100)
  release      -> back to cruise, from either direction

So the throttle SELECTS a target speed rather than adding thrust — which is what a
reimplementation would most likely have assumed from Acceleration/Deceleration
alone. Those govern the convergence rate instead: ~440 units/s^2 measured on
release (Deceleration 500) and ~470-560 under RT (Acceleration 600).

Recorded as 🟡: measured world speeds run ~1.2-1.3x the definition numbers in all
three regimes while the HUD shows the definition value exactly (350 at cruise), so
world coordinates are a constant multiple (~1.25) of the definition's velocity unit;
the spread is wider than the constant is precise because the craft manoeuvres while
sampled.

Three traps documented: RT/LT are analogue triggers (the button verb is a silent
no-op and the first run measured an unflown craft), per-sample differentiation
aliases against the guest's update rate (0, 1519, 1985, 0, 2681 for smooth flight),
and the player entity only enters the typed scan ~15 s in while the craft dies within
minutes if nobody flies it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 15:08:11 +00:00
6d0bdf0179 re(units): S08 closes the story stages (68 units), and GAME_CLEAR unlocks nothing
S08 gave the last two story-stage units — UN_be005_ADAN_SpaceFortress and
UN_mn500_ADAN_FloatingMine — plus six S08 asteroid collision meshes: 68 units,
9 393 rows, 7 115 defaulted-on-disc values. Every unit any story mission fields is
now read (689 more disc cross-checks, 0 disagreements).

Probe recorded as a negative: setting Game Status (GHAD +48 and its header mirror
+0x18) to 2 = STATE_GAME_CLEAR leaves both menus unchanged — the title still shows
NEW GAME / LOAD GAME / TUTORIAL / OPTIONS / EXTRAS and EXTRAS still shows only
MISSION SELECT / MOVIE THEATER / BACK. So the EX/challenge rosters are not gated on
that field.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 14:39:05 +00:00
0221217968 re(units): six targeted harvests — 60 of 110 units, 6 071 defaulted values
S03, S06, S09, S13, S15, S16 (plus the earlier run): 21 -> 60 units,
963 -> 6 071 defaulted-on-disc values, 8 241 rows. Disc cross-checks agree with
0 disagreements throughout.

- UN_e901_ADAN_Boss and UN_e910_core_ADAN_GeneratorCore are harvested (HP 10 000,
  Size_X 500, Size_Radius 250, MaximumVelocity 450) WITHOUT the boss ever being on
  screen: definitions are instantiated at stage load, so a unit only needs to be in
  the roster. That is far weaker than what the draw-capture work requires.
- The extra stages are not reachable via the save's stage field: stage 27 boots to
  the title and then the emulator exits during the load, as do the other S24..S29
  entries, while story stages 1-16 all load. The field addresses the story campaign
  only; EX/challenge rosters need the Challenge-mode menu path.

Remaining 50 units are almost all EX variants in S24/S25/S27/S28/S29; the only
story-stage stragglers are UN_mn500_ADAN_FloatingMine and
UN_be005_ADAN_SpaceFortress in S08.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 14:14:18 +00:00
bf6825e278 re(units): target missions by roster, harvest S09 — 36 units / 3 439 defaulted values
examples/roster_target.rs ranks stages by how many roster units are still
unharvested. The EnumUnit_S<NN> tables are found by hashing candidate TOC paths
(hash::TOC_NAME_SCHEMES) — UnitRoster::stage can only infer a tag when the roster
carries a UN_S<NN>_ prop, which most do not.

It picked S09 (10 missing). Flying it: 26 -> 36 units, 3 345 -> 4 785 rows,
2 351 -> 3 439 defaulted-on-disc values. New: e102_Battleship, e104_Carrier,
e107_AAFrigate, e011_Attacker_B, e008_TurretPlus, be001_TerrafoamingUnit,
e001_Elan_GR{,_Violeta}, f102_LightCarrier_Inv, f106_Destroyer_Inv.

Also settled: the definition objects are mission-independent. Eleven units appear in
more than one snapshot and four are not byte-identical, but compared through the
layout ZERO mapped fields differ — the 12 differing slots are all unmapped (offsets
4/8/16/20 and 0x250/0x268/0x300-0x308/0x330-0x338: object header and sub-object
pointers). So a harvested value is the definition, not a per-mission tweak, and the
earlier UN_f201_TCAF_Tanker flag resolves the same way. Cross-checks over three
snapshots: 1 052 agree, 0 disagree.

Third angle field found the same way (Through_AngleMaximum = 60 degrees in radians),
so the degrees<->radians rule covers any name containing "Angle".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 13:48:12 +00:00
14d5ed54d1 re(units): read definitions with the code-derived layout — defaulted values 1 059 -> 2 351
unit_runtime.py can only place fields the disc values (it scores triples against
disc records): 58 of 153 from one snapshot. data/unit_definition_layout.txt came
from the title's loader instead, so it places all 159 — including the fields no
disc record sets, which is the Route-B target.

tools/re-capture/unit_dump_layout.py reads every field of every live definition
object with that layout and keeps the discipline: a field the disc DOES value is a
check, not a new value. Over two snapshots (19 objects): 700 cross-checks agree,
0 disagree.

  fields placed per object            58 of 153 -> 159
  rows over those 19 units                  609 -> 2 736
  defaulted-on-disc values (whole file)   1 059 -> 2 351

Two traps recorded: the layout table's offsets are DECIMAL while the solver CSV
prints hex (parsing as hex fails the cross-check on everything — which is how it
announced itself), and angle fields can carry a prefix (AB_AA_PitchPlus is still an
angle, so the AV_/AA_ test must match anywhere in the name).

Flagged: UN_f201_TCAF_Tanker's object is not byte-identical between the two
missions — per-mission override or a runtime-mutated field; needs a third snapshot
to separate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 13:30:49 +00:00
d61baddaf0 re(units): stage select lifts the per-stage coverage limit — 21 -> 26 units
Unit definitions are instantiated per stage, so the parked "coverage grows by
visiting missions" limit was blocked on progress. With the save's stage field
solved, any story stage can be flown from a hand-edited save and snapshotted.

First harvest (a Night Ravens mission, 027 objectives, different roster):
  units with runtime values   21 -> 26
  csv rows                 1 827 -> 2 143
  defaulted-on-disc values   963 -> 1 059

New: UN_e004_ADAN_ElanPlus_N, UN_e006_ADAN_Vindicator_Margras,
UN_f002_TCAF_DeltaSaber_W, UN_f002_TCAF_DeltaSaber_W_Player (a second player craft)
and UN_mn040_Asteroid_Big (47 defaulted values, Size_Z = 2000).

Two traps recorded with the fix: launch_mission.sh presses A on the PRESELECTED
slot, which is the last-used one (03 here), so a probe in slot 01 is ignored — the
first attempt flew stage 02 again and the solver correctly found 0 new units; patch
every slot or confirm the highlighted slot by screenshot. And back up before
patching: the mid-run backup already held the probe, so slot 01 was restored from
the earlier pristine copy (md5 142b4f43…, verified byte-identical).

Token file for the solver: idxd_tokens <GP_MAIN_GAME_E.pak> Generic — 110 UN_*
records, the disc's full unit count.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 13:16:04 +00:00
d1b50dc1e6 re(xbg7): characterise the residual 47 misses — 99.25% of resources decode
examples/why_missed.rs reports the furthest gate per undecoded resource. Disc-wide
that is 47 rows / 43 distinct names, and they are mostly not ship geometry:

  30  e_rou_/_rou_ pose & proxy composites (24-vertex marker boxes, extent 0.010)
   6  .DAT particle composites in ptc_pack
   8  damage/LOD variants (e101_bdy_02_d, e901_wing_05_*_m, ...)
   3  props/other (g005 extent 0.196, _rou_f001_wep_05, e_rou_e005)

By gate: extent 32, coverage 8, winding 7. The extent bucket is almost entirely the
pose-proxy boxes, and lowering that floor was measured and refuted earlier. The one
genuinely interesting residual is e901_wing_05_L/R at winding 0.587/0.570 against the
0.70 floor — the signature of a thin double-sided sheet, unproven without a capture
with the boss on screen (flying stage 16 puts the container in memory but the unit
never appeared).

So: 6 247 / 6 294 resources decode (99.25 %), and every real mesh drawn in three
captured missions decodes at the GPU's own offsets with index runs matching byte for
byte (93/93 and 128/128).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 12:50:19 +00:00
3b35c48fce fix(xbg7): grouped selection prefers the candidate explaining the whole pool; per-sub-mesh decls on by default
With per-sub-mesh declarations enabled, n201_01 decoded as a 2-part fragment 4 bytes
off. Both starts validate for the pivot — 0x32BA718 at pad 2 (earlier in file order,
so first-match took it) and the capture-proven 0x32BA71C at pad 0 — so the pivot
alone cannot separate them; at the early one two of four sub-meshes fall out as
out-of-range.

anchor_grouped_meshes now builds each accepted candidate and keeps the one that
explains the most of the declared pool: it returns immediately when a candidate
explains all n sub-meshes, else keeps the best partial, so it can never decode less
than first-match did. n201_01 lands on all four capture-proven offsets
(0x32BA71C / 0x32BEFF4 / 0x32C416C / 0x32C536C) and its two sibling copies take their
own pools, so the twin collapse is gone.

XBG7_SUBMESH_DECLS is therefore on by default (=0 reverts):

  resources that never decode        85 -> 47
  resources decoding in no container 63 -> 30
  degenerate index runs               1 -> 1   (unchanged)
  cross-container minority decodes   96 -> 96  (unchanged)
  captured index runs, stage-02      93/93     (unchanged)
  captured index runs, stage-05     124/128 -> 128/128

The last line is the point: the buffers the capture could not name are the n201
family, and they now decode and match the GPU's indices byte for byte. Suite green
including twin_pairs_do_not_share_a_buffer, apart from the pre-existing
known-failing cross-container consistency test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 12:27:56 +00:00
4cdbbc2d48 feat(xbg7): read the per-sub-mesh vertex declarations (XBG7_SUBMESH_DECLS, off by default)
desc_dump shows each index marker is followed by its OWN element triples: n201_01
declares strides 24, 24, 24 and 28 (the last sub-mesh has a fourth element), which
matches the runtime capture's stride=28 on that draw and the four distinct vertex
shaders. parse_vertex_decl read the first declaration for the whole pool.

all_vertex_decls reads one per marker; anchor_grouped_meshes uses each sub-mesh's
own stride for the pool walk, the pivot validation and the read. debug_grouped_report
follows the same setting so the diagnostic cannot blame the wrong gate — at n201_01's
capture-proven pool start it now reports "pad 0: ACCEPTED" instead of a NaN position.

With XBG7_SUBMESH_DECLS=1: resources that never decode 85 -> 47, resources decoding
in no container 63 -> 30, capture oracles unchanged (93/93 index runs, 42/42 index
counts), consistency unchanged at 96.

Off by default because selection has not caught up: the three n201_0x copies then
settle on one pool (twin_pairs_do_not_share_a_buffer fails), production still picks
a start 4 bytes before sub-mesh #1 rather than the proven one even though the proven
start validates and is unclaimed, and four newly decoded ptc_pack .dat composites
carry degenerate triangles. Format truth is settled; choosing among candidates is
the remaining work.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 11:45:20 +00:00
27577538cb re(xbg7): a capture names a never-decoding family, and the cause is mixed strides in one pool
capture_ib_truth now proposes an identity for each drawn buffer our decoder cannot
place, by matching (vertex, index) counts against declared-but-not-decoded
resources. That identified n201_01/_02/_03 in Stage_S02.xpr — three of the 63
resources that decode in no container — and the capture pins all four sub-meshes:

  #0 vb 0x32BA71C ib 0x32B39FC 4464 idx 777 v stride 24
  #1 vb 0x32BEFF4 ib 0x32B5CDC 4464 idx 869 v stride 24
  #2 vb 0x32C416C ib 0x32B7FBC  576 idx 192 v stride 24
  #3 vb 0x32C536C ib 0x32B843C 4464 idx 869 v stride 28   <- different

The layout matches our assumptions exactly (tight index packing, last buffer flush
against vb0 so pad 0, span 27936 == align4-summed markers, contiguous vertex
buffers, max index == verts-1 everywhere). The defect is that sub-mesh #3 has a
different stride AND its own vertex shader: anchor_grouped_meshes parses one
declaration per resource and applies its stride to every sub-mesh, so it reads #3
out of phase (372 non-finite position components of 2607), and since the pivot is
the largest index count with ties going to the last marker, the pivot IS that
sub-mesh — so the whole resource is declined.

Also adds examples/miss_targets.rs (which container to aim a capture at): 63
resources decode nowhere, 58 of them in exactly one container, clustering as
Stage_S16 21 (e901_wing_05_*), ptc_pack 12, Base 6, then per-stage n2xx groups.
Flying stage 16 did not draw the e901 wings — the container is resident but the
unit must also be on screen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 10:52:35 +00:00
92d36ec10f re(xbg7): a Stage-05 capture validates the pad fix out of sample, and shows how containers load
Ran ship_capture_close.sh in story stage 05 (reachable now via the save's stage
field) instead of stage 02: 3 logs, ~11 200 draws.

- Out-of-sample check of the pad-scoring fix: 124 of 124 index runs identical to
  the GPU's, 2 769 index elements, 0 differing — on draws the fix was not derived
  from (the stage-02 capture gave 93/93).
- A mission keeps SEVERAL stage containers resident: 65 drawn buffers place in
  Stage_S02.xpr at 0x17FE3FF4 (the shared TCAF/ADAN fleet) and 5 in Stage_S05.xpr
  at its own constant 0x1927B7F4 (the f101 ACROPOLIS, this mission's escort) —
  the first capture-truth rows for a container other than Stage_S02. Both sets
  have exact index counts and exact coverage.
- Why: f105_bdy_01 lives in 13 of the 22 stage containers and not in Stage_S05 at
  all, so the resident set follows the mission's unit roster, not the stage number.

Consequence for the residual misses: a different story stage is not a different
container. Aiming a capture at a specific container is a static question (resource
names per container x the stage's EnumUnit roster).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 10:20:00 +00:00
9fd5dcd37d re(savegame): GHAD +52 is the stage number — a hand-edited save plays Stage 05
Static analysis of the header builder (0x822870b4..0x82287128) shows the GDHA
container header carries a SUMMARY of the progress block, and the screens read
that: hdr+0x14 <- GHAD+52, hdr+0x18 <- GHAD+48, hdr+0x1c <- +24 (Points),
hdr+0x20 <- +4 (flight), hdr+0x24 <- the computed clear ratio, hdr+0x28 <- +12.
savegame_edit.py copies the donor header verbatim, so payload-only probes left a
stale summary — which is why +52 looked refuted.

Patching both (hdr[0x14] = 5, ghad[+52] = 5) makes the title read
"STAGE 05 - Star System Escape", load it, brief the Gallia Asteroid Group, and fly
an asteroid-field mission with a different objective and roster. So +52 is the
stage number, 1-based, and one u32 chooses the mission.

Also corrected in the GHAD table: +48 is the Game Status enum (0 = At Standby,
matching the screen's STATE_STAND_BY/STAGE_CLEAR/GAME_CLEAR list) and +12 is Times
Cleared, both via their header mirrors.

This unlocks runtime capture in containers other than Stage_S02 (the 85 XBG7
misses, box identity, ship-placement generalisation) and per-stage unit
definitions. Slot 01 was backed up and restored byte-identically.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 09:46:08 +00:00
0cf9220d24 re(savegame): stage-unlock probes are negative, and the Details panel is not a payload oracle
Four probes against slot 01 (the save the title-menu screens read), each backed up
and restored byte-identically:

- SHAB[1..7] filled -> MISSION SELECT still locks Stage02-08, cursor will not
  leave Stage01. The per-stage record table is not the unlock gate; the earlier
  SHAB[1] attempt used a throwaway slot and could not show this.
- GHAD +36/+52/+56 = 5 -> still locked, panel still STAGE 02 / EASY.
- GHAD +16 = 4 -> panel still STAGE 02, so it is not a 0-based stage index.
- live-RAM writes into the loaded GDHA header -> panel unchanged.

The useful part is why the panel cannot answer this: guest RAM at that screen holds
NO payload bytes (neither the 4101/4101/79 triple nor the 54-byte develop blob),
but it does hold the save's GDHA container header with a summary copy of Points,
flight time, clear ratio and a FILETIME. savegame_edit.py copies the donor header
verbatim, so a payload edit leaves that summary stale — "the panel did not change"
therefore cannot separate "not the stage field" from "the panel never reads the
payload". Future stage/difficulty probes must patch the header too, or be judged by
what the game does on load.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 09:18:46 +00:00
0776beb6f4 fix(xbg7): degenerate index runs 582 -> 1 (grouped path + prefer a clean candidate)
Two follow-ups to the pad-scoring fix, both driven by the same invariant (a
correctly located index run has no degenerate triangles):

- anchor_grouped_meshes picked its pad by first-match too; scoring the pivot run
  the same way cleared every remaining ptc_pack composite (f102/f104/e107).
- anchor_pool_mesh now prefers a degenerate-free candidate over an earlier dirty
  one. examples/better_home.rs showed the last two resources each had exactly one
  degenerate-free, pool-covering block, sitting later in file order than the
  lookalike we took. First-match order is kept for every clean hit, and a dirty
  block is still used if nothing clean exists, so coverage cannot regress.

  degenerate index runs, disc-wide:      582 -> 11 -> 1
  captured index runs identical:         93/93 (unchanged)
  resources decoded / misses:            6 209 / 85 (unchanged)
  index runs changed / anchors moved:    590 / 10 (_rou_f402_dead x8, e201_bdy_03_m x2)

Cross-container minority decodes 89 -> 96, and that is progress: all seven new
rows are _rou_f402_dead, which now has a majority (32x25x8) for the first time, so
its seven wrong copies are named instead of hidden behind "no majority".

The last dirty run (_rou_f402_dead in Stage_S09) is blocked by distinct assignment
— its clean block is claimed by e_rou_f003_Near, both 24-vertex bounding boxes. A
winding-floor escalation for that case was written, measured to fire for nothing,
and reverted; the reasoning is kept as a comment.

Regression threshold tightened to 1. Suite green with --include-ignored apart from
the pre-existing known-failing cross-container consistency test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 08:52:41 +00:00
33dc12c948 re(xbg7): render the before/after — the index shift shredded capital-ship hulls
ship_render --static on f101 (ACROPOLIS) with and without XBG7_PAD_FIRST_MATCH=1.
Identical triangle count, placements and bounds; the old wiring renders as a mess
of shards, the fixed one as a coherent hull. Kept as the evidence image for the
pad-scoring fix.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 07:28:40 +00:00
41b59faf5f fix(xbg7): the index run was one element late for 575 sub-meshes
Extending the capture comparison from index COUNTS to index VALUES
(`examples/capture_index_bytes.rs`, using the batch offsets the new ib logging
gives) showed 76 of 93 Stage_S02 index runs identical to the GPU's and 17
differing — every difference a shift by exactly one element, on buffers whose
index data sits at pad 2.

`anchor_pool_mesh` returned the FIRST pad that validated, and pad 0 is tried
first with the looser winding gate (0.70 vs 0.85). Read at pad 0, a pad-2 block
yields [true[1], true[2], …, garbage]: every index in range, the pool covered,
the positions right, the winding often just above 0.70 — so it validated, and
every triangle was mis-wired. Nothing count-based could see it.

The signature is decidable without the capture: a shifted run wires arbitrary
vertices, so triangles come out degenerate. 282 of 283 correctly anchored
Stage_S02 blocks have zero degenerate triangles, while the shifted readings carry
1–2 156. So score every validating pad by (degenerate triangles, then winding)
and keep the best. `XBG7_PAD_FIRST_MATCH=1` restores the old behaviour.

  captured index runs identical:            76/93  ->  93/93  (2 025 elements)
  decoded runs with a degenerate triangle:    579  ->     16  (disc-wide)
  sub-meshes whose index run changed:                    575  of 8 850
  resources decoded / vertex anchors / consistency:  unchanged (6 209 / same vb / 89)

Locked in by tests/mesh_disc.rs::decoded_index_runs_have_almost_no_degenerate_triangles.
Suite green with --include-ignored apart from the pre-existing known-failing
cross-container consistency test (the 24-vertex bounding-box class).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 07:26:52 +00:00
6d92e6c114 re(xbg7): the [index][vertex] layout is runtime-verified, and the indices= mystery was batching
The decoder's central unstated assumption — a block's index buffer sits
immediately before its vertex buffer (`vb - idx_count*2 - pad`, pad <= 3) — was
also the prime suspect for the residual anchor misses, since a capture-proven
`e106_eng_02_l` block was rejected outright. Measured it instead of assuming:

- extended the F10 ship capture to log each draw's index buffer (base, count,
  min/max index) and to key its de-dup on the index range, so every draw batch
  is recorded rather than only the first;
- `examples/capture_ib_truth.rs` places each drawn buffer in the container by its
  dumped positions and scores the capture against our decode.

Stage_S02, 42 drawn buffers placed: our idx_count == the sum of the draw's index
batches for 42/42, the batch union covers the vertex pool exactly for 42/42, and
all 30 single-block cases sit at pad <= 3 (20 at pad 0, 10 at pad 2). The other
12 are grouped pools, where one index pool serves the whole group. So the layout
holds, the decoded index count is exact, and eng_02_l died on the connectivity
gate (since replaced by the winding gate) — not on index location. The shipped
exact-coverage rule is independently confirmed.

The recorded "capture indices=21 vs our 246" disagreement was an artefact of the
old de-dup key: 21 was the first of two batches, 21 + 225 = 246. Any conclusion
from a pre-2026-08-13 capture's `indices=` or `vbase - ibase` is about one batch,
not about the block.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
2026-08-13 05:57:44 +00:00
1b618f500f re: cross-validate the code-derived layout against the earlier RAM-binding solver
Two independent derivations of the unit definition layout -- the earlier
disc-value-to-RAM-word solver and this session's extraction from the loader's own
key strings -- agree on 25 of 25 shared offsets, 0 disagreements. The code-derived
table covers 159 fields against 27 confirmed, while the earlier one uniquely holds
ScorePoint (+0x08c) and MassScore (+0x094).

Also flags a tentative entry as an artefact: Slalom_CutoffRatio at +0x00c records
2.8026e-45 / 1.4013e-45, which are the denormal readings of the integers 2 and 1 --
the same trap that produced a false YawDragFactor hit while building the new map.
INDEX updated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-13 01:11:43 +00:00
7cd9fb8e0b feat(formats): land the verified unit-definition layout as data + API + test
The offset->field map read out of sub_82341A20 is now usable rather than just
documented: data/unit_definition_layout.txt carries the 159 fields with their
provenance and the two conventions (angles are degrees on disc and radians in the
object; a defaulted field keeps the accessor's 0.0 miss value), and
sylpheed_formats::unit_layout exposes fields()/field_at()/offset_of() so a memory
snapshot can be read by name.

tests/unit_layout_disc.rs replays the verification against the checked-in live
dump -- every mapped float of all 11 identified objects must equal its disc value,
angles compared in radians -- asserting 0 disagreements and >=400 agreements. It
needs no emulator. Full suite green: 11 binaries.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-13 00:44:26 +00:00
19b338d9d8 re(route-b): map generalises to units -- 406/0 across 11 objects, 121 defaulted fields
Applying the map to turrets, fighters, an attacker and a station (UNIT records
rather than VESSEL) gives 406 field values agreeing with the disc and 0
disagreeing across 11 objects, so one layout serves both schemas.

Two consequences the four-value signature could not give: the map IDENTIFIES an
object -- 0xbd3b6a00 is UN_bf001_TCAF_SchlosBase (14 agree, 0 disagree), not
UN_be005_ADAN_SpaceFortress (12 agree, 2 disagree on Color_R/Color_G) -- and
variants are provably identical, with ArrowHead/_EX4/_EX5 at 48/48, Turret/_EX4
at 51/51 and three DeltaSaber player variants at 49/49.

121 defaulted fields now have runtime values. FiringRange (0 in all 11) and
ShieldRatio (1 in all 6) look like true constants; HQRatio, ThrusterRatio and
AttackCraftPoint vary per unit and are recorded as such.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-13 00:12:45 +00:00
d674cddad4 re(route-b): full field map verified 154/154, and 101 defaulted fields read out
Anchoring each key string to the first store AFTER the accessor call makes the
extraction exact: 159 fields, 125 of them floats, and verify_fieldmap now checks
every one against the live objects -- 154 agree with the disc, 0 disagree.

The last ten mismatches taught the rule: angle fields are degrees on disc and
RADIANS at runtime (AV_PitchPlus_Max 3.6 -> 0.0628319; MaximumBank_Normal 60 ->
1.0472), an exact conversion across every angle field and unit.

101 defaulted fields now have runtime values: angle limits default to 3.6 degrees,
afterburner/turn-attack fields to 0, FiringRange to 0 (matching the loader's miss
value), Size_Y to that unit's Size_X, and the ratio family is per-unit rather than
constant (HQRatio 0.2 or 1, DefencePoint 0.1 or 0.25, ...).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 23:44:57 +00:00
0434afa6a6 re(route-b): the field map comes out of the code, and with it the Ratio family
The filler builds each key as addi r4, r30, -N with r30 = 0x82088f94, so every
store's field NAME is a string in the image. Pairing keys with the following stfs
gives the layout outright: Size_X/Y/Z at +48/52/56, HQRatio +88, ShieldRatio +92,
ThrusterRatio +96, resistances +116..132, Radar/FCS/FiringRange +672/676/680,
Attack/Defence points +692/696/700. verify_fieldmap.rs checks it against the live
dump: 62 fields agree with the disc, 0 disagree.

That yields the runtime value of each field for units whose record omits it --
HQRatio 0.2/1, ThrusterRatio 0.2/1, ShieldRatio 1, ResistanceToPlayer 1,
ResistanceToShell 0.1, ResistanceToExplosion 0.5, AttackVesselPoint 0.1,
AttackCraftPoint 0.1/0.5, DefencePoint 0.1/0.25, FiringRange 0, Size_Y = Size_X.
Recorded with the caveat that several show two values across units, so these are
per-unit runtime values rather than one global default.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 23:17:05 +00:00
2ed475868b re: Size_Y is genuinely defaulted, and the loader leaves it at 0.0
pool_window.rs shows the Destroyer's raw tokens: "200.0" "Size_X" "Size_Y"
"2000.0" "Size_Z" -- Size_Y is a bare key, so the 13 runtime values recovered
earlier are real defaults, not a reader artefact.

The filler reads each size field through sub_822FC5A8, which loads f31 from
0x8209fd28 = 0.0 at entry and returns it on a pool miss, then stores to +52.
Nothing else in the 15876-byte filler writes +52, so the definition leaves a
defaulted Size_Y at 0.0 and the runtime 200 is written later.

Two corrections: the +48/+52/+56 comparison block builds a size-class bitmask
against 1000.0 (constant 0x8209fd20), not a has-value mask; and both earlier
Size_Y derivation candidates are refuted (one is a conditional pick, the other
multiplies into a different struct).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 22:47:43 +00:00
be42e998bc re: the unit filler is sub_82341A20, and its 1.0 constant is not a default
Call graph completes: sub_82341048 allocates 880 bytes, calls the zero-filling
constructor, then sub_82341A20 (3969 instructions, 157 stfs, 892 calls) fills the
fields. A repeated lfs/stfs pattern writes the constant at 0x820854cc -- read from
the .pe as 1.0 -- into ten offsets, which looks like a blanket default.

Checking those offsets in the live objects first shows it is not: they hold
per-unit radian angles (10/15/16/30/40/45/60 degrees), so the 1.0 belongs to the
degree-to-radian conversion, not to a default. The ordinary default is 0 from the
constructor; non-zero defaults like Size_Y <- Size_X are specific derivations.
Incidental and useful: angle fields are radians at runtime, degrees on disc.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 22:18:56 +00:00
71adafe7f7 re: the definition constructor zero-fills -- defaults are derived after parsing
sub_8233FAF8 (0x8233faf8) writes vtable 0x820af844 -- the class dumped from a live
mission -- and every one of its 32 stores writes zero, out past +872. So defaults
are NOT constructor immediates, which was the hypothesis this tick set out to
test. Since a defaulted Size_Y nevertheless reads back non-zero at runtime (always
equal to Size_X), the value must be derived by a post-parse fixup -- the same
shape as the inheritance rule derived statically from sibling records.

Two candidate derivation sites (0x82217e18, 0x823081e8) are recorded as leads
only: the first is a conditional assignment rather than a copy, and offsets 48/52
are generic enough to belong to unrelated structures.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 21:49:48 +00:00
a3868fab5b re: the static route locates the reflective parser and reframes the defaults
sylpheed.db has the machinery named: IdxdLoad_Dispatch 0x824486c0, Idxd_Parse
0x82449640, Reflect_FindFieldIndex 0x8244a2f0, Reflect_SetField 0x8244a4b0.
FindFieldIndex looks a field up by NAME at runtime (strlen + compare), which
supports the reflective-read reading -- but Idxd_Parse is a text parser that
calls SetField on a target object, so a parsed record does exist and the earlier
'no flat record' hypothesis is weakened.

The useful consequence: Idxd_Parse only writes fields the text contains, so a
DEFAULTED field keeps whatever the constructor stored. The defaults are therefore
immediates in each definition class's constructor -- reachable by walking the call
graph above IdxdLoad_Dispatch -- not values to be scanned for in RAM.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 21:21:21 +00:00
bab2f9e6ca re: three probes for the parsed record all miss -- hypothesis: there is not one
Searched RAM for HP 25000 (200+ hits, too common), for the rare float
AttackVesselPoint 0.08 (64 hits, no window holds the unit's other values, one hit
is a code constant), and for the ID string itself (two copies, each pointed at
from -0x10, but the surrounding 256 words hold none of the numbers because that
region is the IDXD string pool where values are ASCII).

Hypothesis recorded as 🟡: IDXD is reflective and the engine likely reads values
from the pool by key on demand, caching only the per-frame ones -- which is
exactly what the 0x820af844 object contains at any dump depth. If so, a defaulted
field has no value anywhere in data and the default is applied by code at read
time, so Route B for the Ratio/Count family needs the read path or the static
DuckDB route, not more scanning. The 13 Size_Y values worked because Size_Y is
one of the cached fields.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 21:00:48 +00:00
f4f3bcb20a re: a deeper window does not help -- the 0x820af844 object is not the definition record
Dumping 512 words instead of 96 finds exactly the same 4 of ~50 disc values, for
all five correlated units, so the rest of the record is not in this structure.
Also corrects the reason recorded last commit: get_f32 is NOT unreliable on
default-heavy records -- it resolves 46-57 numeric fields per unit, which is what
made the emptiness of the correlation measurable in the first place. The one
automated hit (YawDragFactor -> +0x0c) remains false: +0x0c holds the integer 2
as a denormal and collided with the float 2.0.

Next probe is a RAM-wide search for a unit-distinctive value, not a bigger window.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 20:49:19 +00:00
892f1e3979 re: partial field map inside the live definition object, and why the automation failed
Anchoring on a unit whose disc record sets a field locates it in the live object:
Size_X/Y/Z (+0x30/34/38) and HP (+0x54) confirmed across five capital ships and
the player fighter; +0x74 (0.8) and +0x84 (0.97) are probable ThrusterRatio and
ResistanceParalyze but rest on a single anchoring unit; +0x40 varies per unit and
is unidentified.

live_offsets.rs automates the correlation and currently produces one hit which is
false -- YawDragFactor 2.0 collided with the integer 2 at +0x0c stored as a
denormal. Causes recorded: get_f32 is unreliable on default-heavy IDXD records
because the value-before-key pairing shifts, and 96 words only reaches +0x180
while RadarRange/FCSRange sit beyond it. Next run dumps 512 words.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 20:36:57 +00:00
3322202732 re(route-b): 13 defaulted Size_Y values read out of the running game
Live definition objects carry no name, so identity comes from the values:
unit_signatures.rs prints (HP, Size_X/Y/Z) for every disc unit and vessel, and a
live object is the record whose known fields it reproduces. 7 of 14 match a disc
record outright; the other 7 match nothing because their records default a field
-- 18 of 23 vessel records are missing at least one, nearly always Size_Y.

Matching each single-default record against the live object that reproduces its
remaining fields resolves 13 values (Destroyer 200, Cruiser 600/700, ASFrigate
80, ADAN Destroyer 300, Acropolis 400, ISCMissile 300, plus _Inv/_EX variants).
Every one equals that unit's Size_X, so the engine's own parsed definitions
confirm the statically-derived inheritance rule.

Limits stated: variants share one live object, and the ...Ratio/...Count family
is not resolved -- their offsets in the live object are still unknown.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 20:28:55 +00:00
a836f8e9ea re: live unit definitions from a running Stage 02, and the recipe that gets there
The runtime track is unblocked. Two environment facts cost most of the effort:
audio must be --audio --apu=sdl WITH SDL_AUDIODRIVER=dummy (muting with --apu=nop
fills the log with CreateDriver failures and the guest never passes the movie),
and everything must happen inside ONE blocking foreground call because anything
outliving its call is reaped. Boot is 25s to the flight HUD once caches are warm,
which is what makes launch-and-dump fit in one call. numpy/PIL are absent so the
analysis scripts do not run; gmem.py is stdlib and does.

Result: 14 live definition objects dumped (vtable 0x820af844, 96 words each).
The +0x54 column reads as HP across three orders of magnitude and +0x30..0x38 as
Size_X/Y/Z, corroborating the earlier single-snapshot layout, and five of the
fourteen have Size_Y == Size_X exactly, supporting the inheritance default rule.
Open: no name/id field in the first 96 words, so objects are not yet matched to
their disc records.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 20:18:32 +00:00
4d8c1b9457 docs: bring INDEX and BACKLOG up to the measured state
INDEX's XBG7 row still said 5480 decode (87.1%) and 125 of 681 shared resources
failing; it is now 6209 of 6294 (98.7%) with zero real meshes disagreeing across
containers and 46/46 capture-verified drawn buffers. The capital-ship row blamed
an XBG7 mis-decode for the user-reported assembly bug -- that mis-decode (a shared
turret ~100x too large) is fixed, so the BACKLOG entry is marked resolved at the
format layer, keeping the viewer-side pointers and the note that no metric caught
it: it took rendering the ship and looking.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 19:02:54 +00:00
33a7bf836b perf(mesh): memoise the whole-container decode
Filtering after the assignment made every subset query a full decode (~15s on a
50MB container). full_decode_cached memoises it per container -- fingerprint is
length plus three sampled 4KB windows, keyed with min_consistency, last four kept.
Decoding five ships from Stage_S02 in turn: 10.5s for the first, then 48us-1.4ms.
A stage now costs one decode rather than one per ship. Ten suites green, viewer
builds, and a spot-checked resource still lands on the same offset.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 18:57:50 +00:00
c79c0f6ccf fix(mesh): filtered decode must not depend on the requested subset
models_named pruned to the wanted set BEFORE distinct assignment, so collision
resolution saw a different resource population and returned different offsets:
27 of 356 resources in Stage_S02 decoded differently when asked for alone,
including real geometry (f001_bdy_30, f106_sld_02_l/m/d, f101_wep_01_l). Both the
viewer and assemble_ship decode subsets, so both could disagree with the
container's own answer. This was a regression from distinct assignment itself.

Fixed by filtering the OUTPUT: the assignment always runs over the whole
container. One-name, three-name and full decodes now agree exactly. Cost: a
single-resource query on a 50MB container goes from near-instant to ~15s;
per-container caching is the follow-up. Ten suites green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 18:47:41 +00:00
e8434541f2 re: monotone assignment refuted again -- box identity needs descriptor data
XBG7_MONOTONE=1 enforces descriptor order per (stride, vtx, idx) signature: 89
minority decodes, unchanged. Monotonicity constrains order WITHIN a container
while the disagreement is BETWEEN containers, which hold different numbers of
these boxes in different arrangements. The remaining 89 are bounding-box identity
ambiguities needing descriptor-level information, not another anchoring
heuristic. Knob kept, default off, measurement recorded; suites green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 18:30:58 +00:00
1d8b783d26 re: all 89 remaining disagreements are 24-vertex boxes -- no real mesh disagrees
Checking the vertex count of every minority decode: all 89 are 24-vertex
resources, including e101_wep_01_l, which last commit called the one real
geometry disagreement -- it is a 24-vert box too. So after this thread's fixes no
real mesh on the disc decodes differently in different containers; what remains
is structurally identical bounding boxes swapping identities, which needs an
ordering rule rather than a validity gate. Monotone anchoring was refuted before
but under a decoder with other defects, and is now cheap to judge: 89 -> 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 18:11:20 +00:00
cdaeac8e1b re: the consistency figure is mostly composite bounding boxes -- real disagreement is 1
consensus_check names the minority container instead of just flagging
disagreement: 89 minority decodes across 477 resources with a majority, and 88
are scene composites. A composite's descriptor carries a 24-vertex bounding box
(e_rou_e106 -> 22x22x22, e_rou_f106 -> 745x718x718); those boxes look
interchangeable so the assignment shuffles per container. 1141 of 6209 decoded
resources have scene nodes. Counting only real geometry the disc has ONE
disagreement: e101_wep_01_l in Stage_S25.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 18:02:06 +00:00
0625976ed7 re: the coverage fix moved 29 anchors, 22 of which carried another resource's geometry
Whole-disc comparison at XBG7_COVER_SLACK=4 vs =1: 29 resources changed anchor,
3 stopped decoding, 6207 unchanged. Of the moved ones present in several
containers, 0 matched the sibling consensus before and 9 after -- it moved them
onto the block their own copies agree on and none away. 22 of 29 were carrying
ANOTHER resource's geometry under their own name, including a shift chain in
Stage_S28 where n054_bdy_l held n056_bdy_l's mesh and n056_bdy_l held
n055_bdy_l's. Confidently-wrong-under-the-right-name is invisible to every
count-based metric; the coverage invariant is what separated them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 17:40:22 +00:00
095816834a re: CORRECTION -- the static assembler is not at fault, the pre-fix decoder was
Last iteration reported e303_wep_01 as inflated 30-110x by assemble_ship. Wrong:
the composite nodes carry scale 1.0 and orthonormal matrices, and under the
current decoder the turret places as 49x23x42 at +/-179. The 1600x2100x4800 box
only appears with XBG7_COVER_SLACK=4 -- the exact-coverage fix had already
repaired the turret too. The error came from comparing a deliberately pre-fix
render against post-fix measurements.

The containment screen's blindness therefore has a mundane cause: one mis-decode
inflated the envelope and hid another. Kept as a forward-looking invariant with
that caveat.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 17:28:18 +00:00
27fd9f186f re: containment screen fails too -- the static assembler inflates a shared turret
envelope_screen measures per-axis protrusion past the sibling envelope, the
relationship the eye used. It still does not flag e106_bdy_03, and dumping the
static assembly shows why: e303_wep_01's world box is 1600x2100x4800 around a
~400x400x2000 hull, so nothing can protrude. The decode is innocent -- that
resource is 49x23x42 in every container -- so the static assembler is inflating
it 30-110x per axis, non-uniformly. The screen is only meaningful once placement
is trustworthy, and the assembler now has a worse defect than the decoder had.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 17:20:52 +00:00
85ad540a7e re: the other four ships are clean; automating the slab check failed
Rendered f101/f105/f106/e105 statically -- all coherent, no stray masses, so the
e106 slab was specific. slab_screen.rs tries to automate the check by comparing
each part's min-axis extent to its ship median, but it produces identical flags
with and without the coverage fix at both 4x and 2.5x: it never sees
e106_bdy_03, the part it was built for. The eye used relationship (a mass apart
from the hull), not scale; a containment test is the right analogue and is not
built. Kept for what it does show: f002_bdy_22's 100000-unit tether and
t901_e01_D's mast are legitimate, and capture-verified f101_bdy_01 flags at 6x.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 07:22:43 +00:00
f340815db6 fix(mesh): require exact pool coverage -- found by rendering, not by a metric
Rendering assembled e106 from Stage_S02 showed the old slab: e106_bdy_03 spanning
600x1600x998 where three other containers give 276x236x941. Its anchor had slack
3, and the coverage gate tolerated up to three unreferenced tail vertices --
tolerance that was hiding a mis-anchor, since real blocks reach their last vertex
exactly (8580 of 8629). Requiring exact coverage moves it to the block the other
containers agree on and the slab disappears.

Costs 3 resources (6212 -> 6209), inconsistency 39 -> 38, capture oracle
unchanged at 46/46, suite green. Evidence: captures/e106-cover-slack-before-after.png

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 06:56:49 +00:00
9d33345560 re: the grouped pivot floor is not the blocker either -- anchor work plateaus at 98.7%
Sweeping XBG7_GROUPED_CONSISTENCY 0.85 -> 0.80 -> 0.75 decodes no additional
resources and leaves inconsistency at 39, while changing which geometry some
grouped models get -- strictly worse, so 0.85 stays. With the degeneracy/extent
fix already refuted, the remaining 82 misses are not a threshold away; they need
a structural answer (marker lists that do not map onto stored blocks), which
means a capture, not more tuning. Records the state of the four shipped changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 06:34:41 +00:00
2f0ce19f68 re: 98.7% coverage, and the scale-free degeneracy fix is refuted
Under the winding gate, coverage is 6212/6294 (98.7%) with 82 misses left,
attributed 42 degenerate/extent, 31 winding, 9 coverage, 0 connectivity. The
biggest bucket turns out NOT to be the blocker: replacing the absolute area test
with a scale-free collinearity test decodes no more resources and raises
inconsistency 39 -> 44, and dropping the extent floor to 0.05 adds two. Both stay
as opt-in knobs (XBG7_REL_DEGEN, XBG7_MIN_EXTENT) rather than defaults. Also
fixed another stale default label in edge_cap_sweep.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 06:19:38 +00:00
f835705b48 fix(mesh): winding consistency replaces the connectivity heuristic
Gate attribution put connectivity behind 153 of 225 misses -- the largest
blocker, and the gate already known to reject a capture-proven block. Testing it
against winding consistency (an objective topology signal: ~1.0 or ~0.0 for a
real mesh, ~0.5 for a mis-carve) shows a floor of 0.70 with connectivity inert
dominates the previous default on both axes: 6212 resources decoded (+143) with
39 shared inconsistencies (-17), capture oracle unchanged at 46/46, twin
invariant clean, coverage invariant intact. Suite green.

The 0.80 cliff (5770 resources, 0 inconsistent) is documented, not taken --
consistency is the weaker witness, and both points are one env var apart.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 05:47:01 +00:00
ee2b98341d fix(mesh): pre-pivot sub-meshes must cover their pool, not just index in range
The last two blocks that under-covered their vertex pool were f102_break.dat and
f104_break.dat in ptc_pack.xpr, each reading a neighbouring block's index buffer
against the wrong declaration (414 verts indexed to 404; 160 indexed to 79).
Their marker lists do not map onto the stored blocks -- only 2 of 9 and 4 of 10
sub-meshes decoded at all. Requiring coverage (max_idx + 4 >= vtx_count) for
pre-pivot sub-meshes drops exactly the mismatched pieces.

Every decoded sub-mesh disc-wide now covers its pool: 8580 at slack 0, 49 within
tolerance, none beyond, none negative. Coverage 6069/6294, inconsistency 56,
truth table 46/46 -- all unchanged. Suite green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 04:57:49 +00:00
6634d79c2e fix(mesh): grouped pools no longer emit sub-meshes with out-of-range indices
coverage_audit measures index coverage per decoded sub-mesh. 8586 of them
reference their last vertex exactly, so the 'buffer not covered' gate is well
founded -- but 18 had NEGATIVE slack: indices up to 364 vertices past the end of
their own buffer, emitted because anchor_grouped_meshes reads pre-pivot
sub-meshes unconditionally. Quality gates stay relaxed there (a tiny flat lead
part is legitimately poor) but index range is now required.

Coverage 6069/6294 unchanged, inconsistency 56 unchanged, truth table still 46/46
claimed, suite green; the vertex total drops by exactly the 1546 garbage verts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 04:41:17 +00:00
c9c98cf942 re: coverage is 96.4% (6069/6294) -- and the 225 misses get a gate breakdown
undecoded.rs supplies the denominator the coverage numbers never had; the disc
holds 6294 XBG7 resources, 6069 decode, 225 are searched and missed, 0 lack a
descriptor. gate_histogram.rs attributes each miss to the furthest gate its best
candidate reached: 120 connectivity, 74 grouped-pool (different path), 15
degenerate/extent, 9 winding, 7 buffer-not-covered. Recorded as a work-list, not
a verdict -- a wrong candidate can pass more gates than the true block.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 04:22:43 +00:00
db8104ab99 re: n206 was fixed after all -- the audit was classifying by geometry, not buffer
debug_grouped_report (why_rejected) shows n206_02's alternative pool is ACCEPTED
at pad 0 under production gates and is in the candidate list -- and the decoder
does take it: n206_02 now anchors at 0x342d984. The 'still collapsed' reading
came from the audit comparing decoded geometry, and that offset holds a direct
(unmirrored) copy, so a separated pair still looked identical. The audit now
requires a SHARED BUFFER to call it a collapse: disc-wide 18 exact mirrors, 16
related, 0 collapses, 0 unrelated -- and the regression test drops its exception.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 04:10:05 +00:00
bb0c94c0ce fix(mesh): distinct assignment now covers grouped pools too
anchor_grouped_meshes takes the same taken set; a colliding grouped model is
re-placed whole past everything claimed, or keeps what it had. Runtime oracle
unchanged (45/46 exact, 0 unclaimed), coverage unchanged (6069), cross-container
inconsistency 62 -> 56, suite green.

It does not clear the n206 twin collapse: no alternative pool validates for the
loser, so that pair is a validator case (like eng_02_l before the cap move), not
a selection one. Also fixes a stale '0.28 (default)' label in edge_cap_sweep.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 03:53:10 +00:00
fd34d350f2 test: lock in the twin invariant -- 0 unrelated pairs disc-wide, 1 known collapse
twin_mirror_audit applies the capture-derived rule to all 166 containers: of 34
equal-count twin pairs, 18 are exact X-mirrors, 15 related another way, 1
identical, 0 unrelated. Two calibration fixes were needed first (authored halves
need a tolerance, and a mirrored pair may be stored in another vertex order).
The one collapse, n206_01/_02, is a grouped-pool pair -- the path distinct
assignment excludes -- so it names the next target. Added a disc-gated
regression test; refreshed the stale ignore message on the consistency test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 03:44:29 +00:00
55e1fe3783 re: the break-composite alarm is false -- the container stores 3-6 copies of each buffer
locate_draw counts copies of a captured buffer. The f105 parts _rou_f105_break
claims exist 3-6 times over (the 2336-vert one: 6 direct AND 6 mirrored), and
every live LOD checked is anchored on a direct, byte-identical copy -- so the
composite taking the drawn copy costs nothing. This also calibrates the oracle:
'exact' (anchored at the drawn offset) is stricter than correct, so 45/46 is a
lower bound. Open: a resource landing on a MIRRORED copy would be a real defect
invisible to every count-based metric.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 03:32:58 +00:00
7f1ac41563 fix(mesh): raise the connectivity cap 0.28 -> 0.42 on runtime evidence
Swept against the 46 capture-named Stage_S02 buffers with distinct assignment in
place: 0.28 anchors 40 exactly and leaves 4 unclaimed; 0.42 anchors 45 and leaves
none; nothing above 0.42 improves further, so it is the least permissive value
that captures the whole gain. 589 more resources decode, nothing is lost. The
cross-container consistency proxy worsens (46 -> 62) -- it cannot see a
systematic mis-anchor, and where the two disagree the capture wins. Suite green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 03:25:50 +00:00
d83bdd3b68 fix(mesh): distinct anchor assignment -- no two resources may claim one buffer
Selection was per-resource and greedy, so two resources could take one vertex
buffer while a valid one sat unused. A runtime capture proved that wrong for the
mirrored e106 hull twins: the container holds both halves and the engine draws
each from its own address. Now the first claimant keeps a buffer and later
resources re-anchor past everything already claimed (coverage can never regress;
grouped-pool models untouched).

Against the 46 capture-named Stage_S02 buffers: exact anchors 29 -> 40, unclaimed
12 -> 4. Disc-wide: 5480 resources decoded (unchanged), cross-container
inconsistency 125 -> 46.

The twins' mirror therefore lives in the DATA, not in the placement matrix: the
embedded e106_bdy_02 row and the two assertions encoding the old convention are
updated, each with the reason recorded. Full suite green incl. disc/ISO gates.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 03:16:51 +00:00
1815490d01 re: scored against the runtime, relaxing the cap is monotone -- the regressions are collisions
Against the 46 capture-named Stage_S02 buffers: 0.28 gives 29 exact anchors,
0.42 gives 31 with 0 lost and 2 fewer unclaimed. The 18 cross-container
consistency regressions are a different phenomenon: the decisive one is the
32-vertex buffer at 0x24ce5f4, unclaimed at 0.28 and claimed by BOTH f303_body_l
and e302_barrel_l at 0.42 -- a collision from greedy per-resource selection, not
a mis-placement. So the cap and the selection must change together.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 03:06:15 +00:00
b58f42e46d re: the capture is Stage_S02 -- provenance corrected, oracle grows to 46 buffers
capture_truth_scan places every drawn buffer across all 166 containers by modal
vbase-offset. Stage_S02 wins with 64 matches at one constant against Stage_S01's
16, and the logs carry f101/f105/f106/e105 -- a Stage-02 cast. Stage_S01 looked
consistent because the shared block is duplicated verbatim (twins 0x116F0 apart
in both), so the earlier structural findings hold; only the loaded-container
claim was wrong. The S02 table places 46 buffers, 12 claimed by nobody, and
resolves the six Stage_S01 mystery buffers as e105 parts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 02:59:40 +00:00
df7a10749a re: calibrate the connectivity cap -- +612 resources against 18 consistency regressions
XBG7_EDGE_CAP / XBG7_SMALL_TRIS make the threshold sweepable (defaults unchanged,
full suite green). Above 0.417 the capture-proven eng_02_l anchors exactly right
and no e106 part regresses, and nothing that decoded at 0.28 is lost -- but ~250
existing anchors move silently and 18 shared resources lose cross-container
consistency. Not changed: the movers have no oracle yet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 02:47:07 +00:00
845b63d7dd re: eng_02_l's real block is adjacent -- the connectivity heuristic rejects it
debug_find_index_buffer scans the container for an index buffer that validates
against a capture-proven vertex buffer. For eng_02_l nothing validates with the
connectivity test on; with it off the nearest hit is exact pad-0 adjacency
(vb-ib = 144 = 72*2). The block's mean_edge/diag is 0.417 against a 0.28 cap --
the documented false positive for coarse LODs, now caught with ground truth.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 02:31:53 +00:00
dde52c02e7 re: correct the 3.4% reuse figure -- the capture dedups by (vbase, transform)
Read off the emulator patch rather than inferred: CaptureShipDrawForRE dedups by
(vbase, WVP hash), so a buffer drawn repeatedly at one transform appears once.
The 3.4% counts multi-instance placement, not buffers serving several parts, and
is not the population evidence about sharing it was written up as. Also pins
vcount = buffer capacity and indices = that draw's num_indices.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 02:24:44 +00:00
51723af59a re: the twins' correct block validates -- distinctness is a real fix; eng_02_l is not
debug_try_anchor asks validate_block directly at the capture-proven offsets. Both
119-vert twin buffers are accepted by both twins (so the correct block lost the
first-match race, and a distinct assignment fixes it); the drawn 51-vert bridge
buffer is accepted by both bridge resources; eng_02_l's proven offset is rejected
outright, even with the pad widened to 64 -- a validator gap, not a selection one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 02:17:55 +00:00
76a433f75c re: the proven offsets ARE candidates -- these mis-anchors are selection failures
debug_vertex_run_starts exposes the anchor scan's candidate list: Stage_S01 has
15710 stride-24 starts and all three capture-proven offsets (0x3c55d8 twin,
0x40e418 bridge, 0x44a32c eng_02_l) are among them. anchor_pool_mesh takes the
first that validates, so an earlier lookalike wins. Scoped to the current
decoder's e106 cases; does not overturn the residual-51 finding.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 02:11:41 +00:00
26f1bdf6fd re: exact anchor offsets (GameMesh.vbuf_offset) -- correcting yesterday's defect table
The first read of the capture-truth table located our resources by searching the
container for their leading vertices, which reads much worse than reality: the
same leading run occurs at several offsets in one container. GameMesh now carries
the offset the anchor scan actually chose, so the comparison is exact -- 4 of the
ship's drawn buffers are anchored correctly, 2 are the twin collapse, and 2 are
real mis-anchors of a size we do decode (brg 51 verts, eng_02_l 44).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 02:04:55 +00:00
3245aca8cb re: the capture names file offsets -- the twin collapse is an anchoring error
Locating each drawn buffer's positions inside Stage_S01.xpr shows vbase - offset
is one constant (0x1A94FFF4, same in two runs), so a capture gives ground truth
at file-offset granularity. Read against our anchor scan it is a defect list:
full/_m resources starting at their own _l buffer, eight drawn buffers claimed by
nobody, and the bdy_01_l/bdy_02_l twins sharing one buffer while the container
carries both halves (0x3b3ee8 and its exact X-mirror at 0x3c55d8).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 01:55:13 +00:00
aa82d293a9 re: the capture logs are the sharing oracle -- engine reuses a buffer only 3.4% of the time
The raw Canary capture logs from the 2026-07 sessions are still on disc at
/sylph-home/re/shipcap/xenia_ship_capture_*.log, and their DRAW lines carry
vbase -- the GPU vertex base, i.e. ground truth for which buffer the engine draws
a part from. That is precisely the oracle the shared-decode question needs, and
it needs no new capture run.

Restricted to the ship-geometry stride 24, across the three logs: 6093 draws from
2291 distinct vbases, and only 77 vbases (3.4%) drawn more than once. So one
buffer serving several parts is the exception in the engine, while our decoder
has 19% of resources sharing geometry.

The measures differ (draws-per-buffer vs resources-per-geometry) so this is
evidence not proof, but it points the same way as e106_bdy_02 == e106_bdy_03_m:
much of that 19% is anchoring error rather than asset reuse.

Per-part use is already available: correlate_capture matches a draw to a resource
by vcount plus decoded positions, and the same match yields each part's vbase --
so two resources our decoder gives identical geometry can be checked directly,
different vbase meaning our shared decode is wrong.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 01:40:56 +00:00
6d96446735 re: the descriptor does not address geometry, and consistency does not prove reuse
Two follow-ups, both negative, both worth recording so the next attempt does not
repeat them.

The descriptor cannot replace the candidate scan. If entry.data_offset located
the geometry, anchoring would be direct addressing. Across e106's resources in
Stage_S01, anchored_vb - data_offset ranges from 1199052 to 4173988 with no
constant or stride; data_offset locates the DESCRIPTOR and none of the first six
descriptor words tracks the vertex pool.

And yesterday's "1241 of 1242 pairs identical in every container, so sharing is
legitimate reuse" is weaker than it read. A SYSTEMATIC error is invisible to a
consistency test, because it is consistent. The same dump shows e106_bdy_02 and
e106_bdy_03_m anchoring to the identical offset (1505556), and e106_bdy_01_l with
e106_brg_01_m (4251208) -- a hull half and a different body's medium LOD, a hull
half and a bridge LOD. Different parts; one of each pair is wrong.

Honest position: sharing is common (19%), some is certainly legitimate (a
mirrored twin pair genuinely shares one geometry) and some certainly is not, and
cross-container consistency cannot separate them. What can: comparing a shared
pair against a runtime capture.

Instrumentation reverted; only docs land here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 01:32:34 +00:00
f655c90b0c re: shared decodes are mostly legitimate reuse -- correcting yesterday's claim
I wrote that "two distinct resources sharing one decode is itself the bug" when
withdrawing the neighbourhood anchor. Measured, that is wrong.

1043 of 5480 decoded resources (19%) share geometry with another resource, and of
1242 related pairs that share a decode somewhere, 1241 are identical in EVERY
container they co-occur in. That is what legitimate asset reuse looks like, not a
defect. A mirrored pair like bdy_01/bdy_02 is SUPPOSED to share one geometry with
the reflection applied at placement -- which is precisely what apply_twin_mirrors
does.

So the twin-mirror regression was never about sharing. It is about WHICH of two
mirrored buffers is canonical: the disc holds an X+ and an X- version, the engine
treats one as the base, and the neighbourhood anchor moved these resources to the
nearer buffer, which is the other one. The fix is to pin the canonical buffer
with the capture as oracle, not to split the twins apart.

Exactly one pair is provably mis-anchored by this test: e105_bdy_02_l /
e105_brg_m, identical in 7 of the 15 containers holding both and different in the
rest -- two names cannot be the same geometry only sometimes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 01:25:44 +00:00
aedad811bc test: fix the stale default disc paths -- three tests could never run unaided
texture_disc.rs and mesh_disc.rs fall back to "/home/fabi/RE Project Sylpheed/..."
when SYLPHEED_ISO / SYLPHEED_RES3D are unset. The directory is "RE - Project
Sylpheed"; the fallbacks were missing the " - ", so stage_models_decode,
stage_models_sweep and stage_models_quality_audit failed with NotFound for anyone
who did not happen to know the env var. They now pass unaided (10/10 in
mesh_disc).

Found while auditing what the suite actually exercises after withdrawing the
anchor change: an ISO-gated test skipping, and an ignored test failing on a typo,
are both "green" in a normal run.

Full state, with SYLPHEED_ISO/DISC/RES3D set and --include-ignored: 82 lib tests
and every disc/ISO suite pass; the single failure is
shared_resources_decode_identically_in_every_container, which is deliberately
written as the target state and #[ignore]d.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 01:18:10 +00:00
64d372c7e8 revert(mesh): withdraw the neighbourhood anchor -- it regressed the e106 twin mirror
The neighbourhood anchor (f18d591) and its refinement (27a0701) took
cross-container inconsistency from 125 to 51 with coverage unchanged, and made
e106 render as a destroyer rather than a slab. Both are reverted.

ship::tests::static_assembly_matches_runtime_capture is gated on SYLPHEED_ISO, so
it SKIPS in an ordinary cargo test -- which is why the regression was invisible
in every suite run so far. With the ISO it fails:

  e106_bdy_01: static M row0 [-1.0, 0.0, 0.0] != captured [1.0, 0.0, 0.0]

e106_bdy_01 and _02 are a mirrored pair whose two buffers hold the same geometry
reflected in X, and BOTH resources currently decode to the SAME buffer (identical
counts, span and mean_x). apply_twin_mirrors picks which instance to reflect from
the sign of that mean_x, so which buffer wins flips the decision:

  before  both twins mean_x = -66.83  -> mirror bdy_02  (matches the capture)
  after   both twins mean_x = +66.83  -> mirror bdy_01  (contradicts it)

Neither is right -- two resources sharing one decode is itself the bug and the
mirror heuristic has been compensating. The capture is ground truth, so a change
that contradicts it does not ship. The real fix must give each twin its own
buffer first.

Kept from the attempt: this test now also asserts the SET of static placements
against the capture (allow-list {e303_wep_01} for vbase dedup), so extra
placements can finally fail it -- the direction it could never fail in before.

Docs, backlog, INDEX and the ignored test's message all corrected to say
diagnosed-not-fixed rather than fixed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 01:08:41 +00:00
0f9c95c52e re: selection fixes are exhausted for the last 51 -- the correct block is not a candidate
Implemented the proposed tiebreak as a last resort (take the attractor only if
nothing else validates), keyed first on "all coordinates multiples of 50" and
then on the sharper "all coordinates integral" -- the attractor reads
(42, -900, 2400), (-600, -500, -950) while real geometry carries fractions like
(24.55, 9.84, 4.46). Neither changed anything: still 51 inconsistent, 5480
decoded.

The null result is the finding. A mechanism that defers the attractor whenever
another candidate exists, and changes nothing, means no alternative candidate
validates for any of the 51: the correct block is not in the candidate list at
all. So the residual is not a selection problem and no reordering, scoring or
tiebreak will move it.

The frontier is vertex_run_starts -- the unit-normal run scan that builds the
candidate list -- which emits no start for these resources' real vertex buffers.

Both attempts reverted; only docs land here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 00:57:09 +00:00
343a26ecc0 re: the remaining mis-decodes share one attractor, not pairwise confusion
Tested the tempting explanation for the last 51 -- that _l/_dead variants share
their base's vertex and index counts, making them mutually confusable and
adjacent so locality cannot help. It is FALSE: 2714 variant/base pairs across
every container, and exactly zero share identical counts.

What is actually happening is better news. e010_bdy_01_l is 171 verts / 90 tris
and NO other resource in its container shares those counts, yet in Stage_S02 and
S26 it decodes to 1600x2100x4800 -- the same bounds e303_wep_01 (172/110)
produced before the fix. Differently-shaped resources land on the same place, so
the attractor is a region of round axis-aligned box data that validates for many
(vtx, idx) shapes at once, not "another mesh with my shape".

That also explains why the neighbourhood fix helped so broadly: it steers
resources away from one strong attractor rather than resolving many pairwise
confusions.

Candidate next step recorded with its risk: de-prefer candidates whose sampled
positions are all multiples of 50 with a large span. It must be a TIEBREAK
between validating candidates rather than a rejection -- an earlier sweep for
that signature also flagged legitimate e_rou_* composite proxies -- and it needs
the same gate (decoded must not fall from 5480).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 00:46:32 +00:00
27a0701e0d fix(mesh): refine the anchor map before using it -- inconsistency 63 -> 51
Pass 1's anchor map contains exactly the mistakes the neighbourhood is meant to
correct, so a resource sitting beside a mis-anchored neighbour inherits a bad
reference. Re-anchoring against the improving map and repeating converges
quickly: two rounds, and a third changes nothing (the loop exits early when a
round is a fixpoint).

  before                 decoded 5480/6294  inconsistent 125
  neighbourhood anchor   decoded 5480/6294  inconsistent  63
  + refining the map     decoded 5480/6294  inconsistent  51

Coverage still unchanged. The 51 that remain cluster in _l (LOD) and _dead
variants -- e001_l, e010_bdy_01_l, e106_eng_02_l, _rou_f302_base_dead,
e303_base_dead and friends. A plausible reading is that a variant shares its
base's vertex and index counts, making the two mutually confusable so that
locality cannot separate them; recorded as untested rather than asserted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 00:39:35 +00:00
f18d5919f7 fix(mesh): anchor XBG7 resources by neighbourhood -- inconsistency 125 -> 63, ships render right
anchor_pool_mesh took the FIRST candidate in file order from a container-global
vertex-run scan, so a resource could be handed another resource's block whenever
both shared (stride, vertex count, index count). Both blocks are real geometry and
both pass every quality gate, so only position separates them.

anchor_pool_mesh_near now tries candidates in order of distance from a reference,
and anchor_models_filtered runs two passes: pass 1 anchors first-match to learn
where resources land, pass 2 re-anchors each resource preferring the median anchor
of its +/-2 descriptor neighbours. Too few anchored neighbours -> keep pass 1, so
nothing regresses to guesswork.

  before  decoded 5480/6294  shared 681  inconsistent 125
  after   decoded 5480/6294  shared 681  inconsistent  63

Coverage unchanged, inconsistency halved. e303_wep_01 decodes to 49x23x42 in ALL
containers now, and e106 renders as a destroyer instead of a slab -- its two
shared turrets symmetric at X[-203,-154] and X[154,203]. That resolves the
user-reported "capital ships assemble wrong" for this cause.

The filtered path needed care: models_named (what the viewer uses) dropped
non-wanted resources, which would have left filtered decodes with no
neighbourhood and silently kept the old behaviour. Resources are now collected
regardless of the filter, but only the asked-for ones and their +/-2 neighbours
are decoded in pass 1, so a filtered decode stays proportional to what was asked.

63 cases remain; mesh_consistency_disc stays ignored and now records 63, not 125.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 00:31:20 +00:00
d660705c47 re: the correct anchor is already a candidate -- locality selects it, monotonicity does not
Enumerating every validating candidate for e303_wep_01 in Stage_S02 gives exactly
two:

  vb = 18403456   span 1600 x 2100 x 4800   <- taken, only because it is first
  vb = 52257440   span   49 x   23 x   42   <- correct, the size all 11 good
                                               containers give

So the scan is not missing anything; the wrong block merely appears earlier in
file order.

Monotonic anchoring is REFUTED as the constraint: recording each resource's
accepted anchor in descriptor order gives 25/47 increasing steps in Stage_S01 and
130/248 in Stage_S02, no better than chance. Locality holds instead -- in
Stage_S02 the descriptor neighbours anchor at 51974668 and 52218424, the correct
candidate is 52257440, and the wrongly-taken block sits at 18403456, two thirds
of the file from its own family.

Proposed rule, needing no new format knowledge: among validating candidates
prefer the one nearest the neighbouring resources' anchors, falling back to
first-match when there is no neighbour yet. It selects 52257440 here.

Not implemented: it moves the anchor for all 6294 resources, so it needs the
before/after measurement (decoded must not fall from 5480, inconsistent should
fall from 125) and then un-ignoring mesh_consistency_disc.

Instrumentation reverted; only docs land here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 00:16:22 +00:00
7c514e3a57 re: ROOT CAUSE of the silent XBG7 mis-decodes -- the candidate list is container-global
anchor_pool_mesh walks candidates from vertex_run_starts(bytes, data_base,
stride): ONE scan of the whole container per stride, shared by every resource of
that stride, and it accepts the first candidate that validates. Nothing ties the
chosen block to the resource it belongs to, so two resources sharing (stride,
vertex count, index count) are interchangeable to this search.

The wrong block is not distinguishable by quality. Tracing the accept for
e303_wep_01:

  Stage_S01  vb=4600480   span   49 x   23 x   42   passes 0.85 = true
  Stage_S02  vb=18403456  span 1600 x 2100 x 4800   passes 0.85 = true

Both clear the strict winding gate, because the wrongly-taken block IS real
coherent geometry -- another resource's. That rules out a family of fixes: no
threshold, scoring, or best-of-N selection can help, which is exactly why the
previous iteration's attempt changed nothing.

The search space must be constrained instead. Two candidates recorded, ordered by
how much new format knowledge they need: per-resource data extents from the XPR2
resource table, or monotonic anchoring (resource k's vb after resource k-1's) if
data blocks follow descriptor order -- testable against the 556 resources that
already decode consistently.

Instrumentation reverted; only docs land here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 00:08:38 +00:00
b5a4764567 re: the XBG7 silent mis-decode is in the per-block anchor, not the grouped-pool one
Tried the obvious fix: make anchor_grouped_meshes pick the best-scoring vb0
instead of the first candidate clearing the 0.85 gate. It changed nothing --
still 5480 of 6294 decoded, still 125 inconsistent -- and instrumenting the pivot
loop shows why: for e303_wep_01 that function never runs. The resource has a
single sub-mesh, so it goes through the per-block adjacency path
(anchor_pool_mesh) instead.

Recorded because the grouped-pool anchor is the prominent, well-documented one
and the natural first suspect; the fault is in the other path.

The change is reverted -- untargeted, unproven, and it added a scoring path for
no measured benefit. The idea behind it (several vb0 candidates can clear the
gate, and first-in-scan-order is an arbitrary tiebreak) still applies to whichever
anchor is actually at fault.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 00:00:37 +00:00
f34280476d test: lock today's format findings into disc-wide guards
Each finding today was originally missed by reasoning from a sample, so these
assert DISC-WIDE invariants rather than one hand-picked file.

  ui_surfaces_disc.rs (3 passing)
    every_t8ad_on_the_disc_decodes            -- all ~19216 surfaces; the old
                                                 256-grid model looked like 96%
    lsta_count_equals_sprites_plus_primitives -- header counts T8aD AND PRMD,
                                                 64/64, which is what made the
                                                 count look unreliable
    ratc_nesting_is_exactly_one_level         -- nested records are leaves; zero
                                                 grandchildren disc-wide

  mesh_consistency_disc.rs (1 ignored, deliberately)
    shared_resources_decode_identically_in_every_container

The mesh test is written as the TARGET state, not a snapshot of the bug: a
resource shared by several containers must decode to the same bounds, which today
fails for 125 of 681 shared resources. Fixing the anchor scan makes it pass;
un-ignoring it is then the last step rather than a rewrite. It only compares
decodes that agree on vertex/triangle counts, so "found different geometry" stays
a separate question from "placed the same geometry differently".

All suites green: 81 lib + the disc guards, with 2 ignored.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 23:50:20 +00:00
140856b3f9 docs(re): session log for 2026-08-11, and correct the capital-ship INDEX row
The capital-ship row still said placement was the open question. Today's work
says otherwise: placement is sound (hull static-exact, cross-id mounting is 2
pairs across 335 ships) and the user-reported "ships assemble wrong" is an XBG7
mis-decode instead. The row now says that and points at the backlog and the mesh
doc, and keeps the one-way-test problem visible.

SESSION-2026-08-11.md summarises the run for review, leading with the single item
that needs the user's decision (editing save slot 01, deliberately not done) and
separating findings, the two disc defects found, and the process notes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 23:41:58 +00:00
4097e8503f re: a detector for silent XBG7 mis-decodes -- 125 of 681 shared resources fail it
Following the e106 slab to its cause. e303_wep_01 decodes from 14 containers: in
11 it is a 49x23x42 turret with organic vertices, in Stage_S02/S08/S26 the same
resource -- identical 172 verts and 330 indices -- decodes to 1600x2100x4800 of
axis-aligned box corners with (0,0,1) normals. The anchor scan found a different
buffer that happens to share both counts, so every size-based check passes. That
is the "declined for location, not format" risk succeeding wrongly instead of
declining.

The detector needs no ground truth: a resource shared by several containers must
decode to the same bounds. 681 resources appear in >=2 containers and 125 decode
to different bounds while reporting identical vertex/triangle counts -- a lower
bound, since a resource wrong everywhere is invisible to it. _rou_f401 is
62x25x10 in 16 containers and 4738x3147x4738 in 2; _rou_e011_wep05 gives four
different spans across 8.

Majority vote would resolve 104 of the 125 (14 are exact 50/50 splits) and agrees
with ground truth in the one case that has a render and a runtime capture behind
it. Recorded as a heuristic, not applied: for _rou_e302_base_break the majority
is the LARGER span and nothing yet says which is right. Flag, do not silently
rewrite geometry on a vote.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 23:34:31 +00:00
c9916bcb41 re: CORRECTION -- the e106 slab is a container-dependent mis-decode, not a stray volume
One iteration ago I concluded assemble_ship was drawing a non-renderable
collision volume. That named the wrong cause, and decoding the same resource from
every container that holds it settles it:

  Stage_S01  172 verts 110 tris  49 x 23 x 42        <- a turret, correct
  Stage_S02  172 verts 110 tris  1600 x 2100 x 4800  <- wrong
  Stage_S08  same                1600 x 2100 x 4800  <- wrong
  Stage_S26  same                1600 x 2100 x 4800  <- wrong
  eleven others                  49 x 23 x 42        <- correct

Same resource, same vertex and triangle counts, correct in eleven containers and
wrong in three. So the placement is legitimate (e303_wep_01 is a small shared
turret cross-mounted on e101/e106), the original author's vbase-dedup explanation
of the capture's silence stands, and my "dedup would show one, not zero"
objection does not survive -- at its true size the turret is ordinary geometry.
The defect is in the mesh decoder.

The wider point: the decoder can produce wrong geometry WITHOUT declining. The
XBG7 audit counted 814 honest refusals; this is the other kind, silently 100x too
large. A screen for the signature (bounds exact multiples of 50, span > 1000)
flags 22-32 models each in S02/S03/S08/S26/S27, but it also catches legitimate
e_rou_* composite proxies, so that is a candidate list and not a bug count.

Next: diff the anchor scan's chosen vb0 for this resource between Stage_S01 and
Stage_S02 -- same resource, two outcomes -- and turn whatever distinguishes them
into a post-decode sanity check so a silent mis-decode becomes a decline.

Kept from the previous entry: the test can only fail one way, and cross-id
placement is genuinely narrow (2 pairs across 335 ships).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 23:25:55 +00:00
c5a5065389 re: the format layer is NOT exonerated -- assemble_ship draws a non-renderable volume
Did the visual the backlog kept naming as the next step, and it overturns the
conclusion. Rendering e106 from the static assembly and from the baked runtime
capture: the capture has 8 placements, the static assembly 11 -- the same 8 plus
e303_wep_01 x2 and a second e106_eng_01. In the render the destroyer sits inside
a white slab that dwarfs it.

That slab is e303_wep_01: 172 verts, 110 tris, bounds X[-1000,600] Y[-1050,1050]
Z[-2400,2400] = 1600 x 2100 x 4800. A real e106 turret (wep_02_01) is 269x179x417
with 772 tris; the bridge is 105x76x305. So it is not a turret -- it reads as a
collision/trigger volume, and whatever it is the game does not draw it: the e106
capture contains no e303_wep_01 at all.

Why it was missed: assemble_ship treats every rou_* composite node as drawable,
the cross-id mount is documented as intended, and the test asserts
count("e303_wep_01") == 2. The capture's silence was explained as vbase dedup,
but dedup would show one instance, not zero -- and the test walks capture parts
looking them up in the static output, so EXTRA static placements cannot fail it.
Same shape as the earlier include_external gap: a test that can only fail one way.

Scope stated carefully: sweeping 335 ships for "ship-scale span with <400 tris"
flags 20 ships and 58 placements over 28 resources, but ONLY the e106 case is
proven (render + capture absence + geometry). Others may be legitimately large
low-poly parts and need the same three checks.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 23:15:22 +00:00
5b8b5e0ab1 re: measure the XBG7 declined set, and close off the descriptor shortcut
"A few multi-stream / quantized bodies remain" declined understates it. Across
all 166 resource3d containers: 6294 XBG7 resources, 5480 decoded (87.1%), 814
declined, in 31 of 166 containers. By name the declined set is 492 e* (enemy
craft), 142 f*, 73 n*, 23 eff*, plus *_dead destroyed variants -- not hero
bodies.

Also recorded as a dead end, so nobody repeats it: the descriptor's third word
looks like (streams << 16) | format -- decoded g001..g003 carry 0x00010001 while
declined t170/t180 carry 0x00020004 -- but histogramming it disc-wide puts
decoded AND declined at every value (0x00010001 alone: 4479 decoded, 328
declined). Its low half tracks sub-mesh count. Decodability is not declared in
the descriptor; it is whether the unit-normal anchor scan can locate vb0, which
the code already tests. 229 declined resources carry the most common word[2] with
under 1 KB of data, i.e. small meshes with too little signal to anchor rather
than exotic formats.

No decode gained this iteration; the gap is now quantified and one attractive
wrong turn is closed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 23:03:58 +00:00
d9c69c566c lsta: the count was never unreliable -- it counts sprites AND PRMD primitives
The module said "a few entries disagree with the actual frame count, so we walk
by the T8aD magic instead". They do not disagree. An LSTA is a display list of
inline elements that are either T8aD sprites or PRMD primitives (the flat
coloured quad the UI bundles use to dim a scene), and the count at 0x04 counts
both: across all 64 lists on the disc, count == T8aD + PRMD, with no exceptions.

The six lists that looked wrong (GP_DEBRIEFING_PILOTLOG, GP_MISSION_SELECT, two
language builds each) each hold exactly one primitive, which is the whole of the
off-by-one.

Also measured after the T8aD rectangle-list fix: all 1281 sprite frames decode,
100%.

parse() still returns sprites and skips primitives -- that is the useful
behaviour -- but the docs now say so instead of blaming the header.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 22:52:02 +00:00
d9ffc223bc re: RATC "one level deep" is not a limitation -- measured, plus a second dangling asset
INDEX read as if the parser stopped at one level. Measurement says there is
nothing deeper: 2859 top-level bundles hold 18002 children at depth 1 and ZERO at
depth 2, with no blob failing to parse.

The children that are themselves RATC -- the .rat layout records -- are leaves.
They carry no child list and reference their siblings BY NAME (the sprite they
place, and via "opt " their focused variant): 3311 such leaves, every one
embedding sibling names, and 10144 of 10148 references resolve within the same
bundle. That is the same by-name convention used one level up (a screen config
naming .prt components) and one level up again (the movie table naming
<lang>.pak+<member>).

The 4 unresolved references are a disc defect, not a parse gap: pmbase.rat in
GP_STAGE_CLEAR.pak's four language builds places pmbase.t32, and that sprite
exists nowhere -- not a pak member, not a child of those bundles. Second such
dangling asset after SUBTITLE_S12B.tbl, so a reimplementation should skip a
missing sprite rather than call it a decode failure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 22:44:19 +00:00
ac10d3bd19 t8ad: a surface is a list of sub-rectangles, not a 256 grid -- disc decode 96% -> 100%
The "~15% deferred variants" were not variants. Auditing every T8aD on the disc
gave 19216 surfaces, 18442 decoding (96.0%) and 774 failing in two clusters:
GP_DIALOG strips declaring 524x63 with a "tile count" of 1 or 2 instead of 3, and
small textures in the six *2D language paks whose pixels ran past the end of the
file.

Both fall out of the per-tile header, which is not opaque flags: it is four BE
u32 -- dst X, dst Y, width, height. A 15x18 icon stores a 13x18 rectangle at
(1,0); pdmes010 stores (59,6,256,54) and (315,6,149,54), the second beginning
exactly 16 + 256*54*4 bytes after the first. So 0x1c is a RECTANGLE COUNT and the
256-grid reading was an accident of most surfaces being stored as full-width
bands.

Parser rewritten to that model, still refusing to guess: a rectangle must fit the
declared surface and its pixels must fit the file, else None. Disc decode is now
19216/19216 = 100.00%.

Two test fixtures were built to the old model and are corrected rather than
worked around. lsta's t8ad_frame wrote NO offset-table entry, so the decoder read
"pixels" from inside the header -- the test passed only because it checked
dimensions alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 22:37:21 +00:00
9228255bfa re: validate the screen layout against the running game -- eight rows, +/-2 px
Booted to the ARSENAL and detected the eight teal category chips by colour, then
compared their row centres against the eight prbtn1..8.rat placements parsed from
eng\prmain_scr.prt. All eight fit

    screen_Y = placement_Y + pivotY(14) + chrome(45)

with residuals -1,-1,-1,-2,0,-2,-1,-2 px. The spacings are the real signature:
predicted 54,56,55,54,56,55,55 against observed 54,56,54,56,54,56,54 -- an
irregular alternating pattern, not a round number that could match by luck. The
one free parameter is the 45 px emulator window chrome, which is not part of the
game, and the residual is centroid measurement noise.

Confirms three things together: the declaration table is the element set, the
placement region gives real screen coordinates, and the pivot composes additively
(pivotY 14 = half the 28 px chip, so placement is top-left as documented).

Explicitly NOT confirmed: the max-dwell rule for animated elements. These buttons
are static -- every keyframe identical -- which is exactly what makes them a clean
ruler. That rule needs an element captured mid-slide.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 22:25:18 +00:00
35e2d1067f re: placement X/Y are SIGNED, the tail word is time, and the resting pose is max-dwell
Dumping the remaining Arsenal components turned up placements reading as
4294966780 and 4294966856 -- negative as i32 (-516, -440). X and Y are signed;
off-screen animation starts are negative, and read as unsigned a reimplementation
would draw them four billion pixels off.

The raw region then showed the rest of it. The trailing word is a TIME, and a
group is an in -> hold -> out animation: prselect_win1 runs
t=4:-516 -> 6:-71 -> 7:81 -> 8:127 -> 23:134 -> 24:134 -> 25:127 -> 27:81 ->
31:-71 -> 1:-516. So NEITHER the first nor the last keyframe is where the element
sits -- both are off-screen. The resting position is the max-dwell keyframe,
(127,155)..(134,155) here, which is where the weapon-list panel actually appears.

This corrects my own note from earlier today, which reported "final=" positions.
Static elements were unaffected (the pause menu's buttons have identical
keyframes) but animated ones were misread. screen_layout.rs now reports the
max-dwell pose plus the full timeline, and both captures are regenerated.

Also seen while dumping: kind 0x2, and a .sbo child (scrollbar) parented to the
list window.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 22:14:36 +00:00
de357ffdc9 re: the screen parse generalises to the ARSENAL, plus kind 0x4 and the component model
examples/screen_layout.rs dumps a bundle's declaration table and placement region
together. It reproduces the tutorial pause menu exactly and reads the ARSENAL the
same way -- 23 elements that match the running game: eight buttons prbtn1..8.rat
at X=242 evenly spaced (the config declares WEAPON_CATEGORIES = 8, and eight
categories are what the Arsenal shows), prexp3.t32 declared SEVEN times at X=726
34px apart (the DATA SHEET rows), prexp1 sliding (726,143)->(1286,143) with
prexp1a parented to it, and prmsg at (151,645).

Two additions to the format:

  kind = 0x4 marks a REPEATED INSTANCE of a sprite -- prexp3.t32 appears once
  with 0x0 then six times with 0x4, each with its own placement. So the element
  name is not a key; the declaration index is.

  A screen composes from named .prt components. GP_HANGAR_ARSENAL.pak has 510
  RATC entries because its config names components (Menu = prmain_scr.prt, etc.)
  and they resolve under the config's own PATH prefix: prmain_scr.prt is absent,
  eng\prmain_scr.prt is present -- the same <lang>+<member> convention the movie
  table uses. A sub-component reads identically: psselect_win1 declares 4
  elements, three parented to element 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 22:06:00 +00:00
f65387143e re: the UI screen gap is closed -- the bundle also carries every element's placement
Immediately after the declaration table the RATC bundle holds a placement region,
one group per element: a header of (u32 element index, u32 keyframe count)
followed by that many 40-byte keyframes carrying scale/tint/X/Y. The element
index is stated in the header, so the correspondence is read, not inferred from
order.

Tutorial pause bundle: 11 groups for 11 elements, every header index and count
matching the blocks present. The values are self-evidently right -- three menu
buttons at X=546 exactly 70 px apart (288/358/428), title (540,119), message
(451,545), and the eff* sprites carrying multi-position fly-ins.

Cross-checked: pgp_ttrl_btn10.rat places its own sprite at (546,288), identical
to its inline group, so the inline region is the same placement data and it
covers the eff*/deli*/msg elements that have no record of their own.

So a screen is fully reconstructible from its bundle alone: element list and
order from the declaration table, placement and animation from this region,
plus the sprites, with "opt " supplying focused states. This retires the caveat
added earlier today that only the order was known.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 21:58:21 +00:00
dd8770826b docs: INDEX — retire the stale 'loop1.rat not decoded' note
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 21:50:39 +00:00
8814df843b re: the RATC declaration table IS the screen's draw list, and +32 is a parent index
The doc's open gap was "where does the screen's draw list live" -- the eff/deli/msg
sprites have no .rat and loop1.rat turned out to be an animation. It is the
bundle's own declaration table, which is NOT the child listing: children are
grouped by type (all .t32, then all .rat) while the declaration table names
ELEMENTS in a plausible back-to-front order and contains exactly the missing set.
For the in-mission pause menu it lists 23 elements ending with loop1.rat, and it
omits the focused button variants -- those are reached via each base record's
"opt " link -- so it is the screen's element set, not an inventory.

Also corrects the entry layout: it is FIVE words after the name, not "u32 x4
flags", and word +32 is a PARENT ELEMENT INDEX (0xffffffff = none). pgpeff02a
carries 3 and element 3 is pgpeff02; pgpeff03a carries 5 and element 5 is
pgpeff03. Verified on two independent language builds, no out-of-range value in
any bundle, and the tutorial bundle (no "a" variants) is 0xffffffff throughout.

Bounded honestly: what is drawn and in what order is now answered; WHERE the
eff/deli/msg sprites land is not -- the declaration entry has a pivot but no X/Y.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 21:50:13 +00:00
8b7c9da067 re: clear mirror handling and the exhaust cones -- the viewer bug's static avenue is exhausted
Mirror handling: the concern was that apply() bakes R*(S*v)+T while the viewer
decides winding from det(m) alone and rotates normals by m alone, so a mirror
encoded as negative SCALE would reflect geometry without flipping winding. It
never happens -- across 1485 assembled parts in all 22 containers there are 22
mirrored parts, every one with det(m) < 0, and ZERO negative or non-uniform
scales. apply_twin_mirrors writes the reflection into m, so the flip always
fires and ignoring s for normals is harmless.

Exhaust cones: the only geometry the viewer invents, drawn at GN_Jet/GN_SJet
frames because the real engine geometry is recessed. Across 335 assembled ships,
192 with exhaust frames, not one cone sits outside its hull bounding box (10% of
span tolerance). Caveat kept in the doc: inside-the-box does not prove a cone is
correctly oriented or sized -- it rules out the reported symptom, no more.

Every mechanism the diagnosis proposed is now eliminated (include_external,
duplicate names, mirrors, cone placement). The visual comparison is no longer
the next step but the only remaining one, and if it agrees the original report
needs re-grounding against a specific ship and expectation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 21:41:20 +00:00
a7905d0f6b re: kill the duplicate-resource-name hypothesis for the viewer bug, and reconcile 22 vs 16 stages
build_ship_model resolves each placement with find(|m| m.name == p.resource) --
first match wins -- so a repeated resource name inside a container would draw
the wrong geometry. It cannot happen: decoding every XBG7 resource in all 22
stage containers gives 4603 resources and ZERO repeated names. Per ship it is
tighter still: e106 wants 9 distinct names and decodes exactly 9 models for 11
placements, e105 9 for 9, f105 5 for 6.

Two of the three remaining candidates for the user-reported viewer bug are now
gone (this and include_external), leaving mirror handling and the exhaust cones,
plus the untried visual comparison.

The container sweep also reconciles a number I flagged earlier: the disc has 22
stage CONTAINERS -- Stage_S01..S16 plus Stage_S24..S29 -- i.e. 16 story stages
plus 6 extra. The save screen's 16 STAGE sprites and the notes' "22 stages" are
both right and count different things; neither gets edited to match the other.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 21:31:18 +00:00
671891f9bf re: XPR2 channel order confirmed against the running game -- the second "dynamic unknown" closed
INDEX carried XPR2 as "colours unverified (dynamic item)". The failure mode that
matters is a swapped red/blue channel: invisible on greys, invisible without
ground truth, and it poisons every asset silently.

Method: pick an asset that is strongly asymmetric in hue and has known in-game
appearance. DeltaSaber_T.xpr (1024x1024 Dxt1, 11 mips) decodes to white/grey
panels with orange-rust accents; the game renders the same hull in the ARSENAL
scene.

  decoded texture : 1073 warm px, 0 cool, median saturated hue 23.3 deg
  in-game render  :  916 warm px, 124 cool, median saturated hue  9.3 deg

Both orange/red; a red<->blue swap would put the texture at ~200 deg. The cool
pixels are the blue UI behind the model and the 14 deg offset is the hangar's
red key light -- neither can move a hue by 180.

Stated as a bounded result, not "colours are correct": a hue-family comparison
cannot see a gamma/sRGB error, premultiplied alpha, or a per-channel scale, so
exact fidelity stays open and needs a flat unlit known-value surface. Cubemap
face ordering untouched. BG_Earth.xpr (A8R8G8B8 cubemap face) decoding to a
coherent nebula is corroboration for the de-tile step, not proof.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 21:21:55 +00:00
38f58ea559 re: the movie/subtitle/voice link is solved statically -- INDEX called it a dynamic unknown
INDEX carried IXUD as "movie<->track link unknown (dynamic item)". It is a
config record on the disc: tables.pak schema 0x067025b9, whose keys match the
movie game-part symbols in the executable (MOVIE / TELOP / SUBTITLE /
VOICETRACK, plus SUBTITLE_FONT / SUBTITLE_Y / SUBTITLE_HEIGHT next to
silph::GamePart_Movie::Impl::OnPrepare).

101 movies mapped: 94 with a subtitle, 83 with a voice track, 21 with a telop.
Every subtitle reference was looked up in dat/movie/<lang>.pak and 93 of 94
resolve -- SUBTITLE_S12B.tbl resolves in NONE of the six languages, a dangling
reference on the retail disc rather than a decode failure.

Naming is SUBTITLE_<base>.tbl and VOICE_<base>, with the staff roll and five
supply movies (VOICE_D_450..454) as documented exceptions, so a reimplementation
can resolve by convention and fall back to the table for those six.

Deliberately NOT published: the record's ~104 script ids paired to movies.
Positional pairing drifts by three -- visible at the tail, where
S24/S27_SUPPLY_ACROPOLIS would have to map to hokyu_LS_s24A/s27A and do not --
because the IDXD pool dedupes repeated values and an id whose movie was already
named contributes no token. The CSV is keyed by movie file instead.

For the intro-movie work: ADV.wmv has VOICE_ADV and no subtitle, no telop.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 21:10:08 +00:00
bb9e75fe6a re: the title-menu screens read the auto-save (slot 01), and the high score is computed not stored
Two results, both from a safe probe.

Slot 03 was given SHAB[0] = (a=1, b=12345, c=60000) -- a one-minute best time --
and MISSION SELECT still showed 4612 P EASY / 05:24.77 EASY, i.e. slot 01's
numbers. So the title-menu screens read the AUTO-SAVE, and any probe written to
a throwaway slot is invisible there. The previous SHAB identification is
unaffected: it matched slot 01's own bytes, which is what the screen renders.

The consequence is a decision, not a task: mapping the difficulty enum (a) or
testing b needs slot 01 itself edited -- the only save with real progress. Left
undone deliberately and flagged in the doc; a full content backup exists and
slot 01's bytes are archived, so it is recoverable, but it is the user's call.

Also: High Score 4612 is stored NOWHERE. It is absent from both .gpd profile
files, all three saves (compressed and inflated) and xconfig.settings, while the
best time 324773 is present in slot 01 alone. The score is computed at display
time, which is why SHAB[0].b = 4101 does not equal it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 21:00:16 +00:00
df45a1986b re: SHAB is the per-stage record table -- record 0 is Stage 01, and c is its best time
EXTRAS -> MISSION SELECT renders per-stage records and they match the table.
Stage 01 shows "High Score 4612 P EASY / Best Time 05:24.77 EASY" while SHAB[0]
is (2, 4101, 324773, FILETIME): 324773 ms IS 5m24.773s, the displayed best time.
Sixteen records, sixteen story stages -> the table is indexed by stage, and
record 0 is Stage 01, the only stage this save has cleared.

  a = 2       difficulty of the record (both entries tagged EASY)
  b = 4101    NOT the displayed high score 4612; equals GHAD +24/+28
  c = 324773  best clear time in ms -- confirmed against the screen
  d,e         FILETIME

This also explains the probe that filled SHAB[1] and changed nothing: the table
holds stage RECORDS, not progress, and Stage 02 has never been cleared so its
record is legitimately empty. Promotes the earlier "per-stage result record"
guess to confirmed for the layout.

Route: title -> EXTRAS -> MISSION SELECT. Only cleared stages are selectable (16
d-pad presses never left Stage 01) and the screen has its own difficulty
selector (Y).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 20:50:06 +00:00
98b3cf56ac re: name the save read path, and locate the save state at game_object+304
Disassembling around the serializer names its mirror and the whole read side:
deserializer 0x822C0380 (reads GDAA + phase string), GHAD reader 0x822BF858
(called with save+8, pairs with the writer 0x822BF678), SHAB reader 0x822BFD60
(save+136, count 16).

The GHAD reader is a plain unrolled byte copy with no clamping or validation
anywhere, which is why hand-written field values survive into the object exactly
as written.

The deserializer's only caller builds its argument as
lwz r11,4(r30) / lwz r11,0(r11) / addi r4,r11,304, so the save state lives at
+304 of a game object and every field now has a fixed absolute offset there --
Points at +336, clear ratio at +320, the develop blob at +380, the SHAB table at
+440. That is what a live-RAM read of the save state needs.

Recorded as a negative too: searching those absolute offsets does NOT find the
panel's populate code. lwz rX,336(rY) has 193 matches, and the windows holding
several right offsets at once are a vtable thunk table (slots 308-340) and a
float-parameter block. The stage/difficulty fields need the screen-side path.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 20:24:47 +00:00
bc42c0970e re: the save screen's key table is compiled into the executable -- a 4th difficulty, 3 states, 16 stages
Static, no emulator. The LOAD/SAVE screen's config keys sit in .rdata as a
pointer array at 0x820a0074, identified as config keys (not loose strings) by
the Arsenal's own key list sitting a few hundred bytes earlier and matching its
pak record exactly.

  - GAME_VERY_HARD exists alongside EASY/NORMAL/HARD, while the stage tables
    only carry BonusPoint_EASY/NORMAL/HARD -- a fourth, unpriced tier.
  - Game Status is a 3-valued enum: STATE_STAND_BY (our save's "At Standby"),
    STATE_STAGE_CLEAR, STATE_GAME_CLEAR.
  - Exactly 16 STAGE sprite keys, matching weapon.tbl's stage01..16 (plus 6
    tutorials and 6 challenges). So 16 is the story-stage count and the "22
    stages" figure used elsewhere counts a different set -- flagged, not
    silently changed.

Also recovered: the panel's field names and positions (Points, FlightTime
%03d:%02d:%02d, ClearTimes, CompletionRate, RatioOfClear, Index, Label, Date,
BrokenData).

It does NOT name the stage/difficulty save fields, and it explains why the probe
sweep could not: the screen picks a sprite key BY INDEX through a config lookup,
so there is no lis/ori immediate to xref back to the selecting code.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 20:13:01 +00:00
2da9b8a9b8 re: the whole GHAD block is neither stage nor difficulty -- sixteen probe saves
Extends the previous refutation to a sweep. Probed with no effect on STAGE 02 or
Difficulty EASY: every scalar in the GHAD block (+0, +12, +16, +20, +28, +32,
+36 at 1/3/9, +40 u64, +48, +52, +56, +60, +64 raw), SHAB[0].a, and the SHAB
FILL COUNT in both directions -- record 1 filled with a copy of record 0, and
record 0 cleared. The "stage = filled-record count + 1" idea dies with it, and
so does the reading that made SHAB a per-stage result table by that route.

The panel does re-read each slot: slot 02 holds Points 4101 / Clear Ratio 5 %
and displays exactly that while its neighbours show 101 / 6 %.

Left: the phase string, the trailer, or the blob. Recorded caveat -- every save
on disc is genuinely Stage 02 EASY, so "field not found" and "panel does not vary
those two labels per slot" are not yet separated, and another probe round cannot
separate them. The next move is static: find the code that formats STAGE %02d
and read which offset it loads.

savegame_edit.py --set now packs an int into raw_* byte fields.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 20:01:26 +00:00
eac3435cc7 re: +36/+52/+56 are neither stage nor difficulty -- refuted with eleven probe saves
Those three fields all hold 2, and "difficulty or stage, undecidable from one
save" has been the reading since the format was parsed. Writing saves makes it
decidable and the answer is neither.

boot_menu.sh boots to the title menu WITHOUT loading anything, and LOAD GAME's
slot list renders each slot's Details panel from that slot's payload. Extra
slots can be fabricated (copy the directory plus a gameNN.header with its
UTF-16BE display string and ASCII name patched), so four probes fit in one boot,
read-only.

Probed: +36 at 1/3/9, +52 and +56 at 1/9, and +0, +16, +32, +48, +28,
SHAB[0].a. Every one left the panel at STAGE 02 / EASY / At Standby /
Times Cleared 0.

The negative is meaningful because the panel does read each payload -- slot 02
shows 5% clear ratio against the others' 6%, and Points tracked +24 exactly.
Two controls: patching a slot header to "STAGE09 HARD" changed nothing (the
display is payload-driven, not header text), and the row date follows the
container FILETIME.

Remaining candidates: +12, +20, +40 (u64), +60, +64, or the phase string.

Also here: savegame_edit.py --slot for SHAB records, and boot_menu.sh itself --
nav_probe.sh's boot loads a save, which with probe slots on disc loads a probe,
and a dropped d-pad step there put A on TAKE OFF and spent a boot loading a
mission.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 19:37:06 +00:00
6e0fbe52a6 docs: retire the last three sentences that predate the solved index space
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 19:01:43 +00:00
841156a95d re: the develop blob's index space is SOLVED -- it follows strings.tbl, cut items and all
Three hand-written probe saves settled what a mission payout could not.

  all 54 owned  -> every tab fills and the lists WRAP, giving exact counts
                   (GUN 8, BEAM 8, LASER 4, MPM 5, ASM 5, B/R 7, CANNON 6,
                   SPECIAL 6 = 43 displayed) and confirming the display order is
                   weapon.tbl's order item-for-item. It also killed the idea
                   that gate-unmet owned flags are suppressed: Maelstrom Bomb
                   (Stage 6) and Grav Cannon XGS (Stage 12) both rendered at a
                   Stage-2 save.
  only 9 + 39   -> STILETTO BG1 Developed (control) AND TOMAHAWK ALPHA RAIL GUN
                   Developed. The CANNON block starts at 39, not 38.
  only 39 + 48  -> JAMMING SYSTEM Developed. SPECIAL starts at 48, and with six
                   SPECIAL items the array closes exactly at 53, nothing spare.

So the blob is indexed by strings.tbl's item order -- the display order PLUS the
items only the localisation file carries (Adhesive Mine B2A, and three of
Ballista GSH / Designator LH / Smoke Marker Launcher / Bumble UV). They never
appear in the Arsenal but they hold slots, which is the entire reason the tail
looked broken. It also explains the retail save's five "unexplained" owned
entries at 33 and 45/46/47: cut items, shipped flagged owned, never rendered.

That weapon.tbl's No_Equipment..Wep_83 run is ALSO 54 long is a coincidence, and
it cost real time -- the two orders agree only to index 32. Recorded as such.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 19:01:14 +00:00
dc97dc215d docs: reconcile the 'free items are granted' wording with the 0 P purchase the probe caught
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 18:10:58 +00:00
f5f95be0a1 re: saves can be written back, which settles what the develop blob's 4s mean and refutes the tail
The container's derived fields turned out to be reproducible -- length+10 at
+0x30, payload length at +0x8c, adler32(payload) at +0x8e, everything else
copied -- and savegame_edit.py re-wraps a real save BYTE-IDENTICALLY, which is
the check that those three are the only ones. A hand-written save then loaded.

That replaced a blocked experiment (the tail question needed a mission payout,
and none of the currently developable items even sit in the disputed range) with
a direct one: write the blob, read the Arsenal.

  - controls: 4 at index 9 -> STILETTO BG1 Developed, 21 -> FALCON 9AM
    Developed. A hand-written 4 reaches the screen.
  - tail: 4 at 33 and 45 left their rows dashed (both on screen, not below the
    fold), and 38 left TOMAHAWK ALPHA RAIL GUN at "0 P" -- not owned. So the
    tail is not the weapon.tbl order continued.
  - clearing the real save's {22,26,39,46,47} cost the Tomahawk its Developed
    status, which puts its flag in that set (39 positionally) -- but a uniform
    +1 fails for SPECIAL, so no shift is asserted. Indices >=32 stay marked.

Two behaviours fell out. The title RE-DERIVES developable state on load and
announces it ("You can now develop Broad Sword ..."), so only the 4s are stored
state and a written 2 is pointless. And a no-cost item is bought for 0 P rather
than granted -- TOMAHAWK at "0 P" is what unowned looks like -- which is the
actual reason items read Developed in a save where nothing was spent.

Slot 03 was restored from its archived original (md5 verified); slots 01/02 were
never touched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 18:10:28 +00:00
f88f4f6847 re: the Arsenal develop economy, and the save blob's index space (first 32 confirmed)
GP_HANGAR_ARSENAL.pak's screen config points at weapon.tbl (item ids, in the
8-category display order) and strings.tbl (names, descriptions, and a
"Conditions to obtain" block per item). The id run No_Equipment .. Wep_83 is
exactly 54 long -- the save blob's length -- and all 60 conditions blocks are
extracted to a CSV: gates are stage completion, a predecessor item, or an ace
kill; costs run 3000-350000 P, and 20 items cost nothing once gated (which is
why items the player never bought read as Developed).

Predicting the save state from those conditions -- before looking at the blob --
says exactly six items are developable here, and the blob's six 2s sit on those
six, in weapon.tbl order, at indices 1/5/10/12/27/31. With the four obtained
items and the differential's own two transitions that is twelve concordances
over indices 0-31, nothing fitted. Broad Sword SG1 at index 5 needed scrolling
the GUN list to see, which is the only one the first screenshots missed.

The tail is NOT settled and is marked so: the Tomahawk is weapon.tbl index 38
and the screen shows it Developed, but blob[38] = 0, and the other tail 4s
(33/39/45/46/47) land on items the Arsenal shows as locked -- the SPECIAL tab is
entirely empty. A +1 shift does not repair it either. Settling it needs a second
development in a late category, which needs a mission payout.

Also recorded: IDXD string pools dedupe repeated values, so only the first
record of a table can be read from the token stream -- record 2 shows just its
unique values, record 6 no cost at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 17:38:45 +00:00
6ebf2ba00a re: capture the Hangar screen — it is a loadout picker, not a craft data sheet
The Hangar lists NOSE / MAIN WEAPON 1-3 with the mounted weapon and a derived
'Gross Weight: Light'. It shows no craft stat fields at all, so the Hangar is
not a route to the unit definition's defaulted fields — the Arsenal DATA SHEET
(weapons only) and the live-RAM route remain the only two.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 17:19:21 +00:00
f0ceda1c6f re: developing one Arsenal weapon separates Points from its twin and names the save blob
A third save, taken in the running game after developing exactly one item
(Light Machine Gun MG I, 4000 P) and declining the mount prompt, moves exactly
three things against the same-state save:

  +24  Points      4101 -> 101   and +28 does NOT move, which separates the
                                 pair one save could not tell apart; the
                                 Details panel then reads Points 101 P, so
                                 +24 is the spendable balance
  +8   clear ratio 5 -> 6        so the ratio counts collection, not stages
  +68  blob[1],[2]  2->4, 0->2   the item bought, and the successor the game
                                 announced as newly developable

One action, two blob transitions, two on-screen events in the same order — which
is what makes 0 locked / 2 developable / 4 developed a reading rather than a
guess, and rules out a plain owned-bitmask (it could not hold the middle state).
Which item each of the 54 indices is stays open: the arsenal id lists in
GP_HANGAR_ARSENAL.pak union to 35, and MG I sits at index 1, not 0.

Also recorded: inside a modal yes/no dialog a 60 ms d-pad tap is ignored (the
list menus accept it), and the develop confirm starts on NO while the mount
prompt right after it starts on YES.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 17:16:57 +00:00
5cc995e864 docs/re: INDEX — reflect the named save fields and the pure-state result 2026-08-11 06:02:31 +00:00
882dbc2ae2 re: a second save names Points, flight time and clear ratio — and shows the payload is pure state
Made a second save in-game (READY ROOM -> SYSTEM -> SAVE GAME -> empty slot) so
the format had a differential to read against. nav_probe.sh drives it: boot to
the READY ROOM, walk a scripted step list, screenshot after every step and stamp
every save file's md5, so the trail says which keypress wrote a save. That stamp
is what caught the first attempt failing -- the save confirm starts on YES,
unlike the load confirm which starts on NO, so the load flow's extra up-press
selected NO and wrote nothing.

Result 1: saving the same loaded state into a new slot produces a BYTE-IDENTICAL
545-byte payload. Only the GDHA header moves, and every byte that moves is either
the container FILETIME or one of the guest-pointer words -- which empirically
confirms those words are uninitialised padding rather than data. So the payload
holds no timestamp, no slot number and no name; a save's identity is entirely in
its content header.

Result 2: the LOAD/SAVE screen's Details panel prints Points 4101 P, Flight Time
000:05:24 and Clear Ratio 5 % for exactly this state, which names GHAD +24
(Points), +4 (flight time in ms -- 324773 ms = 5m24.773s) and +8 (clear ratio %).
Difficulty EASY and STAGE 02 both being 2, and three fields holding 2, is left
undecided on purpose: one save cannot separate them.

Result 3: the 16 SHAB records are not the UI's save slots. The UI has 20, slots
are separate gameNN files, and record 0's FILETIME stayed at 2026-07-23 in a save
written on 2026-08-11 -- so the table is part of the game state, most likely a
per-stage result record (one stage finished, one record filled), which the next
cleared stage will falsify or confirm.

The original save was backed up first and is untouched; the new save went to an
empty slot.
2026-08-11 06:02:21 +00:00
398e8ae0af re: the save file is a GDHA/zlib chunk stream — layout read off the title's own serializer
The whole retail save is 545 bytes: a GDHA container wrapping a zlib payload,
which is a chunk stream — 'GDAA', a length-prefixed game-phase name (GP_BUNK,
one of the title's GP_* screen ids), a 'GHAD' 122-byte progress block, a
count-prefixed table of 16 20-byte save slots, and a trailer.

None of it is guessed. The layout comes from the serializer at 0x822C00E8 and
its callee 0x822BF678: the writer primitive is 0x821885A8(stream, buf, len), the
slot count 16 and the 20-byte stride are literals, and the GHAD block is ten u32,
a u64, four u32, a raw 4-byte field and a raw 54-byte blob = 122 bytes, which is
exactly what the file carries. savegame.py re-serializes the parse and asserts
byte-identity.

Because the struct is written field-by-field with no packing changes, a payload
offset is also the offset in the live save object -- save+8 for GHAD, save+136
for the slot table, and 136+16*20 = 456 is the serializer's very next access.

Confirmed independently: slot 0's trailing two u32 decode as a FILETIME to
2026-07-23 20:07:23 UTC, and the content header's display string (written by the
game) says 07/23/2026 21:08 at UTC+1; the 15 empty slots hold 2006-01-01 rather
than zero.

Field meanings are left  on purpose -- the naming oracle is a diff of two
saves, and all four copies on disk are byte-identical, so a second save has to
be made first. Nothing has been written back to any save.
2026-08-11 05:40:26 +00:00
5c3e3dfe47 re: making turrets targets does not save the escort — the effect is inside the noise
The Stage-02 outcome write-up ended by naming "turrets near the asset must
become targets" as the fix worth ~50% of the escort damage. That was an
inference from a co-presence attribution, not a measurement. Run it and it
does not hold.

Also corrects the run labelling: pilot.py gained the SYLPH_KILL_TURRETS gate
two minutes before mission02 started, so mission02 was already a treatment run,
not a second baseline. Only mission01 (0 of 3968 pilot frames targeting a
turret) is the baseline.

At a common t=428s: baseline 46.9% escort hull, treatment 44.5% and 53.0%. The
two runs of the same arm differ by more than either differs from the baseline,
and the escort still reaches zero at t~590-670s in all three. So the
transferable finding is the power limit: one 430s flight cannot resolve an
effect below ~9 percentage points, and every single-run pilot conclusion,
including this one's, is inside it.

What does reproduce: the assault is scripted (onset 166/167/166s), and the
e007/e010 damage split is 50/50 in all three arms including the one that never
fires at a turret -- so that attribution measures the wave script, not us.

Also records that the viewer's include_external hypothesis in BACKLOG is dead
(it defaults true and is threaded through unchanged).
2026-08-11 05:29:52 +00:00
f4d59c5783 re: Stage 02 is lost at ~11 minutes, and the pilot's survival rule is what guarantees it
First session whose deliverable was the mission's ENDING rather than a
measurement (mission_run.sh, 500 s, hull of every entity at 2 Hz). The ACROPOLIS
is untouched to t=170 s then falls at ~53 HP/s with no let-up, reaching zero at
t=640-720 s — so "no mission completed" is not an artifact of the 240 s
time-boxes, and not of the 600 s cap on a blocking tool call. A longer session
would only watch the loss arrive.

Attributing the damage by co-presence, exactly two classes are ever near the
asset: e007 turrets (8483) and e010 bombers (8334). pilot.py treats turrets as
keep-out zones at 2500 units and never as targets — the rule that made it
survive — so roughly half the escort damage comes from the one class it is
designed to avoid. Survival and the objective are in direct conflict and the
pilot resolves it entirely for survival: WARSHIPS 0000, WARPLANES 0009,
REMAINING OB rising 004 -> 008, our hull untouched at 1500/1500 with 120
missiles spent. That is unspent risk budget, not a good run.

Also corrects launch_mission.sh: a harness-tracked BACKGROUND task does not keep
the display alive (lost 11 s in, at the turn boundary) — the
one-blocking-foreground-call rule stands.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-10 20:57:43 +00:00
530555de9f re: the weapons are the control — sibling-default inheritance is unit-schema-specific, not engine-wide
Four rules from 21 units invites the coincidence objection, so run the identical
sweep against the Weapon/Shell capture, which has COMPLETE coverage (126
records). It finds no sibling rule at all: the one 100%-agreement candidate has a
single distinct value and is really a constant default. Weapon defaults vary per
record exactly as unit defaults do, so "defaults are computed" is general while
"defaults come from a sibling field" is not.

Size_Y <- Size_X survives, and is now checked at the raw-token level rather than
through the sub-record merge: e105, f105 and f101 each declare Size_X/Size_Z/
Size_Radius and no Size_Y, and each reads back its own Size_X at runtime. The
two two-unit hypotheses are demoted to coincidence-not-excluded.

Also records a negative for planning: Stage 01, the only other reachable stage,
adds four uncaptured units that are variants of already-captured ones, so it
would re-measure rather than test the rules.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-10 20:09:14 +00:00
69b4a2e569 re: a unit field left unset on disc is not a global constant — Size_Y inherits Size_X
Attacks the 21/110 unit-coverage limit from the cheap side: if a defaulted field
always took one runtime value, the captured units would pin it for all 110. Only
6 of 24 confirmed defaulted fields behave that way. The other 18 vary per unit,
so the default is computed.

Asking which OTHER field of the same unit holds that value — counting only
non-zero cases, and checking the two fields sit at different offsets so the
layout solver cannot be aliasing them — gives four rules. Size_Y <- Size_X is
solid: seven unrelated ships (e105 600, e106 300, e108 80, e201 300, f101 400,
f105 700, f106 200) each omit it on disc and each shows its own Size_X live,
while the two fields differ freely when both are on disc. Size_Radius fits both
min(X,Z) and the median of the three axes and cannot yet be separated;
e010_ADAN_Attacker_S is what rules out the simpler Size_X rule. FCSRange and
DefencePoint rest on two independent units each and ship as HYPOTHESIS.

Applied across the disc the rules recover 65 (unit, field) values in units that
have never been visited. Falsification test recorded: load any uncaptured stage
and compare one predicted value.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-10 19:44:24 +00:00
139 changed files with 32879 additions and 1902 deletions

View File

@@ -12,7 +12,12 @@
ship e106 ref=e106_bdy_04
e106_bdy_01 1 0 0 0 1 0 0 0 1 -263.9948 -150.43242 1164.8667
e106_bdy_02 -1 0 0 0 1 0 0 0 1 264.0088 -150.41339 1164.8651
# 2026-08-12: this rotation was diag(-1,1,1) - the X-flip `correlate` bakes in
# when a draw's buffer is the mirror of the decoded one. With distinct anchor
# assignment the twins now decode to their OWN buffers (the container carries
# both halves), so the mirror lives in the data and the placement is plain
# identity. Re-emitting from the capture agrees: `1 0 0 0 1 0 0 0 1 264.04343`.
e106_bdy_02 1 0 0 0 1 0 0 0 1 264.0088 -150.41339 1164.8651
e106_bdy_03 1 0 0 0 1 0 0 0 1 0.0029247368 -34.517372 1075.878
e106_bdy_04 1 0 0 0 1 0 0 0 1 0 0 0
e106_brg_01 1 0 0 0 1 0 0 0 1 -0.005471501 153.31795 -164.03748

View File

@@ -0,0 +1,177 @@
# Unit / vessel definition object layout — offset, field, kind.
#
# Read out of the title's own loader, not inferred: `sub_82341A20` builds every
# key as `addi r4, r30, -N` with `r30 = 0x82088f94`, so the field NAME for each
# store is a string in the executable image; pairing each key with the first
# store after its accessor call gives the offset. The accessor for floats is
# `sub_822FC5A8`, which returns 0.0 when the pool has no value for the key.
#
# Verified against live objects dumped from a running Stage 02: 406 field values
# agree with the disc records and 0 disagree, over 11 objects spanning both the
# UNIT and VESSEL schemas (see docs/re/live-unit-definitions.md).
#
# Two conventions matter for a reimplementation:
# * angle fields are DEGREES on disc and RADIANS in this object;
# * a field the disc record omits is left at the accessor's miss value (0.0 for
# floats) unless something later derives it — `Size_Y` takes `Size_X`.
#
# offset kind field
24 str Model
28 str CollisionModel
48 f32 Size_X
52 f32 Size_Y
56 f32 Size_Z
64 f32 Color_R
68 f32 Color_G
72 f32 Color_B
80 f32 Size_Radius
84 f32 HP
88 f32 HQRatio
92 f32 ShieldRatio
96 f32 ThrusterRatio
100 word IsDestructible
104 str NamePlate
112 word MountedShieldGenerator
116 f32 ResistanceToOptics
120 f32 ResistanceToShell
124 f32 ResistanceToExplosion
128 f32 ResistanceToPlayer
132 f32 ResistanceParalyze
136 str HUDMarkerID
156 f32 MinimumVelocity
160 f32 MaximumVelocity
164 f32 CruisingVelocity
168 f32 Acceleration
172 f32 Deceleration
176 f32 AV_PitchPlus_Max
180 f32 AV_PitchPlus_Min
184 f32 AA_PitchPlus_Max
188 f32 AA_PitchPlus_Min
192 f32 AV_PitchMinus_Max
196 f32 AV_PitchMinus_Min
200 f32 AA_PitchMinus_Max
204 f32 AA_PitchMinus_Min
208 f32 AV_Yaw_Max
212 f32 AV_Yaw_Min
216 f32 AA_Yaw_Max
220 f32 AA_Yaw_Min
224 f32 AV_Roll_Max
228 f32 AV_Roll_Min
232 f32 AA_Roll_Max
236 f32 AA_Roll_Min
248 f32 SideThrustVelocity_Max
252 f32 SideThrustAcceleration
256 f32 MaximumBank_Normal
260 f32 YawDragFactor
264 f32 PitchDragFactor
268 f32 RollDragFactor
272 f32 DragFactorThreshold
276 f32 ArterBurner_Vc
280 f32 ReverseThrust_Vc
284 f32 ArterBurner_Acc
288 f32 ReverseThrust_Acc
292 f32 AccPitchFactor
296 f32 DecPitchFactor
300 f32 AV_AxisMode_Max
304 f32 AV_AxisMode_Min
308 f32 AA_AxisMode_Max
312 f32 AA_AxisMode_Min
316 f32 PowerCutConsumeShield
320 f32 PowerCutDeceleration
324 f32 AB_ConsumeShield_Begin
328 f32 AB_ConsumeShield
332 f32 AB_AV_PitchPlus
336 f32 AB_AA_PitchPlus
340 f32 AB_AV_PitchMinus
344 f32 AB_AA_PitchMinus
348 f32 AB_AV_Yaw
352 f32 AB_AA_Yaw
356 f32 AB_AV_Roll
360 f32 AB_AA_Roll
364 word SideRoll
368 f32 SideRoll_Time
372 f32 SideRoll_Length
376 word BarrelRoll
380 f32 BarrelRoll_CountMinimum
384 f32 BarrelRoll_CountMaximum
388 f32 BarrelRoll_Time
392 f32 BarrelRoll_Radius
396 word TurnAttack
400 f32 TurnAttack_CutoffRatio
404 f32 TurnAttack_DoubleRatio
408 f32 CutoffTimeMin
412 f32 CutoffTimeMax
416 f32 TurnAttack_DoubleTimeMin
420 f32 TurnAttack_DoubleTimeMax
424 word TurnAway
428 f32 Turn_AngularVelocity
432 f32 TurnAway_Time_Minimum
436 f32 TurnAway_Time_Maximum
440 word BoostAway
444 f32 BoostAway_Time_Minimum
448 f32 BoostAway_Time_Maximum
452 word HoldPosition
456 f32 HoldPosition_LengthMin
460 f32 HoldPosition_LengthMax
464 f32 HoldPosition_MinimumTime
468 f32 HoldPosition_MaximumTime
472 f32 HoldPosition_SideRatio
476 f32 HoldPosition_BackRatio
480 f32 HoldPosition_CutoffRatio
484 f32 HoldPosition_CancelTime
488 word Slalom
492 f32 Slalom_CutoffRatio
496 f32 Slalom_TurnCount_Min
500 f32 Slalom_TurnCount_Max
504 word Through
508 f32 Through_CutoffRatio
512 f32 Through_AngleMinimum
516 f32 Through_AngleMaximum
520 f32 Through_Time1Max
524 f32 Through_Time1Min
528 f32 Through_Time2Max
532 f32 Through_Time2Min
536 f32 Through_LengthMinimum
540 f32 Through_LengthMaximum
544 word SolidCutoff
548 f32 SolidCutoff_Ratio
552 f32 SolidCutoff_LengthMin
556 f32 SolidCutoff_LengthMax
560 f32 HomingResistAdjustment
564 f32 UsingChaffRatio
568 f32 MaxValue
572 f32 ChargeDelay
576 f32 ChargeDelay_Break
580 f32 ChargeSpeed
584 f32 Delay
588 f32 DelayAdjustment
596 str LowerHPFxModel
604 str ExplosionFxModel
612 str DestroyMotionName
620 str ExplosionMotionName
624 f32 DestroyMotionTime
628 f32 DryMass
632 f32 GrossMass
636 word Thruster
640 word SideThruster
644 word ExplosionSE
648 word JumpIn
652 word JumpOut
656 word ShipEnvironmentSE
660 word LowerHPSE
664 f32 LowerHPThresholdRatio
668 f32 SELength
672 f32 RadarRange
676 f32 FCSRange
680 f32 FiringRange
684 word MountedFCS
692 f32 AttackVesselPoint
696 f32 AttackCraftPoint
700 f32 DefencePoint
736 str ShieldRecoverEffectName
740 str ShieldHitEffectName
744 str JumpIn
748 str JumpOut
752 str FadeIn
756 str FadeOut
760 str Effect_Paralyze

View File

@@ -0,0 +1,22 @@
//! Time repeated per-ship decodes of one container, as the viewer does.
use std::collections::HashSet;
use std::time::Instant;
use sylpheed_formats::mesh::Xbg7Model;
use sylpheed_formats::ship::{is_base_part, ship_id_of};
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).unwrap();
let names = sylpheed_formats::mesh::xbg7_resource_names(&bytes);
let ids: Vec<String> = {
let mut v: Vec<String> = names.iter().filter(|n| is_base_part(n))
.filter_map(|n| ship_id_of(n).map(|s| s.to_string())).collect();
v.sort(); v.dedup(); v.truncate(5); v
};
for id in &ids {
let want: HashSet<String> = names.iter()
.filter(|n| ship_id_of(n) == Some(id.as_str())).cloned().collect();
let t = Instant::now();
let got = Xbg7Model::models_named(&bytes, &want, &|| false);
println!("{id}: {} models in {:?}", got.len(), t.elapsed());
}
}

View File

@@ -0,0 +1,123 @@
//! Does a resource have a CLEANER home in its container than the one we picked?
//!
//! After the pad-scoring fix, only two resources on the disc still decode to an
//! index run with degenerate triangles — `e201_bdy_03_m` (2 containers) and
//! `_rou_f402_dead` (9). Degeneracy says the run does not fit the pool, so either
//! the vertex block is wrong or the candidate list never offered the right one.
//! This walks every candidate vertex-run start for the resource's declaration and
//! scores each `(start, pad)` the way the anchor now does — degenerate triangles
//! first, then winding, plus coverage — so the answer is one of:
//! * a strictly cleaner candidate exists (the selection is at fault),
//! * several are equally clean (genuinely ambiguous), or
//! * nothing is clean (the block is not in the candidate list at all).
//!
//! Usage: better_home <container.xpr> <resource-name>
use sylpheed_formats::mesh::{debug_resource_params, debug_vertex_run_starts, Xbg7Model};
fn be16(b: &[u8], at: usize) -> u32 {
((b[at] as u32) << 8) | b[at + 1] as u32
}
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).expect("container");
let name = &a[2];
let Some((markers, stride)) = debug_resource_params(&bytes, name) else {
eprintln!("no such XBG7 resource: {name}");
std::process::exit(1);
};
let (vc, ic) = markers[0];
println!("{name}: {} marker(s), first = {vc} verts / {ic} indices, stride {stride}", markers.len());
// Where did the decoder put it?
let ours = Xbg7Model::stage_models(&bytes)
.into_iter()
.find(|m| m.name == *name)
.and_then(|m| m.meshes.first().and_then(|s| s.vbuf_offset));
println!("our anchor: {ours:?}");
let starts = debug_vertex_run_starts(&bytes, stride);
println!("{} candidate vertex-run starts for stride {stride}", starts.len());
// Score every (start, pad): degenerate triangles, winding against the stored
// normals, and whether the run covers the pool exactly.
let mut rows: Vec<(usize, f32, usize, usize, usize, bool)> = Vec::new(); // degen, wind, start, pad, max_idx, covered
for &vb in &starts {
for pad in 0..=3usize {
if vb < ic * 2 + pad {
continue;
}
let ib = vb - ic * 2 - pad;
if ib + ic * 2 > bytes.len() || vb + vc * stride > bytes.len() {
continue;
}
let idx: Vec<u32> = (0..ic).map(|k| be16(&bytes, ib + k * 2)).collect();
let max_idx = *idx.iter().max().unwrap_or(&0) as usize;
if max_idx >= vc {
continue; // out of range — not a candidate at all
}
let pos: Vec<[f32; 3]> = (0..vc)
.map(|v| {
let at = vb + v * stride;
[
f32::from_be_bytes(bytes[at..at + 4].try_into().unwrap()),
f32::from_be_bytes(bytes[at + 4..at + 8].try_into().unwrap()),
f32::from_be_bytes(bytes[at + 8..at + 12].try_into().unwrap()),
]
})
.collect();
if pos.iter().any(|p| p.iter().any(|c| !c.is_finite() || c.abs() > 1e6)) {
continue;
}
let mut degen = 0usize;
let (mut agree, mut counted) = (0usize, 0usize);
for t in idx.chunks_exact(3) {
let (x, y, z) = (t[0] as usize, t[1] as usize, t[2] as usize);
if x == y || y == z || x == z {
degen += 1;
continue;
}
// Winding needs normals; use the geometric centroid normal as a
// stand-in so this stays declaration-agnostic: a consistent mesh
// has all faces pointing away from the centroid on a convex-ish
// hull. Weak, so degeneracy leads the sort.
let e1 = [pos[y][0] - pos[x][0], pos[y][1] - pos[x][1], pos[y][2] - pos[x][2]];
let e2 = [pos[z][0] - pos[x][0], pos[z][1] - pos[x][1], pos[z][2] - pos[x][2]];
let f = [
e1[1] * e2[2] - e1[2] * e2[1],
e1[2] * e2[0] - e1[0] * e2[2],
e1[0] * e2[1] - e1[1] * e2[0],
];
let cx: [f32; 3] = {
let mut c = [0.0f32; 3];
for p in &pos {
for k in 0..3 {
c[k] += p[k] / pos.len() as f32;
}
}
c
};
let out = [pos[x][0] - cx[0], pos[x][1] - cx[1], pos[x][2] - cx[2]];
counted += 1;
if f[0] * out[0] + f[1] * out[1] + f[2] * out[2] > 0.0 {
agree += 1;
}
}
let w = if counted == 0 { 0.0 } else { agree as f32 / counted as f32 };
rows.push((degen, w.max(1.0 - w), vb, pad, max_idx, max_idx + 1 == vc));
}
}
rows.sort_by(|a, b| a.0.cmp(&b.0).then(b.1.total_cmp(&a.1)));
println!("\n{} in-range candidates; best 12 by (degenerate, winding):", rows.len());
for (d, w, vb, pad, mx, cov) in rows.iter().take(12) {
let mark = if Some(*vb) == ours { " <-- ours" } else { "" };
println!(
" vb 0x{vb:07X} pad {pad} degen {d:>4} wind {w:.3} max_idx {mx}/{} {}{mark}",
vc - 1,
if *cov { "covers" } else { "SHORT" }
);
}
let clean = rows.iter().filter(|r| r.0 == 0 && r.5).count();
println!("\n{clean} candidates are degenerate-free AND cover the pool exactly");
}

View File

@@ -0,0 +1,53 @@
//! Does a resource's DESCRIPTOR carry its bounding box?
//!
//! The last cross-container disagreements are 24-vertex bound boxes swapping
//! identities; no anchoring rule can pin them (see docs). If the descriptor
//! states the box, that is the missing information. This decodes the resource,
//! takes the box its geometry actually spans, and searches the descriptor for
//! those float values.
//!
//! Usage: bounds_in_descriptor <container.xpr> <resource>...
use sylpheed_formats::mesh::{xbg7_descriptor_range, Xbg7Model};
use std::collections::HashSet;
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).expect("container");
let want: HashSet<String> = a[2..].iter().cloned().collect();
for m in Xbg7Model::models_named(&bytes, &want, &|| false) {
let (mut lo, mut hi) = ([f32::MAX; 3], [f32::MIN; 3]);
for s in &m.meshes {
for q in &s.positions {
for k in 0..3 {
lo[k] = lo[k].min(q[k]);
hi[k] = hi[k].max(q[k]);
}
}
}
let Some((d0, d1)) = xbg7_descriptor_range(&bytes, &m.name) else { continue };
println!(
"{} descriptor 0x{d0:x}..0x{d1:x} ({} bytes), box lo{:?} hi{:?}",
m.name,
d1 - d0,
lo.map(|v| v.round()),
hi.map(|v| v.round())
);
// Where in the descriptor does each bound value appear (±0.01)?
let targets: Vec<(&str, f32)> = vec![
("lo.x", lo[0]), ("lo.y", lo[1]), ("lo.z", lo[2]),
("hi.x", hi[0]), ("hi.y", hi[1]), ("hi.z", hi[2]),
];
for (label, v) in targets {
let mut at: Vec<usize> = Vec::new();
let mut o = d0;
while o + 4 <= d1 {
let f = f32::from_be_bytes(bytes[o..o + 4].try_into().unwrap());
if (f - v).abs() <= 0.01 * (1.0 + v.abs()) {
at.push(o - d0);
}
o += 4;
}
println!(" {label:5} {v:10.3} at descriptor offsets {:x?}", &at[..at.len().min(6)]);
}
}
}

View File

@@ -0,0 +1,222 @@
//! Where does a drawn block's INDEX buffer really live?
//!
//! Our XBG7 anchor scan only ever *assumes* the layout `[index buffer][vertex
//! buffer]` with a pad of at most 3 bytes between them (`anchor_pool_mesh`:
//! `ib = vb - idx_count*2 - pad`). Nothing on disc states it, and it is the gate
//! that rejected the capture-proven `e106_eng_02_l` block
//! (docs/re/captures/…): the block's index data was not where the decoder
//! looked. The F10 ship capture was extended on 2026-08-13 to log each draw's
//! index-buffer base, count and min/max index value, so the assumption is now
//! directly checkable:
//!
//! * `vbase - ibase` is the real gap in guest memory, and a stage container is
//! uploaded contiguously (see `shared_vbase_check`), so the same difference
//! holds in the file;
//! * `max index vs vcount` says whether a draw covers its whole vertex pool —
//! the "buffer not covered" miss class is a *sub-range draw* if it does not.
//!
//! Usage:
//! cargo run --release --example capture_ib_truth -- <Stage_SNN.xpr> <capture.log>...
use sylpheed_formats::mesh::{debug_resource_params, xbg7_resource_names, Xbg7Model};
use sylpheed_formats::ship_capture::{parse_capture, CapturedDraw};
use std::collections::HashMap;
fn q(v: f32) -> i64 {
(v as f64 * 1e4).round() as i64
}
fn main() {
let a: Vec<String> = std::env::args().collect();
if a.len() < 3 {
eprintln!("usage: capture_ib_truth <container.xpr> <capture.log>...");
std::process::exit(2);
}
let bytes = std::fs::read(&a[1]).expect("container");
// One entry per (log, vbase): the capture already de-dups per placement, and
// a buffer drawn at several transforms has the same index buffer each time.
let mut draws: Vec<CapturedDraw> = Vec::new();
let mut seen = std::collections::HashSet::new();
for log in &a[2..] {
let text = std::fs::read_to_string(log).expect("log");
for d in parse_capture(&text) {
// One entry per (log, vbase, index range): the engine issues SEVERAL
// draws over one vertex buffer, each with its own index sub-range, and
// it is their UNION that describes the block. (Captures taken before
// 2026-08-13 de-dup by (vbase, transform) and so hold only the first
// batch — such a log reads as a mysteriously short draw.)
let k = d.ib.map(|i| (i.ibase, i.icount)).unwrap_or((0, 0));
if d.ib.is_some() && d.pos.len() >= 4 && seen.insert((log.clone(), d.vbase, k)) {
draws.push(d);
}
}
}
eprintln!("{} drawn buffers with an index buffer", draws.len());
// ── Place the drawn buffers in the file: POSITION is f32×3 big-endian at
// vertex offset 0, so the dumped positions are a literal byte pattern.
let be = |at: usize| f32::from_be_bytes(bytes[at..at + 4].try_into().unwrap());
let mut index: HashMap<(i64, i64, i64), Vec<u32>> = HashMap::new();
let mut o = 0usize;
while o + 12 <= bytes.len() {
let (x, y, z) = (be(o), be(o + 4), be(o + 8));
if x.is_finite() && y.is_finite() && z.is_finite() && x.abs() < 1e6 && y.abs() < 1e6 && z.abs() < 1e6 {
index.entry((q(x), q(y), q(z))).or_default().push(o as u32);
}
o += 4;
}
let mut deltas: HashMap<i64, usize> = HashMap::new();
let mut hits: Vec<(i64, usize, &CapturedDraw)> = Vec::new(); // (delta, file offset, draw)
for d in &draws {
let k = (q(d.pos[0][0]), q(d.pos[0][1]), q(d.pos[0][2]));
for dx in -1..=1i64 {
for dy in -1..=1i64 {
for dz in -1..=1i64 {
let Some(cands) = index.get(&(k.0 + dx, k.1 + dy, k.2 + dz)) else { continue };
for &off in cands {
for stride in (12..=64).step_by(4) {
let ok = (1..4).all(|j| {
let at = off as usize + j * stride;
at + 12 <= bytes.len()
&& (0..3).all(|c| (be(at + c * 4) - d.pos[j][c]).abs() <= 1e-4)
});
if ok {
let delta = d.vbase as i64 - off as i64;
*deltas.entry(delta).or_default() += 1;
hits.push((delta, off as usize, d));
break;
}
}
}
}
}
}
}
let Some((&base_delta, &n)) = deltas.iter().max_by_key(|(_, n)| **n) else {
eprintln!("no draw could be placed in this container");
std::process::exit(1);
};
println!("container load constant: vbase - file_offset = 0x{base_delta:X} ({n} buffers agree)");
// ── Our decoder's view of the same container.
let models = Xbg7Model::stage_models(&bytes);
let mut by_off: HashMap<usize, Vec<(String, usize, usize)>> = HashMap::new();
for m in &models {
for sm in &m.meshes {
if let Some(off) = sm.vbuf_offset {
by_off
.entry(off)
.or_default()
.push((m.name.clone(), sm.positions.len(), sm.indices.len()));
}
}
}
println!("decoded {} resources, {} distinct vertex offsets\n", models.len(), by_off.len());
// Declared-but-not-decoded resources, indexed by their first marker's
// (vertex, index) counts. A drawn buffer our decoder cannot name is the one
// thing a capture can give the residual misses: ground truth for where the
// block actually is. Matching on counts is enough to propose an identity —
// then `debug_try_anchor` at that offset says which gate rejects it.
let decoded_names: std::collections::HashSet<String> =
models.iter().map(|m| m.name.clone()).collect();
let mut undecoded_by_counts: HashMap<(usize, usize), Vec<String>> = HashMap::new();
for n in xbg7_resource_names(&bytes) {
if decoded_names.contains(&n) {
continue;
}
if let Some((markers, _)) = debug_resource_params(&bytes, &n) {
if let Some(&(v, i)) = markers.first() {
undecoded_by_counts.entry((v, i)).or_default().push(n);
}
}
}
// ── The report: one row per drawn BUFFER, aggregating its index batches.
let mut per_buf: HashMap<u32, (usize, Vec<sylpheed_formats::ship_capture::CapturedIndexBuffer>, u32)> =
HashMap::new();
for (delta, voff, d) in &hits {
if *delta != base_delta {
continue;
}
let e = per_buf.entry(d.vbase).or_insert((*voff, Vec::new(), d.vcount));
let ib = d.ib.unwrap();
if !e.1.contains(&ib) {
e.1.push(ib);
}
}
let (mut pad0, mut pad_small, mut pad_off, mut unnamed) = (0usize, 0usize, 0usize, 0usize);
let (mut cover_exact, mut cover_short, mut idx_equal, mut idx_partial) = (0usize, 0usize, 0usize, 0usize);
let mut rows: Vec<(usize, String)> = Vec::new();
for (_, (voff, ibs, vcount)) in per_buf.iter() {
let batches = ibs.len();
let total: u32 = ibs.iter().map(|i| i.icount).sum();
let lo = ibs.iter().map(|i| i.ibase).min().unwrap() as i64 - base_delta;
let hi = ibs.iter().map(|i| i.ibase + i.icount * 2).max().unwrap() as i64 - base_delta;
let umax = ibs.iter().map(|i| i.imax).max().unwrap();
let gap = *voff as i64 - hi; // bytes from the end of the index data to the vertex buffer
let names = by_off.get(voff);
let dec_idx = names
.and_then(|v| v.iter().find(|(_, p, _)| *p as u32 == *vcount).map(|(_, _, i)| *i as u32));
// The decoder's assumption, scored: it expects the whole index buffer at
// `vb - 2*idx_count - pad`, pad ≤ 3.
let dec_pad = dec_idx.map(|i| *voff as i64 - (i as i64) * 2 - lo);
match dec_pad {
Some(0) => pad0 += 1,
Some(p) if (1..=3).contains(&p) => pad_small += 1,
Some(_) => pad_off += 1,
None => unnamed += 1,
}
if umax + 1 == *vcount {
cover_exact += 1;
} else {
cover_short += 1;
}
match dec_idx {
Some(i) if i == total => idx_equal += 1,
Some(_) => idx_partial += 1,
None => {}
}
rows.push((
*voff,
format!(
"vb 0x{:07X} v={:<6} batches {:<3} idx {:<6} span {:<7} gap {:<8} decpad {:<7} cover {:<10} {}",
voff,
vcount,
batches,
total,
hi - lo,
gap,
dec_pad.map(|p| p.to_string()).unwrap_or_else(|| "?".into()),
if umax + 1 == *vcount { "exact".to_string() } else { format!("{}/{}", umax, vcount - 1) },
names
.map(|v| v
.iter()
.map(|(n, p, i)| format!("{n}(v{p},i{i})"))
.collect::<Vec<_>>()
.join(" "))
.unwrap_or_else(|| {
// Nothing of ours sits here — is it a resource that never
// decodes? Propose it by (vertex, index) counts.
undecoded_by_counts
.get(&(*vcount as usize, total as usize))
.map(|v| format!("MISSED? {}", v.join(" ")))
.unwrap_or_else(|| "-".into())
})
),
));
}
rows.sort();
for (_, r) in &rows {
println!("{r}");
}
println!("\nplaced {} drawn buffers in this container", rows.len());
println!(
"DECODER layout assumption — whole index buffer at vb - 2*idx_count - pad: pad 0 {pad0} · pad 1..3 {pad_small} · elsewhere {pad_off} · not decoded here {unnamed}"
);
println!(
"index extent: our idx_count == sum of captured batches for {idx_equal} buffers, differs for {idx_partial}"
);
println!("vertex-pool coverage by the union of batches: exact {cover_exact} · short {cover_short}");
}

View File

@@ -0,0 +1,175 @@
//! Do our decoded triangle indices equal the ones the GPU actually read?
//!
//! `capture_ib_truth` established *where* a block's index buffer lives and that
//! its length matches ours. This asks the stronger question: are the index VALUES
//! the same, in the same order? The capture prints the first 24 indices of every
//! draw batch verbatim (`idx: …`), and a batch's `ibase` locates it inside the
//! block's index buffer — so for each drawn buffer we can line the captured run
//! up against `GameMesh::indices` at the right offset and compare element by
//! element. That tests the whole index path at once: the anchor, the u16
//! big-endian read, the triangle-list interpretation (a strip would disagree
//! immediately), and the sub-mesh carve.
//!
//! Usage:
//! cargo run --release --example capture_index_bytes -- <Stage_SNN.xpr> <capture.log>...
use sylpheed_formats::mesh::Xbg7Model;
use sylpheed_formats::ship_capture::{parse_capture, CapturedDraw};
use std::collections::HashMap;
fn q(v: f32) -> i64 {
(v as f64 * 1e4).round() as i64
}
fn main() {
let a: Vec<String> = std::env::args().collect();
if a.len() < 3 {
eprintln!("usage: capture_index_bytes <container.xpr> <capture.log>...");
std::process::exit(2);
}
let bytes = std::fs::read(&a[1]).expect("container");
let mut draws: Vec<CapturedDraw> = Vec::new();
let mut seen = std::collections::HashSet::new();
for log in &a[2..] {
let text = std::fs::read_to_string(log).expect("log");
for d in parse_capture(&text) {
let k = d.ib.map(|i| (i.ibase, i.icount)).unwrap_or((0, 0));
if d.ib.map_or(false, |i| i.head_len > 0) && d.pos.len() >= 4 && seen.insert((log.clone(), d.vbase, k)) {
draws.push(d);
}
}
}
eprintln!("{} draw batches with an index head", draws.len());
// Place each drawn buffer in the file by its dumped positions (see
// capture_ib_truth for the method) and keep the modal load constant.
let be = |at: usize| f32::from_be_bytes(bytes[at..at + 4].try_into().unwrap());
let mut index: HashMap<(i64, i64, i64), Vec<u32>> = HashMap::new();
let mut o = 0usize;
while o + 12 <= bytes.len() {
let (x, y, z) = (be(o), be(o + 4), be(o + 8));
if x.is_finite() && y.is_finite() && z.is_finite() && x.abs() < 1e6 && y.abs() < 1e6 && z.abs() < 1e6 {
index.entry((q(x), q(y), q(z))).or_default().push(o as u32);
}
o += 4;
}
let mut deltas: HashMap<i64, usize> = HashMap::new();
let mut hits: Vec<(i64, usize, &CapturedDraw)> = Vec::new();
for d in &draws {
let k = (q(d.pos[0][0]), q(d.pos[0][1]), q(d.pos[0][2]));
for dx in -1..=1i64 {
for dy in -1..=1i64 {
for dz in -1..=1i64 {
let Some(cands) = index.get(&(k.0 + dx, k.1 + dy, k.2 + dz)) else { continue };
for &off in cands {
for stride in (12..=64).step_by(4) {
let ok = (1..4).all(|j| {
let at = off as usize + j * stride;
at + 12 <= bytes.len()
&& (0..3).all(|c| (be(at + c * 4) - d.pos[j][c]).abs() <= 1e-4)
});
if ok {
*deltas.entry(d.vbase as i64 - off as i64).or_default() += 1;
hits.push((d.vbase as i64 - off as i64, off as usize, d));
break;
}
}
}
}
}
}
}
let Some((&base_delta, _)) = deltas.iter().max_by_key(|(_, n)| **n) else {
eprintln!("no draw could be placed in this container");
std::process::exit(1);
};
println!("load constant 0x{base_delta:X}");
// Our decode, indexed by vertex offset. A model may hold several sub-meshes;
// compare against the one whose vertex count matches the draw.
let models = Xbg7Model::stage_models(&bytes);
let mut by_off: HashMap<usize, Vec<(String, usize, Vec<u32>)>> = HashMap::new();
for m in &models {
for sm in &m.meshes {
if let Some(off) = sm.vbuf_offset {
by_off
.entry(off)
.or_default()
.push((m.name.clone(), sm.positions.len(), sm.indices.clone()));
}
}
}
// Where does each buffer's index data START? Take it from the capture, not
// from an assumed pad: `capture_ib_truth` established that a buffer's batches
// tile its index buffer exactly (sum of counts == our idx_count, span ==
// 2*count), so the lowest `ibase` over a buffer's batches IS the block's
// index start. Assuming `vb - 2*len` instead is wrong for the buffers that
// sit at pad 2 and shifts the whole comparison by one element.
let mut ib_start: HashMap<u32, i64> = HashMap::new();
for (delta, _, d) in &hits {
if *delta != base_delta {
continue;
}
let ibase = d.ib.unwrap().ibase as i64;
ib_start.entry(d.vbase).and_modify(|e| *e = (*e).min(ibase)).or_insert(ibase);
}
let (mut agree, mut disagree, mut unmatched, mut nooverlap) = (0usize, 0usize, 0usize, 0usize);
let mut bad: Vec<String> = Vec::new();
let mut checked_elems = 0usize;
let mut done: std::collections::HashSet<(u32, u32)> = std::collections::HashSet::new();
for (delta, voff, d) in &hits {
if *delta != base_delta {
continue;
}
let ib = d.ib.unwrap();
if !done.insert((d.vbase, ib.ibase)) {
continue;
}
let Some(cands) = by_off.get(voff) else {
unmatched += 1;
continue;
};
let Some((name, _, ours)) = cands.iter().find(|(_, p, _)| *p as u32 == d.vcount) else {
unmatched += 1;
continue;
};
// Element 0 of our index list is the block's index start, as observed.
let ours_start = ib_start[&d.vbase] - base_delta;
let batch_off = ib.ibase as i64 - base_delta - ours_start;
if batch_off < 0 || batch_off % 2 != 0 {
nooverlap += 1;
continue;
}
let first = (batch_off / 2) as usize;
let n = (ib.head_len as usize).min(ours.len().saturating_sub(first));
if n == 0 {
nooverlap += 1;
continue;
}
let mism = (0..n).find(|&k| ours[first + k] != ib.head[k]);
checked_elems += n;
match mism {
None => agree += 1,
Some(k) => {
disagree += 1;
if bad.len() < 8 {
bad.push(format!(
"{name} vb 0x{:07X} batch@{first}: ours {:?} != captured {:?} (first differs at {k})",
voff,
&ours[first..first + n.min(12)],
&ib.head[..n.min(12)]
));
}
}
}
}
println!(
"index runs compared: {agree} identical · {disagree} differing · {unmatched} no decoded resource · {nooverlap} batch outside our buffer"
);
println!("{checked_elems} index elements checked against the GPU");
for b in &bad {
println!(" MISMATCH {b}");
}
}

View File

@@ -0,0 +1,112 @@
//! Which container did each captured draw come from, and where in it?
//!
//! Extends the single-container `--map` check in `shared_vbase_check` to a whole
//! `resource3d` directory. For each container it indexes every 4-byte-aligned
//! position triple, looks up each draw's first dumped position, confirms the run
//! at a fixed stride, and reports the modal `vbase offset`. A container the
//! engine loaded shows one dominant constant; an unrelated one shows noise.
//!
//! The output is capture-named ground truth for anchors far beyond the one ship
//! `Stage_S01` gave us.
//!
//! Usage: capture_truth_scan <resource3d_dir> <capture.log>...
use sylpheed_formats::ship_capture::{parse_capture, parse_drawlog, CapturedDraw};
use std::collections::HashMap;
fn q(v: f32) -> i64 {
(v as f64 * 1e4).round() as i64
}
fn main() {
let a: Vec<String> = std::env::args().collect();
let dir = &a[1];
let mut draws: Vec<CapturedDraw> = Vec::new();
let mut seen = std::collections::HashSet::new();
for log in &a[2..] {
let text = std::fs::read_to_string(log).expect("log");
let mut d = parse_capture(&text);
if d.is_empty() {
d = parse_drawlog(&text);
}
for x in d {
// One entry per buffer; the logs are already deduped per transform.
if x.pos.len() >= 8 && x.vcount >= 20 && seen.insert((log.clone(), x.vbase)) {
draws.push(x);
}
}
}
eprintln!("{} distinct (log, vbase) draws to place", draws.len());
let mut files: Vec<_> = std::fs::read_dir(dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
let mut placed = 0usize;
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
// Index quantised position triples. Junk floats (NaN/huge) are skipped,
// which prunes most of a texture-heavy container.
let be = |at: usize| f32::from_be_bytes(bytes[at..at + 4].try_into().unwrap());
let mut index: HashMap<(i64, i64, i64), Vec<u32>> = HashMap::new();
let mut o = 0usize;
while o + 12 <= bytes.len() {
let (x, y, z) = (be(o), be(o + 4), be(o + 8));
if x.is_finite() && y.is_finite() && z.is_finite() && x.abs() < 1e6 && y.abs() < 1e6 && z.abs() < 1e6
{
index.entry((q(x), q(y), q(z))).or_default().push(o as u32);
}
o += 4;
}
let mut deltas: HashMap<i64, Vec<(u32, u32)>> = HashMap::new();
for d in &draws {
let k = (q(d.pos[0][0]), q(d.pos[0][1]), q(d.pos[0][2]));
// ±1 in each axis: the log rounds, our file value may round the
// other way at a tie.
for dx in -1..=1i64 {
for dy in -1..=1i64 {
for dz in -1..=1i64 {
let Some(cands) = index.get(&(k.0 + dx, k.1 + dy, k.2 + dz)) else {
continue;
};
for &off in cands {
for stride in (12..=64).step_by(4) {
let ok = (1..4).all(|j| {
let at = off as usize + j * stride;
at + 12 <= bytes.len()
&& (0..3).all(|c| {
(be(at + c * 4) - d.pos[j][c]).abs() <= 1e-4
})
});
if ok {
deltas
.entry(d.vbase as i64 - off as i64)
.or_default()
.push((d.vbase, d.vcount));
break;
}
}
}
}
}
}
}
let mut top: Vec<_> = deltas.into_iter().collect();
top.sort_by_key(|(_, v)| std::cmp::Reverse(v.len()));
if let Some((delta, hits)) = top.first() {
if hits.len() >= 3 {
placed += hits.len();
println!(
"{:<22} base=0x{:<10X} buffers={}",
f.file_name().unwrap().to_string_lossy(),
delta,
hits.len()
);
}
}
}
eprintln!("{placed} draws placed in a container");
}

View File

@@ -0,0 +1,34 @@
//! How much of the "decoded geometry" belongs to SCENE COMPOSITES rather than to
//! real meshes? A composite (`rou_*`, `e_rou_*`) carries node transforms; the
//! anchor scan nevertheless finds a block for it, and that pseudo-geometry lands
//! in coverage and consistency counts.
//! Usage: composite_geometry <resource3d_dir>
use sylpheed_formats::mesh::{scene_world_nodes, Xbg7Model};
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
let (mut total, mut composite, mut composite_named) = (0usize, 0usize, 0usize);
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
for m in Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false) {
total += 1;
let has_nodes = !scene_world_nodes(&bytes, &m.name).is_empty();
let named = m.name.starts_with("rou_") || m.name.starts_with("e_rou_");
if has_nodes {
composite += 1;
}
if named {
composite_named += 1;
}
}
}
println!(
"{total} decoded; {composite} have scene nodes (a composite), {composite_named} are named rou_/e_rou_"
);
}

View File

@@ -0,0 +1,87 @@
//! Minority report: which container decodes a shared resource differently from
//! all the others?
//!
//! Cross-container consistency has been measured as "do the spans agree", which
//! only says a resource is inconsistent — not which copy is wrong. With three or
//! more copies the majority is the reference, and the minority names the
//! container AND the resource to look at. That is what caught the `n054`/`n056`
//! shift chain after the exact-coverage fix.
//!
//! Usage: consensus_check <resource3d_dir> [--list]
use sylpheed_formats::mesh::Xbg7Model;
use std::collections::{BTreeMap, HashMap};
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let list = std::env::args().any(|a| a == "--list");
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
// name -> [(container, verts, tris, span)]
let mut seen: BTreeMap<String, Vec<(String, usize, usize, [i64; 3])>> = BTreeMap::new();
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
let where_ = f.file_name().unwrap().to_string_lossy().to_string();
for m in Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false) {
let (mut lo, mut hi) = ([f32::MAX; 3], [f32::MIN; 3]);
for s in &m.meshes {
for q in &s.positions {
for k in 0..3 {
lo[k] = lo[k].min(q[k]);
hi[k] = hi[k].max(q[k]);
}
}
}
if lo[0] == f32::MAX {
continue;
}
let v: usize = m.meshes.iter().map(|s| s.positions.len()).sum();
let t: usize = m.meshes.iter().map(|s| s.indices.len() / 3).sum();
let span = [
(hi[0] - lo[0]).round() as i64,
(hi[1] - lo[1]).round() as i64,
(hi[2] - lo[2]).round() as i64,
];
seen.entry(m.name.clone()).or_default().push((where_.clone(), v, t, span));
}
}
let (mut resources, mut minority) = (0usize, 0usize);
let mut rows: Vec<String> = Vec::new();
for (name, list_) in &seen {
// Only compare decodes that agree on how much geometry they found, and
// only where a majority can exist.
if list_.len() < 3 || !list_.iter().all(|e| e.1 == list_[0].1 && e.2 == list_[0].2) {
continue;
}
let mut votes: HashMap<[i64; 3], usize> = HashMap::new();
for e in list_ {
*votes.entry(e.3).or_default() += 1;
}
let (best, n) = votes.iter().max_by_key(|(_, n)| **n).unwrap();
if *n * 2 <= list_.len() {
continue; // no majority — cannot call anyone the odd one out
}
resources += 1;
for e in list_.iter().filter(|e| e.3 != *best) {
minority += 1;
rows.push(format!(
"{:<22} {name:<26} v={:<6} {:?} vs the other {n} containers' {:?}",
e.0, e.1, e.3, best
));
}
}
if list {
for r in &rows {
println!("{r}");
}
}
println!(
"{minority} minority decodes across {resources} resources that have a majority"
);
}

View File

@@ -16,7 +16,7 @@
//! Usage:
//! SYLPHEED_ISO=... cargo run --release --example correlate_capture -- \
//! <capture.log> <Stage_SNN> <ship_id> [ref_part_substr] [--emit]
//! e.g. SYLPHEED_ISO="/home/fabi/RE Project Sylpheed/Project Sylpheed - Arc of
//! e.g. SYLPHEED_ISO="/home/fabi/RE - Project Sylpheed/Project Sylpheed - Arc of
//! Deception (USA, Europe) (En,Ja).iso" \
//! cargo run --release --example correlate_capture -- \
//! xenia_ship_capture.log Stage_S01 e106 bdy_04 --emit

View File

@@ -0,0 +1,48 @@
//! Do real index buffers address their whole vertex pool?
//!
//! `validate_block` rejects a block whose indices reach fewer than `vtx_count4`
//! vertices ("buffer not covered"). That gate is the furthest-reached rejection
//! for a handful of resources that never decode — so the question is whether it
//! is well founded. This measures the slack on every block that DOES decode: if
//! real geometry always covers its pool, under-coverage is good evidence of a
//! wrong candidate and the gate stands.
use sylpheed_formats::mesh::Xbg7Model;
use std::collections::BTreeMap;
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
let mut hist: BTreeMap<i64, usize> = BTreeMap::new();
let mut worst: Vec<(i64, String)> = Vec::new();
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
for m in Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false) {
for sub in &m.meshes {
if sub.positions.is_empty() || sub.indices.is_empty() {
continue;
}
let max_idx = *sub.indices.iter().max().unwrap() as i64;
let slack = sub.positions.len() as i64 - 1 - max_idx;
*hist.entry(slack.min(20)).or_default() += 1;
if slack > 4 {
worst.push((slack, format!("{} in {}", m.name, f.file_name().unwrap().to_string_lossy())));
}
}
}
}
println!("unreferenced tail vertices (vtx_count 1 max index), over decoded sub-meshes:");
for (slack, n) in &hist {
println!(" {:>3}{} : {n}", slack, if *slack == 20 { "+" } else { " " });
}
worst.sort_by_key(|(s, _)| std::cmp::Reverse(*s));
for (s, w) in worst.iter().take(5) {
println!(" largest slack {s}: {w}");
}
}

View File

@@ -0,0 +1,71 @@
//! Dump an XBG7 resource's descriptor around each index marker, to see whether a
//! grouped pool carries a declaration PER sub-mesh (the 2026-08-13 mixed-stride
//! finding says it must: n201's four sub-meshes use strides 24/24/24/28 and four
//! different vertex shaders).
//! Usage: desc_dump <container.xpr> <resource>
fn be32(b: &[u8], o: usize) -> u32 {
u32::from_be_bytes(b[o..o + 4].try_into().unwrap())
}
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).unwrap();
let want = &a[2];
// Walk the XPR2 directory by hand (the crate's reader is private).
// 16-byte directory entries at 0x10: type tag, data offset, descriptor size,
// name offset — all relative to 0x10 (see texture::Xpr2ResourceEntry).
let num = be32(&bytes, 12) as usize;
for i in 0..num {
let e = &bytes[0x10 + i * 16..0x10 + i * 16 + 16];
let tag = &e[0..4];
let data_off = be32(e, 4) as usize + 0x10;
let desc_size = be32(e, 8) as usize;
let name_off = be32(e, 12) as usize + 0x10;
if tag != b"XBG7" {
continue;
}
let name = {
let s = name_off.min(bytes.len());
let end = bytes[s..].iter().position(|&c| c == 0).unwrap_or(0) + s;
String::from_utf8_lossy(&bytes[s..end]).to_string()
};
if name != *want {
continue;
}
let desc = &bytes[data_off..(data_off + desc_size).min(bytes.len())];
println!("{name}: descriptor at 0x{data_off:X}, {} bytes", desc.len());
// markers: a == c*2, c%3==0, vertex count 32 bytes earlier
let mut rel = 0usize;
while rel + 8 <= desc.len() {
let (x, c) = (be32(desc, rel), be32(desc, rel + 4));
if c >= 3 && c % 3 == 0 && c < 400_000 && x == c * 2 && rel >= 32 {
let vc = be32(desc, rel - 32);
if (3..=200_000).contains(&vc) {
println!("\n marker @0x{rel:X}: {vc} verts / {c} indices — declaration triples after it:");
let mut r = rel + 8;
let mut stride = 0u32;
for _ in 0..12 {
if r + 12 > desc.len() {
break;
}
let (o, code, usage) = (be32(desc, r), be32(desc, r + 4), be32(desc, r + 8) >> 16);
if o == 0x00FF_0000 || code == 0xFFFF_FFFF || o > 0x1000 {
println!(" end marker @0x{r:X}: off=0x{o:X} code=0x{code:X}");
break;
}
println!(" off {o:>3} code 0x{:06X} usage {usage}", code & 0xFF_FFFF);
stride = stride.max(o + 4);
r += 12;
}
println!(" (min stride from element offsets: {stride})");
rel += 8;
continue;
}
}
rel += 4;
}
return;
}
eprintln!("resource not found");
}

View File

@@ -0,0 +1,80 @@
//! Calibrate the connectivity cap against the whole disc.
//!
//! `XBG7_EDGE_CAP` sets the cap; this reports, for one setting, how much
//! geometry decodes and how self-consistent it is across containers — the two
//! numbers any change to the cap has to trade off. Run it once per cap value.
use sylpheed_formats::mesh::Xbg7Model;
use std::collections::BTreeMap;
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
// name -> (verts, tris) -> spans seen, exactly as mesh_consistency_disc.rs.
let mut seen: BTreeMap<String, Vec<([i64; 3], usize, usize)>> = BTreeMap::new();
let (mut models, mut verts) = (0usize, 0usize);
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
for m in Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false) {
let (mut lo, mut hi) = ([f32::MAX; 3], [f32::MIN; 3]);
for s in &m.meshes {
for q in &s.positions {
for k in 0..3 {
lo[k] = lo[k].min(q[k]);
hi[k] = hi[k].max(q[k]);
}
}
}
if lo[0] == f32::MAX {
continue;
}
let v: usize = m.meshes.iter().map(|s| s.positions.len()).sum();
let t: usize = m.meshes.iter().map(|s| s.indices.len() / 3).sum();
models += 1;
verts += v;
if std::env::var("DUMP").is_ok() {
// Per-resource signature, so two cap settings can be diffed:
// a cap change that silently MOVES an existing anchor is the
// risk a coverage count cannot see.
println!(
"{}|{}|{v}|{t}|{}|{}|{}|{}",
f.file_name().unwrap().to_string_lossy(),
m.name,
m.meshes[0].vbuf_offset.unwrap_or(0),
(hi[0] - lo[0]).round() as i64,
(hi[1] - lo[1]).round() as i64,
(hi[2] - lo[2]).round() as i64
);
}
seen.entry(m.name.clone()).or_default().push((
[
(hi[0] - lo[0]).round() as i64,
(hi[1] - lo[1]).round() as i64,
(hi[2] - lo[2]).round() as i64,
],
v,
t,
));
}
}
let (mut shared, mut inconsistent) = (0usize, 0usize);
for (_, list) in &seen {
if list.len() < 2 || !list.iter().all(|e| e.1 == list[0].1 && e.2 == list[0].2) {
continue;
}
shared += 1;
if list.iter().any(|e| e.0 != list[0].0) {
inconsistent += 1;
}
}
println!(
"cap={} models={models} verts={verts} shared={shared} inconsistent={inconsistent}",
std::env::var("XBG7_EDGE_CAP").unwrap_or_else(|_| "library default".into())
);
}

View File

@@ -0,0 +1,106 @@
//! Does every part of a ship sit inside the envelope its siblings describe?
//!
//! `slab_screen` compared *scale* and could not see the `e106` slab. What the eye
//! used when the render exposed it was **relationship**: a blocky mass sitting
//! apart from the hull. This measures that — assemble a ship, and for each part
//! ask how far its world box protrudes beyond the box of all the OTHER parts,
//! relative to the ship's own size. A mis-anchored block sticks out; a real part,
//! however big, is part of the silhouette.
//!
//! Usage: envelope_screen <resource3d_dir> [protrusion_fraction]
use sylpheed_formats::mesh::Xbg7Model;
use sylpheed_formats::ship::{assemble_ship, ship_id_of};
use std::collections::{BTreeSet, HashSet};
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let limit: f32 = std::env::args().nth(2).and_then(|s| s.parse().ok()).unwrap_or(0.35);
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
let mut flagged = 0usize;
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
let ids: BTreeSet<String> = Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false)
.iter()
.filter_map(|m| ship_id_of(&m.name).map(|s| s.to_string()))
.collect();
for id in &ids {
let placed = assemble_ship(&bytes, id, true);
if placed.len() < 3 {
continue;
}
let want: HashSet<String> = placed.iter().map(|p| p.resource.clone()).collect();
let models = Xbg7Model::models_named(&bytes, &want, &|| false);
// World box per placement.
let mut boxes: Vec<(String, [f32; 3], [f32; 3])> = Vec::new();
for p in &placed {
let Some(m) = models.iter().find(|m| m.name == p.resource) else { continue };
let (mut lo, mut hi) = ([f32::MAX; 3], [f32::MIN; 3]);
for s in &m.meshes {
for q in &s.positions {
let w = p.apply(*q);
for k in 0..3 {
lo[k] = lo[k].min(w[k]);
hi[k] = hi[k].max(w[k]);
}
}
}
if lo[0] != f32::MAX {
boxes.push((p.resource.clone(), lo, hi));
}
}
if boxes.len() < 3 {
continue;
}
for i in 0..boxes.len() {
// Envelope of every OTHER part.
let (mut lo, mut hi) = ([f32::MAX; 3], [f32::MIN; 3]);
for (j, b) in boxes.iter().enumerate() {
if i == j {
continue;
}
for k in 0..3 {
lo[k] = lo[k].min(b.1[k]);
hi[k] = hi[k].max(b.2[k]);
}
}
// Per-AXIS: a bow legitimately extends the ship along its long
// axis, so protrusion only means something measured against the
// envelope's size IN THAT AXIS. The e106 slab stuck ~1 500 out in
// Y where its siblings spanned ~800.
let mut worst = 0.0f32;
let mut worst_out = 0.0f32;
for k in 0..3 {
let size_k = hi[k] - lo[k];
if size_k <= 1.0 {
continue;
}
let out_k = (lo[k] - boxes[i].1[k]).max(boxes[i].2[k] - hi[k]).max(0.0);
if out_k / size_k > worst {
worst = out_k / size_k;
worst_out = out_k;
}
}
let (out, size) = (worst_out, 1.0f32);
let _ = size;
if worst > limit {
flagged += 1;
println!(
"{:<20} {:<22} protrudes {:>7.0} beyond its siblings ({:.0}% of the ship)",
f.file_name().unwrap().to_string_lossy(),
boxes[i].0,
out,
100.0 * worst
);
}
}
}
}
println!("{flagged} parts protrude more than {:.0}% of their ship's size", 100.0 * limit);
}

View File

@@ -0,0 +1,35 @@
//! Does a FILTERED decode agree with the full one?
//!
//! Distinct anchor assignment resolves collisions against the set of resources
//! being decoded — so `models_named` (a filtered subset, used by the ship
//! assembler and the viewer) can reach a different answer from a whole-container
//! decode. This measures that directly.
//! Usage: filter_consistency <container.xpr> [resource...]
use sylpheed_formats::mesh::Xbg7Model;
use std::collections::HashSet;
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).expect("container");
let full = Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false);
let names: Vec<String> = if a.len() > 2 {
a[2..].to_vec()
} else {
full.iter().map(|m| m.name.clone()).collect()
};
let mut differ = 0usize;
for n in &names {
let want: HashSet<String> = std::iter::once(n.clone()).collect();
let one = Xbg7Model::models_named(&bytes, &want, &|| false);
let (Some(f), Some(s)) = (full.iter().find(|m| &m.name == n), one.first()) else {
continue;
};
let off = |m: &Xbg7Model| m.meshes.first().and_then(|s| s.vbuf_offset).unwrap_or(0);
if off(f) != off(s) {
differ += 1;
if differ <= 10 {
println!("{n}: full decode at 0x{:x}, filtered at 0x{:x}", off(f), off(s));
}
}
}
println!("{differ} of {} resources decode differently when filtered", names.len());
}

View File

@@ -0,0 +1,27 @@
//! Where could a resource's index buffer be, given the vertex buffer a runtime
//! capture proves the engine drew from? Tests the anchor scan's adjacency
//! assumption against ground truth.
use sylpheed_formats::mesh::{debug_find_index_buffer, debug_resource_params};
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).unwrap();
for pair in a[2..].iter() {
let (name, off) = pair.split_once('@').unwrap();
let vb = usize::from_str_radix(off.trim_start_matches("0x"), 16).unwrap();
let params = debug_resource_params(&bytes, name);
let markers = params.as_ref().map(|(m, _)| m.clone()).unwrap_or_default();
println!("{name} @ 0x{vb:x} markers={markers:?}");
let hits = debug_find_index_buffer(&bytes, name, vb);
if hits.is_empty() {
println!(" no index buffer anywhere in the container validates this block");
}
let mut hits = hits;
hits.sort_by_key(|(_, d)| d.abs());
for (ib, d) in hits.iter().take(8) {
println!(" ib 0x{ib:x} vb-ib = {d} bytes");
}
if hits.len() > 8 {
println!("{} total", hits.len());
}
}
}

View File

@@ -0,0 +1,44 @@
//! Does the container hold an X-mirrored copy of a resource's decoded buffer?
//!
//! The twin invariant (see `twin_mirror_audit`) flags `…_01`/`…_02` pairs that
//! decode to unrelated geometry. If the mirror of one twin's buffer exists
//! somewhere else in the container, that offset is where the other twin belongs
//! and the pair is a mis-anchor; if it does not exist, the pair is simply not a
//! mirrored pair.
//!
//! Usage: find_mirror <container.xpr> <resource>...
use sylpheed_formats::mesh::Xbg7Model;
use std::collections::HashSet;
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).expect("container");
let want: HashSet<String> = a[2..].iter().cloned().collect();
let models = Xbg7Model::models_named(&bytes, &want, &|| false);
let be = |at: usize| f32::from_be_bytes(bytes[at..at + 4].try_into().unwrap());
for m in &models {
let pos: Vec<[f32; 3]> = m.meshes.iter().flat_map(|s| s.positions.clone()).take(8).collect();
if pos.len() < 8 {
continue;
}
let anchored = m.meshes[0].vbuf_offset.unwrap_or(0);
let (mut direct, mut mirror) = (Vec::new(), Vec::new());
for o in (0..bytes.len().saturating_sub(12 + 8 * 24)).step_by(4) {
for (flip, out) in [(1.0f32, &mut direct), (-1.0f32, &mut mirror)] {
if (0..8).all(|k| {
let at = o + k * 24;
(be(at) - flip * pos[k][0]).abs() <= 1e-4
&& (be(at + 4) - pos[k][1]).abs() <= 1e-4
&& (be(at + 8) - pos[k][2]).abs() <= 1e-4
}) {
out.push(o);
}
}
}
println!(
"{:<20} anchored 0x{anchored:x} direct copies {:x?} mirrored copies {:x?}",
m.name, direct, mirror
);
}
}

View File

@@ -0,0 +1,60 @@
//! Which gate stops the resources that never decode?
//! Usage: gate_histogram <resource3d_dir> [max_resources]
use sylpheed_formats::mesh::{debug_best_rejection, xbg7_resource_names, Xbg7Model};
use std::collections::{BTreeMap, HashSet};
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let cap: usize = std::env::args().nth(2).and_then(|s| s.parse().ok()).unwrap_or(usize::MAX);
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
let mut hist: BTreeMap<usize, (usize, String)> = BTreeMap::new();
let mut done = 0usize;
for f in &files {
if done >= cap {
break;
}
let Ok(bytes) = std::fs::read(f) else { continue };
let names = xbg7_resource_names(&bytes);
if names.is_empty() {
continue;
}
let got: HashSet<String> = Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false)
.into_iter()
.map(|m| m.name)
.collect();
for n in names.iter().filter(|n| !got.contains(*n)) {
if done >= cap {
break;
}
done += 1;
if let Some((rank, why)) = debug_best_rejection(&bytes, n) {
let e = hist.entry(rank).or_insert((0, String::new()));
e.0 += 1;
if e.1.is_empty() {
e.1 = format!("{n}: {why}");
}
}
}
}
println!("furthest gate reached, over {done} resources that never decode:");
let label = |r: usize| match r {
0 => "no gate reached",
1 => "index out of range",
2 => "buffer not covered by indices",
3 => "degenerate / implausible positions",
4 => "connectivity (mean edge / diagonal)",
5 => "winding consistency",
9 => "grouped pool (different path)",
_ => "?",
};
for (r, (n, ex)) in &hist {
println!(" {:<38} {n:>5} e.g. {ex}", label(*r));
}
}

View File

@@ -0,0 +1,2 @@
fn main(){let a:Vec<String>=std::env::args().collect();let b=std::fs::read(&a[1]).unwrap();
for l in sylpheed_formats::mesh::debug_grouped_report(&b,&a[2],a[3].parse().unwrap()){println!("{l}")}}

View File

@@ -0,0 +1,32 @@
//! Dump a fingerprint of every decoded index run, so two decoder settings can be
//! diffed exactly. Usage: index_hash_dump <resource3d_dir>
use sylpheed_formats::mesh::Xbg7Model;
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
let w = f.file_name().unwrap().to_string_lossy().to_string();
for m in Xbg7Model::stage_models(&bytes) {
for (k, sm) in m.meshes.iter().enumerate() {
let mut h = 1469598103934665603u64;
for i in &sm.indices {
h = (h ^ *i as u64).wrapping_mul(1099511628211);
}
println!(
"{w} {} {k} vb={:?} n={} h={h:016x}",
m.name,
sm.vbuf_offset,
sm.indices.len()
);
}
}
}
}

View File

@@ -0,0 +1,134 @@
//! Is our index list one element late? A capture-free check of the `pad` choice.
//!
//! `anchor_pool_mesh` tries `ib = vb idx_count*2 pad` for `pad` in `0..=3`,
//! **pad 0 first and with the looser winding gate** (`XBG7_PAD0_CONSISTENCY`,
//! 0.70) than the pad ≥ 1 path (0.85). The 2026-08-13 index-byte comparison
//! against the runtime showed 17 draw batches whose captured indices equal our
//! decoded list shifted by exactly one element — all of them on buffers whose
//! real index data sits at pad 2. A one-element shift re-wires every triangle,
//! and it is invisible to every count-based metric (the count, the coverage and
//! the positions are all still right).
//!
//! This reproduces that finding from the container alone: for each resource it
//! reads the index run at pad 0 and at pad 2 and scores both on two properties a
//! correct triangle list has — **no degenerate triangles** (two equal indices)
//! and consistent winding against the stored normals.
//!
//! Usage: index_pad_check <container.xpr> [name-substring]
use sylpheed_formats::mesh::Xbg7Model;
fn be16(b: &[u8], at: usize) -> u32 {
((b[at] as u32) << 8) | b[at + 1] as u32
}
/// Degenerate triangles (a repeated index) and the fraction of triangles whose
/// face normal agrees with their vertices' stored normals.
fn score(idx: &[u32], pos: &[[f32; 3]], nrm: &[[f32; 3]]) -> (usize, f32, usize) {
let mut degen = 0usize;
let mut agree = 0usize;
let mut counted = 0usize;
for t in idx.chunks_exact(3) {
let (a, b, c) = (t[0] as usize, t[1] as usize, t[2] as usize);
if a == b || b == c || a == c {
degen += 1;
continue;
}
if a >= pos.len() || b >= pos.len() || c >= pos.len() {
continue;
}
let e1 = [pos[b][0] - pos[a][0], pos[b][1] - pos[a][1], pos[b][2] - pos[a][2]];
let e2 = [pos[c][0] - pos[a][0], pos[c][1] - pos[a][1], pos[c][2] - pos[a][2]];
let f = [
e1[1] * e2[2] - e1[2] * e2[1],
e1[2] * e2[0] - e1[0] * e2[2],
e1[0] * e2[1] - e1[1] * e2[0],
];
if nrm.len() <= a {
continue;
}
let n = nrm[a];
let dot = f[0] * n[0] + f[1] * n[1] + f[2] * n[2];
counted += 1;
if dot > 0.0 {
agree += 1;
}
}
let frac = if counted == 0 { 0.0 } else { agree as f32 / counted as f32 };
(degen, frac.max(1.0 - frac), counted)
}
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).expect("container");
let filter = a.get(2).cloned().unwrap_or_default();
let models = Xbg7Model::stage_models(&bytes);
println!(
"{:<22} {:>6} {:>6} {:<26} {:<26} verdict",
"resource", "verts", "idx", "pad 0 (what we decode)", "pad 2 (2 bytes earlier)"
);
let (mut better_p2, mut better_p0, mut tie) = (0usize, 0usize, 0usize);
let mut hist_ok: Vec<(usize, String, usize)> = Vec::new();
for m in &models {
if !filter.is_empty() && !m.name.contains(&filter) {
continue;
}
if m.meshes.len() != 1 {
continue; // single-block path only; grouped pools use another formula
}
let sm = &m.meshes[0];
let Some(vb) = sm.vbuf_offset else { continue };
let n = sm.indices.len();
if n < 6 || sm.normals.is_empty() || vb < n * 2 + 2 {
continue;
}
let read_at = |start: usize| -> Vec<u32> { (0..n).map(|k| be16(&bytes, start + k * 2)).collect() };
let l0 = read_at(vb - n * 2);
let l2 = read_at(vb - n * 2 - 2);
// Sanity: l0 must be what the decoder emitted, or the assumption that we
// took pad 0 is wrong for this resource and the comparison is meaningless.
let took_pad0 = l0 == sm.indices;
if !took_pad0 {
continue;
}
let (d0, c0, _) = score(&l0, &sm.positions, &sm.normals);
let (d2, c2, _) = score(&l2, &sm.positions, &sm.normals);
let max_i0 = l0.iter().max().copied().unwrap_or(0);
let max_i2 = l2.iter().max().copied().unwrap_or(0);
let v = sm.positions.len() as u32;
// A shifted list typically also overruns the pool by one vertex or leaves
// the last vertex unreferenced, so carry the coverage as evidence too.
let verdict = if d2 < d0 && c2 >= c0 {
better_p2 += 1;
"pad 2 is the real one"
} else if d0 < d2 || c0 > c2 {
better_p0 += 1;
"pad 0 fine"
} else {
tie += 1;
"indistinguishable"
};
if verdict == "pad 0 fine" {
hist_ok.push((d0, m.name.clone(), n));
}
if verdict != "pad 0 fine" || !filter.is_empty() {
println!(
"{:<22} {:>6} {:>6} degen {:>5} wind {:.3} max {:<5} degen {:>5} wind {:.3} max {:<5} {}",
m.name, v, n, d0, c0, max_i0, d2, c2, max_i2, verdict
);
}
}
println!("\npad 2 wins: {better_p2} · pad 0 wins: {better_p0} · indistinguishable: {tie}");
// Is "no degenerate triangle" a safe invariant for a correctly anchored
// block? Distribution over the resources where pad 0 is the better choice.
let zero = hist_ok.iter().filter(|(d, _, _)| *d == 0).count();
println!(
"of the {} pad-0-correct resources, {zero} have ZERO degenerate triangles",
hist_ok.len()
);
let mut worst: Vec<_> = hist_ok.iter().filter(|(d, _, _)| *d > 0).collect();
worst.sort_by_key(|(d, _, _)| std::cmp::Reverse(*d));
for (d, n, idx) in worst.iter().take(10) {
println!(" {n}: {d} degenerate of {} triangles", idx / 3);
}
}

View File

@@ -0,0 +1,90 @@
//! Where does each declared field sit inside the engine's live definition object?
//!
//! A live object carries no names, so the mapping has to be inferred: take a unit
//! whose disc record SETS a field, look for that value in the dumped words of the
//! matching live object, and keep the offsets that agree across several units.
//!
//! Run: live_offsets <disc-root> <live-dump.txt> <ID=0xVA> ...
//! e.g. … UN_f106_TCAF_Destroyer=0xbd3ee300 UN_f105_TCAF_Cruiser=0xbd40e200
use std::collections::BTreeMap;
use sylpheed_formats::idxd::IdxdObject;
use sylpheed_formats::pak::PakArchive;
fn main() {
let mut a = std::env::args().skip(1);
let disc = a.next().expect("disc root");
let dump = a.next().expect("live dump");
let pairs: Vec<(String, String)> = a
.filter_map(|s| s.split_once('=').map(|(i, v)| (i.to_string(), v.to_string())))
.collect();
// live: va -> offset -> f32
let mut live: BTreeMap<String, BTreeMap<usize, f32>> = BTreeMap::new();
let mut cur = String::new();
for line in std::fs::read_to_string(&dump).expect("dump").lines() {
if let Some(rest) = line.strip_prefix("=== ") {
cur = rest.trim().to_string();
continue;
}
let f: Vec<&str> = line.split_whitespace().collect();
if f.len() >= 4 && f[1].starts_with('+') {
if let (Ok(off), Ok(val)) =
(usize::from_str_radix(&f[1][1..], 16), f[3].parse::<f32>())
{
live.entry(cur.clone()).or_default().insert(off, val);
}
}
}
let pak = PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).expect("pak");
// key -> offset -> how many units agree
let mut votes: BTreeMap<String, BTreeMap<usize, usize>> = BTreeMap::new();
let mut units = 0usize;
for entry in pak.entries() {
let Ok(bytes) = pak.read(entry) else { continue };
let Ok(obj) = IdxdObject::parse(&bytes) else { continue };
let Some(id) = obj.get_raw("ID") else { continue };
let Some((_, va)) = pairs.iter().find(|(i, _)| i == id) else { continue };
let Some(words) = live.get(va) else { continue };
units += 1;
let mut numeric = 0usize;
let mut hit = 0usize;
for key in obj.tokens() {
let Some(v) = obj.get_f32(key) else { continue };
if !v.is_finite() || v == 0.0 {
continue; // zero matches everywhere and says nothing
}
numeric += 1;
let mut found = false;
for (off, w) in words {
if (*w - v).abs() <= v.abs() * 1e-6 {
*votes.entry(key.clone()).or_default().entry(*off).or_default() += 1;
found = true;
}
}
if found {
hit += 1;
}
}
eprintln!(" {id}: {numeric} numeric fields set on disc, {hit} found in the dumped window");
}
println!("{units} units correlated against their live objects\n");
println!("{:<28} {:>8} offsets agreeing (votes)", "field", "unique?");
for (key, offs) in &votes {
let best = offs.iter().max_by_key(|(_, n)| **n).unwrap();
if *best.1 < units.max(2) {
continue; // needs every correlated unit to agree
}
let list: Vec<String> = offs
.iter()
.filter(|(_, n)| **n == *best.1)
.map(|(o, n)| format!("+{o:03x}×{n}"))
.collect();
println!(
"{:<28} {:>8} {}",
key,
if list.len() == 1 { "unique" } else { "ambig" },
list.join(" ")
);
}
}

View File

@@ -0,0 +1,53 @@
//! How many copies of a captured buffer does a container hold?
//!
//! The twins showed that two resources decoding to one buffer can mean the
//! container really holds two (mirrored) copies and our scan found only one.
//! This asks that question for any draw: give it a `vbase`, and it reports every
//! offset whose leading vertices match the draw's dumped positions — directly, and
//! X-mirrored.
//!
//! Usage: locate_draw <container.xpr> <capture.log> <vbase-hex>...
use sylpheed_formats::ship_capture::{parse_capture, parse_drawlog};
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).expect("container");
let text = std::fs::read_to_string(&a[2]).expect("log");
let mut draws = parse_capture(&text);
if draws.is_empty() {
draws = parse_drawlog(&text);
}
let be = |at: usize| f32::from_be_bytes(bytes[at..at + 4].try_into().unwrap());
for want in &a[3..] {
let vb = u32::from_str_radix(want.trim_start_matches("0x"), 16).expect("hex vbase");
let Some(d) = draws.iter().find(|d| d.vbase == vb) else {
println!("vbase 0x{vb:08X}: not in this log");
continue;
};
let n = d.pos.len().min(8);
let mut direct = Vec::new();
let mut mirror = Vec::new();
for o in (0..bytes.len().saturating_sub(12 + 64 * 24)).step_by(4) {
for (flip, out) in [(1.0f32, &mut direct), (-1.0f32, &mut mirror)] {
let hit = (0..n).all(|k| {
let at = o + k * 24;
(be(at) - flip * d.pos[k][0]).abs() <= 1e-4
&& (be(at + 4) - d.pos[k][1]).abs() <= 1e-4
&& (be(at + 8) - d.pos[k][2]).abs() <= 1e-4
});
if hit {
out.push(o);
}
}
}
println!(
"vbase 0x{vb:08X} vcount={}: {} direct copy/copies {:x?}, {} mirrored {:x?}",
d.vcount,
direct.len(),
&direct[..],
mirror.len(),
&mirror[..]
);
}
}

View File

@@ -0,0 +1,86 @@
//! Which container should the next runtime capture aim at?
//!
//! The 2026-08-13 stage-05 capture showed that a mission keeps several containers
//! resident and that its OWN `Stage_SNN.xpr` is among them (the f101 ACROPOLIS was
//! drawn from `Stage_S05.xpr`), so a capture can be aimed by choosing the mission.
//! This ranks the targets: for every XBG7 resource on the disc it records the
//! containers where it decodes and the ones where it does not, then reports
//!
//! * resources that decode **nowhere** — the real gaps, where a capture is the
//! only ground truth left;
//! * per container, how many of those it holds (fly that mission);
//! * resources that miss in one container but decode in another — a defect worth
//! fixing, but the geometry is already recoverable, so a capture is not needed.
//!
//! Usage: miss_targets <resource3d_dir>
use sylpheed_formats::mesh::{xbg7_resource_names, Xbg7Model};
use std::collections::{BTreeMap, BTreeSet};
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
// resource -> (containers where it decodes, containers where it misses)
let mut ok: BTreeMap<String, BTreeSet<String>> = BTreeMap::new();
let mut miss: BTreeMap<String, BTreeSet<String>> = BTreeMap::new();
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
let where_ = f.file_name().unwrap().to_string_lossy().to_string();
let declared: BTreeSet<String> = xbg7_resource_names(&bytes).into_iter().collect();
if declared.is_empty() {
continue;
}
let decoded: BTreeSet<String> =
Xbg7Model::stage_models(&bytes).into_iter().map(|m| m.name).collect();
for n in &declared {
if decoded.contains(n) {
ok.entry(n.clone()).or_default().insert(where_.clone());
} else {
miss.entry(n.clone()).or_default().insert(where_.clone());
}
}
}
let never: BTreeMap<&String, &BTreeSet<String>> =
miss.iter().filter(|(n, _)| !ok.contains_key(*n)).collect();
let recoverable: Vec<&String> = miss.keys().filter(|n| ok.contains_key(*n)).collect();
println!("resources that decode NOWHERE: {}", never.len());
println!("resources that miss somewhere but decode elsewhere: {}\n", recoverable.len());
// Rank containers by how many never-decoding resources they hold.
let mut per_container: BTreeMap<&String, Vec<&String>> = BTreeMap::new();
for (n, wheres) in &never {
for w in wheres.iter() {
per_container.entry(w).or_default().push(n);
}
}
let mut ranked: Vec<_> = per_container.iter().collect();
ranked.sort_by_key(|(_, v)| std::cmp::Reverse(v.len()));
println!("container never-decoding resources it holds");
for (w, v) in ranked.iter().take(14) {
let sample: Vec<&str> = v.iter().take(6).map(|s| s.as_str()).collect();
println!("{:<26} {:>3} {}", w, v.len(), sample.join(", "));
}
// Exclusives: a never-decoding resource that only ONE container holds is only
// reachable through whatever loads that container.
let excl: Vec<(&&String, &&BTreeSet<String>)> =
never.iter().filter(|(_, w)| w.len() == 1).collect();
println!("\nof the never-decoding, {} live in exactly one container", excl.len());
let mut by_one: BTreeMap<&String, Vec<&String>> = BTreeMap::new();
for (n, w) in &excl {
by_one.entry(w.iter().next().unwrap()).or_default().push(n);
}
let mut b: Vec<_> = by_one.iter().collect();
b.sort_by_key(|(_, v)| std::cmp::Reverse(v.len()));
for (w, v) in b.iter().take(10) {
println!(" {:<24} {:>3} {}", w, v.len(), v.iter().take(5).map(|s| s.as_str()).collect::<Vec<_>>().join(", "));
}
}

View File

@@ -0,0 +1,20 @@
//! Dump a composite's scene nodes with their scale — the transform the static
//! assembler copies verbatim into a placement.
//! Usage: node_scale <container.xpr> <composite name>
use sylpheed_formats::mesh::scene_world_nodes;
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).expect("container");
for n in scene_world_nodes(&bytes, &a[2]) {
// Row norms of `m`: a rotation has all three at 1.0; anything else is a
// scale baked into the matrix, which `s` does not show.
let norm = |r: [f32; 3]| (r[0] * r[0] + r[1] * r[1] + r[2] * r[2]).sqrt();
println!(
"{:<26} s[{:7.3}{:7.3}{:7.3}] |m rows|[{:7.3}{:7.3}{:7.3}] t[{:9.1}{:9.1}{:9.1}]",
n.resource,
n.s[0], n.s[1], n.s[2],
norm(n.m[0]), norm(n.m[1]), norm(n.m[2]),
n.t[0], n.t[1], n.t[2]
);
}
}

View File

@@ -0,0 +1,129 @@
//! How much geometry on the disc was being read one index element late?
//!
//! The pad-scoring fix (2026-08-13) makes `anchor_pool_mesh` choose the pad whose
//! index run is cleanest instead of the first that validates. This measures the
//! blast radius: per container, how many single-block resources now decode from a
//! run that is NOT the old first-match (`pad 0`) one, and how many decoded runs
//! still contain degenerate triangles (the shift signature) afterwards.
//!
//! Usage: pad_shift_audit <resource3d_dir>
use sylpheed_formats::mesh::Xbg7Model;
fn be16(b: &[u8], at: usize) -> u32 {
((b[at] as u32) << 8) | b[at + 1] as u32
}
/// Fraction of triangles whose face normal agrees with the stored normals,
/// folded to `max(na, 1-na)` so both authored windings read as ≈1.
fn winding(idx: &[u32], pos: &[[f32; 3]], nrm: &[[f32; 3]]) -> f32 {
let (mut agree, mut n) = (0usize, 0usize);
for t in idx.chunks_exact(3) {
let (a, b, c) = (t[0] as usize, t[1] as usize, t[2] as usize);
if a == b || b == c || a == c || a.max(b).max(c) >= pos.len() || a >= nrm.len() {
continue;
}
let e1 = [pos[b][0] - pos[a][0], pos[b][1] - pos[a][1], pos[b][2] - pos[a][2]];
let e2 = [pos[c][0] - pos[a][0], pos[c][1] - pos[a][1], pos[c][2] - pos[a][2]];
let f = [
e1[1] * e2[2] - e1[2] * e2[1],
e1[2] * e2[0] - e1[0] * e2[2],
e1[0] * e2[1] - e1[1] * e2[0],
];
let nv = nrm[a];
n += 1;
if f[0] * nv[0] + f[1] * nv[1] + f[2] * nv[2] > 0.0 {
agree += 1;
}
}
if n == 0 {
return 1.0;
}
let fr = agree as f32 / n as f32;
fr.max(1.0 - fr)
}
fn degenerate(idx: &[u32]) -> usize {
idx.chunks_exact(3)
.filter(|t| t[0] == t[1] || t[1] == t[2] || t[0] == t[2])
.count()
}
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
let (mut total, mut moved, mut still_degen) = (0usize, 0usize, 0usize);
let mut weak = 0usize;
let mut weak_wind: Vec<(f32, f32, String)> = Vec::new();
let mut worst: Vec<(usize, String, String)> = Vec::new();
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
let where_ = f.file_name().unwrap().to_string_lossy().to_string();
let mut c_moved = 0usize;
for m in Xbg7Model::stage_models(&bytes) {
// Degeneracy is counted over EVERY sub-mesh (grouped pools included —
// they have their own pad choice); the pad-0 comparison below only
// applies to single-block resources, whose run starts at `vb - 2n`.
for sm in &m.meshes {
let d = degenerate(&sm.indices);
if d > 0 {
still_degen += 1;
worst.push((d, m.name.clone(), where_.clone()));
}
}
if m.meshes.len() != 1 {
continue;
}
let sm = &m.meshes[0];
let Some(vb) = sm.vbuf_offset else { continue };
let n = sm.indices.len();
if n < 6 || vb < n * 2 {
continue;
}
total += 1;
let pad0: Vec<u32> = (0..n).map(|k| be16(&bytes, vb - n * 2 + k * 2)).collect();
if pad0 != sm.indices {
moved += 1;
c_moved += 1;
// How strong was the evidence for moving? A pad-0 run with
// degenerate triangles is a decisive shift signature; one with
// none moved on winding alone, which is weaker.
if degenerate(&pad0) == 0 {
weak += 1;
// Record how far apart the two runs' winding is, to see
// whether these look like the same shift signature as the
// decisive cases (pad-0 winding drifting toward 0.5) or like
// noise between two equally clean readings.
let w0 = winding(&pad0, &sm.positions, &sm.normals);
let w2: f32 = {
let l2: Vec<u32> = (0..n).map(|k| be16(&bytes, vb - n * 2 - 2 + k * 2)).collect();
winding(&l2, &sm.positions, &sm.normals)
};
weak_wind.push((w0, w2, m.name.clone()));
}
}
}
if c_moved > 0 {
println!("{where_:<24} {c_moved} resources read from a non-pad-0 index run");
}
}
println!("\n{moved} of {total} single-block resources moved off the pad-0 run");
println!("{still_degen} decoded runs still contain a degenerate triangle");
println!("of the moved, {weak} had a pad-0 run with no degenerate triangle (moved on winding alone)");
let clear = weak_wind.iter().filter(|(w0, w2, _)| *w2 - *w0 > 0.15).count();
let close = weak_wind.iter().filter(|(w0, w2, _)| (*w2 - *w0).abs() <= 0.05).count();
println!(" of those: {clear} show the shift signature (pad-2 winding > pad-0 by >0.15), {close} are within 0.05 (noise)");
for (w0, w2, n) in weak_wind.iter().take(8) {
println!(" {n}: pad0 wind {w0:.3} -> pad2 {w2:.3}");
}
worst.sort_by_key(|(d, _, _)| std::cmp::Reverse(*d));
for (d, n, w) in worst.iter().take(15) {
println!(" {n} ({w}): {d} degenerate triangles");
}
}

View File

@@ -0,0 +1,13 @@
fn main(){
let a:Vec<String>=std::env::args().collect();
let bytes=std::fs::read(&a[1]).unwrap();
let filter=a.get(2).cloned().unwrap_or_default();
for n in sylpheed_formats::mesh::xbg7_resource_names(&bytes) {
if !filter.is_empty() && !n.contains(&filter) { continue }
if let Some((m,stride))=sylpheed_formats::mesh::debug_resource_params(&bytes,&n) {
let strides = sylpheed_formats::mesh::debug_decl_strides(&bytes, &n);
println!("{n:<28} decl-stride {stride} markers {:?} per-sub-mesh strides {:?}",
&m[..m.len().min(4)], strides);
}
}
}

View File

@@ -0,0 +1,29 @@
//! Raw token sequence around a key, for one record — the ground truth for
//! "is this field actually defaulted, or is our reader missing it?"
//! Run: pool_window <disc-root> <ID substring> <key>
use sylpheed_formats::idxd::IdxdObject;
use sylpheed_formats::pak::PakArchive;
fn main() {
let disc = std::env::args().nth(1).unwrap();
let want = std::env::args().nth(2).unwrap();
let key = std::env::args().nth(3).unwrap();
let pak = PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).unwrap();
for e in pak.entries() {
let Ok(b) = pak.read(e) else { continue };
let Ok(o) = IdxdObject::parse(&b) else { continue };
let Some(id) = o.get_raw("ID") else { continue };
if !id.contains(&want) { continue; }
let t = o.tokens();
println!("=== {id} get_f32({key}) = {:?}", o.get_f32(&key));
for (i, tok) in t.iter().enumerate() {
if tok == &key {
let lo = i.saturating_sub(6);
let hi = (i + 7).min(t.len());
for j in lo..hi {
println!(" [{j}]{} {:?}", if j == i { " <-- key" } else { " " }, t[j]);
}
println!();
}
}
}
}

View File

@@ -0,0 +1,6 @@
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).unwrap();
let vb: usize = a[3].parse().unwrap();
println!("{:?}", sylpheed_formats::mesh::debug_try_anchor(&bytes, &a[2], vb, 3));
}

View File

@@ -0,0 +1,60 @@
//! Which mission should the next unit harvest fly?
//!
//! Unit definitions are instantiated per stage, so coverage grows by visiting
//! missions — but only if the mission fields units we have not read yet. This
//! ranks every stage by how many of its roster units are missing from the
//! harvested CSV.
//!
//! Usage: roster_target <disc-root> <unit-runtime-fields.csv>
use sylpheed_formats::hash::name_hash;
use sylpheed_formats::idxd::IdxdObject;
use sylpheed_formats::pak::PakArchive;
use std::collections::{BTreeMap, BTreeSet};
fn main() {
let a: Vec<String> = std::env::args().collect();
let pak = PakArchive::open(format!("{}/dat/GP_MAIN_GAME_E.pak", a[1])).expect("pak");
let have: BTreeSet<String> = std::fs::read_to_string(&a[2])
.expect("csv")
.lines()
.skip(1)
.filter_map(|l| l.split(',').next().map(str::to_string))
.collect();
// Label each roster by STAGE: the TOC stores a hash of the original path, and
// the table names are known (`EnumUnit_SNN.tbl`), so hashing the candidates
// maps entries back to stages. Most rosters carry no `UN_S<NN>_` prop id, which
// is all `UnitRoster::stage` can infer from.
let mut by_hash: BTreeMap<u32, String> = BTreeMap::new();
// The TOC hashes a PATH, and these tables live under a directory — try the
// known schemes (see hash::TOC_NAME_SCHEMES) rather than the bare name.
for i in 1..=29 {
let stage = format!("S{i:02}");
for pre in ["", "unit\\", "battle\\", "stage\\", "enemy\\"] {
for suf in [".tbl", ""] {
by_hash.insert(name_hash(&format!("{pre}EnumUnit_{stage}{suf}")), stage.clone());
}
}
}
let mut rows: Vec<(usize, String, Vec<String>)> = Vec::new();
for e in pak.entries() {
let Some(stage) = by_hash.get(&e.name_hash).cloned() else { continue };
let Ok(b) = pak.read(e) else { continue };
let Ok(o) = IdxdObject::parse(&b) else { continue };
let mut units: Vec<String> = Vec::new();
for id in o.tokens().iter().filter(|s| s.starts_with("UN_")) {
let prop = id.contains("Asteroid") || id.contains("cmesh") || id.contains("_Box");
if !prop && !units.iter().any(|u| u == id) {
units.push(id.clone());
}
}
let missing: Vec<String> = units.iter().filter(|u| !have.contains(*u)).cloned().collect();
rows.push((missing.len(), stage, missing));
}
rows.sort_by_key(|(n, _, _)| std::cmp::Reverse(*n));
println!("units already harvested: {}\n", have.len());
println!("stage missing roster units not yet read");
for (n, stage, missing) in rows.iter().take(12) {
let s: Vec<&str> = missing.iter().take(6).map(|s| s.as_str()).collect();
println!("{stage:<8} {n:>5} {}", s.join(", "));
}
}

View File

@@ -0,0 +1,111 @@
//! Dump a UI screen's full layout from one RATC bundle: the element declaration
//! table (what is drawn, in back-to-front order, with pivots and parent links)
//! plus the placement region that follows it (per element: a keyframe group of
//! scale / tint / X / Y).
//!
//! See docs/re/structures/ui-rat-layout.md. Run:
//! cargo run -p sylpheed-formats --example screen_layout -- <PAK> [0xHASH]
//! With no hash, the largest RATC entry in the pak is used.
use sylpheed_formats::pak::PakArchive;
fn be32(b: &[u8], o: usize) -> u32 {
u32::from_be_bytes([b[o], b[o + 1], b[o + 2], b[o + 3]])
}
fn main() {
let mut args = std::env::args().skip(1);
let pak = args.next().expect("usage: screen_layout <pak> [0xHASH]");
let want = args.next();
let arc = PakArchive::open(&pak).expect("open pak");
let bytes = match want {
Some(h) if h.starts_with("0x") => {
let h = u32::from_str_radix(h.trim_start_matches("0x"), 16).expect("hash");
arc.read_by_hash(h).expect("entry").expect("decompress")
}
Some(name) => arc.read_by_name(&name).expect("entry present").expect("decompress"),
None => arc
.entries()
.iter()
.filter_map(|e| arc.read(e).ok())
.filter(|b| b.len() > 16 && &b[..4] == b"RATC")
.max_by_key(|b| b.len())
.expect("no RATC entry"),
};
assert_eq!(&bytes[..4], b"RATC", "not a RATC bundle");
let count = be32(&bytes, 0x14) as usize;
let mut names = Vec::with_capacity(count);
let mut meta = Vec::with_capacity(count);
for i in 0..count {
let e = &bytes[0x20 + i * 60..0x20 + (i + 1) * 60];
let name = String::from_utf8_lossy(&e[..28])
.trim_end_matches('\0')
.trim_end_matches(char::from(0))
.to_string();
let parent = be32(e, 32);
let kind = be32(e, 40);
let (px, py) = (be32(e, 48), be32(e, 52));
names.push(name);
meta.push((parent, kind, px, py));
}
// Placement region: groups of (u32 element index, u32 keyframe count) then
// `count` 40-byte keyframes; the X/Y sit 12 bytes into the scale/tint block.
let mut pos = 0x20 + count * 60;
// X/Y are SIGNED: off-screen animation starts are negative (e.g. -516).
let mut placements: Vec<Vec<(i32, i32, u32)>> = vec![Vec::new(); count];
for _ in 0..count {
if pos + 8 > bytes.len() { break }
let idx = be32(&bytes, pos) as usize;
let frames = be32(&bytes, pos + 4) as usize;
if idx >= count || frames == 0 || frames > 4096 { break }
let first = pos + 28; // header + lead-in, verified on the pause bundles
let mut group = Vec::with_capacity(frames);
for k in 0..frames {
let blk = first + k * 40;
if blk + 20 > bytes.len() { break }
group.push((be32(&bytes, blk + 12) as i32, be32(&bytes, blk + 16) as i32, be32(&bytes, blk + 20)));
}
placements[idx] = group;
pos = first + frames * 40 - 20;
}
println!("{} elements", count);
println!("{:<3} {:<30} {:>7} {:>8} {:>12} {:>4} placement", "#", "element", "parent", "kind", "pivot", "kf");
for i in 0..count {
let (parent, kind, px, py) = meta[i];
let p = &placements[i];
// A group is an in → hold → out animation, so neither the first nor the
// last keyframe is where the element sits: report the MAX-DWELL one
// (longest gap to the next keyframe's time).
let shown = if p.is_empty() {
"".into()
} else if p.len() == 1 {
format!("({},{})", p[0].0, p[0].1)
} else {
let mut best = (0usize, 0u32);
for k in 0..p.len() - 1 {
let d = p[k + 1].2.saturating_sub(p[k].2);
if d > best.1 { best = (k, d) }
}
let r = p[best.0];
format!(
"rest ({},{}) t={}..{} [{}]",
r.0, r.1, r.2, p[best.0 + 1].2,
p.iter().map(|(x, y, t)| format!("{t}:{x},{y}")).collect::<Vec<_>>().join(" ")
)
};
println!(
"{:<3} {:<30} {:>7} {:>8} {:>12} {:>4} {}",
i,
names[i],
if parent == u32::MAX { "-".into() } else { parent.to_string() },
format!("{kind:#x}"),
format!("({px},{py})"),
p.len(),
shown
);
}
}

View File

@@ -0,0 +1,262 @@
//! Ask the runtime capture whether two resources that our decoder gives the
//! **same geometry** really are the same geometry.
//!
//! Our XBG7 anchor scan sometimes lands two different resource names on one
//! vertex buffer. Statics cannot separate "the container genuinely reuses a
//! buffer" from "the scan picked the wrong candidate" — but a capture can: the
//! engine uploads a buffer per resource and reuses one only 3.4 % of the time
//! (see docs/re/structures/xbg7-mesh.md), so a group of `k` resources our
//! decoder collapses onto one buffer should show up as `k` distinct `vbase`s
//! carrying that same vertex count and those same positions. Fewer means at
//! most one member of the group is really that geometry.
//!
//! Usage:
//! cargo run --release --example shared_vbase_check -- \
//! <Stage_SNN.xpr> <capture.log>...
use sylpheed_formats::mesh::Xbg7Model;
use sylpheed_formats::ship_capture::{parse_capture, parse_drawlog, CapturedDraw};
use std::collections::{BTreeMap, BTreeSet};
/// Quantised position key — the logs print 4 decimals, so compare at that scale.
fn key(p: [f32; 3]) -> (i64, i64, i64) {
(
(p[0] as f64 * 1e4).round() as i64,
(p[1] as f64 * 1e4).round() as i64,
(p[2] as f64 * 1e4).round() as i64,
)
}
/// Where in the container does a captured buffer live? POSITION is `f32×3` big
/// endian at vertex offset 0, so a draw's dumped positions are a literal byte
/// pattern: find the first one, then confirm the next few at a fixed stride.
/// This turns a capture into ground truth for a resource we mis-anchored.
fn locate_run(bytes: &[u8], pos: &[[f32; 3]]) -> Vec<(usize, usize)> {
if pos.len() < 4 {
return Vec::new();
}
// The log prints 4 decimals, so match on value with the printing tolerance
// rather than on bytes.
let be = |b: &[u8], at: usize| f32::from_be_bytes(b[at..at + 4].try_into().unwrap());
let same = |b: &[u8], at: usize, p: [f32; 3]| {
at + 12 <= b.len() && (0..3).all(|c| (be(b, at + c * 4) - p[c]).abs() <= 1e-4)
};
let mut out = Vec::new();
for o in (0..bytes.len().saturating_sub(12)).step_by(4) {
if !same(bytes, o, pos[0]) {
continue;
}
for stride in (12..=64).step_by(4) {
if (1..4).all(|k| same(bytes, o + k * stride, pos[k])) {
out.push((o, stride));
break;
}
}
}
out
}
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() < 3 {
eprintln!("usage: shared_vbase_check <Stage_SNN.xpr> <capture.log>...");
std::process::exit(2);
}
let bytes = std::fs::read(&args[1]).expect("read container");
// Every draw from every log, keyed by vertex count.
// Keep the logs apart: each is its own emulator run, so a `vbase` only
// means something within one log.
let mut logs: Vec<(String, Vec<CapturedDraw>)> = Vec::new();
for log in args[2..].iter().filter(|a| !a.starts_with("--")) {
let text = std::fs::read_to_string(log).expect("read log");
let mut d = parse_capture(&text);
if d.is_empty() {
d = parse_drawlog(&text);
}
eprintln!("{log}: {} draws", d.len());
logs.push((log.rsplit('/').next().unwrap_or(log).to_string(), d));
}
// `--map`: is a draw's guest `vbase` just the container file offset plus a
// constant? If the container is uploaded contiguously it is — and then a
// capture names the exact offset of every buffer the engine drew, which is
// ground truth the anchor scan currently has to guess at.
if args.iter().any(|a| a == "--map") {
for (log, draws) in &logs {
let mut seen: BTreeSet<u32> = BTreeSet::new();
let mut delta: BTreeMap<i64, usize> = BTreeMap::new();
let mut unfound = 0usize;
for d in draws {
if d.pos.len() < 8 || d.vcount < 20 || !seen.insert(d.vbase) {
continue;
}
let at = locate_run(&bytes, &d.pos);
if at.is_empty() {
unfound += 1;
continue;
}
for (o, _) in at {
*delta.entry(d.vbase as i64 - o as i64).or_default() += 1;
}
}
let mut top: Vec<_> = delta.iter().collect();
top.sort_by_key(|(_, n)| std::cmp::Reverse(**n));
println!("{log}: {} distinct vbases located, {unfound} not in this container", seen.len() - unfound);
for (d, n) in top.iter().take(5) {
println!(" vbase - offset = 0x{:X} ×{n}", d);
}
}
return;
}
// Decode the container and group resources by the exact geometry they got.
let models = Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false);
// `--truth <base>`: with the container's guest load address (from `--map`),
// every draw names a file offset. Print it against the offset our anchor
// scan chose for each resource — a direct read-out of what we got wrong.
if let Some(a) = args.iter().find_map(|a| a.strip_prefix("--truth=")) {
let base = u32::from_str_radix(a.trim_start_matches("0x"), 16).expect("base");
// Where the anchor scan actually put each sub-mesh — exact, from the
// decoder, not inferred by searching for its leading vertices (the same
// leading run occurs at several offsets in a container, so a search
// cannot tell where a resource was anchored).
let mut ours: BTreeMap<usize, Vec<(String, usize)>> = BTreeMap::new();
for m in &models {
for sub in &m.meshes {
if let Some(o) = sub.vbuf_offset {
ours.entry(o).or_default().push((m.name.clone(), sub.positions.len()));
}
}
}
if args.iter().any(|a| a == "--anchors") {
println!("{:<12} where our decode put each resource", "file offset");
for (o, v) in &ours {
for (n, c) in v {
println!("0x{o:<10x} {n} ({c} verts)");
}
}
return;
}
let mut drawn: BTreeMap<usize, u32> = BTreeMap::new();
for (_, draws) in &logs {
for d in draws {
let off = d.vbase.wrapping_sub(base) as usize;
if off < bytes.len() && d.vcount >= 20 {
drawn.insert(off, d.vcount);
}
}
}
// Which resources have the drawn vertex count, wherever we put them?
// Right size + wrong place is a different bug from never finding it.
let mut by_count: BTreeMap<usize, Vec<String>> = BTreeMap::new();
for m in &models {
let n: usize = m.meshes.iter().map(|s| s.positions.len()).sum();
by_count.entry(n).or_default().push(m.name.clone());
}
// Is a capture-proven offset even a candidate the scan considers?
// Absent ⇒ the run scan misses it; present ⇒ selection picked another.
let starts: BTreeSet<usize> =
sylpheed_formats::mesh::debug_vertex_run_starts(&bytes, 24).into_iter().collect();
eprintln!("{} stride-24 candidate starts in this container", starts.len());
println!("{:<12} {:>7} {:>9} {:<44} our resources with that vcount", "file offset", "vcount", "candidate", "claimed by our decode");
for (off, vcount) in &drawn {
let who = ours
.get(off)
.map(|v| {
v.iter().map(|(n, c)| format!("{n}({c})")).collect::<Vec<_>>().join(", ")
})
.unwrap_or_else(|| "— NOBODY".into());
let same = by_count
.get(&(*vcount as usize))
.map(|v| v.join(", "))
.unwrap_or_else(|| "— none".into());
// Nearest resource we anchored at or before this offset — the
// likely owner of a buffer nobody claims.
let near = ours
.range(..=*off)
.next_back()
.map(|(o, v)| format!("{} @ -0x{:x}", v[0].0, off - o))
.unwrap_or_default();
let cand = if starts.contains(off) { "yes" } else { "NO" };
println!("0x{off:<10x} {vcount:>7} {cand:>9} {who:<44} {same:<34} {near}");
}
return;
}
let mut groups: BTreeMap<Vec<(i64, i64, i64)>, Vec<String>> = BTreeMap::new();
for m in &models {
let pos: Vec<(i64, i64, i64)> =
m.meshes.iter().flat_map(|s| s.positions.iter().copied()).map(key).collect();
if pos.is_empty() {
continue;
}
groups.entry(pos).or_default().push(m.name.clone());
}
let shared: Vec<_> = groups.iter().filter(|(_, n)| n.len() > 1).collect();
eprintln!(
"{} models, {} distinct geometries, {} shared by >1 resource",
models.len(),
groups.len(),
shared.len()
);
for (pos, names) in shared {
let vcount = pos.len() as u32;
// A draw belongs to this geometry if every dumped position is one of
// the decoded ones (the log dumps at most the first 64).
let want: BTreeSet<(i64, i64, i64)> = pos.iter().copied().collect();
println!("\n{} ({vcount} verts, {} resources)", names.join(""), names.len());
for (log, draws) in &logs {
let hits: Vec<&CapturedDraw> = draws.iter().filter(|d| d.vcount == vcount).collect();
let all: BTreeSet<u32> = hits.iter().map(|d| d.vbase).collect();
let matching: Vec<&&CapturedDraw> = hits
.iter()
.filter(|d| !d.pos.is_empty() && d.pos.iter().all(|p| want.contains(&key(*p))))
.collect();
let ok: BTreeSet<u32> = matching.iter().map(|d| d.vbase).collect();
// A buffer we do NOT match may still be the mirrored twin: same
// geometry with x negated. That is the case our assembler papers
// over with `apply_twin_mirrors`.
let mirrored: BTreeSet<u32> = hits
.iter()
.filter(|d| !ok.contains(&d.vbase))
.filter(|d| {
!d.pos.is_empty()
&& d.pos.iter().all(|p| want.contains(&key([-p[0], p[1], p[2]])))
})
.map(|d| d.vbase)
.collect();
println!(
" {log:32} draws={:<5} vbases@vcount={:<3} ours={} mirrored={} other={}",
hits.len(),
all.len(),
ok.len(),
mirrored.len(),
all.len() - ok.len() - mirrored.len()
);
// Where does each captured buffer live in the container? One
// representative draw per vbase is enough.
let mut done: BTreeSet<u32> = BTreeSet::new();
for d in &hits {
if d.pos.len() < 8 || !done.insert(d.vbase) {
continue;
}
let kind = if ok.contains(&d.vbase) {
"ours"
} else if mirrored.contains(&d.vbase) {
"mirror"
} else {
"other"
};
let at = locate_run(&bytes, &d.pos);
let shown: Vec<String> =
at.iter().take(4).map(|(o, s)| format!("0x{o:x}/stride{s}")).collect();
println!(
" vbase=0x{:08X} [{kind:6}] in container at: {}",
d.vbase,
if shown.is_empty() { "NOT FOUND".into() } else { shown.join(" ") }
);
}
}
}
}

View File

@@ -0,0 +1,74 @@
//! Screen every ship family for a part that is wildly out of scale with its
//! siblings — the "slab" signature of a mis-anchored block.
//!
//! Rendering `e106` found such a part (`bdy_03`, 600×1600×998 beside parts of
//! ~250) that coverage, cross-container consistency, the capture oracle and the
//! twin invariant were all blind to. Eyeballing does not scale to 166 containers;
//! this does the same comparison numerically.
//!
//! Usage: slab_screen <resource3d_dir> [factor]
use sylpheed_formats::mesh::Xbg7Model;
use sylpheed_formats::ship::{is_base_part, ship_id_of};
use std::collections::BTreeMap;
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let factor: f32 = std::env::args().nth(2).and_then(|s| s.parse().ok()).unwrap_or(4.0);
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
let mut flagged = 0usize;
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
let mut by_ship: BTreeMap<String, Vec<(String, f32)>> = BTreeMap::new();
for m in Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false) {
if !is_base_part(&m.name) {
continue;
}
let Some(id) = ship_id_of(&m.name) else { continue };
let (mut lo, mut hi) = ([f32::MAX; 3], [f32::MIN; 3]);
for s in &m.meshes {
for q in &s.positions {
for k in 0..3 {
lo[k] = lo[k].min(q[k]);
hi[k] = hi[k].max(q[k]);
}
}
}
if lo[0] == f32::MAX {
continue;
}
// Compare the part's SMALLEST axis span, not its diagonal. A long
// thin part (an antenna, a 100 000-unit tether on `f002`) is
// legitimately huge in one axis and would swamp a diagonal test; a
// mis-anchored block is bulky in all three, which is what the e106
// slab looked like (600×1600×998 beside siblings of ~250).
let thin = (hi[0] - lo[0]).min(hi[1] - lo[1]).min(hi[2] - lo[2]);
by_ship.entry(id.to_string()).or_default().push((m.name.clone(), thin));
}
for (id, parts) in &by_ship {
if parts.len() < 3 {
continue; // no meaningful median
}
let mut d: Vec<f32> = parts.iter().map(|(_, x)| *x).collect();
d.sort_by(|a, b| a.partial_cmp(b).unwrap());
let median = d[d.len() / 2];
for (name, diag) in parts {
if *diag > median * factor {
flagged += 1;
println!(
"{:<22} {name:<22} min-axis {diag:>8.0} vs ship median {median:>8.0} ({:.1}×)",
f.file_name().unwrap().to_string_lossy(),
diag / median
);
}
}
}
}
println!("{flagged} parts flagged at {factor}× the ship median");
}

View File

@@ -0,0 +1,13 @@
use sylpheed_formats::mesh::{debug_resource_params, debug_vertex_run_starts};
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).unwrap();
let (markers, stride) = debug_resource_params(&bytes, &a[2]).expect("resource");
println!("{}: stride={stride} markers={markers:?}", a[2]);
let starts = debug_vertex_run_starts(&bytes, stride);
println!("{} candidate starts at stride {stride}", starts.len());
for off in &a[3..] {
let o = usize::from_str_radix(off.trim_start_matches("0x"), 16).unwrap();
println!(" 0x{o:x} in candidate list: {}", starts.binary_search(&o).is_ok());
}
}

View File

@@ -0,0 +1,7 @@
fn main(){let a:Vec<String>=std::env::args().collect();let b=std::fs::read(&a[1]).unwrap();
let stride:usize=a[2].parse().unwrap(); let want:usize=a[3].parse().unwrap();
let s=sylpheed_formats::mesh::debug_vertex_run_starts(&b,stride);
println!("{} candidate starts at stride {}", s.len(), stride);
println!("contains {:#x}: {}", want, s.contains(&want));
let near:Vec<String>=s.iter().filter(|&&o| o.abs_diff(want)<0x200).map(|o|format!("{o:#x}")).collect();
println!("nearby: {}", near.join(" "));}

View File

@@ -0,0 +1,34 @@
//! Per-sub-mesh vertex/index/coverage dump for one resource.
//! Usage: submesh_dump <container.xpr> <resource>...
use sylpheed_formats::mesh::{debug_resource_params, Xbg7Model};
use std::collections::HashSet;
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).expect("container");
let want: HashSet<String> = a[2..].iter().cloned().collect();
for m in Xbg7Model::models_named(&bytes, &want, &|| false) {
let markers = debug_resource_params(&bytes, &m.name).map(|(mk, _)| mk).unwrap_or_default();
println!("{}{} sub-meshes decoded, {} markers declared", m.name, m.meshes.len(), markers.len());
for (i, s) in m.meshes.iter().enumerate() {
let max_idx = s.indices.iter().max().copied().unwrap_or(0) as usize;
let (mut lo, mut hi) = ([f32::MAX; 3], [f32::MIN; 3]);
for q in &s.positions {
for k in 0..3 {
lo[k] = lo[k].min(q[k]);
hi[k] = hi[k].max(q[k]);
}
}
println!(
" #{i:<2} at 0x{:<9x} verts {:<6} idx {:<6} max_idx {:<6} slack {} span [{:.0} {:.0} {:.0}]",
s.vbuf_offset.unwrap_or(0),
s.positions.len(),
s.indices.len(),
max_idx,
s.positions.len() as i64 - 1 - max_idx as i64,
hi[0] - lo[0],
hi[1] - lo[1],
hi[2] - lo[2]
);
}
}
}

View File

@@ -0,0 +1,17 @@
//! Does the capture-proven offset validate for the resource that should own it?
use sylpheed_formats::mesh::debug_try_anchor;
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).unwrap();
// The production scan tries pads 0..=3; pass a bigger one to ask whether the
// block would validate at all with a wider index/vertex gap.
let max_pad: usize = std::env::var("MAX_PAD").ok().and_then(|v| v.parse().ok()).unwrap_or(3);
for pair in a[2..].iter() {
let (name, off) = pair.split_once('@').unwrap();
let off = usize::from_str_radix(off.trim_start_matches("0x"), 16).unwrap();
match debug_try_anchor(&bytes, name, off, max_pad) {
Some((v, i, pad)) => println!("{name:22} @ 0x{off:x} ACCEPTED v={v} idx={i} pad={pad}"),
None => println!("{name:22} @ 0x{off:x} rejected"),
}
}
}

View File

@@ -0,0 +1,119 @@
//! Do port/starboard twins decode to mirror images of each other?
//!
//! A runtime capture proved the container stores both halves of the `e106` hull
//! as separate, X-reflected buffers. That gives a **capture-free invariant**:
//! a `…_01`/`…_02` pair of equal vertex count should decode to geometry that is
//! an exact X-mirror — never to identical geometry (that is the collapse the
//! distinct-assignment fix targets), and never to something unrelated (that is a
//! mis-anchor no count-based metric can see).
//!
//! Usage: twin_mirror_audit <resource3d_dir>
use sylpheed_formats::mesh::Xbg7Model;
use std::collections::BTreeMap;
fn key(p: [f32; 3]) -> (i64, i64, i64) {
(
(p[0] * 1e3).round() as i64,
(p[1] * 1e3).round() as i64,
(p[2] * 1e3).round() as i64,
)
}
/// Elementwise equality with a tolerance. Truncating keys is too strict for a
/// mirrored pair: the halves are authored, not bit-negated, so they differ in
/// the last digits and an exact key test reports them as unrelated.
fn near(p: [f32; 3], q: [f32; 3]) -> bool {
(0..3).all(|c| (p[c] - q[c]).abs() <= 1e-3 * (1.0 + q[c].abs()))
}
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
let (mut same, mut mirrored, mut unrelated, mut related) = (0usize, 0usize, 0usize, 0usize);
let mut examples: Vec<String> = Vec::new();
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
let models = Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false);
let by_name: BTreeMap<&str, &Xbg7Model> =
models.iter().map(|m| (m.name.as_str(), m)).collect();
for m in &models {
let Some(stem) = m.name.strip_suffix("_01") else { continue };
let Some(t) = by_name.get(format!("{stem}_02").as_str()) else { continue };
let a: Vec<[f32; 3]> = m.meshes.iter().flat_map(|s| s.positions.clone()).collect();
let b: Vec<[f32; 3]> = t.meshes.iter().flat_map(|s| s.positions.clone()).collect();
if a.len() != b.len() || a.is_empty() {
continue;
}
let ident = a.iter().zip(&b).all(|(p, q)| near(*p, *q));
let mirr = a.iter().zip(&b).all(|(p, q)| near([-p[0], p[1], p[2]], *q));
// A pair that is neither may still be RELATED: mirrored on another
// axis, or the same point cloud in a different vertex order. Only a
// pair that is none of these is evidence of a mis-anchor.
let mirr_y = a.iter().zip(&b).all(|(p, q)| near([p[0], -p[1], p[2]], *q));
let mirr_z = a.iter().zip(&b).all(|(p, q)| near([p[0], p[1], -p[2]], *q));
let set = |v: &Vec<[f32; 3]>| {
let mut s: Vec<_> = v.iter().map(|p| key(*p)).collect();
s.sort_unstable();
s
};
let same_cloud = set(&a) == set(&b);
// …and the same point cloud after mirroring, for a pair whose
// halves are authored in different vertex order.
let mirrored_cloud = {
let am: Vec<[f32; 3]> = a.iter().map(|p| [-p[0], p[1], p[2]]).collect();
set(&am) == set(&b)
};
if !ident && !mirr && (mirr_y || mirr_z || same_cloud || mirrored_cloud) {
related += 1;
continue;
}
// Identical GEOMETRY is only a collapse if it also comes from the
// same buffer: a container may store a part twice unmirrored, and
// then two twins on two copies decode identically and correctly.
let shared_buffer = m.meshes[0].vbuf_offset.is_some()
&& m.meshes[0].vbuf_offset == t.meshes[0].vbuf_offset;
if ident && !shared_buffer {
related += 1;
continue;
}
if ident {
same += 1;
if examples.len() < 6 {
examples.push(format!(
"identical: {} / {}_02 in {}",
m.name,
stem,
f.file_name().unwrap().to_string_lossy()
));
}
} else if mirr {
mirrored += 1;
} else {
unrelated += 1;
if examples.len() < 6 {
examples.push(format!(
"unrelated: {} / {}_02 in {}",
m.name,
stem,
f.file_name().unwrap().to_string_lossy()
));
}
}
}
}
println!("twin pairs of equal vertex count: {}", same + mirrored + unrelated + related);
println!(" exact X-mirror (expected) : {mirrored}");
println!(" IDENTICAL, one buffer (collapse) : {same}");
println!(" related other way (Y/Z mirror, reordered): {related}");
println!(" unrelated (mis-anchor?) : {unrelated}");
for e in examples {
println!(" e.g. {e}");
}
}

View File

@@ -0,0 +1,56 @@
//! Which XBG7 resources never decode, and how big is that population?
//!
//! Coverage has been reported as "resources decoded" without a denominator. This
//! prints both, per container and in total, and names the misses so the gate
//! attribution (`why_rejected`) has a work list.
use sylpheed_formats::mesh::{debug_resource_params, xbg7_resource_names, Xbg7Model};
use std::collections::HashSet;
fn main() {
let dir = std::env::args().nth(1).expect("resource3d dir");
let show = std::env::args().nth(2).is_some();
let mut files: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
let (mut total, mut decoded, mut no_decl) = (0usize, 0usize, 0usize);
let mut misses: Vec<String> = Vec::new();
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
let names = xbg7_resource_names(&bytes);
if names.is_empty() {
continue;
}
let got: HashSet<String> = Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false)
.into_iter()
.map(|m| m.name)
.collect();
for n in &names {
total += 1;
if got.contains(n) {
decoded += 1;
} else if debug_resource_params(&bytes, n).is_none() {
// No vertex declaration / no index markers: the anchor scan
// never even considers these, so they are a different question
// from "searched and not found".
no_decl += 1;
} else {
misses.push(format!("{}|{n}", f.file_name().unwrap().to_string_lossy()));
}
}
}
println!(
"XBG7 resources: {total} total, {decoded} decoded ({:.1}%), {no_decl} without a usable descriptor, {} searched-and-missed",
100.0 * decoded as f64 / total as f64,
misses.len()
);
if show {
for m in &misses {
println!("{m}");
}
}
}

View File

@@ -0,0 +1,31 @@
//! Every key/value a named unit record actually sets on disc.
//!
//! The live definition object in guest RAM has no field names; to find where a
//! field like `HQRatio` sits inside it, anchor on a unit whose disc record DOES
//! set that field and look for the value. This prints those anchors.
//! Run: unit_fields <disc-root> <substring of ID>...
use sylpheed_formats::idxd::IdxdObject;
use sylpheed_formats::pak::PakArchive;
fn main() {
let disc = std::env::args().nth(1).expect("disc root");
let want: Vec<String> = std::env::args().skip(2).collect();
let pak = PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).expect("pak");
for entry in pak.entries() {
let Ok(bytes) = pak.read(entry) else { continue };
let Ok(obj) = IdxdObject::parse(&bytes) else { continue };
let Some(id) = obj.get_raw("ID") else { continue };
if !want.iter().any(|w| id.contains(w.as_str())) {
continue;
}
println!("=== {id} (schema {:08x})", obj.schema_hash);
// The pool interleaves VALUE before KEY (see the module docs), so the
// pairs read (t[i] = value, t[i+1] = key).
let t = obj.tokens();
let mut i = 0;
while i + 1 < t.len() {
println!(" {:<30} {}", t[i + 1], t[i]);
i += 2;
}
}
}

View File

@@ -0,0 +1,33 @@
//! (HP, Size_X, Size_Y, Size_Z) for every craft unit and vessel on the disc.
//!
//! A live definition object in guest RAM carries HP at `+0x54` and the sizes at
//! `+0x30/34/38` but no name in its first words, so identity has to come from the
//! values themselves: this is the lookup table for that match.
//! Run: unit_signatures <disc-root>
use sylpheed_formats::game_data::{load_units, load_vessels};
use sylpheed_formats::PakArchive;
fn main() {
let disc = std::env::args().nth(1).expect("disc root");
let pak = PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).expect("pak");
println!("{:<34} {:>9} {:>8} {:>8} {:>8} kind", "id", "hp", "size_x", "size_y", "size_z");
for u in load_units(&pak) {
println!(
"{:<34} {:>9} {:>8} {:>8} {:>8} unit",
u.id.unwrap_or_default(),
u.hp.map(|v| v.to_string()).unwrap_or("".into()),
u.size_x.map(|v| v.to_string()).unwrap_or("".into()),
u.size_y.map(|v| v.to_string()).unwrap_or("".into()),
u.size_z.map(|v| v.to_string()).unwrap_or("".into()),
);
}
for v in load_vessels(&pak) {
println!(
"{:<34} {:>9} {:>8} {:>8} {:>8} vessel",
v.id.unwrap_or_default(),
v.hp.map(|x| x.to_string()).unwrap_or("".into()),
v.size_x.map(|x| x.to_string()).unwrap_or("".into()),
v.size_y.map(|x| x.to_string()).unwrap_or("".into()),
v.size_z.map(|x| x.to_string()).unwrap_or("".into()),
);
}
}

View File

@@ -0,0 +1,22 @@
use sylpheed_formats::idxd::IdxdObject;
use sylpheed_formats::pak::PakArchive;
fn main() {
let disc = std::env::args().nth(1).unwrap();
let want = std::env::args().nth(2).unwrap();
let pak = PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).unwrap();
for e in pak.entries() {
let Ok(b) = pak.read(e) else { continue };
let Ok(o) = IdxdObject::parse(&b) else { continue };
let Some(id) = o.get_raw("ID") else { continue };
if !id.contains(&want) { continue; }
println!("=== {id}");
let mut seen = std::collections::BTreeSet::new();
for k in o.tokens() {
if let Some(v) = o.get_f32(k) {
if v != 0.0 && seen.insert(k.clone()) {
println!(" {:<28} {:<12} 0x{:08x}", k, v, v.to_bits());
}
}
}
}
}

View File

@@ -0,0 +1,70 @@
//! Check the code-derived offset→field map against the live dump, then read out
//! the runtime value of every field the disc record leaves defaulted.
//! Run: verify_fieldmap <disc-root> <live-dump> <ID=0xVA>...
use std::collections::BTreeMap;
use sylpheed_formats::idxd::IdxdObject;
use sylpheed_formats::pak::PakArchive;
// Offsets read out of sub_82341A20's own key strings (stfs stores only).
// Offsets and names recovered from `sub_82341A20` itself: each key is built as
// `addi r4, r30, -N` (r30 = 0x82088f94, so the name is a string in the image),
// and the value lands in the first store into the object after the accessor
// call. 125 float-typed fields.
const MAP: &[(usize, &str)] = &[(48, "Size_X"), (52, "Size_Y"), (56, "Size_Z"), (64, "Color_R"), (68, "Color_G"), (72, "Color_B"), (80, "Size_Radius"), (84, "HP"), (88, "HQRatio"), (92, "ShieldRatio"), (96, "ThrusterRatio"), (116, "ResistanceToOptics"), (120, "ResistanceToShell"), (124, "ResistanceToExplosion"), (128, "ResistanceToPlayer"), (132, "ResistanceParalyze"), (156, "MinimumVelocity"), (160, "MaximumVelocity"), (164, "CruisingVelocity"), (168, "Acceleration"), (172, "Deceleration"), (176, "AV_PitchPlus_Max"), (180, "AV_PitchPlus_Min"), (184, "AA_PitchPlus_Max"), (188, "AA_PitchPlus_Min"), (192, "AV_PitchMinus_Max"), (196, "AV_PitchMinus_Min"), (200, "AA_PitchMinus_Max"), (204, "AA_PitchMinus_Min"), (208, "AV_Yaw_Max"), (212, "AV_Yaw_Min"), (216, "AA_Yaw_Max"), (220, "AA_Yaw_Min"), (224, "AV_Roll_Max"), (228, "AV_Roll_Min"), (232, "AA_Roll_Max"), (236, "AA_Roll_Min"), (248, "SideThrustVelocity_Max"), (252, "SideThrustAcceleration"), (256, "MaximumBank_Normal"), (260, "YawDragFactor"), (264, "PitchDragFactor"), (268, "RollDragFactor"), (272, "DragFactorThreshold"), (276, "ArterBurner_Vc"), (280, "ReverseThrust_Vc"), (284, "ArterBurner_Acc"), (288, "ReverseThrust_Acc"), (292, "AccPitchFactor"), (296, "DecPitchFactor"), (300, "AV_AxisMode_Max"), (304, "AV_AxisMode_Min"), (308, "AA_AxisMode_Max"), (312, "AA_AxisMode_Min"), (316, "PowerCutConsumeShield"), (320, "PowerCutDeceleration"), (324, "AB_ConsumeShield_Begin"), (328, "AB_ConsumeShield"), (332, "AB_AV_PitchPlus"), (336, "AB_AA_PitchPlus"), (340, "AB_AV_PitchMinus"), (344, "AB_AA_PitchMinus"), (348, "AB_AV_Yaw"), (352, "AB_AA_Yaw"), (356, "AB_AV_Roll"), (360, "AB_AA_Roll"), (368, "SideRoll_Time"), (372, "SideRoll_Length"), (380, "BarrelRoll_CountMinimum"), (384, "BarrelRoll_CountMaximum"), (388, "BarrelRoll_Time"), (392, "BarrelRoll_Radius"), (400, "TurnAttack_CutoffRatio"), (404, "TurnAttack_DoubleRatio"), (408, "CutoffTimeMin"), (412, "CutoffTimeMax"), (416, "TurnAttack_DoubleTimeMin"), (420, "TurnAttack_DoubleTimeMax"), (428, "Turn_AngularVelocity"), (432, "TurnAway_Time_Minimum"), (436, "TurnAway_Time_Maximum"), (444, "BoostAway_Time_Minimum"), (448, "BoostAway_Time_Maximum"), (456, "HoldPosition_LengthMin"), (460, "HoldPosition_LengthMax"), (464, "HoldPosition_MinimumTime"), (468, "HoldPosition_MaximumTime"), (472, "HoldPosition_SideRatio"), (476, "HoldPosition_BackRatio"), (480, "HoldPosition_CutoffRatio"), (484, "HoldPosition_CancelTime"), (492, "Slalom_CutoffRatio"), (496, "Slalom_TurnCount_Min"), (500, "Slalom_TurnCount_Max"), (508, "Through_CutoffRatio"), (512, "Through_AngleMinimum"), (516, "Through_AngleMaximum"), (520, "Through_Time1Max"), (524, "Through_Time1Min"), (528, "Through_Time2Max"), (532, "Through_Time2Min"), (536, "Through_LengthMinimum"), (540, "Through_LengthMaximum"), (548, "SolidCutoff_Ratio"), (552, "SolidCutoff_LengthMin"), (556, "SolidCutoff_LengthMax"), (560, "HomingResistAdjustment"), (564, "UsingChaffRatio"), (568, "MaxValue"), (572, "ChargeDelay"), (576, "ChargeDelay_Break"), (580, "ChargeSpeed"), (584, "Delay"), (588, "DelayAdjustment"), (624, "DestroyMotionTime"), (628, "DryMass"), (632, "GrossMass"), (664, "LowerHPThresholdRatio"), (668, "SELength"), (672, "RadarRange"), (676, "FCSRange"), (680, "FiringRange"), (692, "AttackVesselPoint"), (696, "AttackCraftPoint"), (700, "DefencePoint")];
fn main() {
let mut a = std::env::args().skip(1);
let disc = a.next().unwrap();
let dump = a.next().unwrap();
let pairs: Vec<(String, String)> =
a.filter_map(|s| s.split_once('=').map(|(i, v)| (i.into(), v.into()))).collect();
let mut live: BTreeMap<String, BTreeMap<usize, f32>> = BTreeMap::new();
let mut cur = String::new();
for line in std::fs::read_to_string(&dump).unwrap().lines() {
if let Some(r) = line.strip_prefix("=== ") { cur = r.trim().into(); continue; }
let f: Vec<&str> = line.split_whitespace().collect();
// dump columns: addr +off hex u32 f32 -- the float is f[4], not f[3]
if f.len() >= 5 && f[1].starts_with('+') {
if let (Ok(o), Ok(v)) = (usize::from_str_radix(&f[1][1..], 16), f[4].parse::<f32>()) {
live.entry(cur.clone()).or_default().insert(o, v);
}
}
}
let pak = PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).unwrap();
let (mut agree, mut disagree) = (0, 0);
let mut defaults: BTreeMap<String, Vec<(String, f32)>> = BTreeMap::new();
for e in pak.entries() {
let Ok(b) = pak.read(e) else { continue };
let Ok(o) = IdxdObject::parse(&b) else { continue };
let Some(id) = o.get_raw("ID") else { continue };
let Some((_, va)) = pairs.iter().find(|(i, _)| i == id) else { continue };
let Some(w) = live.get(va) else { continue };
for (off, key) in MAP {
let Some(got) = w.get(off) else { continue };
match o.get_f32(key) {
Some(want) => {
// Angle fields are stored in RADIANS at runtime and degrees on
// disc, so a match is either the raw value or its conversion.
let rad = want * std::f32::consts::PI / 180.0;
let ok = (want - got).abs() <= want.abs() * 1e-4
|| (rad - got).abs() <= rad.abs() * 1e-4;
if ok { agree += 1 } else {
disagree += 1;
println!(" MISMATCH {id} {key}: disc {want}, live +{off} = {got}");
}
}
None => defaults.entry((*key).into()).or_default().push((id.into(), *got)),
}
}
}
println!("\nmap check: {agree} fields agree with the disc, {disagree} disagree\n");
println!("runtime value where the disc record DEFAULTS the field:");
for (key, hits) in &defaults {
let vals: Vec<String> = hits.iter().map(|(_, v)| format!("{v}")).collect();
let uniq: std::collections::BTreeSet<&String> = vals.iter().collect();
println!(" {:<22} {:<28} ({} units)", key,
uniq.iter().map(|s| s.as_str()).collect::<Vec<_>>().join(", "), hits.len());
}
}

View File

@@ -0,0 +1,19 @@
//! Why does a named resource never decode? Reports the furthest gate its best
//! candidate reached. Usage: why_missed <container.xpr> [name-substring]
use sylpheed_formats::mesh::{debug_best_rejection, xbg7_resource_names, Xbg7Model};
use std::collections::HashSet;
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).unwrap();
let filter = a.get(2).cloned().unwrap_or_default();
let decoded: HashSet<String> = Xbg7Model::stage_models(&bytes).into_iter().map(|m| m.name).collect();
for n in xbg7_resource_names(&bytes) {
if decoded.contains(&n) || (!filter.is_empty() && !n.contains(&filter)) {
continue;
}
match debug_best_rejection(&bytes, &n) {
Some((rank, why)) => println!("{n:<28} rank {rank} {why}"),
None => println!("{n:<28} (no candidate reached any gate / skipped before anchoring)"),
}
}
}

View File

@@ -0,0 +1,14 @@
//! Why does the decoder refuse a grouped-pool resource at a given pool start?
//! Usage: why_rejected <container.xpr> <resource>@<vb0-hex>...
use sylpheed_formats::mesh::debug_grouped_report;
fn main() {
let a: Vec<String> = std::env::args().collect();
let bytes = std::fs::read(&a[1]).expect("container");
for pair in &a[2..] {
let (name, off) = pair.split_once('@').expect("name@hex");
let vb0 = usize::from_str_radix(off.trim_start_matches("0x"), 16).expect("hex");
for line in debug_grouped_report(&bytes, name, vb0) {
println!("{line}");
}
}
}

View File

@@ -68,6 +68,10 @@ pub mod localization;
// Whole-ship assembly from XBG7 part families (capital ships as split parts).
pub mod ship;
/// The runtime layout of a unit / vessel definition object, read out of the
/// title's loader and verified against a live mission (see the module docs).
pub mod unit_layout;
// Exact capital-ship placement from a runtime F10 ship-capture (ground truth).
pub mod ship_capture;

View File

@@ -1,9 +1,18 @@
//! `LSTA` — a sprite list: a header followed by N inline [`T8aD`](crate::t8ad)
//! frames concatenated back-to-back.
//! `LSTA` — a display list: a header followed by N inline elements concatenated
//! back-to-back, each either a [`T8aD`](crate::t8ad) sprite or a `PRMD`
//! primitive (a flat coloured quad — the same primitive the UI bundles use to
//! dim a scene).
//!
//! A `count` lives at `@0x04`, but a few entries disagree with the actual frame
//! count, so we walk by the `T8aD` magic instead (robust) and decode each frame
//! from its slice up to the next frame (or end).
//! The `count` at `@0x04` is **exact, and counts both kinds**: across all 64
//! lists on the disc, `count == T8aD frames + PRMD primitives` with no
//! exceptions (measured 2026-08-11). An earlier note here said "a few entries
//! disagree with the actual frame count" — they do not; that comparison was
//! counting sprites against a total that includes primitives.
//!
//! [`parse`] walks by magic and returns the **sprites**, deliberately skipping
//! `PRMD` entries, so its result length is `count` only for lists that hold no
//! primitives. Six lists do (in `GP_DEBRIEFING_PILOTLOG`, `GP_MISSION_SELECT`),
//! each with exactly one.
use crate::t8ad::{self, T8adImage, T8AD_MAGIC};
@@ -15,8 +24,9 @@ pub fn is_lsta(bytes: &[u8]) -> bool {
bytes.len() >= 4 && bytes[0..4] == LSTA_MAGIC
}
/// Decode all inline T8aD frames. Frames that don't decode (unsupported T8aD
/// variant) are skipped. Returns `None` only for non-LSTA input.
/// Decode the inline T8aD sprites, skipping `PRMD` primitives. Returns `None`
/// only for non-LSTA input. Every one of the 1 281 sprite frames on the disc
/// decodes (measured 2026-08-11, after the T8aD rectangle-list fix).
pub fn parse(bytes: &[u8]) -> Option<Vec<T8adImage>> {
if !is_lsta(bytes) {
return None;
@@ -48,12 +58,21 @@ pub fn parse(bytes: &[u8]) -> Option<Vec<T8adImage>> {
mod tests {
use super::*;
/// A faithful one-rectangle T8aD frame: base header, a 1-entry offset table,
/// then the rectangle header (dst 0,0, size w×h) and its pixels. (Before
/// 2026-08-11 this fixture wrote no offset-table entry at all and the decoder
/// read "pixels" from inside the header — the test only ever checked the
/// dimensions, so it passed anyway.)
fn t8ad_frame(w: u32, h: u32) -> Vec<u8> {
let mut b = vec![0u8; 64];
let mut b = vec![0u8; 0x2c];
b[0..4].copy_from_slice(&T8AD_MAGIC);
b[0x14..0x18].copy_from_slice(&w.to_be_bytes());
b[0x18..0x1c].copy_from_slice(&h.to_be_bytes());
b[0x1c..0x20].copy_from_slice(&1u32.to_be_bytes());
b.extend_from_slice(&0x30u32.to_be_bytes()); // offset table → rect at 0x30
for v in [0u32, 0, w, h] {
b.extend_from_slice(&v.to_be_bytes()); // dst X, dst Y, width, height
}
b.extend_from_slice(&vec![0x80u8; (w * h * 4) as usize]);
b
}

File diff suppressed because it is too large Load Diff

View File

@@ -615,18 +615,44 @@ mod tests {
}
}
}
// ── Extras: the direction this test could not previously fail in. ──
// The loop above walks the CAPTURE's parts and looks each up in ours, so
// a static placement with no counterpart was invisible to it — which is
// how a resource decoded 100x too large (`e303_wep_01`, 2026-08-12) sat
// here unnoticed. Pin the set instead: the capture legitimately misses
// repeated instances of a shared resource (vbase dedup), so `e303_wep_01`
// is expected; anything else appearing only in the static assembly is a
// regression.
let captured: std::collections::BTreeSet<&str> =
cap.parts.iter().map(|p| p.part.as_str()).collect();
let extra: std::collections::BTreeSet<&str> = placed
.iter()
.map(|p| p.resource.as_str())
.filter(|r| !captured.contains(r))
.collect();
let allowed: std::collections::BTreeSet<&str> = ["e303_wep_01"].into_iter().collect();
assert_eq!(
extra, allowed,
"static placements with no counterpart in the runtime capture"
);
// Multi-instance coverage the capture couldn't see (vbase dedup).
let count = |res: &str| placed.iter().filter(|p| p.resource == res).count();
assert_eq!(count("e106_eng_01"), 2, "both engine nacelles placed");
assert_eq!(count("e303_wep_01"), 2, "both shared turrets placed");
// The mirrored starboard hull reflects (det < 0), the port one doesn't.
// NEITHER hull reflects: the twins' geometry is mirrored on the disc,
// so both placements are proper rotations. This flipped on 2026-08-12 —
// while both twins decoded to one buffer, `apply_twin_mirrors` had to
// synthesise the reflection here; a runtime capture showed the container
// holds both halves, and distinct anchor assignment now hands each twin
// its own (see docs/re/structures/xbg7-mesh.md).
let det = |m: &[[f32; 3]; 3]| {
m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1])
- m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0])
+ m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0])
};
let one = |res: &str| placed.iter().find(|p| p.resource == res).unwrap();
assert!(det(&one("e106_bdy_02").m) < 0.0, "starboard hull mirrored");
assert!(det(&one("e106_bdy_02").m) > 0.0, "starboard hull plain (mirror is in the data)");
assert!(det(&one("e106_bdy_01").m) > 0.0, "port hull plain");
}

View File

@@ -49,6 +49,33 @@ pub struct CapturedDraw {
/// First few LOCAL vertex positions dumped with the draw (buffer order).
/// Used to disambiguate same-vcount twins (mirrored port/starboard parts).
pub pos: Vec<[f32; 3]>,
/// The draw's INDEX buffer, when the capture recorded one (`ib base=…`,
/// added 2026-08-13): guest base address, index count, and the min/max index
/// value the emulator read out of guest memory. `None` for older logs and
/// for auto-index draws. This is ground truth for two things the offline
/// decoder can only assume — where a block's index buffer lives relative to
/// its vertex buffer, and how much of the vertex pool a draw really covers.
pub ib: Option<CapturedIndexBuffer>,
}
/// The index buffer a captured draw used. See [`CapturedDraw::ib`].
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CapturedIndexBuffer {
/// Guest base address of the index data.
pub ibase: u32,
/// Number of indices the draw issued (== `VGT_DRAW_INITIATOR.num_indices`).
pub icount: u32,
/// Lowest index value in the buffer.
pub imin: u32,
/// Highest index value in the buffer — with `vcount` this says whether the
/// draw covers its whole vertex pool or only a sub-range.
pub imax: u32,
/// The first indices, verbatim (the capture prints up to 24). Byte-level
/// ground truth for the offline index decode: a matched block's decoded
/// index prefix must equal this run.
pub head: [u32; 24],
/// How many of `head` the capture actually carried.
pub head_len: u8,
}
/// A ship part to match against the capture. `part` is the **base** part name
@@ -100,13 +127,16 @@ pub fn parse_capture(text: &str) -> Vec<CapturedDraw> {
let mut vcount = 0u32;
let mut pos: Vec<[f32; 3]> = Vec::new();
let mut consts: Vec<(usize, [f64; 4])> = Vec::new();
let mut ib: Option<CapturedIndexBuffer> = None;
let flush = |vbase: u32,
vcount: u32,
pos: &mut Vec<[f32; 3]>,
ib: &mut Option<CapturedIndexBuffer>,
consts: &[(usize, [f64; 4])],
out: &mut Vec<CapturedDraw>| {
let pos = std::mem::take(pos);
let ib = ib.take();
if vbase == 0 {
return;
}
@@ -115,18 +145,47 @@ pub fn parse_capture(text: &str) -> Vec<CapturedDraw> {
return; // no WorldView for this draw — skip it
};
if let Some((r, t)) = normalize_wvp([c0, c1, c2]) {
out.push(CapturedDraw { vbase, vcount, r, t, pos });
out.push(CapturedDraw { vbase, vcount, r, t, pos, ib });
}
};
for line in text.lines() {
let l = line.trim();
if let Some(rest) = l.strip_prefix("DRAW ") {
flush(vbase, vcount, &mut pos, &consts, &mut out);
flush(vbase, vcount, &mut pos, &mut ib, &consts, &mut out);
consts.clear();
let f = |k: &str| rest.split_whitespace().find_map(|t| t.strip_prefix(k));
vbase = f("vbase=0x").and_then(|s| u32::from_str_radix(s, 16).ok()).unwrap_or(0);
vcount = f("vcount=").and_then(|s| s.parse().ok()).unwrap_or(0);
} else if let Some(rest) = l.strip_prefix("ib base=0x") {
// `ib base=0x… count=N fmt=u16 endian=E len=L delta_vb=D min=a max=b idx: …`
let f = |k: &str| rest.split_whitespace().find_map(|t| t.strip_prefix(k));
let base = rest
.split_whitespace()
.next()
.and_then(|s| u32::from_str_radix(s, 16).ok());
if let (Some(ibase), Some(icount)) = (base, f("count=").and_then(|s| s.parse().ok())) {
let mut head = [0u32; 24];
let mut head_len = 0u8;
if let Some((_, list)) = l.split_once("idx:") {
for tok in list.split_whitespace() {
let Ok(v) = tok.parse::<u32>() else { break };
if head_len as usize >= head.len() {
break;
}
head[head_len as usize] = v;
head_len += 1;
}
}
ib = Some(CapturedIndexBuffer {
ibase,
icount,
imin: f("min=").and_then(|s| s.parse().ok()).unwrap_or(0),
imax: f("max=").and_then(|s| s.parse().ok()).unwrap_or(0),
head,
head_len,
});
}
} else if l.starts_with("pos:") || l.starts_with("positions:") {
pos = parse_pos_line(l, 8);
} else if l.starts_with("vsconst") {
@@ -147,7 +206,7 @@ pub fn parse_capture(text: &str) -> Vec<CapturedDraw> {
}
}
}
flush(vbase, vcount, &mut pos, &consts, &mut out);
flush(vbase, vcount, &mut pos, &mut ib, &consts, &mut out);
out
}
@@ -242,7 +301,9 @@ pub fn parse_drawlog(text: &str) -> Vec<CapturedDraw> {
let get = |i: usize| consts.iter().find(|(k, _)| *k == i).map(|(_, v)| *v);
let (Some(c0), Some(c1), Some(c2)) = (get(0), get(1), get(2)) else { return };
if let Some((r, t)) = normalize_wvp([c0, c1, c2]) {
out.push(CapturedDraw { vbase: base, vcount: size / stride, r, t, pos });
// The draw-logger format carries an index base too, but it de-dups
// by vertex declaration, so it never lines up per part — left None.
out.push(CapturedDraw { vbase: base, vcount: size / stride, r, t, pos, ib: None });
}
};
@@ -717,10 +778,17 @@ mod tests {
assert_eq!(e106.reference, "e106_bdy_04");
assert_eq!(e106.parts.len(), 8, "all 8 e106 parts placed");
let get = |p: &str| e106.parts.iter().find(|x| x.part == p).unwrap();
// Port/starboard hull pair: X = ∓264, the starboard copy mirrored.
// Port/starboard hull pair: X = ∓264, **both plain**. The mirror is
// baked into the disc data, not into the placement: a runtime capture
// shows the container carrying two 119-vertex buffers whose contents are
// exact X-reflections, each drawn from its own address (see
// docs/re/structures/xbg7-mesh.md). Until 2026-08-12 both twins decoded
// to ONE buffer and this row carried diag(-1,1,1) to compensate; with
// distinct anchor assignment they decode to their own, and re-emitting
// from the capture produces identity here.
assert!((get("e106_bdy_01").t[0] + 264.0).abs() < 0.1);
assert!((get("e106_bdy_02").t[0] - 264.0).abs() < 0.1);
assert_eq!(get("e106_bdy_02").m[0][0], -1.0);
assert_eq!(get("e106_bdy_02").m[0][0], 1.0);
assert_eq!(get("e106_bdy_01").m[0][0], 1.0);
// Bridge: centreline, above and aft of the hull reference.
let brg = get("e106_brg_01");

View File

@@ -1,20 +1,28 @@
//! `T8aD` — the game's 2D UI/HUD texture format.
//!
//! A 32bpp **A8R8G8B8** (Xbox byte order) surface stored as **256×256 raster
//! tiles in row-major order** — each tile prefixed by a 16-byte tile header, edge
//! tiles clipped to the image bounds. Fully reversed 2026-07-17 from the file
//! header and verified against the running game (title screen).
//! A 32bpp **A8R8G8B8** (Xbox byte order) surface stored as a list of
//! **arbitrary sub-rectangles**, each with its own destination origin and size.
//! Reversed 2026-07-17 (verified against the running game's title screen) and
//! **corrected 2026-08-11**, when the per-tile header turned out to carry the
//! rectangle's placement rather than being opaque flags.
//!
//! ```text
//! 0x00 4 Magic "T8aD"
//! 0x14 4 width (BE u32)
//! 0x14 4 width (BE u32) the full surface
//! 0x18 4 height (BE u32)
//! 0x1c 4 tile count (BE u32) = ceil(w/256) * ceil(h/256)
//! 0x2c tiles*4 offset table: absolute byte offset of each row-major tile
//! <off> 16 per-tile header (flags + tile w/h), then:
//! <off+16> tile_w * tile_h * 4 bytes of A8R8G8B8 pixels, row-major
//! 0x1c 4 rectangle count (BE u32) — NOT ceil(w/256)*ceil(h/256)
//! 0x2c count*4 offset table: absolute byte offset of each rectangle
//! <off> 16 rectangle header, four BE u32: dst X, dst Y, width, height
//! <off+16> width * height * 4 bytes of A8R8G8B8 pixels, row-major
//! ```
//!
//! Most surfaces happen to be stored as full-width 256-tall bands, which is why
//! treating the file as a 256×256 grid decoded 96 % of the disc correctly. It is
//! not the model, though: a dialogue strip declares 524×63 and stores **one**
//! 173×25 rectangle at (175,20), and `pdmes010` stores two — (59,6,256,54) and
//! (315,6,149,54), the second beginning exactly `16 + 256*54*4` bytes after the
//! first. Anything the rectangles do not cover stays transparent.
//!
//! Surfaces ≤256px wide are a single tile column, so the first tile's pixels sit
//! at `44 + tiles*4 + 16 = 64` — which is why the old "type→header size 64/84/…"
//! rule (header = 44 + tiles*20) happened to decode small textures correctly: for
@@ -43,18 +51,11 @@ fn be32(b: &[u8], off: usize) -> u32 {
}
/// Side of the square storage tile, in texels, and the per-tile header size.
const TILE: usize = 256;
const TILE_HDR: usize = 16;
/// Bytes of per-rectangle header before its pixels: dst X, dst Y, w, h.
const RECT_HDR: usize = 16;
/// Decode a T8aD surface from a slice whose first bytes ARE the magic. Returns
/// `None` for non-T8aD input or a variant we can't decode as RGBA (never guesses).
///
/// Layout (reversed from the header + verified against the running game):
/// a 44-byte base header, then a `tiles`-entry big-endian u32 **offset table** at
/// `0x2c`, where `tiles` = the field at `0x1c` = `ceil(w/256) * ceil(h/256)`.
/// Each entry is the absolute byte offset of a **row-major** 256×256 tile; every
/// tile is a 16-byte tile header followed by `tile_w*tile_h*4` A8R8G8B8 pixels,
/// edge tiles clipped to the image bounds.
/// `None` if any rectangle fails to fit the surface or the file — never guesses.
pub fn parse(bytes: &[u8]) -> Option<T8adImage> {
if !is_t8ad(bytes) || bytes.len() < 0x40 {
return None;
@@ -64,33 +65,38 @@ pub fn parse(bytes: &[u8]) -> Option<T8adImage> {
if !(1..=4096).contains(&width) || !(1..=4096).contains(&height) {
return None;
}
let tiles = be32(bytes, 0x1c) as usize;
let cols = width.div_ceil(TILE);
let rows = height.div_ceil(TILE);
// The field at 0x1c must be the tile count; otherwise it's a variant we don't
// decode (e.g. DXT / palettized) — defer rather than misdecode.
if tiles == 0 || tiles != cols * rows {
let rects = be32(bytes, 0x1c) as usize;
if rects == 0 || rects > 4096 {
return None;
}
const TABLE: usize = 0x2c;
if bytes.len() < TABLE + tiles * 4 {
if bytes.len() < TABLE + rects * 4 {
return None;
}
// Anything no rectangle covers stays transparent.
let mut rgba = vec![0u8; width * height * 4];
for ty in 0..rows {
for tx in 0..cols {
let tile = ty * cols + tx;
let pixels = be32(bytes, TABLE + tile * 4) as usize + TILE_HDR;
let tw = TILE.min(width - tx * TILE);
let th = TILE.min(height - ty * TILE);
if pixels + tw * th * 4 > bytes.len() {
return None; // truncated / not the layout we expect
for r in 0..rects {
let at = be32(bytes, TABLE + r * 4) as usize;
if at + RECT_HDR > bytes.len() {
return None;
}
for row in 0..th {
let mut s = pixels + row * tw * 4;
let mut d = ((ty * TILE + row) * width + tx * TILE) * 4;
for _ in 0..tw {
let dx = be32(bytes, at) as usize;
let dy = be32(bytes, at + 4) as usize;
let rw = be32(bytes, at + 8) as usize;
let rh = be32(bytes, at + 12) as usize;
// Never guess: a rectangle must fit the surface and its pixels the file.
if rw == 0 || rh == 0 || dx + rw > width || dy + rh > height {
return None;
}
let pixels = at + RECT_HDR;
if pixels + rw * rh * 4 > bytes.len() {
return None;
}
for row in 0..rh {
let mut s = pixels + row * rw * 4;
let mut d = ((dy + row) * width + dx) * 4;
for _ in 0..rw {
// A8R8G8B8 → RGBA8.
rgba[d] = bytes[s + 1];
rgba[d + 1] = bytes[s + 2];
@@ -101,7 +107,6 @@ pub fn parse(bytes: &[u8]) -> Option<T8adImage> {
}
}
}
}
Some(T8adImage {
width: width as u32,
height: height as u32,
@@ -123,7 +128,11 @@ mod tests {
b[0x18..0x1c].copy_from_slice(&h.to_be_bytes());
b[0x1c..0x20].copy_from_slice(&1u32.to_be_bytes()); // 1 tile
b.extend_from_slice(&0x30u32.to_be_bytes()); // offset table: tile 0 @ 0x30
b.extend_from_slice(&[0u8; 16]); // 16-byte tile header → pixels at 0x40
// rectangle header: dst (0,0), size w×h
b.extend_from_slice(&0u32.to_be_bytes());
b.extend_from_slice(&0u32.to_be_bytes());
b.extend_from_slice(&w.to_be_bytes());
b.extend_from_slice(&h.to_be_bytes());
for i in 0..(w * h) {
b.extend_from_slice(&[(i & 0xff) as u8, 0x24, 0x63, 0xB2]); // A, R, G, B
}
@@ -143,8 +152,8 @@ mod tests {
}
#[test]
fn assembles_row_major_tiles_via_offset_table() {
// 300×1 → 2 tiles: (0,0)=256×1 red, (1,0)=44×1 blue, each +16-byte header.
fn assembles_rectangles_via_offset_table() {
// 300×1 → 2 rectangles: (0,0) 256×1 red, then (256,0) 44×1 blue.
let (w, h): (u32, u32) = (300, 1);
let mut b = vec![0u8; 0x2c];
b[0..4].copy_from_slice(&T8AD_MAGIC);
@@ -155,9 +164,9 @@ mod tests {
let off1 = off0 + 16 + 256 * 4; // tile-0 header + its 256 pixels
b.extend_from_slice(&(off0 as u32).to_be_bytes());
b.extend_from_slice(&(off1 as u32).to_be_bytes());
b.extend_from_slice(&[0u8; 16]);
for v in [0u32, 0, 256, 1] { b.extend_from_slice(&v.to_be_bytes()) } // dst(0,0) 256×1
b.extend_from_slice(&[0xFF, 0xFF, 0, 0].repeat(256)); // A,R,G,B red
b.extend_from_slice(&[0u8; 16]);
for v in [256u32, 0, 44, 1] { b.extend_from_slice(&v.to_be_bytes()) } // dst(256,0) 44×1
b.extend_from_slice(&[0xFF, 0, 0, 0xFF].repeat(44)); // A,R,G,B blue
let img = parse(&b).expect("decodes");
assert_eq!((img.width, img.height), (300, 1));
@@ -166,10 +175,11 @@ mod tests {
}
#[test]
fn rejects_wrong_tilecount_and_short() {
// tile-count field that isn't ceil(w/256)*ceil(h/256) → None
fn rejects_out_of_range_rect_and_short() {
// a rectangle that does not fit the declared surface → None, never guess
let mut b = synth(2, 2);
b[0x1c..0x20].copy_from_slice(&7u32.to_be_bytes());
let at = 0x2c + 4;
b[at + 8..at + 12].copy_from_slice(&99u32.to_be_bytes()); // width 99 > 2
assert!(parse(&b).is_none());
// truncated pixel data → None
let b = synth(64, 64);

View File

@@ -0,0 +1,105 @@
//! The runtime layout of a unit / vessel definition object.
//!
//! The game parses an [`crate::idxd`] record into a fixed 880-byte object whose
//! field offsets are **not** guessable from the disc data: the record is a
//! reflective key/value pool, and the loader assigns each key to a member by
//! name. This table is that assignment, read out of the loader itself
//! (`sub_82341A20` — every key is built as `addi r4, r30, -N`, so the field name
//! for each store is a string in the executable image), and verified against
//! objects dumped from a running mission: **406 values agree with the disc
//! records, 0 disagree**, over 11 objects covering both schemas.
//!
//! Why a reimplementation wants it:
//!
//! - it names the field behind every word of a live definition object, so a
//! memory snapshot can be read directly;
//! - it says which fields a record leaves **defaulted**, and what the loader
//! leaves there — the float accessor returns `0.0` on a pool miss;
//! - it carries two conventions that are invisible on disc: **angles are degrees
//! in the data and radians in the object**, and **`Size_Y` takes `Size_X`**
//! when omitted.
//!
//! See `docs/re/live-unit-definitions.md` for the derivation and the measured
//! default values.
/// How a field is stored in the definition object.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Kind {
/// IEEE-754 single, big-endian.
F32,
/// Pointer to a string.
Str,
/// 32-bit word (bool / enum / count / id).
Word,
}
/// One field of the definition object.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Field {
/// Byte offset from the start of the object.
pub offset: usize,
/// Field name, exactly as the disc record spells it.
pub name: &'static str,
/// Storage kind.
pub kind: Kind,
}
const TABLE: &str = include_str!("../data/unit_definition_layout.txt");
/// Every mapped field, in offset order.
pub fn fields() -> Vec<Field> {
TABLE
.lines()
.filter(|l| !l.trim_start().starts_with('#') && !l.trim().is_empty())
.filter_map(|l| {
let mut it = l.split_whitespace();
let offset = it.next()?.parse().ok()?;
let kind = match it.next()? {
"f32" => Kind::F32,
"str" => Kind::Str,
_ => Kind::Word,
};
// `name` is a &'static str because TABLE is 'static.
let name = it.next()?;
let name: &'static str = TABLE.get(
TABLE.find(name).map(|s| s..s + name.len())?,
)?;
Some(Field { offset, name, kind })
})
.collect()
}
/// The field at `offset`, if one is mapped there.
pub fn field_at(offset: usize) -> Option<Field> {
fields().into_iter().find(|f| f.offset == offset)
}
/// The offset of `name`, if it is mapped.
pub fn offset_of(name: &str) -> Option<usize> {
fields().into_iter().find(|f| f.name == name).map(|f| f.offset)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn table_parses_and_is_ordered() {
let f = fields();
assert!(f.len() > 150, "expected the full map, got {}", f.len());
assert!(f.windows(2).all(|w| w[0].offset < w[1].offset), "offsets must be strictly increasing");
}
#[test]
fn known_fields_sit_where_the_loader_puts_them() {
// Spot-checks from the verified map; these four also anchor the
// identification of a live object (see docs/re/live-unit-definitions.md).
assert_eq!(offset_of("Size_X"), Some(48));
assert_eq!(offset_of("Size_Y"), Some(52));
assert_eq!(offset_of("Size_Z"), Some(56));
assert_eq!(offset_of("HP"), Some(84));
assert_eq!(offset_of("HQRatio"), Some(88));
assert_eq!(field_at(96).map(|f| f.name), Some("ThrusterRatio"));
assert_eq!(field_at(48).map(|f| f.kind), Some(Kind::F32));
}
}

View File

@@ -0,0 +1,144 @@
//! Cross-container consistency for XBG7 geometry.
//!
//! A geometry resource shared by several stage containers must decode to the
//! same bounds in each. This needs no ground truth, and on 2026-08-11 it found
//! **125 of 681** shared resources decoding to different bounds while reporting
//! identical vertex and triangle counts — the anchor scan locating a different
//! buffer of the same size (see `docs/re/structures/xbg7-mesh.md`).
//!
//! The test is `#[ignore]`d because the decoder does not satisfy it yet. It is
//! written as the *target* state so that fixing the anchor scan makes it pass,
//! rather than as a snapshot of the bug.
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use sylpheed_formats::mesh::Xbg7Model;
fn disc_root() -> Option<PathBuf> {
if let Ok(p) = std::env::var("SYLPHEED_DISC") {
let p = PathBuf::from(p);
if p.join("dat").is_dir() {
return Some(p);
}
}
let default = Path::new(
"/home/fabi/RE - Project Sylpheed/Project Sylpheed - Arc of Deception (USA, Europe) (En,Ja)",
);
if default.join("dat").is_dir() {
return Some(default.to_path_buf());
}
None
}
/// Rounded (w, h, d) of a model's own geometry.
fn span(m: &Xbg7Model) -> Option<[i64; 3]> {
let (mut lo, mut hi) = ([f32::MAX; 3], [f32::MIN; 3]);
for s in &m.meshes {
for q in &s.positions {
for k in 0..3 {
lo[k] = lo[k].min(q[k]);
hi[k] = hi[k].max(q[k]);
}
}
}
if lo[0] == f32::MAX {
return None;
}
Some([
(hi[0] - lo[0]).round() as i64,
(hi[1] - lo[1]).round() as i64,
(hi[2] - lo[2]).round() as i64,
])
}
#[test]
#[ignore = "known-failing: 62 of 714 shared resources decode inconsistently (was 125 of 681; distinct anchor assignment + the 0.42 connectivity cap fixed the rest). Note this metric is the WEAKER witness — a systematic mis-anchor is consistent — see docs/re/structures/xbg7-mesh.md"]
fn shared_resources_decode_identically_in_every_container() {
let Some(root) = disc_root() else {
eprintln!("SKIP: extracted disc not found (set SYLPHEED_DISC to enable)");
return;
};
let dir = root.join("hidden/resource3d");
let mut files: Vec<PathBuf> = std::fs::read_dir(&dir)
.expect("resource3d/")
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
// name -> (verts, tris) -> set of spans seen
let mut seen: BTreeMap<String, Vec<([i64; 3], usize, usize, String)>> = BTreeMap::new();
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
let where_ = f.file_name().unwrap().to_string_lossy().to_string();
for m in Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false) {
let Some(sp) = span(&m) else { continue };
let v: usize = m.meshes.iter().map(|s| s.positions.len()).sum();
let t: usize = m.meshes.iter().map(|s| s.indices.len() / 3).sum();
seen.entry(m.name.clone()).or_default().push((sp, v, t, where_.clone()));
}
}
let mut bad: Vec<String> = Vec::new();
for (name, list) in &seen {
if list.len() < 2 {
continue;
}
// Only compare decodes that agree on how much geometry they found;
// a differing vertex/triangle count is a different question.
if !list.iter().all(|e| e.1 == list[0].1 && e.2 == list[0].2) {
continue;
}
let spans: std::collections::BTreeSet<[i64; 3]> = list.iter().map(|e| e.0).collect();
if spans.len() > 1 && bad.len() < 10 {
bad.push(format!("{name}: {spans:?}"));
}
}
assert!(
bad.is_empty(),
"{} shared resources decode to different bounds; first: {bad:?}",
bad.len()
);
}
/// Port/starboard twins must not decode to the *same* buffer.
///
/// A runtime capture showed the container stores both halves of the `e106` hull
/// as separate X-reflected buffers, so a `…_01`/`…_02` pair of equal vertex
/// count should come out mirrored (or related by another axis / vertex order) —
/// never identical, which is the collapse distinct assignment fixes. Since that
/// fix reached grouped pools too, this holds for **every** twin pair on the disc
/// — including `n206`, which was the last exception.
#[test]
fn twin_pairs_do_not_share_a_buffer() {
let Some(root) = disc_root() else {
eprintln!("SKIP: extracted disc not found (set SYLPHEED_DISC to enable)");
return;
};
let mut files: Vec<PathBuf> = std::fs::read_dir(root.join("hidden/resource3d"))
.expect("resource3d/")
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
let mut collapsed: Vec<String> = Vec::new();
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
let models = Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false);
let by_name: BTreeMap<&str, &Xbg7Model> =
models.iter().map(|m| (m.name.as_str(), m)).collect();
for m in &models {
let Some(stem) = m.name.strip_suffix("_01") else { continue };
let Some(t) = by_name.get(format!("{stem}_02").as_str()) else { continue };
let (a, b) = (m.meshes[0].vbuf_offset, t.meshes[0].vbuf_offset);
if a.is_some() && a == b {
collapsed.push(format!("{}/{stem}_02 in {}", m.name, f.file_name().unwrap().to_string_lossy()));
}
}
}
assert!(collapsed.is_empty(), "twin pairs sharing one buffer: {collapsed:?}");
}

View File

@@ -17,7 +17,7 @@ fn res3d_dir() -> Option<PathBuf> {
}
}
let default =
PathBuf::from("/home/fabi/RE Project Sylpheed/sylph_extract/hidden/resource3d");
PathBuf::from("/home/fabi/RE - Project Sylpheed/sylph_extract/hidden/resource3d");
default.is_dir().then_some(default)
}
@@ -321,7 +321,7 @@ fn hero_ship_grouped_pool_decodes() {
fn stage_models_decode() {
use sylpheed_formats::mesh::Xbg7Model;
let dir = std::env::var("SYLPHEED_RES3D").unwrap_or_else(|_| {
"/home/fabi/RE Project Sylpheed/sylph_extract/hidden/resource3d".to_string()
"/home/fabi/RE - Project Sylpheed/sylph_extract/hidden/resource3d".to_string()
});
let path = format!("{dir}/Stage_S10.xpr");
let bytes = std::fs::read(&path).expect("read Stage_S10");
@@ -359,7 +359,7 @@ fn stage_models_sweep() {
use sylpheed_formats::mesh::Xbg7Model;
use std::time::Instant;
let dir = std::env::var("SYLPHEED_RES3D").unwrap_or_else(|_| {
"/home/fabi/RE Project Sylpheed/sylph_extract/hidden/resource3d".to_string()
"/home/fabi/RE - Project Sylpheed/sylph_extract/hidden/resource3d".to_string()
});
let mut names: Vec<_> = std::fs::read_dir(&dir)
.unwrap()
@@ -386,7 +386,7 @@ fn stage_models_sweep() {
fn stage_models_quality_audit() {
use sylpheed_formats::mesh::Xbg7Model;
let dir = std::env::var("SYLPHEED_RES3D").unwrap_or_else(|_| {
"/home/fabi/RE Project Sylpheed/sylph_extract/hidden/resource3d".to_string()
"/home/fabi/RE - Project Sylpheed/sylph_extract/hidden/resource3d".to_string()
});
let bytes = std::fs::read(format!("{dir}/Stage_S07.xpr")).unwrap();
let models = Xbg7Model::stage_models(&bytes);
@@ -424,3 +424,59 @@ fn stage_models_quality_audit() {
assert!(huge < models.len() / 20, "few huge (skybox-plane) models");
assert!(worst_deg < 0.35, "no model should be mostly-degenerate");
}
/// A correctly located index run has **no degenerate triangles**. That is the
/// signature the 2026-08-13 pad-scoring fix keys on: an index list read one
/// element late still passes every count-based gate but wires arbitrary
/// vertices, which produces triangles with a repeated index. Before the fix
/// **579** decoded runs on the disc carried such triangles (and a runtime
/// capture confirmed 17 of 93 index batches disagreed with the GPU); after it and
/// the two follow-ups (pad scoring in the grouped path, and preferring a
/// degenerate-free candidate over an earlier dirty one), exactly **one** does.
/// Locking the
/// number in, because the defect is invisible to coverage and to the anchor
/// oracle: every count stays correct while the geometry is mis-wired.
#[test]
#[ignore = "requires extracted disc models — set SYLPHEED_RES3D"]
fn decoded_index_runs_have_almost_no_degenerate_triangles() {
let Some(dir) = res3d_dir() else {
eprintln!("SKIP: resource3d dir not found (set SYLPHEED_RES3D)");
return;
};
let mut files: Vec<PathBuf> = std::fs::read_dir(&dir)
.expect("resource3d/")
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
.collect();
files.sort();
let mut offenders: Vec<(String, String, usize)> = Vec::new();
for f in &files {
let Ok(bytes) = std::fs::read(f) else { continue };
let where_ = f.file_name().unwrap().to_string_lossy().to_string();
for m in Xbg7Model::stage_models(&bytes) {
for sm in &m.meshes {
let d = sm
.indices
.chunks_exact(3)
.filter(|t| t[0] == t[1] || t[1] == t[2] || t[0] == t[2])
.count();
if d > 0 {
offenders.push((m.name.clone(), where_.clone(), d));
}
}
}
}
// The one at default settings: `_rou_f402_dead` in `Stage_S09`, whose
// degenerate-free block is claimed by `e_rou_f003_Near` — both 24-vertex
// bounding boxes, the identity class that needs descriptor-level data. (With
// `XBG7_SUBMESH_DECLS=1` four newly decoded `ptc_pack` `.dat` composites join
// it; that knob is off by default.) Anything else here is a regression.
assert!(
offenders.len() <= 1,
"{} decoded index runs contain degenerate triangles (expected ≤ 1): {:?}",
offenders.len(),
&offenders[..offenders.len().min(20)]
);
}

View File

@@ -19,7 +19,7 @@ fn iso_path() -> Option<PathBuf> {
}
}
let default = PathBuf::from(
"/home/fabi/RE Project Sylpheed/Project Sylpheed - Arc of Deception (USA, Europe) (En,Ja).iso",
"/home/fabi/RE - Project Sylpheed/Project Sylpheed - Arc of Deception (USA, Europe) (En,Ja).iso",
);
default.is_file().then_some(default)
}

View File

@@ -0,0 +1,152 @@
//! Disc-wide guards for the 2D surface formats, locking in what was measured on
//! 2026-08-11. Skipped (as no-ops) when the extracted disc is absent.
//!
//! These assert *disc-wide invariants* rather than one hand-picked file, because
//! each of the findings they guard was originally missed by reasoning from a
//! sample: T8aD's "~15 % unsupported variants" were a wrong model, and LSTA's
//! "a few entries disagree with the count" was a miscount.
use std::path::{Path, PathBuf};
use sylpheed_formats::{lsta, pak::PakArchive, ratc, t8ad};
fn disc_root() -> Option<PathBuf> {
if let Ok(p) = std::env::var("SYLPHEED_DISC") {
let p = PathBuf::from(p);
if p.join("dat").is_dir() {
return Some(p);
}
}
let default = Path::new(
"/home/fabi/RE - Project Sylpheed/Project Sylpheed - Arc of Deception (USA, Europe) (En,Ja)",
);
if default.join("dat").is_dir() {
return Some(default.to_path_buf());
}
None
}
macro_rules! skip_without_disc {
($root:ident) => {
let Some($root) = disc_root() else {
eprintln!("SKIP: extracted disc not found (set SYLPHEED_DISC to enable)");
return;
};
};
}
/// Every entry of every pak, plus every RATC child, as raw bytes.
fn for_each_blob(root: &Path, mut f: impl FnMut(&str, &str, &[u8])) {
let mut paks: Vec<PathBuf> = std::fs::read_dir(root.join("dat"))
.expect("dat/")
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().and_then(|s| s.to_str()) == Some("pak"))
.collect();
paks.sort();
for p in &paks {
let pak_name = p.file_name().unwrap().to_string_lossy().to_string();
let Ok(arc) = PakArchive::open(p) else { continue };
for e in arc.entries() {
let Ok(bytes) = arc.read(e) else { continue };
f(&pak_name, &format!("{:08x}", e.name_hash), &bytes);
if ratc::is_ratc(&bytes) {
if let Some(kids) = ratc::parse(&bytes) {
for k in &kids {
if k.offset + k.size <= bytes.len() {
f(&pak_name, &k.name, &bytes[k.offset..k.offset + k.size]);
}
}
}
}
}
}
}
/// A T8aD surface is a list of sub-rectangles, and on this disc **every** one
/// decodes. Regressing the rectangle model would show up here as a decode gap,
/// which is exactly how the old 256-grid reading looked (96 %, not 100 %).
#[test]
fn every_t8ad_on_the_disc_decodes() {
skip_without_disc!(root);
let (mut total, mut ok) = (0usize, 0usize);
let mut first_failure = None;
for_each_blob(&root, |pak, name, b| {
if !t8ad::is_t8ad(b) || b.len() < 0x40 {
return;
}
total += 1;
if t8ad::parse(b).is_some() {
ok += 1;
} else if first_failure.is_none() {
first_failure = Some(format!("{pak}:{name}"));
}
});
assert!(total > 19_000, "expected the disc's ~19 216 surfaces, saw {total}");
assert_eq!(ok, total, "first failure: {first_failure:?}");
}
/// An LSTA's header count is exact and counts **both** kinds of element: T8aD
/// sprites and `PRMD` primitives. (It was long read as unreliable because the
/// comparison ignored primitives.)
#[test]
fn lsta_count_equals_sprites_plus_primitives() {
skip_without_disc!(root);
let count_magic = |b: &[u8], magic: &[u8; 4]| {
let (mut n, mut i) = (0usize, 4usize);
while i + 4 <= b.len() {
if &b[i..i + 4] == magic {
n += 1;
i += 4;
} else {
i += 1;
}
}
n
};
let (mut lists, mut exact) = (0usize, 0usize);
let mut bad = Vec::new();
for_each_blob(&root, |pak, name, b| {
if !lsta::is_lsta(b) || b.len() < 8 {
return;
}
lists += 1;
let declared = u32::from_be_bytes([b[4], b[5], b[6], b[7]]) as usize;
let sprites = count_magic(b, b"T8aD");
let prims = count_magic(b, b"PRMD");
if declared == sprites + prims {
exact += 1;
} else if bad.len() < 4 {
bad.push(format!("{pak}:{name} declared {declared} != {sprites}+{prims}"));
}
});
assert!(lists >= 60, "expected the disc's 64 LSTA lists, saw {lists}");
assert_eq!(exact, lists, "mismatches: {bad:?}");
}
/// Nested RATC records are **leaves**: they carry no child list of their own.
/// "One level deep" describes the data, not a parser limit.
#[test]
fn ratc_nesting_is_exactly_one_level() {
skip_without_disc!(root);
let mut grandchildren = 0usize;
let mut bundles = 0usize;
for_each_blob(&root, |_, _, b| {
if !ratc::is_ratc(b) {
return;
}
let Some(kids) = ratc::parse(b) else { return };
bundles += 1;
for k in &kids {
if k.offset + k.size > b.len() {
continue;
}
let sub = &b[k.offset..k.offset + k.size];
if ratc::is_ratc(sub) {
grandchildren += ratc::parse(sub).map(|g| g.len()).unwrap_or(0);
}
}
});
assert!(bundles > 2_000, "expected thousands of RATC bundles, saw {bundles}");
assert_eq!(grandchildren, 0, "a nested RATC record listed children");
}

View File

@@ -0,0 +1,96 @@
//! The definition-object layout must keep agreeing with the disc records.
//!
//! `unit_layout` was read out of the game's loader and checked against objects
//! dumped from a running Stage 02. This pins that check: every mapped float
//! field of every identified object must equal the value its disc record sets.
//! It needs no emulator — the dump is checked in under `docs/re/captures/`.
use std::collections::BTreeMap;
use sylpheed_formats::idxd::IdxdObject;
use sylpheed_formats::pak::PakArchive;
use sylpheed_formats::unit_layout::{fields, Kind};
/// Live objects identified in the dump, with the disc record each one is.
/// `bf001` is here because full-record agreement is what identified it: the
/// four-value signature also fitted `UN_be005_ADAN_SpaceFortress`, which
/// disagrees on `Color_R`/`Color_G`.
const IDENTIFIED: &[(&str, &str)] = &[
("UN_f106_TCAF_Destroyer", "0xbd3ee300"),
("UN_f105_TCAF_Cruiser", "0xbd40e200"),
("UN_e105_ADAN_Cruiser", "0xbd3fd800"),
("UN_e106_ADAN_Destroyer", "0xbd3e6f80"),
("UN_f101_TCAF_Acropolis", "0xbd3e1f00"),
("UN_bf001_TCAF_SchlosBase", "0xbd3b6a00"),
("UN_e007_ADAN_Turret", "0xbd3dea80"),
("UN_e010_ADAN_Attacker_S", "0xbd3faa80"),
("UN_f003_TCAF_ArrowHead", "0xbd3dbd00"),
("UN_f001_TCAF_DeltaSaber_T", "0xbd3dfc00"),
("UN_f001_TCAF_DeltaSaber_T_Player", "0xbd3da100"),
];
const DUMP: &str = include_str!("../../../docs/re/captures/stage02-live-unit-definitions-deep.txt");
fn disc_root() -> Option<String> {
if let Ok(p) = std::env::var("SYLPHEED_DISC") {
if std::path::Path::new(&p).join("dat").is_dir() {
return Some(p);
}
}
let d = "/home/fabi/RE - Project Sylpheed/Project Sylpheed - Arc of Deception (USA, Europe) (En,Ja)";
std::path::Path::new(d).join("dat").is_dir().then(|| d.to_string())
}
/// `va -> offset -> value`, from the dump's `addr +off hex u32 f32` columns.
fn live() -> BTreeMap<String, BTreeMap<usize, f32>> {
let mut out: BTreeMap<String, BTreeMap<usize, f32>> = BTreeMap::new();
let mut cur = String::new();
for line in DUMP.lines() {
if let Some(rest) = line.strip_prefix("=== ") {
cur = rest.trim().to_string();
continue;
}
let f: Vec<&str> = line.split_whitespace().collect();
if f.len() >= 5 && f[1].starts_with('+') {
if let (Ok(off), Ok(val)) = (usize::from_str_radix(&f[1][1..], 16), f[4].parse::<f32>())
{
out.entry(cur.clone()).or_default().insert(off, val);
}
}
}
out
}
#[test]
fn mapped_fields_match_the_disc_records() {
let Some(disc) = disc_root() else {
eprintln!("SKIP: extracted disc not found (set SYLPHEED_DISC to enable)");
return;
};
let pak = PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).expect("main pak");
let live = live();
let floats: Vec<_> = fields().into_iter().filter(|f| f.kind == Kind::F32).collect();
let (mut agree, mut bad) = (0usize, Vec::new());
for entry in pak.entries() {
let Ok(bytes) = pak.read(entry) else { continue };
let Ok(obj) = IdxdObject::parse(&bytes) else { continue };
let Some(id) = obj.get_raw("ID") else { continue };
let Some((_, va)) = IDENTIFIED.iter().find(|(i, _)| *i == id) else { continue };
let Some(words) = live.get(*va) else { continue };
for f in &floats {
let (Some(want), Some(got)) = (obj.get_f32(f.name), words.get(&f.offset)) else {
continue;
};
// Angle fields are degrees on disc and radians in the object.
let rad = want * std::f32::consts::PI / 180.0;
if (want - got).abs() <= want.abs() * 1e-4 || (rad - got).abs() <= rad.abs() * 1e-4 {
agree += 1;
} else {
bad.push(format!("{id}.{} disc {want} vs live +{} = {got}", f.name, f.offset));
}
}
}
assert!(bad.is_empty(), "{} fields disagree: {bad:?}", bad.len());
assert!(agree >= 400, "expected ≥400 agreeing fields, got {agree}");
}

View File

@@ -3677,6 +3677,7 @@ fn exhaust_cone_mesh() -> sylpheed_formats::mesh::GameMesh {
uvs: Vec::new(),
indices,
name: Some("exhaust".to_string()),
vbuf_offset: None, // procedural, not read from a container
}
}

View File

@@ -8,8 +8,30 @@ unknown, what evidence exists, and what the first step would be. Move an item in
## Capital ships assemble wrong in the viewer
**Reported:** 2026-07-30, by the user. **Status:** 🔎 **diagnosed 2026-08-10 — the
format layer is exonerated.** Runtime captures of three classes (`f105`, `e105`,
**Reported:** 2026-07-30, by the user. **Status:** **format-side cause found and
fixed 2026-08-12** — see below for the 2026-08-10 diagnosis this supersedes.
The remaining format-side defect this entry pointed at (a shared turret decoding
~100× too large in some containers) was real and is gone. `e303_wep_01` decoded
as a 1600×2100×4800 block in `Stage_S02`, swallowing the `e106` hull; requiring an
index buffer to cover its vertex pool **exactly** moved it to the block every
other container agrees on, and it now decodes 49×23×42 everywhere and places at
±179 on the hull. The same fix repaired `e106_bdy_03` (a 600×1600×998 slab) and
moved 29 anchors disc-wide, 22 of which had been carrying **another resource's
geometry under their own name**. See
[`structures/xbg7-mesh.md`](structures/xbg7-mesh.md).
Two things are worth carrying forward rather than closing:
- the assembler was **audited and exonerated** — every composite node carries
scale 1.0 and an orthonormal matrix, so nothing on that side inflates a part;
- **no metric caught this.** Coverage, cross-container consistency, the capture
oracle and the twin invariant were all green while a 1 600-unit slab sat through
the ship. It was found by *rendering the ship and looking at it*, and the
numeric screens written afterwards to automate that check both failed.
The 2026-08-10 diagnosis follows, and its viewer-side pointers still stand.
**Status (2026-08-10):** 🔎 **the format layer is exonerated.** Runtime captures of three classes (`f105`, `e105`,
`e106`) at controlled range reproduce `assemble_ship` to ≤0.43 units in translation
and to 0.000 in rotation for every part that does not move; see
[`ship-placement-capture-generalisation.md`](ship-placement-capture-generalisation.md)
@@ -58,3 +80,225 @@ class cannot hide behind `e106` passing.
handedness, node-instance recursion) is not re-breaking a correct assembly — compare
the viewer's placement against `assemble_ship`'s output directly before blaming the
format layer.
---
## Viewer: `include_external` is already on — that hypothesis is dead
**Checked 2026-08-11.** The item above names "first that it passes
`include_external = true` (`iso_loader.rs:4012`)" as the cheap first step. It
does: `ShipBrowser::show_external` defaults to `true`
(`iso_loader.rs:643`), the checkbox reads it (`ui.rs:1593`) and it is threaded
through `RequestShipRender``build_ship_model``assemble_ship` unchanged
(`ui.rs:1689`, `iso_loader.rs:4012`). So a ship rendered by the viewer is the
full external assembly, not the bare hull.
The viewer also does not have a transform stack of its own to blame: it bakes
`ScenePart::apply` straight into the vertices and rotates normals by the same
`p.m` (`iso_loader.rs:4030-4062`), so its placement is `assemble_ship`'s output
by construction. What remains unexcluded, in order of cheapness: the mirror
handling (`det < 0` reverses triangle winding only — a reflected part keeps its
reflected geometry), `Xbg7Model::models_named` resolving the wrong sub-model when
a resource name repeats, and the exhaust cones. **Next step is a visual**: the
diagnosis has run out of things it can settle by reading, so the viewer needs to
be run against a known-good class (`e106`) and its render compared with
`ship_render`'s.
---
## Viewer: the duplicate-resource-name hypothesis is dead too
**Checked 2026-08-11.** The diagnosis above left three candidates for why capital
ships assemble wrong in the viewer: mirror handling, `Xbg7Model::models_named`
resolving the wrong sub-model when a resource name repeats, and the exhaust
cones. The second is now **refuted**, and comprehensively.
`build_ship_model` resolves each placement with
`base.iter().find(|m| m.name == p.resource)` (`iso_loader.rs:4041`) — first match
wins — so a repeated resource name inside a container would silently draw the
wrong geometry. It cannot happen: decoding **every** XBG7 resource in **all 22
stage containers** gives **4 603 resources and zero repeated names**.
```
Stage_S01 62/62 Stage_S07 323/323 Stage_S13 290/290 Stage_S25 351/351
Stage_S02 304/304 Stage_S08 388/388 Stage_S14 22/22 Stage_S26 318/318
Stage_S03 214/214 Stage_S09 316/316 Stage_S15 386/386 Stage_S27 321/321
Stage_S04 179/179 Stage_S10 7/7 Stage_S16 65/65 Stage_S28 118/118
Stage_S05 92/92 Stage_S11 157/157 Stage_S24 162/162 Stage_S29 386/386
Stage_S06 266/266 Stage_S12 376/376
```
Per-ship it is tighter still: `e106` wants 9 distinct names and decodes exactly
9 models for 11 placements; `e105` 9 for 9; `f105` 5 for 6. Every placement
resolves to the one model it names.
**So two of the three candidates are gone** (this one and `include_external`),
leaving **mirror handling** and **the exhaust cones** — and the still-untried
visual comparison, which remains the right next step.
---
## Viewer: mirror handling and the exhaust cones are cleared too — the static avenue is exhausted
**Checked 2026-08-11.** Both remaining candidates were tested across every ship
on the disc, and neither shows the reported signature.
**Mirror handling.** The concern was that `ScenePart::apply` bakes `R·(S·v)+T`
while the viewer takes its winding-flip decision from `det(m)` alone and rotates
normals by `m` alone — both ignoring `s`. A mirror encoded as a *negative scale*
would then reflect geometry without flipping winding, drawing the part
inside-out. It never happens: across **1 485 assembled parts** in all 22
containers there are **22 mirrored parts, every one with `det(m) < 0`**, and
**zero** parts with a negative scale or a non-uniform one. `apply_twin_mirrors`
writes the reflection into `m` (negating its X column), so the viewer's flip
always fires, and ignoring `s` for normals is harmless because `s` is always
uniform.
**Exhaust cones.** These are the one piece of geometry the viewer *invents* — a
cone at each `GN_Jet`/`GN_SJet` frame, because the real engine geometry is
recessed and the game draws FX there instead. If they landed wrongly they would
read exactly as "a part in the wrong place". Across **335 assembled ships, 192 of
which have exhaust frames, not one cone sits outside its hull's bounding box**
(tolerance 10 % of the axis span).
**Caveat, stated rather than glossed:** "inside the hull box" does not prove a
cone is *right* — orientation and size are untested, and a cone could be wrong
while still inside. What it does rule out is the reported symptom for that part.
So every mechanism this diagnosis proposed is now eliminated: `include_external`,
duplicate resource names, mirror handling, and cones-in-the-wrong-place. The
format and assembly layers pass every static test available, and **the visual
comparison is no longer merely the next step — it is the only remaining one.**
Render `e106` in the viewer beside `ship_render`'s output of the same
`assemble_ship` result; if they agree, the bug is in neither and the original
report needs re-grounding against a specific ship and a specific expectation.
---
## ⚠️ DIAGNOSED 2026-08-12 — a mis-decode; the locality fix was written, then withdrawn
> Resolution at the end of this entry. Kept in full because the two wrong turns
> along the way (a "stray volume", then "monotonic anchoring") are the useful part.
## ⚠️ The format layer is NOT exonerated — but the cause is a MIS-DECODE, not a stray volume
**Found 2026-08-11 by finally doing the visual**, which the notes above kept
naming as the next step. It overturns their conclusion.
Render `e106` from the static assembly and from the baked runtime capture and
compare — `ship_render` does both:
| | placements | parts |
|---|---|---|
| runtime capture (ground truth) | **8** | `bdy_01…04`, `brg_01`, `eng_01`, `eng_02`, `wep_02_01` |
| `assemble_ship(--static)` | **11** | the same 8, **plus `e303_wep_01` ×2** and a second `e106_eng_01` |
The render makes it obvious: the destroyer sits inside a white slab that dwarfs
it ([capture](captures/e106-static-assembly-volume-bug.png)). That slab is
`e303_wep_01`, and its own geometry is:
```
e303_wep_01 172 verts, 110 tris bounds X[-1000, 600] Y[-1050, 1050] Z[-2400, 2400] 1600 x 2100 x 4800
e106_wep_02_01 1002 verts, 772 tris 269 x 179 x 417 ← what a real e106 turret looks like
e106_brg_01 202 verts, 202 tris 105 x 76 x 305
```
**110 triangles, perfectly round axis-aligned bounds, and bigger than the ship it
is mounted on.**
### CORRECTION (same day, one iteration later): it is not a volume — it is a bad decode
The first reading of this was that `e303_wep_01` is a collision/trigger volume
the assembler wrongly draws. **That is wrong, and the evidence that settles it is
decoding the same resource from every container that holds it:**
```
Stage_S01 172 verts 110 tris X[-24.5, 24.5] Y[0.0, 23.4] Z[-20.8, 20.8] ← 49 × 23 × 42, a turret
Stage_S02 172 verts 110 tris X[-1000, 600] Y[±1050] Z[±2400] ← 1600 × 2100 × 4800
Stage_S03… 172 verts 110 tris 49 × 23 × 42 (correct)
Stage_S08 … 1600 × 2100 × 4800
Stage_S26 … 1600 × 2100 × 4800
```
Same resource, same vertex and triangle count, **decoding correctly in eleven
containers and wrongly in exactly three** (`Stage_S02`, `S08`, `S26`). So:
- the **placement is legitimate**`e303_wep_01` is a small shared turret,
cross-mounted on `e101` and `e106`, and at its true size it is unremarkable;
- the original author's explanation of the capture's silence (**vbase dedup**)
stands, and my "dedup would show one, not zero" objection does not survive:
with the correct decode the turret is small, ordinary geometry;
- **the defect is in the mesh decoder**, which resolved this resource's vertex
data differently in three containers.
The render and the symptom are real; the cause named in the first version of this
entry was not.
### The part that matters more than this one resource
**The decoder can produce wrong geometry without declining.** The
[XBG7 audit](structures/xbg7-mesh.md) counted 814 resources it *refuses* — a
visible, honest failure. This is the other kind: `e303_wep_01` decodes "fine" in
`Stage_S02` and is silently 100× too large. Screening for the signature (bounds
that are exact multiples of 50 with a span over 1000) flags 2232 models in each
of `S02`, `S03`, `S08`, `S26`, `S27` — **but that screen also catches legitimate
`e_rou_*` composite proxies**, so it is a candidate list, not a count of bugs.
**Next:** diff the anchor scan's chosen `vb0` for `e303_wep_01` between
`Stage_S01` (correct) and `Stage_S02` (wrong) — same resource, two outcomes, so
the divergence is directly observable — then use whatever distinguishes them to
add a post-decode sanity check, so a silent 100× mis-decode becomes a decline.
### Why this was missed
`assemble_ship` treats **every** `rou_*` node in the composite as a drawable
part, and the doc comment states the cross-id mount as intended behaviour —
`"INCLUDING repeated instances and cross-id turret mounts (rou_e303_wep_01_root
×2 on the e106 hull)"` — with
`ship::tests::static_assembly_matches_runtime_capture` asserting
`count("e303_wep_01") == 2`. The absence from the capture was explained away as
vbase dedup, but **dedup would show one instance, not zero**.
The test cannot catch it either: it walks the capture's parts and looks each up
in the static output, so **extra** static placements are invisible to it. That is
the same shape of gap as the earlier `include_external` hypothesis — a test that
can only fail one way.
### Scope, stated carefully
Sweeping all 335 assembled ships for the signature *ship-scale span with under
400 triangles* flags **20 ships and 58 placements** over 28 distinct resources
(`e005_ant_*`, `f001_ant_*`, `f002_bdy_*`, `f301_barrel`, `f303_body`,
`e303_wep_01`, …). **Only the `e106`/`e303_wep_01` case is proven** — by render,
by capture absence, and by geometry. Some of the others may be legitimately large
low-poly parts, and each needs the same three checks before being called a bug.
**Still true, and independent of the correction above:**
`static_assembly_matches_runtime_capture` walks the capture's parts and looks each
up in the static output, so **extra static placements can never fail it**. That is
worth fixing regardless — it is the same one-way-test shape as the earlier
`include_external` hypothesis.
Also unchanged: only **two** cross-id placements exist fleet-wide (`e303_wep_01`
on `e101` ×24 and `e106` ×36, across 335 assembled ships), so cross-id mounting is
a narrow, real feature rather than a systemic guess.
---
## Resolution (2026-08-12)
`anchor_pool_mesh` took the **first** candidate in file order from a
container-global scan, so a resource could be handed another resource's block
whenever both shared `(stride, vertex count, index count)`. Fixed by anchoring
each resource near its **descriptor neighbours** (two-pass: learn, then re-anchor).
- it took inconsistency **125 → 51** with coverage unchanged, and made `e106`
render correctly ([after](captures/e106-static-assembly-fixed.png))
- **but it flipped the `e106` twin-mirror decision**, which
`static_assembly_matches_runtime_capture` (ISO-gated, so it skips in a plain
`cargo test`) catches against the runtime capture — so it was **reverted**
- the user-reported "capital ships assemble wrong" is therefore **diagnosed, not
yet fixed**; see [xbg7](structures/xbg7-mesh.md) for what the real fix needs
Still open from this entry: `static_assembly_matches_runtime_capture` walks only
the capture's parts, so **extra** static placements still cannot fail it.

View File

@@ -13,17 +13,19 @@ Promote to a prose `structures/…md` file when a format needs behavioural notes
| IPFB `.pak` archive | ✅ | `sylpheed-formats/src/pak.rs` + `tests/pak_idxd_disc.rs` | header + 12-byte TOC, Z1/zlib payloads |
| name-hash (TOC keys) | ✅ | `sylpheed-formats/src/hash.rs` | Barrett-reduction hash; recovers original paths |
| IDXD object/table | ✅ | `sylpheed-formats/src/idxd.rs` | self-describing; ship/weapon stats verified vs known values |
| XPR2 texture + cubemap | 🟡 | `sylpheed-formats/src/texture.rs` | de-tile + A8R8G8B8; **colours unverified** (dynamic item) |
| T8aD 2D texture | 🟡 | `sylpheed-formats/src/t8ad.rs` | ~85% decode; **colours ✅ CONFIRMED** ([k8888](structures/texture-color-k8888.md)); ~15% variants deferred |
| RATC bundle | 🟡 | `sylpheed-formats/src/ratc.rs` | child listing confirmed; one level deep |
| LSTA sprite list | 🟡 | `sylpheed-formats/src/lsta.rs` | inline T8aD frames |
| IXUD subtitle | 🟡 | `sylpheed-formats/src/ixud.rs` | timed cues; **movie↔track link unknown** (dynamic item) |
| XPR2 texture + cubemap | 🟡/✅ | `sylpheed-formats/src/texture.rs` + [colour check](xpr2-colour-check.md) | de-tile + A8R8G8B8 and DXT1. **Channel order ✅ confirmed against the running game**: the Delta Saber's decoded atlas is orange-dominant (median saturated hue 23.3°, *zero* cool pixels) and the game renders the same hull at 9.3° — a red↔blue swap would sit at ≈200°. Exact fidelity (gamma/sRGB curve, premultiplied alpha, per-channel scale) is 🟡 untested, since a hue comparison cannot see it; cubemap face ordering ❔ |
| T8aD 2D texture | | `sylpheed-formats/src/t8ad.rs` | **100 % of the disc decodes** (19 216/19 216, measured). The "~15 % deferred variants" were a wrong model, not a variant: a surface is a list of **arbitrary sub-rectangles**, each with a 16-byte header of `dst X, dst Y, width, height`, not a 256×256 grid — `0x1c` is the **rectangle count**. Uncovered area stays transparent. **Colours ✅ CONFIRMED** ([k8888](structures/texture-color-k8888.md)) |
| RATC bundle | | `sylpheed-formats/src/ratc.rs` | child listing confirmed. **"One level deep" is not a limitation — there is nothing deeper**: 2 859 bundles hold 18 002 children at depth 1 and **0 at depth 2**, with no parse failures. Nested RATC blobs are **leaf records that reference siblings by name** (`opt `, the sprite name): 3 311 leaves, all embedding sibling names, **10 144 of 10 148 references resolve**. The 4 that do not are one dangling asset — `pmbase.rat``pmbase.t32` in `GP_STAGE_CLEAR.pak`'s four language builds, and `pmbase.t32` is **on the disc nowhere** |
| LSTA sprite list | | `sylpheed-formats/src/lsta.rs` | A display list of inline elements: **T8aD sprites and `PRMD` primitives**. The `count` at `0x04` is **exact and counts both**`count == T8aD + PRMD` for **64/64** lists on the disc, which retires the old "a few entries disagree" note (it compared sprites against a total including primitives). **All 1 281 sprite frames decode** after the T8aD rectangle-list fix |
| IXUD subtitle | 🟡/✅ | `sylpheed-formats/src/ixud.rs` + [movie link](movie-subtitle-link.md) | timed cues. **The movie↔subtitle↔voice link is solved — statically**, from the movie config record in `tables.pak` (schema `0x067025b9`), not from the running game as this row previously assumed: [101 movies mapped](captures/movie-subtitle-voice-map.csv), 94 with subtitles, 83 with voice, 21 with a telop overlay. 93 of 94 subtitle refs resolve in the language paks; **`SUBTITLE_S12B.tbl` is missing from all six languages** — a dangling reference on the disc. Naming is `SUBTITLE_<base>.tbl` / `VOICE_<base>` with six documented exceptions. The record's ~104 **script ids** are ❔ — positional pairing drifts by three because the IDXD pool dedupes repeated values |
| Fonts (ttf/otf/ttc) | ✅ | `sylpheed-formats/src/font.rs` | standard OpenType, parsed via ttf-parser |
| XBG7 mesh | 🟡/❔ | `sylpheed-formats/src/mesh.rs` + `tests/mesh_disc.rs` ([xbg7](structures/xbg7-mesh.md)) | weapons/props: declaration-driven variable stride (36 models), GPU-confirmed. **Stage containers: 5662 sub-models across 22 stages** via content-anchored grouped pools (`stage_models`). Quantized hero bodies (DeltaSaber `f004`) still declined |
| Capital-ship part placement | 🟡 | `sylpheed-formats/src/ship.rs` (static) + [runtime capture](ship-placement-runtime-capture.md) | hull placement static-exact; external parts approximate statically. **Runtime capture** (Canary F10 → VS-constant WorldView) gives ground truth — validated on `e106` destroyer; not yet baked into the viewer |
| XBG7 mesh | ✅/🟡 | `sylpheed-formats/src/mesh.rs` + `tests/mesh_disc.rs` ([xbg7](structures/xbg7-mesh.md)) | **6 294 resources, 6 209 decode (98.7 %), 82 searched-and-missed** (2026-08-12, up from 5 480 / 87.1 %). Five evidence-driven fixes got there: **distinct anchor assignment** (no two resources may claim one buffer — proved by a capture showing the container holds both mirrored `e106` hull halves), the connectivity cap replaced by a **winding-consistency gate at 0.70**, **structural requirements on pre-pivot sub-meshes** (index range, then exact pool coverage), and **filtering after the assignment** so a subset query cannot differ from the full decode. Validated against a runtime capture that names the file offset of every buffer the engine drew: **46/46 drawn buffers claimed, 45 anchored exactly**. **No real mesh now decodes differently in different containers** — all 89 remaining cross-container disagreements are interchangeable 24-vertex bounding boxes, which no anchoring rule can pin (monotone order re-tested and refuted). Remaining misses attribute to the degeneracy/extent gate (42), winding (31) and coverage (9); the first was probed and its "obvious" fix refuted. Every decoded sub-mesh covers its own vertex pool. **The `[index buffer][vertex buffer]` layout is now runtime-verified** (2026-08-13): with the F10 capture extended to log each draw's index buffer, all **42** drawn `Stage_S02` buffers match our decoded index count exactly, all 42 have their index union cover the pool exactly, and the 30 single-block cases all sit at `pad ≤ 3` — so `e106_eng_02_l`'s old rejection was the connectivity gate, not a misplaced index buffer. The `indices=` mystery was the capture keeping only the **first of several index batches** per buffer. **And comparing index VALUES found the biggest silent defect yet**: the anchor took the first `pad` that validated, so a block whose index data sits at pad 2 was read **one element late** — 76/93 captured runs matched, all 17 differences a one-element shift. Scoring pads by degenerate triangles + winding fixes it: **93/93** captured runs now match byte for byte, disc-wide degenerate runs **582 → 1** (the grouped path had the same bug; and two resources were anchored on a degenerate lookalike earlier in file order), **590 of 8 850** sub-meshes re-wired with 10 vertex anchors moved, resources decoded unchanged at 6 209. Cross-container minority decodes 89 → 96 — *because* the decoder improved: `_rou_f402_dead` now has a majority (32×25×8) so its seven wrong copies are named instead of hidden. One dirty run remains, blocked by distinct assignment on a 24-vertex box. **Then the descriptor gave up its last structural secret**: it declares a vertex layout **per sub-mesh** (`n201_01` → strides 24/24/24/**28**, capture-confirmed), and grouped selection must prefer the candidate explaining the **whole** pool rather than the first whose pivot validates — together they take never-decoding resources **85 → 47** (**6 247 / 6 294 = 99.25 %** decode), put `n201_01` on all four capture-proven offsets and raise the stage-05 capture oracle to **128/128**. The residual 47 is 30 pose/proxy composites (0.010-unit marker boxes), 6 `.DAT` particle composites, 8 damage/LOD variants and 3 props — not a threshold away |
| Capital-ship part placement | | `sylpheed-formats/src/ship.rs` (static) + [runtime capture](ship-placement-runtime-capture.md) | Placement is **sound** (hull static-exact against the `e106` capture; cross-id mounting genuinely narrow, 2 pairs across 335 ships). The XBG7 mis-decode this row used to blame for "ships assemble wrong" — a shared turret ~100× too large in some containers — is **fixed** (2026-08-12, the exact-coverage requirement): `e303_wep_01` now decodes 49×23×42 everywhere and places at ±179 on the `e106` hull, and no real mesh disagrees across containers. A composite-node audit confirmed the assembler itself never applied a bad scale (all nodes scale 1.0, orthonormal). Still open: `static_assembly_matches_runtime_capture` walks capture parts only, so **extra** static placements cannot fail it |
| Weapon fields defaulted on disc | ✅ | [runtime struct](structures/weapon-struct-runtime.md) · [DATA SHEET route](weapon-datasheet-runtime.md) | **Solved.** Canary maps guest RAM into `/dev/shm`, so the parsed `Weapon`/`Shell` objects are readable live; their layout is solved against disc ground truth (zero contradictions over 100+ records). All 126 weapons, exact numbers, no story progress needed — [4 393 values](captures/weapon-runtime-fields.csv) the disc does not carry. Supersedes the letter-bucket limit of the DATA SHEET route, which now serves as the independent cross-check |
| Unit (craft/vessel) fields defaulted on disc | ✅/🟡 | [runtime struct](structures/unit-struct-runtime.md) | The parsed `unit\UN_*.tbl` definition object, vtable `0x820af844`, ≥`0x380` bytes, one per unit — **discovered, not assumed** (`unit_discover.py`), and distinguished from the spawned-entity class `0x820af030` by being one-per-ID and byte-constant within a run. Across runs only pointer words move — `--crosscheck` proves **no reported field offset is run-dependent** (two words, `+0x2c8`/`+0x2d0`, are stage-dependent and remain unidentified). 27 fields ✅ (21 units, 7 runs); the `Maneuver` block is **schema declaration order, 4 bytes/field, base `0x9c` with a two-slot gap after `AA_Roll_Min`** (29 anchors, 0 conflicts), which also pins 5 fields *no* disc record ever values. Angles are **radians at runtime, degrees on disc**. Unlike weapons, unit definitions are instantiated **per stage**, so coverage (21/110) grows by visiting missions — [values](captures/unit-runtime-fields.csv) |
| UI screen layout (`.rat`) | ✅/🟡 | [ui-rat-layout](structures/ui-rat-layout.md) | One pak per UI screen; each RATC = one (context × language) build; every `<name>.t32` sprite has a `<name>.rat` **layout record** (BE u32; 1280×720 design space; scale/tint/X/Y, keyframes for animated elements, `opt ` link to the focused state). **The tutorial PAUSE menu and the title main menu both rebuild pixel-accurately from the disc.** `loop1.rat` (screen-level draw order) not yet decoded |
| Unit (craft/vessel) fields defaulted on disc | ✅/🟡 | [runtime struct](structures/unit-struct-runtime.md) | The parsed `unit\UN_*.tbl` definition object, vtable `0x820af844`, ≥`0x380` bytes, one per unit — **discovered, not assumed** (`unit_discover.py`), and distinguished from the spawned-entity class `0x820af030` by being one-per-ID and byte-constant within a run. Across runs only pointer words move — `--crosscheck` proves **no reported field offset is run-dependent** (two words, `+0x2c8`/`+0x2d0`, are stage-dependent and remain unidentified). 27 fields ✅ (21 units, 7 runs); the `Maneuver` block is **schema declaration order, 4 bytes/field, base `0x9c` with a two-slot gap after `AA_Roll_Min`** (29 anchors, 0 conflicts), which also pins 5 fields *no* disc record ever values. Angles are **radians at runtime, degrees on disc**. **Re-derived independently 2026-08-13 from the loader's own key strings** (`sub_82341A20`; the field name for each store is a string in the image): **159 fields**, agreeing with this solver on **25 of 25 shared offsets**, verified at **406 values matching the disc and 0 disagreeing** over 11 live objects spanning UNIT and VESSEL — landed as `data/unit_definition_layout.txt` + `sylpheed_formats::unit_layout` + a no-emulator test, with **121 defaulted fields** read out ([live-unit-definitions](live-unit-definitions.md)). Unlike weapons, unit definitions are instantiated **per stage**, so coverage (21/110) grows by visiting missions — but a defaulted field is **not** a global constant: `Size_Y` provably inherits `Size_X` (7 independent units, 6 distinct values), and three more sibling rules are recorded ❔, recovering 65 values in units never visited — [values](captures/unit-runtime-fields.csv) |
| Arsenal develop economy | ✅/ | [arsenal-develop-economy](arsenal-develop-economy.md) + [conditions](captures/arsenal-develop-conditions.csv) | The Arsenal reads `weapon.tbl` (item ids, in the 8-category display order) and `strings.tbl` (names, descriptions, and a **"Conditions to obtain"** block per item) out of `GP_HANGAR_ARSENAL.pak`. All **60** conditions are extracted: gates are stage completion, a predecessor item, or an **ace kill**; costs run 3 000350 000 P and **20 items are free** once gated. `weapon.tbl`'s first record reproduces the in-game DATA SHEET exactly (Range D / Power E / Speed / Weight 0.3 = Light / 4000 P) — later records are unreadable from the string pool alone because IDXD **dedupes repeated values**. Used to identify the save blob's index space, now **solved**: the blob follows **`strings.tbl`'s** order — the display order *plus* the cut items only the localisation file lists (`Adhesive Mine B2A`, `Ballista GSH`, …) — pinned by four hand-written probe saves (9 Stiletto, 21 Falcon, 39 Tomahawk, 48 Jamming System) and closing exactly at index 53. `weapon.tbl`'s id list is **not** the index space; that it is also 54 long is a coincidence, and the two agree only to index 32. The retail save's five unexplained owned entries are the cut items, shipped owned and never rendered |
| UI screen layout (`.rat`) | ✅/🟡 | [ui-rat-layout](structures/ui-rat-layout.md) | One pak per UI screen; each RATC = one (context × language) build; every `<name>.t32` sprite has a `<name>.rat` **layout record** (BE u32; 1280×720 design space; scale/tint/X/Y, keyframes for animated elements, `opt ` link to the focused state). **The tutorial PAUSE menu and the title main menu both rebuild pixel-accurately from the disc.** `loop1.rat` is decoded — it is a **looping sprite animation**, not a composition. The **screen's draw list is the RATC bundle's own declaration table** (elements in back-to-front order, including the `eff*`/`deli*`/`msg` sprites that have no `.rat`, and excluding focused button variants reached via `opt `); its entry also carries a **parent element index** at `+32`. **A screen is fully reconstructible from its bundle**: the placement region right after the declaration table gives every element a keyframe group (header = element index + keyframe count, then 40-byte blocks of scale/tint/X/Y), including the `.rat`-less sprites — verified 11/11 on the tutorial pause bundle, with `pgp_ttrl_btn10`'s inline (546,288) matching its own record exactly |
| Save file (`savedata`) | ✅/❔ | [savegame-format](structures/savegame-format.md) + [`tools/re-capture/savegame.py`](../../tools/re-capture/savegame.py) | `GDHA` container, zlib payload, chunk stream (`GDAA` / phase name / `GHAD` 122 B progress block / 16×20 B slot table / trailer). **Container and layout read off the title's own serializer `0x822C00E8` and verified by a byte-identical round-trip**; the whole save is 545 B. Payload offsets are also the live save object's offsets (`save+8` GHAD, `save+136` slots). A second save made in-game names **Points** (+24), **flight time in ms** (+4) and **clear ratio %** (+8) off the game's own Details panel; the payload is a **pure function of game state** (same state saved twice = byte-identical, only the header FILETIME and its uninitialised pointer padding move), and the 16 `SHAB` records are **not** the UI's 20 save slots. Difficulty vs stage is undecided — three fields hold 2. **A third save, taken after developing exactly one Arsenal weapon** (Light Machine Gun MG I, 4000 P), moves exactly three things: `+24` Points 4101→101 (which **separates it from `+28`**, that did not move), `+8` clear ratio 5→6 (so the ratio counts *collection*, not only stages), and two entries of the 54-byte blob — `2→4` for the item bought and `0→2` for the successor the game announced as newly developable, giving the blob its alphabet ✅ *0 locked / 2 developable / 4 developed* (only the `4`s are stored — `2` is re-derived at load). **Saves can also be written back**: three derived header fields (length at `+0x30`, payload length at `+0x8c`, `adler32` at `+0x8e`) are all that stand between a parse and a hand-written save that the title loads, and [`savegame_edit.py`](../../tools/re-capture/savegame_edit.py) re-wraps a real save byte-identically. That turned the blob's index space from blocked-on-story-progress into four probe saves — see the [economy note](arsenal-develop-economy.md) |
## Runtime / dynamic-capture technique
@@ -34,6 +36,7 @@ Promote to a prose `structures/…md` file when a format needs behavioural notes
| Live entity state, anchored on the definition | ✅ | [`tools/re-capture/own_state.py`](../../tools/re-capture/own_state.py) · [autopilot](autopilot-memory-driven.md) | An undamaged craft holds its definition's own numbers, so a *solved definition field* locates the matching live field without a value scan: definition `HP` (1500) → **hull at `position+0x154`**, confirmed by a trace across a death (30/60/90 per hit, negative at 0). Reusable for any live counter whose maximum the definition carries |
| Mission / escort state, every entity's hull | ✅ | [`tools/re-capture/mission_state.py`](../../tools/re-capture/mission_state.py) · [escort state](mission-escort-state.md) | `hull = position + 0x154` is a property of the **entity class**, not of the player object: at t=0 it equals each entity's own definition `HP` across 7 classes and 5 distinct HP values (turret 100, fighter 500, destroyer 10000, cruiser 30000, **ACROPOLIS 25000**), falls under fire (780 damage events in 240 s), goes negative at death, and the object then leaves the heap. So an escort objective is scoreable live — `UN_f101_TCAF_Acropolis` measured at 25000 → 23038 over 240 s, attack starting only at t≈170 s. `REMAINING OB` counts objectives, not hostiles (012 on the HUD vs 118 live ADAN); its address is still ❔ |
| In-flight control mapping | ✅/🟡 | [`tools/re-capture/fire_probe.sh`](../../tools/re-capture/fire_probe.sh) · [controls](flight-controls-runtime.md) | Measured by holding each pad input and photographing the HUD ammo counters: **`RB` = nose gun** (6000→5956 in 4 s, ~11 rounds/s, HEAT rises), **`Y` = main mount** (missiles, 300→299), d-pad = **tactical map** overlay, nothing else moves a counter. No target-cycle input exists — the `TARGET` marker is present with nothing pressed, so targeting is automatic and a missile lock is **time-on-target**. That, not target choice or ballistics, is what caps lethality at 2 kills per 98 missiles |
| Throttle → speed law | ✅/🟡 | [flight-speed-law](flight-speed-law.md) | **The throttle selects a TARGET SPEED**, it does not add thrust: no input settles at ~420 (`CruisingVelocity` 350), `RT` at ~1 530 (`MaximumVelocity` 1200), `LT` at ~125 (`MinimumVelocity` 100), and releasing either returns to cruise. `Acceleration`/`Deceleration` govern the convergence rate (measured ~440560 units/s² against 500/600). 🟡 measured world speeds run ≈1.21.3× the definition numbers while the HUD shows the definition value exactly, so world units are a constant (~1.25) multiple of the definition's velocity unit |
| Input → dynamics calibration | ✅ | [`tools/re-capture/ctrl_probe.py`](../../tools/re-capture/ctrl_probe.py) · [`binq.py`](../../tools/re-capture/binq.py) | Hold each pad input in turn and measure the craft's speed as displacement/s of its own position triple — no speed field needed first. Settled the throttle: **`RT` accelerates, `LT` brakes, and the setting persists** (488 → 1510 → 174 units/s), overturning an earlier field-scan conclusion |
## Functions / code paths

View File

@@ -0,0 +1,69 @@
# Session log — 2026-08-11 (autonomous run)
What changed today, in the order a reviewer would want it, with the one item
that needs **your decision** called out first.
## Needs a decision from you
**Editing save slot 01.** Save files can now be written back
([savegame_edit.py](../../tools/re-capture/savegame_edit.py) re-wraps a real save
**byte-identically**), and hand-written saves load. That unblocked several
questions by probing throwaway slots. But the **title-menu screens read the
auto-save (slot 01)**, so the remaining save-field questions (the difficulty
enum, `SHAB.b`) need slot 01 itself edited — the only save with real progress.
Not done. Recoverable (full content backup + slot 01's bytes archived), but it is
your call. Everything else below was done in throwaway slots.
## Findings, by area
### Save format
- **The develop differential**: buying one Arsenal weapon moves exactly three
fields — Points `+24` (which **separates it from `+28`**), clear ratio `+8`
(so the ratio counts *collection*, not stages), and two entries of the 54-byte
blob. Blob alphabet: `0` locked / `2` developable / `4` owned; only the `4`s
are stored, `2` is re-derived at load.
- **The blob's index space is solved** — it follows `strings.tbl`'s item order,
**cut items included**, pinned by four probe saves and closing exactly at 53.
- **`SHAB` is the per-stage record table**: record 0 = Stage 01, and `c` is its
best clear time in ms (`324773` = the `05:24.77` MISSION SELECT shows).
- **Refuted**: every GHAD scalar as stage/difficulty (16 elements probed), and
"stage = filled `SHAB` count + 1".
### Formats
- **T8aD 96 % → 100 %** of the disc: a surface is a list of **sub-rectangles**
(`dst X, dst Y, w, h` per rectangle), not a 256 grid. The "~15 % variants" were
a wrong model.
- **LSTA**: the count was never unreliable — it counts **sprites *and* `PRMD`
primitives** (64/64 exact).
- **RATC**: "one level deep" is not a limitation; nested records are **leaves
that reference siblings by name** (10 144/10 148 resolve).
- **UI screens are fully reconstructible from their bundle** — element list +
order (declaration table, with a **parent index**) and placement/animation
(keyframe region). **Validated against the running game to ±2 px.**
- **Movie ↔ subtitle ↔ voice link solved statically** (101 movies) — `INDEX` had
it filed as needing the running game.
- **XPR2 channel order confirmed** against the game (hue 23.3° vs 9.3°).
### Meshes — the user-reported viewer bug
- Root-caused, **after one wrong turn I corrected in place**: the giant slab on
`e106` is not a stray volume but an **XBG7 mis-decode** — the same resource is a
49×23×42 turret in 11 containers and 1600×2100×4800 in 3.
- **New detector**: a resource shared across containers must decode to the same
bounds. **125 of 681** shared resources fail that check — a measured lower
bound on *silent* mis-decodes (distinct from the 814 honest declines).
## Two disc defects found
`SUBTITLE_S12B.tbl` (referenced by the movie table, present in **no** language)
and `pmbase.t32` (placed by `pmbase.rat`, present **nowhere**). A reimplementation
should skip a missing asset rather than treat it as a decode failure.
## Process notes worth keeping
- Several "the data is inconsistent" comments meant **our model was incomplete**
(T8aD variants, the LSTA count). Re-test such notes rather than routing around
them.
- A test that walks the *oracle's* items and looks each up in our output **can
only fail one way** — it never sees extras. That shape hid the ship bug and,
earlier, `include_external`.
- When a diagnosis has eliminated every hypothesis and the last step is *a
visual*, do the visual first. Three iterations went by before a 30-second
render showed it.

View File

@@ -0,0 +1,255 @@
# The Arsenal develop economy, and what the save's blob indexes
**2026-08-11.** The save file's 54-byte blob was shown to be per-item development
state by [a runtime differential](structures/savegame-format.md#the-develop-differential-one-weapon-three-fields) —
one weapon bought, two entries moved, `2 → 4` for the item and `0 → 2` for the
successor. That named the *values*. This note names the *index space*, and in
passing recovers the whole develop economy from the disc.
## Where the Arsenal gets its data
`dat/GP_HANGAR_ARSENAL.pak` carries one screen-config record per language whose
fields point at the rest:
```
PATH = dat\GP_HANGAR_ARSENAL.pak+eng\
WEAPON = weapon.tbl STRINGS = strings.tbl
WEAPON_CATEGORIES = 8 Detail_Window_Known / Detail_Window_Unknown
ConditionToDevelop = 757,228 WeaponDesc = 734,502 Range = 891,73 …
```
`WEAPON_CATEGORIES = 8` is the eight tabs the screen cycles with LB/RB (GUN,
BEAM, LASER, MULTIPURPOSE MISSILE, ANTI-SHIP MISSILE, BOMB/ROCKET, CANNON,
SPECIAL). The `…= x,y` fields are screen positions for that screen's labels —
`ConditionToDevelop` is *where the conditions text is drawn*, not a condition.
### `eng\weapon.tbl` — the item table (IDXD, schema `0x03c244b5`, 66 records)
Its string pool opens with a stage list, then the literal key `WEAPONS`
followed by the item ids **in table order**:
```
No_Equipment, Machiene_Cannon_MG1, Machiene_Cannon_MG2H, Machiene_Cannon_MG3,
Machiene_Cannon_MG5H, Broad_Sword_SG1, Swing_Sword_SG2H, Twin_Sword_SG3II,
Frail_GP37, Stiletto_BG1, Dagger_BG2, Rapier_BG4H, Pilum_BP, … , Wep_83,
Wep_84, Wep_85, NullWeapon_Arm1, NullWeapon_Arm2, NullWeapon_Arm3
```
The ids are grouped by the eight categories in the same order the screen shows
them — verified item-for-item against the running game (see the all-owned probe
below). Note one **coincidence that cost time**: the run `No_Equipment … Wep_83`
is also 54 entries, the save blob's length, which invites the conclusion that this
list *is* the blob's index space. It is not — the two agree only up to index 32.
The blob follows `strings.tbl`'s order, which carries items this list omits.
Each item then has a record: `Size, Weight, Range, Power, Speed, Stage,
MissionObjective, Dependency, Points`. For the **first** record all of it reads
straight out, and it matches the running game exactly:
| field | disc | in-game DATA SHEET for Light Machine Gun MG I |
|---|---|---|
| Range | `D` | `Range Class D` |
| Power | `E` | `Damage Class E` |
| Speed | `-` | `Speed Class ` |
| Weight | `0.3` | `Weight Class Light` |
| Points | `4000` | `4000 P` on the develop row |
**Caveat, and it is a real one:** IDXD string pools store each distinct string
*once*, so from the second record onward every value that repeats an earlier
string is absent from the token stream. Record 2 (MG2H) shows only its unique
values — `0.4` and `3000` — and record 6 shows no number at all because its cost
had already been seen. So `weapon.tbl`'s per-item fields cannot be read from the
pool alone; they need the binary node/index region, which is still undecoded
(see the module docs in `idxd.rs`). The prose table below is the practical
substitute.
### `eng\strings.tbl` — the economy in prose (IXUD, UTF-16BE)
The same pak's string table holds, per item: the internal id, the display name,
the description, and a **"Conditions to obtain …"** block that spells out the
gate and the price:
> Conditions to obtain Light Swivel Machine Gun MG2H — Completed development of
> the Light Machine Gun MG1 — Must spend 3000 points to develop
All 60 of them are extracted to
[`captures/arsenal-develop-conditions.csv`](captures/arsenal-develop-conditions.csv)
with the stage gate, the cost and the prerequisite split out. The shape of the
economy:
- gates are **stage completion** (`Complete Stage 1 … 15`), **a predecessor
item** (`Completed development of the …`), or **an ace kill** (`Shoot down the
ace pilot in Stage 11/13/14`);
- costs run 3 000 → 350 000 points, and **twenty items have no cost at all**
(`Tomahawk Alpha Rail Gun — Complete Stage 1`). Those are still *bought*, for
**0 P** — see the probe below, which caught one at `0 P` — which is why they
read as `Developed` in a list the player never spent points in;
- two items are anomalies worth flagging: `Adhesive Mine B2A` says "Must spend
points to develop" with **no number**, and ten late entries (`Ballista GSH`,
`Designator LH`, `Smoke Marker Launcher`, `Bumble UV`, `Ballista 24 Rocket
Launcher`, `Thrush 220AM`, `Divider L3GP`, `Mace GP25H`, `Thor Gun System`,
`Spitfire BX`) have a conditions *header* and no conditions — ❔ cut content or
non-player weapons.
## How the first 32 entries were confirmed
Predicting the save state from the conditions and comparing against the actual
blob is a strong test, because it is made **before** looking at the blob. At the
captured state (Stage 1 complete, Stage 02 at standby, 4101 P) the conditions say
exactly six items are developable — Light Machine Gun MG1, Broad Sword SG1,
Dagger BG2, Pilum BP, Hound SMH, Dart 23 Rocket — and the blob's **six** `2`s sit
at WEAPONS-order indices **1, 5, 10, 12, 27, 31**, which are those six items, in
order. Nothing had to be fitted.
Indices 032 are the same item in either order, so this table stands unchanged
under the final mapping.
| blob | value | item | confirmed by |
|---|---|---|---|
| 0 | 4 | `No_Equipment` | always available |
| 1 | 2→4 | `Machiene_Cannon_MG1` | the differential: bought for 4000 P |
| 2 | 0→2 | `Machiene_Cannon_MG2H` | the differential: announced as newly developable |
| 5 | 2 | `Broad_Sword_SG1` | `BROAD SWORD SG1 5000P`, **below the fold** in the GUN list |
| 9 | 4 | `Stiletto_BG1` | `Developed`; "Initially Mounted"; mounted as NOSE WEAPON |
| 10 | 2 | `Dagger_BG2` | `DAGGER BG2 5000P` |
| 12 | 2 | `Pilum_BP` | `PILUM BP 6000P` |
| 21 | 4 | `Falcon_9AM` | `Developed`; "Initially Mounted"; mounted as MAIN WEAPON 1 |
| 22 | 4 | `Buzzard_10AM` | `Developed`; free at Stage 1 |
| 26 | 4 | `Terrier_SMH` | `Developed`; free at Stage 1 |
| 27 | 2 | `Hound_SMH` | `HOUND SMH 10000P` |
| 31 | 2 | `Dirt_23_Rocket` | `DART 23 ROCKET 3500P` ("Dart" is the localised "Dirt") |
Twelve concordances, no contradiction, over indices 031.
## The full index space ✅ — it is the **localisation** order, cut items included
Written after the probes below, which settled it. The blob is **not** indexed by
`weapon.tbl`'s `WEAPONS` id list. It is indexed by the order the items appear in
`strings.tbl` — the same order, *plus* the handful of items that exist only there:
`Adhesive Mine B2A` (a "Conditions to obtain" block whose cost is missing) and the
four late entries with a conditions *header* and no conditions. Those never appear
in the Arsenal, but they **hold slots in the save**, and that is the whole reason
the tail looked broken.
| blob | block | items (display names, in order) |
|---|---|---|
| 0 | — | `No_Equipment` |
| 18 | GUN | Light Machine Gun MG1, Light Swivel MG2H, Heavy MG3, Heavy Swivel MG5H, Broad Sword SG1, Swing Sword SG2H, Twin Sword SG3II, Flail GP37 |
| 916 | BEAM | **Stiletto BG1** ⌾, Dagger BG2, Rapier BG4H, Pilum BP, Multi Pike BP, Spear HBP, Long Spear HBP, Gray Head T76H |
| 1720 | LASER | Saber LG1, Twin Saber LG2H, Needle L1GP, Fire Arrow L2GP |
| 2125 | MPM | **Falcon 9AM** ⌾, Buzzard 10AM, Hawk 75AM, Condor 105AM, Eagle 120AM |
| 2630 | ASM | Terrier SMH, Hound SMH, Pointer SM, Piranha T53, White Shark T53R |
| 3138 | BOMB/ROCKET | **Dart 23 Rocket** ⌾, Arrow 27 Rocket, *Adhesive Mine B2A — never displayed*, EMP Mine B8E, Laser Mine B9L, Cauldron 50 Rocket, Cluster Mine B10, Maelstrom Bomb |
| 3947 | CANNON | **Tomahawk Alpha Rail Gun** ⌾, Sling 75KG, Glaive 120mm Cannon, Arbalest 155KG, Monoceros Long Cannon, Grav Cannon XGS, *+ three never-displayed slots* |
| 4853 | SPECIAL | **Jamming System** ⌾, Shield Doubler, Booster, Fire Control System, Regenerator, Cartridge Holder |
⌾ = pinned by an anchor: `9`, `21`, `39` and `48` were each **written into a save by
hand** and read back off the screen; `31` is the Dart 23 Rocket's price row in the
untouched save. The array ends exactly at 53 with the last SPECIAL item, with
nothing left over — 8+8+4+5+5+8+9+6 plus `No_Equipment` is 54.
The three never-displayed CANNON-block slots are three of `Ballista GSH`,
`Designator LH`, `Smoke Marker Launcher`, `Bumble UV` — the four cut entries
`strings.tbl` lists between Grav Cannon XGS and Jamming System. **Which three** is
🟡 undetermined and does not matter for reading a save; nothing displays them.
**This explains every anomaly in the retail save.** Its `4`s at 33 and at 45/46/47
are the cut items — `Adhesive Mine B2A` and three of the four above — shipped
flagged as owned. They never render, so no player ever sees them, and they are
exactly the five "unexplained" owned entries that made the tail look wrong. The
Tomahawk reading `Developed` at `blob[39]` while `weapon.tbl` puts it at 38 was
the same off-by-N, seen from the other side.
## How the tail was actually settled (and what was wrong first)
Past index 31 the `weapon.tbl` alignment fails, and it fails against the screen,
not against a theory — this is the evidence that sent the investigation to the
localisation order above:
- `Tomahawk_a_Rail_Gun` is WEAPONS index **38** and the CANNON list shows it
`Developed` (it is free once Stage 1 is complete) — but **blob[38] = 0**.
- The blob's remaining `4`s are at **33, 39, 45, 46, 47**. In WEAPONS order those
are `EMP_Mine_B8E`, `Sling_75KG`, `Shield_Doubler`, `Booster`,
`FireControlSystem` — and **every one of them is shown as not developed**:
BOMB/ROCKET lists only `DART 23 ROCKET 3500P`, CANNON only the Tomahawk, and
**the SPECIAL tab is entirely empty** (all rows dashed). Their conditions agree
— Shield Doubler needs Stage 12, Booster an ace kill in Stage 11, FCS Stage 6.
So five `4`s in the tail correspond to nothing the Arsenal reports as owned, and
one genuinely-owned item reads `0`. A single `+1` shift does not repair it
either: `blob[39] = 4` would put the Tomahawk right, but then `blob[33] = 4`
lands on `Arrow_27_Rocket` (Stage 2 + 5000 P, unreachable here) and 45/46/47
still land on locked SPECIAL items.
### Tested actively, with a hand-written save
Waiting for a mission payout was not necessary. The save container's derived
fields turned out to be reproducible (see
[`savegame_edit.py`](../../tools/re-capture/savegame_edit.py) — the whole
container re-wraps **byte-identically**), so the blob could be *written* and the
result read off the screen. A probe save was built in our own throwaway slot 03
with the blob zeroed except `0, 9, 21, 33, 38, 45 = 4` and `39, 46 = 2`, and it
**loaded**.
What it showed:
- **The controls rendered.** `9` → BEAM shows `STILETTO BG1 Developed`; `21`
MULTIPURPOSE MISSILE shows `FALCON 9AM Developed`. So a hand-written `4` does
reach the screen, and indices 9 and 21 are those items — now by experiment,
not by correlation.
- **The tail probes rendered nothing.** `33` should have made a BOMB/ROCKET row
`Developed` (row 3 of that list, on screen, not below the fold) — it stayed
dashed. `45` should have made a SPECIAL row `Developed` — the SPECIAL tab
stayed entirely empty. And `38` should have been the Tomahawk — instead the
CANNON list showed `TOMAHAWK ALPHA RAIL GUN — 0 P`, i.e. *not owned*.
- **Clearing the real save's tail `4`s cost the Tomahawk its status.** In the
unedited save the Tomahawk reads `Developed` while `blob[38] = 0`; the probe
cleared `{22, 26, 39, 46, 47}` and the Tomahawk stopped being owned — so its
flag is one of the cleared entries, with **39** the positional candidate. A
uniform `+1` shift past index 32 would explain that, but it fails elsewhere:
under it the real save's `45/46/47` are Chaff Flare Dispencer / Shield Doubler
/ Booster, and the SPECIAL tab is empty in that same save.
Three further probes settled it, and the reasoning is worth keeping because the
first read of the same evidence was wrong.
1. **Every slot owned.** With all 54 entries set to `4`, every tab filled and the
lists **wrap**, which gives exact counts: GUN 8, BEAM 8, LASER 4, MPM 5, ASM 5,
BOMB/ROCKET **7**, CANNON 6, SPECIAL 6 — 43 items — and the display order is
`weapon.tbl`'s order, item for item. Note what this probe *cannot* do: with
everything owned, any surjective mapping looks the same. It bounds, it does not
pin. It also killed the "gate-unmet flags are suppressed" idea outright —
Maelstrom Bomb (Stage 6) and Grav Cannon XGS (Stage 12) both rendered
`Developed` at a Stage-2 save.
2. **One slot owned: `39`.** `blob = 0` except `9` (control) and `39` → BEAM showed
`STILETTO BG1 Developed` **and CANNON showed `TOMAHAWK ALPHA RAIL GUN
Developed`**. So the CANNON block starts at 39, not 38: exactly one slot more
than the display between Dart 23 (31) and the Tomahawk.
3. **One slot owned: `48`.** `blob = 0` except `39` and `48` → SPECIAL showed
`JAMMING SYSTEM Developed`. That fixes the SPECIAL base, and with six SPECIAL
items the array closes exactly at 53.
The earlier probe's `45 = 4` leaving SPECIAL empty — which had looked like the
mapping failing — is simply a cut item: 45 is in the CANNON block's
never-displayed tail, not in SPECIAL at all.
### Two behaviours the probe exposed
- **`2` is derived, not stored.** On load the title recomputes which items are
developable from its own conditions and *announces the difference* — zeroing
Light Machine Gun MG1 and Broad Sword SG1 produced "You can now develop Broad
Sword …" and both came back priced in the list. Only the owned (`4`) entries
are authoritative state; writing `2` is pointless, and writing `0` over an
item whose conditions are met is undone at load.
- **The free items are bought for zero, not granted.** `TOMAHAWK ALPHA RAIL GUN
— 0 P` is what an unowned no-cost item looks like. That is the real reason a
save where the player never spent points still shows items as `Developed`
(this note previously said "granted" — the mechanism is a 0 P purchase).
## Evidence
- [`captures/arsenal-develop-conditions.csv`](captures/arsenal-develop-conditions.csv) — all 60 conditions blocks.
- [`captures/arsenal-categories-all.png`](captures/arsenal-categories-all.png) — the eight category tabs.
- [`captures/arsenal-gun-below-fold.png`](captures/arsenal-gun-below-fold.png) — Broad Sword SG1, the entry that is not visible without scrolling.
- [`captures/arsenal-probe-save-result.png`](captures/arsenal-probe-save-result.png) — the hand-written save's result: controls at 9/21 render `Developed`, the tail probes render nothing, and the Tomahawk shows `0 P`.
- [`captures/arsenal-gun-list-predevelop.png`](captures/arsenal-gun-list-predevelop.png) · [`captures/arsenal-mg1-developed.png`](captures/arsenal-mg1-developed.png) — the differential itself.

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 KiB

View File

@@ -0,0 +1,61 @@
item,stage_required,points_cost,other_conditions,raw_text
Light Machine Gun MG1,1,4000,,Conditions to obtain Light Machine Gun MG1 - Complete Stage 1 - Must spend 4000 points to develop
Light Swivel Machine Gun MG2H,,3000,Completed development of the Light Machine Gun MG1,Conditions to obtain Light Swivel Machine Gun MG2H - Completed development of the Light Machine Gun MG1 - Must spend 3000 points to develop
Heavy Machine Gun MG3,6,6000,,Conditions to obtain Heavy Machine Gun MG3 - Complete Stage 6 - Must spend 6000 points to develop
Heavy Swivel Machine Gun MG5H,,10000,Completed development of the Heavy Machine Gun MG3,Conditions to obtain Heavy Swivel Machine Gun MG5H - Completed development of the Heavy Machine Gun MG3 - Must spend 10000 points to develop
Broad Sword SG1,1,5000,,Conditions to obtain Broad Sword SG1 - Complete Stage 1 - Must spend 5000 points to develop
Swing Sword SG2H,,10000,Completed development of the Twin Sword SG3II,Conditions to obtain Swing Sword SG2H - Completed development of the Twin Sword SG3II - Must spend 10000 points to develop
Twin Sword SG3II,,8000,Completed development of the Broad Sword SG1,Conditions to obtain Twin Sword SG3II - Completed development of the Broad Sword SG1 - Must spend 8000 points to develop
Flail GP37,6,,,Conditions to obtain Flail GP37 - Complete Stage 6
Stiletto BG1,,,Initially Mounted,Conditions to obtain Stiletto BG1 - Initially Mounted
Dagger BG2,,5000,Development Possible,Conditions to obtain Dagger BG2 - Development Possible - Must spend 5000 points to develop
Rapier BG4H,,12000,Completed development of the Dagger BG2,Conditions to obtain Rapier BG4H - Completed development of the Dagger BG2 - Must spend 12000 points to develop
Pilum BP,,6000,Development Possible,Conditions to obtain Pilum BP - Development Possible - Must spend 6000 points to develop
Multi Pike BP,,30000,Completed development of the Pilum BP,Conditions to obtain Multi Pike BP - Completed development of the Pilum BP - Must spend 30000 points to develop
Spear HBP,,10000,Completed development of the Multi Pike BP,Conditions to obtain Spear HBP - Completed development of the Multi Pike BP - Must spend 10000 points to develop
Long Spear HBP,7,350000,Completed development of the Gray Head T76H,Conditions to obtain Long Spear HBP - Complete Stage 7 - Completed development of the Gray Head T76H - Must spend 350000 points to develop
Gray Head T76H,,25000,Completed development of the Spear HBP,Conditions to obtain Gray Head T76H - Completed development of the Spear HBP - Must spend 25000 points to develop
Saber LG1,14,,,Conditions to obtain Saber LG1 - Complete Stage 14
Twin Saber LG2H,15,,,Conditions to obtain Twin Saber LG2H - Complete Stage 15
Needle L1GP,6,10000,,Conditions to obtain Needle L1GP - Complete Stage 6 - Must spend 10000 points to develop
Fire Arrow L2GP,,20000,Completed development of the Needle L1GP,Conditions to obtain Fire Arrow L2GP - Completed development of the Needle L1GP - Must spend 20000 points to develop
Falcon 9AM,,,Initially Mounted,Conditions to obtain Falcon 9AM - Initially Mounted
Buzzard 10AM,1,,,Conditions to obtain Buzzard 10AM - Complete Stage 1
Hawk 75AM,6,10000,Possess Buzzard 10AM,Conditions to obtain Hawk 75AM - Complete Stage 6 - Possess Buzzard 10AM - Must spend 10000 points to develop
Condor 105AM,6,,,Conditions to obtain Condor 105AM - Complete Stage 6
Eagle 120AM,12,15000,Completed development of the Hawk 75AM,Conditions to obtain Eagle 120AM - Complete Stage 12 - Completed development of the Hawk 75AM - Must spend 15000 points to develop
Terrier SMH,1,,,Conditions to obtain Terrier SMH - Complete Stage 1
Hound SMH,,10000,Development Possible,Conditions to obtain Hound SMH - Development Possible - Must spend 10000 points to develop
Pointer SM,,40000,Completed development of Piranha T53,Conditions to obtain Pointer SM - Completed development of Piranha T53 - Must spend 40000 points to develop
Piranha T53,,25000,Obtain White Shark T53R,Conditions to obtain Piranha T53 - Obtain White Shark T53R - Must spend 25000 points to develop
White Shark T53R,6,,,Conditions to obtain White Shark T53R - Complete Stage 6
Dart 23 Rocket,1,3500,,Conditions to obtain Dart 23 Rocket - Complete Stage 1 - Must spend 3500 points to develop
Arrow 27 Rocket,2,5000,,Conditions to obtain Arrow 27 Rocket - Complete Stage 2 - Must spend 5000 points to develop
Adhesive Mine B2A,3,MISSING,,Conditions to obtain Adhesive Mine B2A - Complete Stage 3 - Must spend points to develop
EMP Mine B8E,6,50000,,Conditions to obtain EMP Mine B8E - Complete Stage 6 - Must spend 50000 points to develop
Laser Mine B9L,6,15000,,Conditions to obtain Laser Mine B9L - Complete Stage 6 - Must spend 15000 points to develop
Cauldron 50 Rocket,14,,,Conditions to obtain Cauldron 50 Rocket - Complete Stage 14
Cluster Mine B10,6,5000,,Conditions to obtain Cluster Mine B10 - Complete Stage 6 - Must spend 5000 points to develop
Maelstrom Bomb,6,200000,,Conditions to obtain Maelstrom Bomb - Complete Stage 6 - Must spend 200000 points to develop
Tomahawk Alpha Rail Gun,1,,,Conditions to obtain Tomahawk Alpha Rail Gun - Complete Stage 1
Sling 75KG,2,5000,,Conditions to obtain Sling 75KG - Complete Stage 2 - Must spend 5000 points to develop
Glaive 120mm Cannon,6,,,Conditions to obtain Glaive 120mm Cannon - Complete Stage 6
Arbalest 155KG,6,25000,,Conditions to obtain Arbalest 155KG - Complete Stage 6 - Must spend 25000 points to develop
Monoceros Long Cannon,,,Shoot down the ace pilot in Stage 14,Conditions to obtain Monoceros Long Cannon - Shoot down the ace pilot in Stage 14
Grav Cannon XGS,12,60000,,Conditions to obtain Grav Cannon XGS - Complete Stage 12 - Must spend 60000 points to develop
Ballista GSH,,,,Conditions to obtain Ballista GSH
Designator LH,,,,Conditions to obtain Designator LH
Smoke Marker Launcher,,,,Conditions to obtain Smoke Marker Launcher
Bumble UV,,,,Conditions to obtain Bumble UV
Jamming System,3,15000,,Conditions to obtain Jamming System - Complete Stage 3 - Must spend 15000 points to develop
Shield Doubler,12,50000,,Conditions to obtain Shield Doubler - Complete Stage 12 - Must spend 50000 points to develop
Booster,,,Shoot down the ace pilot in Stage 11,Conditions to obtain Booster - Shoot down the ace pilot in Stage 11
Fire Control System,6,15000,,Conditions to obtain Fire Control System - Complete Stage 6 - Must spend 15000 points to develop
Regenerator,12,100000,,Conditions to obtain Regenerator - Complete Stage 12 - Must spend 100000 points to develop
Cartridge Holder,,,Shoot down the ace pilot in Stage 13,Conditions to obtain Cartridge Holder - Shoot down the ace pilot in Stage 13
Ballista 24 Rocket Launcher,,,,Conditions to obtain Ballista 24 Rocket Launcher
Thrush 220AM,,,,Conditions to obtain Thrush 220AM
Divider L3GP,,,,Conditions to obtain Divider L3GP
Mace GP25H,,,,Conditions to obtain Mace GP25H
Thor Gun System,,,,Conditions to obtain Thor Gun System
Spitfire BX,,,,Conditions to obtain Spitfire BX
1 item stage_required points_cost other_conditions raw_text
2 Light Machine Gun MG1 1 4000 Conditions to obtain Light Machine Gun MG1 - Complete Stage 1 - Must spend 4000 points to develop
3 Light Swivel Machine Gun MG2H 3000 Completed development of the Light Machine Gun MG1 Conditions to obtain Light Swivel Machine Gun MG2H - Completed development of the Light Machine Gun MG1 - Must spend 3000 points to develop
4 Heavy Machine Gun MG3 6 6000 Conditions to obtain Heavy Machine Gun MG3 - Complete Stage 6 - Must spend 6000 points to develop
5 Heavy Swivel Machine Gun MG5H 10000 Completed development of the Heavy Machine Gun MG3 Conditions to obtain Heavy Swivel Machine Gun MG5H - Completed development of the Heavy Machine Gun MG3 - Must spend 10000 points to develop
6 Broad Sword SG1 1 5000 Conditions to obtain Broad Sword SG1 - Complete Stage 1 - Must spend 5000 points to develop
7 Swing Sword SG2H 10000 Completed development of the Twin Sword SG3II Conditions to obtain Swing Sword SG2H - Completed development of the Twin Sword SG3II - Must spend 10000 points to develop
8 Twin Sword SG3II 8000 Completed development of the Broad Sword SG1 Conditions to obtain Twin Sword SG3II - Completed development of the Broad Sword SG1 - Must spend 8000 points to develop
9 Flail GP37 6 Conditions to obtain Flail GP37 - Complete Stage 6
10 Stiletto BG1 Initially Mounted Conditions to obtain Stiletto BG1 - Initially Mounted
11 Dagger BG2 5000 Development Possible Conditions to obtain Dagger BG2 - Development Possible - Must spend 5000 points to develop
12 Rapier BG4H 12000 Completed development of the Dagger BG2 Conditions to obtain Rapier BG4H - Completed development of the Dagger BG2 - Must spend 12000 points to develop
13 Pilum BP 6000 Development Possible Conditions to obtain Pilum BP - Development Possible - Must spend 6000 points to develop
14 Multi Pike BP 30000 Completed development of the Pilum BP Conditions to obtain Multi Pike BP - Completed development of the Pilum BP - Must spend 30000 points to develop
15 Spear HBP 10000 Completed development of the Multi Pike BP Conditions to obtain Spear HBP - Completed development of the Multi Pike BP - Must spend 10000 points to develop
16 Long Spear HBP 7 350000 Completed development of the Gray Head T76H Conditions to obtain Long Spear HBP - Complete Stage 7 - Completed development of the Gray Head T76H - Must spend 350000 points to develop
17 Gray Head T76H 25000 Completed development of the Spear HBP Conditions to obtain Gray Head T76H - Completed development of the Spear HBP - Must spend 25000 points to develop
18 Saber LG1 14 Conditions to obtain Saber LG1 - Complete Stage 14
19 Twin Saber LG2H 15 Conditions to obtain Twin Saber LG2H - Complete Stage 15
20 Needle L1GP 6 10000 Conditions to obtain Needle L1GP - Complete Stage 6 - Must spend 10000 points to develop
21 Fire Arrow L2GP 20000 Completed development of the Needle L1GP Conditions to obtain Fire Arrow L2GP - Completed development of the Needle L1GP - Must spend 20000 points to develop
22 Falcon 9AM Initially Mounted Conditions to obtain Falcon 9AM - Initially Mounted
23 Buzzard 10AM 1 Conditions to obtain Buzzard 10AM - Complete Stage 1
24 Hawk 75AM 6 10000 Possess Buzzard 10AM Conditions to obtain Hawk 75AM - Complete Stage 6 - Possess Buzzard 10AM - Must spend 10000 points to develop
25 Condor 105AM 6 Conditions to obtain Condor 105AM - Complete Stage 6
26 Eagle 120AM 12 15000 Completed development of the Hawk 75AM Conditions to obtain Eagle 120AM - Complete Stage 12 - Completed development of the Hawk 75AM - Must spend 15000 points to develop
27 Terrier SMH 1 Conditions to obtain Terrier SMH - Complete Stage 1
28 Hound SMH 10000 Development Possible Conditions to obtain Hound SMH - Development Possible - Must spend 10000 points to develop
29 Pointer SM 40000 Completed development of Piranha T53 Conditions to obtain Pointer SM - Completed development of Piranha T53 - Must spend 40000 points to develop
30 Piranha T53 25000 Obtain White Shark T53R Conditions to obtain Piranha T53 - Obtain White Shark T53R - Must spend 25000 points to develop
31 White Shark T53R 6 Conditions to obtain White Shark T53R - Complete Stage 6
32 Dart 23 Rocket 1 3500 Conditions to obtain Dart 23 Rocket - Complete Stage 1 - Must spend 3500 points to develop
33 Arrow 27 Rocket 2 5000 Conditions to obtain Arrow 27 Rocket - Complete Stage 2 - Must spend 5000 points to develop
34 Adhesive Mine B2A 3 MISSING Conditions to obtain Adhesive Mine B2A - Complete Stage 3 - Must spend points to develop
35 EMP Mine B8E 6 50000 Conditions to obtain EMP Mine B8E - Complete Stage 6 - Must spend 50000 points to develop
36 Laser Mine B9L 6 15000 Conditions to obtain Laser Mine B9L - Complete Stage 6 - Must spend 15000 points to develop
37 Cauldron 50 Rocket 14 Conditions to obtain Cauldron 50 Rocket - Complete Stage 14
38 Cluster Mine B10 6 5000 Conditions to obtain Cluster Mine B10 - Complete Stage 6 - Must spend 5000 points to develop
39 Maelstrom Bomb 6 200000 Conditions to obtain Maelstrom Bomb - Complete Stage 6 - Must spend 200000 points to develop
40 Tomahawk Alpha Rail Gun 1 Conditions to obtain Tomahawk Alpha Rail Gun - Complete Stage 1
41 Sling 75KG 2 5000 Conditions to obtain Sling 75KG - Complete Stage 2 - Must spend 5000 points to develop
42 Glaive 120mm Cannon 6 Conditions to obtain Glaive 120mm Cannon - Complete Stage 6
43 Arbalest 155KG 6 25000 Conditions to obtain Arbalest 155KG - Complete Stage 6 - Must spend 25000 points to develop
44 Monoceros Long Cannon Shoot down the ace pilot in Stage 14 Conditions to obtain Monoceros Long Cannon - Shoot down the ace pilot in Stage 14
45 Grav Cannon XGS 12 60000 Conditions to obtain Grav Cannon XGS - Complete Stage 12 - Must spend 60000 points to develop
46 Ballista GSH Conditions to obtain Ballista GSH
47 Designator LH Conditions to obtain Designator LH
48 Smoke Marker Launcher Conditions to obtain Smoke Marker Launcher
49 Bumble UV Conditions to obtain Bumble UV
50 Jamming System 3 15000 Conditions to obtain Jamming System - Complete Stage 3 - Must spend 15000 points to develop
51 Shield Doubler 12 50000 Conditions to obtain Shield Doubler - Complete Stage 12 - Must spend 50000 points to develop
52 Booster Shoot down the ace pilot in Stage 11 Conditions to obtain Booster - Shoot down the ace pilot in Stage 11
53 Fire Control System 6 15000 Conditions to obtain Fire Control System - Complete Stage 6 - Must spend 15000 points to develop
54 Regenerator 12 100000 Conditions to obtain Regenerator - Complete Stage 12 - Must spend 100000 points to develop
55 Cartridge Holder Shoot down the ace pilot in Stage 13 Conditions to obtain Cartridge Holder - Shoot down the ace pilot in Stage 13
56 Ballista 24 Rocket Launcher Conditions to obtain Ballista 24 Rocket Launcher
57 Thrush 220AM Conditions to obtain Thrush 220AM
58 Divider L3GP Conditions to obtain Divider L3GP
59 Mace GP25H Conditions to obtain Mace GP25H
60 Thor Gun System Conditions to obtain Thor Gun System
61 Spitfire BX Conditions to obtain Spitfire BX

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 KiB

View File

@@ -0,0 +1,50 @@
=== eng\prmain_scr.prt ===
23 elements
# element parent kind pivot kf placement
0 preff01.t32 - 0x0 (164,156) 5 rest (256,214) t=6..22 [6:256,214 22:256,214 31:256,214 42:256,214 1:256,214]
1 preff02.t32 - 0x0 (155,175) 7 rest (156,121) t=8..37 [4:305,240 6:193,150 7:165,128 8:156,121 37:155,120 44:155,120 2:305,240]
2 preff03.t32 - 0x0 (155,175) 7 rest (374,269) t=8..37 [4:225,150 6:337,240 7:365,262 8:374,269 37:375,270 44:375,270 3:225,150]
3 preff04.t32 - 0x0 (247,237) 6 rest (173,133) t=8..37 [4:173,133 6:173,133 8:173,133 37:173,133 44:173,133 4:173,133]
4 prwinbase.t32 - 0x0 (136,130) 5 rest (284,240) t=14..35 [6:284,240 14:284,240 35:284,240 43:284,240 5:284,240]
5 prbtn1.rat - 0x3002 (28,14) 5 rest (242,166) t=16..33 [10:242,166 16:242,166 33:242,166 37:242,166 6:242,166]
6 prbtn2.rat - 0x3002 (43,14) 5 rest (242,220) t=17..33 [11:242,220 17:242,220 33:242,220 37:242,220 7:242,220]
7 prbtn3.rat - 0x3002 (58,14) 5 rest (242,276) t=18..33 [12:242,276 18:242,276 33:242,276 37:242,276 8:242,276]
8 prbtn4.rat - 0x3002 (89,14) 5 rest (242,331) t=19..33 [13:242,331 19:242,331 33:242,331 37:242,331 9:242,331]
9 prbtn5.rat - 0x3002 (89,14) 5 rest (242,385) t=20..33 [14:242,385 20:242,385 33:242,385 37:242,385 10:242,385]
10 prbtn6.rat - 0x3002 (104,14) 5 rest (242,441) t=21..33 [15:242,441 21:242,441 33:242,441 37:242,441 11:242,441]
11 prbtn7.rat - 0x3002 (58,14) 5 rest (242,496) t=22..33 [16:242,496 22:242,496 33:242,496 37:242,496 12:242,496]
12 prbtn8.rat - 0x3002 (30,14) 5 rest (242,551) t=23..33 [17:242,551 23:242,551 33:242,551 37:242,551 13:242,551]
13 prexp1.t32 - 0x0 (277,30) 8 rest (726,143) t=31..37 [21:726,143 25:1286,143 27:866,143 28:756,143 29:731,143 31:726,143 37:726,143 14:1286,143]
14 prexp1a.t32 13 0x1 (277,30) 3 rest (1126,143) t=31..37 [31:1126,143 37:1126,143 15:1126,143]
15 prexp3.t32 - 0x0 (205,5) 5 rest (726,381) t=10..29 [10:726,381 29:726,381 31:726,381 39:726,381 16:726,381]
16 prmsg.t32 - 0x0 (330,19) 5 rest (151,645) t=21..29 [21:151,645 29:151,645 31:151,645 37:151,645 17:151,645]
17 prexp3.t32 - 0x4 (205,5) 5 rest (726,415) t=10..29 [10:726,415 29:726,415 31:726,415 39:726,415 18:726,415]
18 prexp3.t32 - 0x4 (205,5) 5 rest (726,449) t=10..29 [10:726,449 29:726,449 31:726,449 39:726,449 19:726,449]
19 prexp3.t32 - 0x4 (205,5) 5 rest (726,483) t=10..29 [10:726,483 29:726,483 31:726,483 39:726,483 20:726,483]
20 prexp3.t32 - 0x4 (205,5) 5 rest (726,517) t=10..29 [10:726,517 29:726,517 31:726,517 39:726,517 21:726,517]
21 prexp3.t32 - 0x4 (205,5) 5 rest (726,551) t=10..29 [10:726,551 29:726,551 31:726,551 39:726,551 22:726,551]
22 prexp3.t32 - 0x4 (205,5) 5 rest (726,585) t=39..1869640736 [10:726,585 29:726,585 31:726,585 39:726,585 1869640736:726,585]
=== eng\prselect_scr.prt ===
8 elements
# element parent kind pivot kf placement
0 prselect_win1.t32 - 0x0 (256,200) 10 rest (127,155) t=8..23 [4:-516,155 6:-71,155 7:81,155 8:127,155 23:134,155 24:134,155 25:127,155 27:81,155 31:-71,155 1:-516,155]
1 prselect_win2.t32 0 0x1 (256,200) 1 (135,560)
2 prselect_win1eff.t32 0 0x1 (256,200) 5 rest (71,92) t=2..14 [2:71,92 14:71,92 21:71,92 27:71,92 3:71,92]
3 prselect_win2eff.t32 0 0x1 (256,200) 5 rest (71,499) t=2..14 [2:71,499 14:71,499 21:71,499 27:71,499 4:71,499]
4 prselect_sbar.sbo 0 0x1 (256,200) 1 (614,172)
5 prselect_type_line.t32 - 0x0 (260,24) 5 rest (123,142) t=14..21 [8:123,142 14:123,142 21:123,142 25:123,142 6:123,142]
6 prselect_msg.t32 - 0x0 (468,19) 5 rest (151,645) t=11..19 [11:151,645 19:151,645 21:151,645 27:151,645 7:151,645]
7 prselect_msgbtn1.t32 - 0x2 (128,19) 5 rest (809,645) t=27..1869640736 [11:809,645 19:809,645 21:809,645 27:809,645 1869640736:809,645]
=== eng\prselect_win3.prt ===
2 elements
# element parent kind pivot kf placement
0 prselect_win3.t32 - 0x0 (245,300) 4 rest (704,39) t=10..16 [8:704,39 10:704,39 16:704,39 1:704,39]
1 prselect_win3eff.t32 - 0x0 (309,352) 4 rest (640,0) t=16..1869640736 [8:640,0 10:640,0 16:640,0 1869640736:640,0]
=== eng\prtitle.prt ===
5 elements
# element parent kind pivot kf placement
0 preff11.t32 - 0x0 (221,6) 6 rest (-160,82) t=16..35 [12:-440,82 14:-440,82 16:-160,82 35:0,82 41:0,82 1:-440,82]
1 preff12.t32 - 0x0 (75,3) 5 rest (0,72) t=20..34 [14:0,72 20:0,72 34:0,72 38:0,72 2:0,72]
2 preff13.t32 - 0x0 (53,3) 5 rest (407,78) t=22..33 [16:407,78 22:407,78 33:407,78 37:407,78 3:407,78]
3 preff14.t32 - 0x0 (52,3) 5 rest (427,68) t=24..32 [18:427,68 24:427,68 32:427,68 36:427,68 4:427,68]
4 prtitle.t32 - 0x0 (94,35) 7 rest (162,26) t=37..1869640736 [20:142,26 23:142,26 25:157,26 26:161,26 31:162,26 37:162,26 1869640736:142,26]

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

View File

@@ -0,0 +1,115 @@
id hp size_x size_y size_z kind
UN_e006_ADAN_Vindicator_MargrasF 6400 12 5 30 unit
UN_be005_ADAN_SpaceFortress 10000 2500 3100 2600 unit
UN_f001_TCAF_DeltaSaber_T 1000 10 7 29 unit
UN_f002_TCAF_DeltaSaber_W 1000 10 7 29 unit
UN_e009_ADAN_Phantom 1000 18 16 24 unit
UN_e001_ADAN_Elan_EX4 500 25 10 30 unit
UN_e011_ADAN_Attacker_B 1500 200 50 100 unit
UN_f001_TCAF_DeltaSaber_T_Ttrl 1000 10 7 29 unit
UN_f202_TCAF_Cargo 4000 1400 600 2000 unit
UN_e007_ADAN_Turret_EX4 100 20 9 22 unit
UN_e010_ADAN_Attacker_S 500 100 40 50 unit
UN_be001_ADAN_TerrafoamingUnit 10000 2600 2200 — unit
UN_e005_ADAN_ElanTypeQ_Margras 3200 24 15 38 unit
UN_e001_ADAN_Elan_GR_Violeta 1200 25 10 30 unit
UN_e004_ADAN_ElanPlus_N 800 24 10 30 unit
UN_e201_ADAN_ISCMissile 3000 300 — 2800 unit
UN_f001_TCAF_DeltaSaber_T_Player_Ttrl1 1500 10 7 29 unit
UN_f001_TCAF_DeltaSaber_T_Player_Ttrl2 1500 10 7 29 unit
UN_f003_TCAF_ArrowHead_EX4 300 10 5 20 unit
UN_f003_TCAF_ArrowHead_EX5 300 10 5 20 unit
UN_e011_ADAN_Attacker_B_HF 2250 200 50 100 unit
UN_e015_ADAN_Puppy — 7 5.5 10 unit
Ship_Test 100 20 14 29 unit
UN_e010_ADAN_Attacker_S_HF 750 100 40 50 unit
Test_ADAN_PrometheusDriver 10000 1 — — unit
UN_f001_TCAF_DeltaSaber_T_EX5 1000 10 7 29 unit
UN_e002_ADAN_Elan_N 800 20 10 30 unit
UN_e008_ADAN_TurretPlus 300 24 9 35 unit
UN_mn040_Asteroid_Big 10000 2000 3500 — unit
UN_mn500_ADAN_FloatingMine 1000 200 — — unit
UN_S04_Asteroid_cmesh_01 10000 46900 55500 13600 unit
UN_S05_Asteroid_cmesh_01 10000 10400 13000 34400 unit
UN_S04_Asteroid_cmesh_03 10000 42800 37700 47400 unit
UN_S04_Asteroid_cmesh_04 10000 59000 56900 21800 unit
UN_S05_Asteroid_cmesh_03 10000 8300 13000 19800 unit
UN_S04_Asteroid_cmesh_05 — 26000 21800 72400 unit
UN_S05_Asteroid_cmesh_04 10000 7400 15800 30100 unit
UN_e011_ADAN_Attacker_B_EX4 1500 200 50 100 unit
UN_e910_core_ADAN_GeneratorCore 10000 2000 — — unit
UN_n001_TTRL_Box 100 0.1 — — unit
UN_e006_ADAN_Vindicator_Margras 6400 12 5 30 unit
UN_e010_ADAN_Attacker_S_EX4 500 100 40 50 unit
UN_bf001_TCAF_SchlosBase 10000 2500 3100 2600 unit
UN_f001_TCAF_DeltaSaber_T_EX5_el 1000 10 7 29 unit
UN_n001_TTRL_Box_move 100 0.1 — — unit
UN_e004_ADAN_ElanPlus_NF 800 24 10 30 unit
Test_ADAN_PrometheusDriver_InsideP2_01 10000 1 — — unit
UN_e001_ADAN_Elan 500 25 10 30 unit
UN_e007_ADAN_Turret 100 20 9 22 unit
UN_e003_ADAN_ElanPlus_Margras 1600 24 10 30 unit
UN_e901_ADAN_Boss 10000 500 1700 — unit
UN_e013_ADAN_ElanPlus_Taskent 1300 24 10 30 unit
UN_e011_ADAN_Attacker_B_HF_Wayne 3000 200 50 100 unit
UN_f003_TCAF_ArrowHead 300 10 5 20 unit
UN_f004_TCAF_DeltaSaber_A_Player 1500 10 7 29 unit
UN_e010_ADAN_Attacker_S_HF_Wayne 1000 100 40 50 unit
UN_e015_ADAN_Puppy_2 — 7 5.5 10 unit
UN_S01_Asteroid_cmesh_01a — 23000 21700 13400 unit
UN_S01_Asteroid_cmesh_02a 10000 20900 24000 23800 unit
UN_S01_Asteroid_cmesh_01b — 18000 20900 14200 unit
UN_S01_Asteroid_cmesh_02b — 20400 21800 26700 unit
UN_S01_Asteroid_cmesh_03a 10000 23600 11700 30300 unit
UN_bf002_TCAF_TransitPlatform 10000 2500 3100 4600 unit
UN_e001_ADAN_Elan_GR 800 25 10 30 unit
UN_S13_Asteroid_cmesh_01a 10000 14200 10200 14700 unit
UN_S01_Asteroid_cmesh_03b — 21800 18600 37200 unit
UN_S01_Asteroid_cmesh_04a — 32800 19900 23300 unit
UN_S13_Asteroid_cmesh_01b 10000 8000 5400 16400 unit
UN_S13_Asteroid_cmesh_02a 10000 6200 5400 11300 unit
UN_S01_Asteroid_cmesh_04b — 26400 23100 19600 unit
UN_S04_Asteroid_cmesh_02a — 25100 20800 61400 unit
UN_S13_Asteroid_cmesh_02b 10000 5100 6900 10500 unit
UN_S05_Asteroid_cmesh_02a 10000 10100 13200 9100 unit
UN_S04_Asteroid_cmesh_02b 10000 25200 19700 67000 unit
UN_S05_Asteroid_cmesh_02b 10000 8700 14900 12300 unit
UN_S08_Asteroid_cmesh_01a 10000 14700 14900 21300 unit
UN_S08_Asteroid_cmesh_01b 10000 14900 14600 15800 unit
UN_S08_Asteroid_cmesh_02a 10000 17400 13400 15200 unit
UN_S04_Asteroid_cmesh_06a — 14400 20800 45900 unit
UN_S08_Asteroid_cmesh_02b 10000 16800 10700 14200 unit
UN_S08_Asteroid_cmesh_03a — 14000 10000 13700 unit
UN_S04_Asteroid_cmesh_06b 10000 14100 16200 21500 unit
UN_S04_Asteroid_cmesh_07a — 23200 14000 67100 unit
UN_S08_Asteroid_cmesh_03b 10000 13900 15100 15700 unit
UN_S04_Asteroid_cmesh_07b 10000 25300 4900 40600 unit
UN_e008_ADAN_TurretPlus_EX4 300 24 9 35 unit
UN_f001_TCAF_DeltaSaber_T_Player 1500 10 7 29 unit
UN_f003_TCAF_ArrowHead_Yoji 400 10 5 20 unit
UN_f002_TCAF_DeltaSaber_W_Player 1500 10 7 29 unit
UN_e104_ADAN_Carrier 20000 2300 1000 3300 vessel
UN_f106_TCAF_Destroyer 10000 200 — 2000 vessel
UN_e105_ADAN_Cruiser 30000 600 — 3800 vessel
UN_e101_ADAN_SDBattleship 100000 1900 2100 12300 vessel
UN_f105_TCAF_Cruiser 30000 700 — 3800 vessel
UN_f102_TCAF_LightCarrier 20000 500 — 1600 vessel
UN_e102_ADAN_BattleshipEX 50000 1900 2300 6500 vessel
UN_e107_ADAN_AAFrigate_EX4 4000 100 200 — vessel
UN_e102_ADAN_Battleship 50000 1900 2300 6500 vessel
UN_f104_TCAF_Battleship 30000 2000 — 6000 vessel
UN_f105_TCAF_Cruiser_EX5 30000 700 — 3800 vessel
UN_e108_ADAN_ASFrigateEX 4000 80 — 350 vessel
UN_f106_TCAF_Destroyer_Inv 10000 200 — 2000 vessel
UN_e107_ADAN_AAFrigate 4000 100 200 — vessel
UN_f104_TCAF_Battleship_EX5 30000 2000 — 6000 vessel
UN_f105_TCAF_Cruiser_Inv 30000 700 — 3800 vessel
UN_f102_TCAF_LightCarrier_Inv 20000 500 — 1600 vessel
UN_e108_ADAN_ASFrigate 4000 80 — 350 vessel
UN_e106_ADAN_DestroyerEX 10000 300 — 2100 vessel
UN_f101_TCAF_Acropolis 25000 400 — 1400 vessel
UN_e105_ADAN_CruiserEX 30000 600 — 3800 vessel
UN_e101_ADAN_SDBattleshipEX 100000 1900 2100 12300 vessel
UN_e106_ADAN_Destroyer 10000 300 — 2100 vessel

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,161 @@
run,turret_rule,t_s,acropolis_hull,e007_alive,e007_killed_cum
mission01,off,0,25000.0,0,0
mission01,off,10,25000.0,5,0
mission01,off,20,25000.0,6,0
mission01,off,30,25000.0,6,0
mission01,off,40,25000.0,6,0
mission01,off,50,25000.0,8,0
mission01,off,60,25000.0,11,0
mission01,off,70,25000.0,11,3
mission01,off,80,25000.0,8,3
mission01,off,90,25000.0,8,3
mission01,off,100,25000.0,10,3
mission01,off,110,25000.0,14,3
mission01,off,120,25000.0,16,3
mission01,off,130,25000.0,17,3
mission01,off,140,25000.0,20,3
mission01,off,150,25000.0,23,3
mission01,off,160,25000.0,26,4
mission01,off,170,24509.5,33,4
mission01,off,180,24509.5,37,4
mission01,off,190,24419.5,38,5
mission01,off,200,24212.5,41,5
mission01,off,210,23447.5,40,5
mission01,off,220,23447.5,40,5
mission01,off,220,23447.5,40,5
mission01,off,230,23447.5,41,5
mission01,off,230,23447.5,41,5
mission01,off,240,22912.0,43,5
mission01,off,240,22867.0,43,5
mission01,off,250,22667.0,42,6
mission01,off,250,22647.0,42,6
mission01,off,260,22334.5,44,6
mission01,off,260,22177.9,44,6
mission01,off,270,21101.2,46,6
mission01,off,270,21101.2,45,6
mission01,off,280,20292.6,46,6
mission01,off,280,20279.1,46,6
mission01,off,290,19598.5,58,6
mission01,off,290,19598.5,58,6
mission01,off,300,18725.2,58,6
mission01,off,300,18658.5,47,6
mission01,off,310,18231.9,47,6
mission01,off,310,18231.9,47,6
mission01,off,320,17425.2,47,6
mission01,off,330,17046.9,49,6
mission01,off,340,16044.8,49,7
mission01,off,350,15461.5,50,7
mission01,off,360,14956.3,51,7
mission01,off,370,14425.5,51,8
mission01,off,380,13910.5,51,8
mission01,off,390,13418.9,49,11
mission01,off,400,13218.9,45,12
mission01,off,410,12517.9,44,12
mission01,off,420,12161.3,44,13
mission01,off,430,11601.3,44,13
mission02,on,0,25000.0,0,0
mission02,on,10,25000.0,5,0
mission02,on,20,25000.0,6,0
mission02,on,30,25000.0,5,0
mission02,on,40,25000.0,5,1
mission02,on,50,25000.0,7,1
mission02,on,60,25000.0,10,1
mission02,on,70,25000.0,7,4
mission02,on,80,25000.0,7,4
mission02,on,90,25000.0,7,4
mission02,on,100,25000.0,7,4
mission02,on,110,25000.0,9,4
mission02,on,120,25000.0,14,4
mission02,on,130,25000.0,16,4
mission02,on,140,25000.0,19,4
mission02,on,150,25000.0,19,4
mission02,on,160,25000.0,23,5
mission02,on,170,24730.0,28,5
mission02,on,180,24730.0,32,5
mission02,on,190,24730.0,36,5
mission02,on,200,24640.0,43,6
mission02,on,210,24190.0,46,6
mission02,on,220,24055.0,47,6
mission02,on,220,24055.0,47,6
mission02,on,230,24055.0,49,6
mission02,on,230,24055.0,49,6
mission02,on,240,23474.5,52,6
mission02,on,240,23474.5,52,6
mission02,on,250,23474.5,53,6
mission02,on,250,23474.5,53,6
mission02,on,260,23474.5,54,6
mission02,on,260,23474.5,54,6
mission02,on,270,22697.0,54,6
mission02,on,270,22697.0,54,6
mission02,on,280,22091.2,56,6
mission02,on,280,22091.2,55,7
mission02,on,290,21577.9,55,7
mission02,on,290,21555.4,55,7
mission02,on,300,20799.1,56,7
mission02,on,310,19781.1,55,7
mission02,on,320,18925.8,56,8
mission02,on,330,18592.5,56,8
mission02,on,340,17432.5,57,8
mission02,on,350,16932.6,59,8
mission02,on,360,16171.6,58,9
mission02,on,370,15017.6,58,11
mission02,on,380,14217.2,59,11
mission02,on,390,13322.2,59,12
mission02,on,400,12808.9,58,13
mission02,on,410,12090.6,61,16
mission02,on,420,11440.6,66,19
mission02,on,430,11127.3,55,19
mission03,on,0,25000.0,0,0
mission03,on,10,25000.0,3,0
mission03,on,20,25000.0,8,0
mission03,on,30,25000.0,5,0
mission03,on,40,25000.0,6,0
mission03,on,50,25000.0,8,0
mission03,on,60,25000.0,9,0
mission03,on,70,25000.0,16,0
mission03,on,80,25000.0,10,0
mission03,on,90,25000.0,11,0
mission03,on,100,25000.0,10,2
mission03,on,110,25000.0,15,2
mission03,on,120,25000.0,12,2
mission03,on,130,25000.0,10,4
mission03,on,140,25000.0,11,6
mission03,on,150,25000.0,14,6
mission03,on,160,25000.0,17,7
mission03,on,170,24685.0,24,7
mission03,on,180,24640.0,23,7
mission03,on,190,24640.0,27,7
mission03,on,200,24460.0,26,8
mission03,on,210,24100.0,28,8
mission03,on,220,24100.0,29,9
mission03,on,230,24100.0,28,11
mission03,on,230,24100.0,28,11
mission03,on,240,23810.0,35,11
mission03,on,240,23810.0,36,11
mission03,on,250,23630.0,36,12
mission03,on,250,23630.0,36,12
mission03,on,260,23630.0,38,13
mission03,on,260,23630.0,38,13
mission03,on,270,22998.0,39,13
mission03,on,270,22908.0,39,13
mission03,on,280,22197.5,40,13
mission03,on,280,22188.5,40,13
mission03,on,290,21602.4,38,13
mission03,on,290,21602.4,38,13
mission03,on,300,21042.4,39,13
mission03,on,300,20975.8,39,13
mission03,on,310,20529.1,41,15
mission03,on,310,20529.1,41,15
mission03,on,320,19812.5,38,17
mission03,on,320,19767.5,38,17
mission03,on,330,19434.2,39,18
mission03,on,340,18785.9,37,19
mission03,on,350,18339.2,37,19
mission03,on,360,17528.1,38,19
mission03,on,370,16901.5,37,19
mission03,on,380,16260.7,35,19
mission03,on,390,15708.2,37,19
mission03,on,400,15346.2,37,19
mission03,on,410,14412.1,36,20
mission03,on,420,13951.9,37,22
mission03,on,430,13211.9,35,23
1 run turret_rule t_s acropolis_hull e007_alive e007_killed_cum
2 mission01 off 0 25000.0 0 0
3 mission01 off 10 25000.0 5 0
4 mission01 off 20 25000.0 6 0
5 mission01 off 30 25000.0 6 0
6 mission01 off 40 25000.0 6 0
7 mission01 off 50 25000.0 8 0
8 mission01 off 60 25000.0 11 0
9 mission01 off 70 25000.0 11 3
10 mission01 off 80 25000.0 8 3
11 mission01 off 90 25000.0 8 3
12 mission01 off 100 25000.0 10 3
13 mission01 off 110 25000.0 14 3
14 mission01 off 120 25000.0 16 3
15 mission01 off 130 25000.0 17 3
16 mission01 off 140 25000.0 20 3
17 mission01 off 150 25000.0 23 3
18 mission01 off 160 25000.0 26 4
19 mission01 off 170 24509.5 33 4
20 mission01 off 180 24509.5 37 4
21 mission01 off 190 24419.5 38 5
22 mission01 off 200 24212.5 41 5
23 mission01 off 210 23447.5 40 5
24 mission01 off 220 23447.5 40 5
25 mission01 off 220 23447.5 40 5
26 mission01 off 230 23447.5 41 5
27 mission01 off 230 23447.5 41 5
28 mission01 off 240 22912.0 43 5
29 mission01 off 240 22867.0 43 5
30 mission01 off 250 22667.0 42 6
31 mission01 off 250 22647.0 42 6
32 mission01 off 260 22334.5 44 6
33 mission01 off 260 22177.9 44 6
34 mission01 off 270 21101.2 46 6
35 mission01 off 270 21101.2 45 6
36 mission01 off 280 20292.6 46 6
37 mission01 off 280 20279.1 46 6
38 mission01 off 290 19598.5 58 6
39 mission01 off 290 19598.5 58 6
40 mission01 off 300 18725.2 58 6
41 mission01 off 300 18658.5 47 6
42 mission01 off 310 18231.9 47 6
43 mission01 off 310 18231.9 47 6
44 mission01 off 320 17425.2 47 6
45 mission01 off 330 17046.9 49 6
46 mission01 off 340 16044.8 49 7
47 mission01 off 350 15461.5 50 7
48 mission01 off 360 14956.3 51 7
49 mission01 off 370 14425.5 51 8
50 mission01 off 380 13910.5 51 8
51 mission01 off 390 13418.9 49 11
52 mission01 off 400 13218.9 45 12
53 mission01 off 410 12517.9 44 12
54 mission01 off 420 12161.3 44 13
55 mission01 off 430 11601.3 44 13
56 mission02 on 0 25000.0 0 0
57 mission02 on 10 25000.0 5 0
58 mission02 on 20 25000.0 6 0
59 mission02 on 30 25000.0 5 0
60 mission02 on 40 25000.0 5 1
61 mission02 on 50 25000.0 7 1
62 mission02 on 60 25000.0 10 1
63 mission02 on 70 25000.0 7 4
64 mission02 on 80 25000.0 7 4
65 mission02 on 90 25000.0 7 4
66 mission02 on 100 25000.0 7 4
67 mission02 on 110 25000.0 9 4
68 mission02 on 120 25000.0 14 4
69 mission02 on 130 25000.0 16 4
70 mission02 on 140 25000.0 19 4
71 mission02 on 150 25000.0 19 4
72 mission02 on 160 25000.0 23 5
73 mission02 on 170 24730.0 28 5
74 mission02 on 180 24730.0 32 5
75 mission02 on 190 24730.0 36 5
76 mission02 on 200 24640.0 43 6
77 mission02 on 210 24190.0 46 6
78 mission02 on 220 24055.0 47 6
79 mission02 on 220 24055.0 47 6
80 mission02 on 230 24055.0 49 6
81 mission02 on 230 24055.0 49 6
82 mission02 on 240 23474.5 52 6
83 mission02 on 240 23474.5 52 6
84 mission02 on 250 23474.5 53 6
85 mission02 on 250 23474.5 53 6
86 mission02 on 260 23474.5 54 6
87 mission02 on 260 23474.5 54 6
88 mission02 on 270 22697.0 54 6
89 mission02 on 270 22697.0 54 6
90 mission02 on 280 22091.2 56 6
91 mission02 on 280 22091.2 55 7
92 mission02 on 290 21577.9 55 7
93 mission02 on 290 21555.4 55 7
94 mission02 on 300 20799.1 56 7
95 mission02 on 310 19781.1 55 7
96 mission02 on 320 18925.8 56 8
97 mission02 on 330 18592.5 56 8
98 mission02 on 340 17432.5 57 8
99 mission02 on 350 16932.6 59 8
100 mission02 on 360 16171.6 58 9
101 mission02 on 370 15017.6 58 11
102 mission02 on 380 14217.2 59 11
103 mission02 on 390 13322.2 59 12
104 mission02 on 400 12808.9 58 13
105 mission02 on 410 12090.6 61 16
106 mission02 on 420 11440.6 66 19
107 mission02 on 430 11127.3 55 19
108 mission03 on 0 25000.0 0 0
109 mission03 on 10 25000.0 3 0
110 mission03 on 20 25000.0 8 0
111 mission03 on 30 25000.0 5 0
112 mission03 on 40 25000.0 6 0
113 mission03 on 50 25000.0 8 0
114 mission03 on 60 25000.0 9 0
115 mission03 on 70 25000.0 16 0
116 mission03 on 80 25000.0 10 0
117 mission03 on 90 25000.0 11 0
118 mission03 on 100 25000.0 10 2
119 mission03 on 110 25000.0 15 2
120 mission03 on 120 25000.0 12 2
121 mission03 on 130 25000.0 10 4
122 mission03 on 140 25000.0 11 6
123 mission03 on 150 25000.0 14 6
124 mission03 on 160 25000.0 17 7
125 mission03 on 170 24685.0 24 7
126 mission03 on 180 24640.0 23 7
127 mission03 on 190 24640.0 27 7
128 mission03 on 200 24460.0 26 8
129 mission03 on 210 24100.0 28 8
130 mission03 on 220 24100.0 29 9
131 mission03 on 230 24100.0 28 11
132 mission03 on 230 24100.0 28 11
133 mission03 on 240 23810.0 35 11
134 mission03 on 240 23810.0 36 11
135 mission03 on 250 23630.0 36 12
136 mission03 on 250 23630.0 36 12
137 mission03 on 260 23630.0 38 13
138 mission03 on 260 23630.0 38 13
139 mission03 on 270 22998.0 39 13
140 mission03 on 270 22908.0 39 13
141 mission03 on 280 22197.5 40 13
142 mission03 on 280 22188.5 40 13
143 mission03 on 290 21602.4 38 13
144 mission03 on 290 21602.4 38 13
145 mission03 on 300 21042.4 39 13
146 mission03 on 300 20975.8 39 13
147 mission03 on 310 20529.1 41 15
148 mission03 on 310 20529.1 41 15
149 mission03 on 320 19812.5 38 17
150 mission03 on 320 19767.5 38 17
151 mission03 on 330 19434.2 39 18
152 mission03 on 340 18785.9 37 19
153 mission03 on 350 18339.2 37 19
154 mission03 on 360 17528.1 38 19
155 mission03 on 370 16901.5 37 19
156 mission03 on 380 16260.7 35 19
157 mission03 on 390 15708.2 37 19
158 mission03 on 400 15346.2 37 19
159 mission03 on 410 14412.1 36 20
160 mission03 on 420 13951.9 37 22
161 mission03 on 430 13211.9 35 23

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 918 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@@ -0,0 +1,102 @@
movie,telop,subtitle,voicetrack
logo1.wmv,,,
logo2.wmv,,,
logo3.wmv,,,
logo4.wmv,,,
ADV.wmv,,,VOICE_ADV
SYLPH_HD720p_8M-CBR_2ch.wmv,pwterop_s01a.prt,SYLPH_HD720p_8M-CBR_2ch.tbl,
S00A.wmv,,SUBTITLE_S00A.tbl,VOICE_S00A
S01A.wmv,,SUBTITLE_S01A.tbl,VOICE_S01A
RT01A.wmv,pwrt01.prt,SUBTITLE_RT01A.tbl,VOICE_RT01A
RT01B.wmv,,SUBTITLE_RT01B.tbl,VOICE_RT01B
RT01C_1.wmv,,SUBTITLE_RT01C_1.tbl,VOICE_RT01C_1
RT01C_2.wmv,,SUBTITLE_RT01C_2.tbl,VOICE_RT01C_2
S02A.wmv,pwterop_s02a.prt,SUBTITLE_S02A.tbl,VOICE_S02A
S02B.wmv,,SUBTITLE_S02B.tbl,VOICE_S02B
S02C.wmv,,SUBTITLE_S02C.tbl,VOICE_S02C
RT02A.wmv,pwrt02.prt,SUBTITLE_RT02A.tbl,VOICE_RT02A
RT02B.wmv,,SUBTITLE_RT02B.tbl,VOICE_RT02B
RT02C.wmv,,SUBTITLE_RT02C.tbl,VOICE_RT02C
RT02D_1.wmv,,SUBTITLE_RT02D_1.tbl,VOICE_RT02D_1
RT02D_2.wmv,,SUBTITLE_RT02D_2.tbl,VOICE_RT02D_2
hokyu_LS_s02A.wmv,,SUBTITLE_hokyu_LS_s02A.tbl,VOICE_D_450
hokyu_LS_s02H.wmv,,SUBTITLE_hokyu_LS_s02H.tbl,VOICE_D_453
S03A.wmv,,SUBTITLE_S03A.tbl,VOICE_S03A
RT03A.wmv,pwrt03.prt,SUBTITLE_RT03A.tbl,VOICE_RT03A
RT03B.wmv,,SUBTITLE_RT03B.tbl,VOICE_RT03B
RT03C.wmv,,SUBTITLE_RT03C.tbl,VOICE_RT03C
RT03D.wmv,,SUBTITLE_RT03D.tbl,VOICE_RT03D
hokyu_LS_s03A.wmv,,SUBTITLE_hokyu_LS_s03A.tbl,
hokyu_LS_s03H.wmv,,SUBTITLE_hokyu_LS_s03H.tbl,
S04A.wmv,,SUBTITLE_S04A.tbl,VOICE_S04A
S04B.wmv,,SUBTITLE_S04B.tbl,VOICE_S04B
RT04A.wmv,pwrt04.prt,SUBTITLE_RT04A.tbl,VOICE_RT04A
RT04B.wmv,,SUBTITLE_RT04B.tbl,VOICE_RT04B
hokyu_DS_s02A.wmv,,SUBTITLE_hokyu_DS_s02A.tbl,VOICE_D_452
S05A.wmv,,SUBTITLE_S05A.tbl,VOICE_S05A
RT05A.wmv,pwrt05.prt,SUBTITLE_RT05A.tbl,VOICE_RT05A
RT05B.wmv,,SUBTITLE_RT05B.tbl,VOICE_RT05B
RT05C.wmv,,SUBTITLE_RT05C.tbl,VOICE_RT05C
S06A.wmv,pwterop_s06a.prt,SUBTITLE_S06A.tbl,VOICE_S06A
S06B.wmv,,SUBTITLE_S06B.tbl,VOICE_S06B
RT06A.wmv,pwrt06.prt,SUBTITLE_RT06A.tbl,VOICE_RT06A
RT06B.wmv,,SUBTITLE_RT06B.tbl,VOICE_RT06B
RT06C.wmv,,SUBTITLE_RT06C.tbl,VOICE_RT06C
RT06D.wmv,,SUBTITLE_RT06D.tbl,VOICE_RT06D
hokyu_LS_s06A.wmv,,SUBTITLE_hokyu_LS_s06A.tbl,
hokyu_LS_s06H.wmv,,SUBTITLE_hokyu_LS_s06H.tbl,
S07A.wmv,,SUBTITLE_S07A.tbl,VOICE_S07A
S07B.wmv,,SUBTITLE_S07B.tbl,VOICE_S07B
RT07A.wmv,pwrt07.prt,SUBTITLE_RT07A.tbl,VOICE_RT07A
RT07B.wmv,,SUBTITLE_RT07B.tbl,VOICE_RT07B
RT07C.wmv,,SUBTITLE_RT07C.tbl,VOICE_RT07C
hokyu_DS_s07A.wmv,,SUBTITLE_hokyu_DS_s07A.tbl,
hokyu_DS_s07H.wmv,,SUBTITLE_hokyu_DS_s07H.tbl,VOICE_D_454
RT08A.wmv,pwrt08.prt,SUBTITLE_RT08A.tbl,VOICE_RT08A
RT08B.wmv,,SUBTITLE_RT08B.tbl,VOICE_RT08B
RT08C.wmv,,SUBTITLE_RT08C.tbl,VOICE_RT08C
hokyu_DS_s08A.wmv,,SUBTITLE_hokyu_DS_s08A.tbl,
S09B.wmv,,SUBTITLE_S09B.tbl,VOICE_S09B
RT09A.wmv,pwrt09.prt,SUBTITLE_RT09A.tbl,VOICE_RT09A
RT09B.wmv,,SUBTITLE_RT09B.tbl,VOICE_RT09B
RT09C.wmv,,SUBTITLE_RT09C.tbl,VOICE_RT09C
RT09D.wmv,,SUBTITLE_RT09D.tbl,VOICE_RT09D
hokyu_LS_s09A.wmv,,SUBTITLE_hokyu_LS_s09A.tbl,VOICE_D_451
hokyu_LS_s09H.wmv,,SUBTITLE_hokyu_LS_s09H.tbl,
S10B.wmv,,SUBTITLE_S10B.tbl,VOICE_S10B
RT10A.wmv,pwrt10.prt,SUBTITLE_RT10A.tbl,VOICE_RT10A
RT10B.wmv,,SUBTITLE_RT10B.tbl,VOICE_RT10B
S11A.wmv,,SUBTITLE_S11A.tbl,VOICE_S11A
S11C.wmv,,SUBTITLE_S11C.tbl,VOICE_S11C
RT11A.wmv,pwrt11.prt,SUBTITLE_RT11A.tbl,VOICE_RT11A
RT11B.wmv,,SUBTITLE_RT11B.tbl,VOICE_RT11B
RT11C.wmv,,SUBTITLE_RT11C.tbl,VOICE_RT11C
hokyu_LS_s11A.wmv,,SUBTITLE_hokyu_LS_s11A.tbl,
S12A.wmv,,SUBTITLE_S12A.tbl,VOICE_S12A
S12B.wmv,,SUBTITLE_S12B.tbl,VOICE_S12B
S12C.wmv,,SUBTITLE_S12C.tbl,VOICE_S12C
RT12A.wmv,pwrt12.prt,SUBTITLE_RT12A.tbl,VOICE_RT12A
RT12B_1.wmv,,SUBTITLE_RT12B_1.tbl,VOICE_RT12B_1
RT12B_2.wmv,,SUBTITLE_RT12B_2.tbl,VOICE_RT12B_2
S13A.wmv,,SUBTITLE_S13A.tbl,VOICE_S13A
S13B.wmv,,SUBTITLE_S13B.tbl,VOICE_S13B
RT13A.wmv,pwrt13.prt,SUBTITLE_RT13A.tbl,VOICE_RT13A
RT13B_1.wmv,,SUBTITLE_RT13B_1.tbl,VOICE_RT13B_1
RT13B_2.wmv,,SUBTITLE_RT13B_2.tbl,VOICE_RT13B_2
hokyu_DS_s13A.wmv,,SUBTITLE_hokyu_DS_s13A.tbl,
S14A.wmv,,SUBTITLE_S14A.tbl,VOICE_S14A
RT14A.wmv,pwrt14.prt,SUBTITLE_RT14A.tbl,VOICE_RT14A
RT14B.wmv,,SUBTITLE_RT14B.tbl,VOICE_RT14B
RT14C.wmv,,SUBTITLE_RT14C.tbl,VOICE_RT14C
hokyu_DS_s14H.wmv,,SUBTITLE_hokyu_DS_s14H.tbl,
S15A.wmv,pwterop_s15a.prt,SUBTITLE_S15A.tbl,VOICE_S15A
S15B.wmv,,SUBTITLE_S15B.tbl,VOICE_S15B
S15C.wmv,,SUBTITLE_S15C.tbl,VOICE_S15C
RT15A.wmv,pwrt15.prt,SUBTITLE_RT15A.tbl,VOICE_RT15A
RT15B.wmv,,SUBTITLE_RT15B.tbl,VOICE_RT15B
RT15C.wmv,,SUBTITLE_RT15C.tbl,VOICE_RT15C
hokyu_LS_s15A.wmv,,SUBTITLE_hokyu_LS_s15A.tbl,
S16A.wmv,pwterop_s16a.prt,SUBTITLE_S16A.tbl,VOICE_S16A
RT16C.wmv,pwrt16.prt,SUBTITLE_RT16C.tbl,VOICE_RT16C
hokyu_LS_s24A.wmv,,,
hokyu_LS_s27A.wmv,,,
1 movie telop subtitle voicetrack
2 logo1.wmv
3 logo2.wmv
4 logo3.wmv
5 logo4.wmv
6 ADV.wmv VOICE_ADV
7 SYLPH_HD720p_8M-CBR_2ch.wmv pwterop_s01a.prt SYLPH_HD720p_8M-CBR_2ch.tbl
8 S00A.wmv SUBTITLE_S00A.tbl VOICE_S00A
9 S01A.wmv SUBTITLE_S01A.tbl VOICE_S01A
10 RT01A.wmv pwrt01.prt SUBTITLE_RT01A.tbl VOICE_RT01A
11 RT01B.wmv SUBTITLE_RT01B.tbl VOICE_RT01B
12 RT01C_1.wmv SUBTITLE_RT01C_1.tbl VOICE_RT01C_1
13 RT01C_2.wmv SUBTITLE_RT01C_2.tbl VOICE_RT01C_2
14 S02A.wmv pwterop_s02a.prt SUBTITLE_S02A.tbl VOICE_S02A
15 S02B.wmv SUBTITLE_S02B.tbl VOICE_S02B
16 S02C.wmv SUBTITLE_S02C.tbl VOICE_S02C
17 RT02A.wmv pwrt02.prt SUBTITLE_RT02A.tbl VOICE_RT02A
18 RT02B.wmv SUBTITLE_RT02B.tbl VOICE_RT02B
19 RT02C.wmv SUBTITLE_RT02C.tbl VOICE_RT02C
20 RT02D_1.wmv SUBTITLE_RT02D_1.tbl VOICE_RT02D_1
21 RT02D_2.wmv SUBTITLE_RT02D_2.tbl VOICE_RT02D_2
22 hokyu_LS_s02A.wmv SUBTITLE_hokyu_LS_s02A.tbl VOICE_D_450
23 hokyu_LS_s02H.wmv SUBTITLE_hokyu_LS_s02H.tbl VOICE_D_453
24 S03A.wmv SUBTITLE_S03A.tbl VOICE_S03A
25 RT03A.wmv pwrt03.prt SUBTITLE_RT03A.tbl VOICE_RT03A
26 RT03B.wmv SUBTITLE_RT03B.tbl VOICE_RT03B
27 RT03C.wmv SUBTITLE_RT03C.tbl VOICE_RT03C
28 RT03D.wmv SUBTITLE_RT03D.tbl VOICE_RT03D
29 hokyu_LS_s03A.wmv SUBTITLE_hokyu_LS_s03A.tbl
30 hokyu_LS_s03H.wmv SUBTITLE_hokyu_LS_s03H.tbl
31 S04A.wmv SUBTITLE_S04A.tbl VOICE_S04A
32 S04B.wmv SUBTITLE_S04B.tbl VOICE_S04B
33 RT04A.wmv pwrt04.prt SUBTITLE_RT04A.tbl VOICE_RT04A
34 RT04B.wmv SUBTITLE_RT04B.tbl VOICE_RT04B
35 hokyu_DS_s02A.wmv SUBTITLE_hokyu_DS_s02A.tbl VOICE_D_452
36 S05A.wmv SUBTITLE_S05A.tbl VOICE_S05A
37 RT05A.wmv pwrt05.prt SUBTITLE_RT05A.tbl VOICE_RT05A
38 RT05B.wmv SUBTITLE_RT05B.tbl VOICE_RT05B
39 RT05C.wmv SUBTITLE_RT05C.tbl VOICE_RT05C
40 S06A.wmv pwterop_s06a.prt SUBTITLE_S06A.tbl VOICE_S06A
41 S06B.wmv SUBTITLE_S06B.tbl VOICE_S06B
42 RT06A.wmv pwrt06.prt SUBTITLE_RT06A.tbl VOICE_RT06A
43 RT06B.wmv SUBTITLE_RT06B.tbl VOICE_RT06B
44 RT06C.wmv SUBTITLE_RT06C.tbl VOICE_RT06C
45 RT06D.wmv SUBTITLE_RT06D.tbl VOICE_RT06D
46 hokyu_LS_s06A.wmv SUBTITLE_hokyu_LS_s06A.tbl
47 hokyu_LS_s06H.wmv SUBTITLE_hokyu_LS_s06H.tbl
48 S07A.wmv SUBTITLE_S07A.tbl VOICE_S07A
49 S07B.wmv SUBTITLE_S07B.tbl VOICE_S07B
50 RT07A.wmv pwrt07.prt SUBTITLE_RT07A.tbl VOICE_RT07A
51 RT07B.wmv SUBTITLE_RT07B.tbl VOICE_RT07B
52 RT07C.wmv SUBTITLE_RT07C.tbl VOICE_RT07C
53 hokyu_DS_s07A.wmv SUBTITLE_hokyu_DS_s07A.tbl
54 hokyu_DS_s07H.wmv SUBTITLE_hokyu_DS_s07H.tbl VOICE_D_454
55 RT08A.wmv pwrt08.prt SUBTITLE_RT08A.tbl VOICE_RT08A
56 RT08B.wmv SUBTITLE_RT08B.tbl VOICE_RT08B
57 RT08C.wmv SUBTITLE_RT08C.tbl VOICE_RT08C
58 hokyu_DS_s08A.wmv SUBTITLE_hokyu_DS_s08A.tbl
59 S09B.wmv SUBTITLE_S09B.tbl VOICE_S09B
60 RT09A.wmv pwrt09.prt SUBTITLE_RT09A.tbl VOICE_RT09A
61 RT09B.wmv SUBTITLE_RT09B.tbl VOICE_RT09B
62 RT09C.wmv SUBTITLE_RT09C.tbl VOICE_RT09C
63 RT09D.wmv SUBTITLE_RT09D.tbl VOICE_RT09D
64 hokyu_LS_s09A.wmv SUBTITLE_hokyu_LS_s09A.tbl VOICE_D_451
65 hokyu_LS_s09H.wmv SUBTITLE_hokyu_LS_s09H.tbl
66 S10B.wmv SUBTITLE_S10B.tbl VOICE_S10B
67 RT10A.wmv pwrt10.prt SUBTITLE_RT10A.tbl VOICE_RT10A
68 RT10B.wmv SUBTITLE_RT10B.tbl VOICE_RT10B
69 S11A.wmv SUBTITLE_S11A.tbl VOICE_S11A
70 S11C.wmv SUBTITLE_S11C.tbl VOICE_S11C
71 RT11A.wmv pwrt11.prt SUBTITLE_RT11A.tbl VOICE_RT11A
72 RT11B.wmv SUBTITLE_RT11B.tbl VOICE_RT11B
73 RT11C.wmv SUBTITLE_RT11C.tbl VOICE_RT11C
74 hokyu_LS_s11A.wmv SUBTITLE_hokyu_LS_s11A.tbl
75 S12A.wmv SUBTITLE_S12A.tbl VOICE_S12A
76 S12B.wmv SUBTITLE_S12B.tbl VOICE_S12B
77 S12C.wmv SUBTITLE_S12C.tbl VOICE_S12C
78 RT12A.wmv pwrt12.prt SUBTITLE_RT12A.tbl VOICE_RT12A
79 RT12B_1.wmv SUBTITLE_RT12B_1.tbl VOICE_RT12B_1
80 RT12B_2.wmv SUBTITLE_RT12B_2.tbl VOICE_RT12B_2
81 S13A.wmv SUBTITLE_S13A.tbl VOICE_S13A
82 S13B.wmv SUBTITLE_S13B.tbl VOICE_S13B
83 RT13A.wmv pwrt13.prt SUBTITLE_RT13A.tbl VOICE_RT13A
84 RT13B_1.wmv SUBTITLE_RT13B_1.tbl VOICE_RT13B_1
85 RT13B_2.wmv SUBTITLE_RT13B_2.tbl VOICE_RT13B_2
86 hokyu_DS_s13A.wmv SUBTITLE_hokyu_DS_s13A.tbl
87 S14A.wmv SUBTITLE_S14A.tbl VOICE_S14A
88 RT14A.wmv pwrt14.prt SUBTITLE_RT14A.tbl VOICE_RT14A
89 RT14B.wmv SUBTITLE_RT14B.tbl VOICE_RT14B
90 RT14C.wmv SUBTITLE_RT14C.tbl VOICE_RT14C
91 hokyu_DS_s14H.wmv SUBTITLE_hokyu_DS_s14H.tbl
92 S15A.wmv pwterop_s15a.prt SUBTITLE_S15A.tbl VOICE_S15A
93 S15B.wmv SUBTITLE_S15B.tbl VOICE_S15B
94 S15C.wmv SUBTITLE_S15C.tbl VOICE_S15C
95 RT15A.wmv pwrt15.prt SUBTITLE_RT15A.tbl VOICE_RT15A
96 RT15B.wmv SUBTITLE_RT15B.tbl VOICE_RT15B
97 RT15C.wmv SUBTITLE_RT15C.tbl VOICE_RT15C
98 hokyu_LS_s15A.wmv SUBTITLE_hokyu_LS_s15A.tbl
99 S16A.wmv pwterop_s16a.prt SUBTITLE_S16A.tbl VOICE_S16A
100 RT16C.wmv pwrt16.prt SUBTITLE_RT16C.tbl VOICE_RT16C
101 hokyu_LS_s24A.wmv
102 hokyu_LS_s27A.wmv

View File

@@ -0,0 +1,13 @@
11 elements
# element parent kind pivot kf placement
0 pgp_ttrl_eff11.t32 - 0x0 (34,33) 7 rest (470,121) t=9..25 [3:603,121 6:603,121 8:503,121 9:470,121 25:463,121 30:463,121 1:493,121]
1 pgp_ttrl_eff12.t32 - 0x0 (34,33) 7 rest (742,121) t=9..25 [3:609,121 6:609,121 8:709,121 9:742,121 25:749,121 30:749,121 2:719,121]
2 pgp_ttrl_eff10.t32 - 0x0 (204,60) 5 rest (436,94) t=14..23 [8:436,94 14:436,94 23:436,94 30:436,94 3:436,94]
3 pgp_ttrl_eff22.t32 - 0x0 (133,130) 5 rest (480,225) t=11..25 [5:480,225 11:480,225 25:460,225 30:460,225 4:490,225]
4 pgp_ttrl_eff23.t32 - 0x0 (138,130) 5 rest (524,271) t=11..25 [5:524,271 11:524,271 25:544,271 30:544,271 5:514,271]
5 pgp_ttrl_eff21.t32 - 0x0 (214,180) 5 rest (426,198) t=9..21 [9:426,198 21:426,198 23:426,198 30:426,198 6:426,198]
6 pgp_ttrl_title.rat - 0x0 (101,36) 6 rest (540,119) t=13..23 [5:540,119 13:540,119 23:540,119 28:540,119 30:540,119 7:540,119]
7 pgp_ttrl_btn10.rat - 0x3002 (43,21) 5 rest (546,288) t=15..23 [9:546,288 15:546,288 23:546,288 26:546,288 8:546,288]
8 pgp_ttrl_btn11.rat - 0x3002 (86,22) 5 rest (546,358) t=11..17 [11:546,358 17:546,358 23:546,358 26:546,358 9:546,358]
9 pgp_ttrl_btn12.rat - 0x3002 (110,21) 5 rest (546,428) t=13..19 [13:546,428 19:546,428 23:546,428 26:546,428 10:546,428]
10 pgp_ttrl_msg.t32 - 0x0 (190,19) 5 rest (451,545) t=28..1869640736 [16:451,545 21:451,545 23:451,545 28:451,545 1869640736:451,545]

View File

@@ -0,0 +1,314 @@
phase,t,fx,fy,fz
slow,0.022,-0.9999999999976801,-5.364418029772711e-07,-2.0861625671338324e-06
slow,0.072,-0.9999999999976801,-5.364418029772711e-07,-2.0861625671338324e-06
slow,0.138,-0.9999999999976801,-5.364418029772711e-07,-2.0861625671338324e-06
slow,0.188,-0.9999999999976801,-5.364418029772711e-07,-2.0861625671338324e-06
slow,0.238,-0.9999996503301273,-0.000739351008976433,0.00039076810084039696
slow,0.288,-0.9995667500505145,-0.025989011351613873,0.013816058859813869
slow,0.338,-0.9991424233572718,-0.03655991231151712,0.01943683769373226
slow,0.388,-0.9974614922372212,-0.06287386978474002,0.03342825155743701
slow,0.441,-0.9974614922372212,-0.06287386978474002,0.03342825155743701
slow,0.491,-0.9974614922372212,-0.06287386978474002,0.03342825155743701
slow,0.542,-0.9974614922372212,-0.06287386978474002,0.03342825155743701
slow,0.592,-0.9756937705208446,-0.19348862930198532,0.10287767735352636
slow,0.642,-0.9599895265779043,-0.24725777991348272,0.13146748317735063
slow,0.692,-0.9065968643570531,-0.3726025922234667,0.19811469861247516
slow,0.742,-0.8880690175394421,-0.405900585102419,0.215819681910719
slow,0.792,-0.8231976038572328,-0.5012983450542031,0.2665439443124295
slow,0.845,-0.8111180643235866,-0.5164209971100269,0.2745848493122731
slow,0.895,-0.8111180643235866,-0.5164209971100269,0.2745848493122731
slow,0.946,-0.8111180643235866,-0.5164209971100269,0.2745848493122731
slow,0.996,-0.8111180643235866,-0.5164209971100269,0.2745848493122731
slow,1.047,-0.6225347328753619,-0.6909879300492386,0.3674046636749054
slow,1.098,-0.4995761468930651,-0.7648708472261829,0.40668939071357624
slow,1.148,-0.42441628069163945,-0.7994799112461082,0.425091392759005
slow,1.198,-0.34635895158661695,-0.8282947460891245,0.440412636350244
slow,1.249,-0.26597407096587283,-0.8511436226859083,0.4525619594430681
slow,1.3,-0.22508987440157757,-0.8602890836759516,0.45742457405551984
slow,1.35,-0.22508987440157757,-0.8602890836759516,0.45742457405551984
slow,1.4,-0.22508987440157757,-0.8602890836759516,0.45742457405551984
slow,1.45,0.0050435963756794286,-0.8829357634414114,0.4694667184920898
slow,1.5,0.1113271185026686,-0.8774582682112876,0.4665546701443904
slow,1.551,0.19530088938670107,-0.8659441420087264,0.46043273724349176
slow,1.601,0.35806279594948665,-0.8244050055782095,0.4383462340826355
slow,1.651,0.4357105639703388,-0.7947284845866424,0.4225670837053784
slow,1.701,0.4357105639703388,-0.7947284845866424,0.4225670837053784
slow,1.751,0.4357105639703388,-0.7947284845866424,0.4225670837053784
slow,1.801,0.581059227173933,-0.7185957552011922,0.38208679003972373
slow,1.854,0.5981621070188505,-0.707571139880663,0.3762249004714446
slow,1.933,0.7102092219298712,-0.6215856943388454,0.3305058027918156
slow,1.983,0.7936818073741404,-0.5371251153693617,0.28559726728869045
slow,2.034,0.8306115980329357,-0.491670162790673,0.2614284304251665
slow,2.085,0.8306115980329357,-0.491670162790673,0.2614284304251665
slow,2.136,0.8306115980329357,-0.491670162790673,0.2614284304251665
slow,2.186,0.8306115980329357,-0.491670162790673,0.2614284304251665
slow,2.236,0.9439254674422402,-0.29151154402331125,0.15500236003072188
slow,2.288,0.9782500298959619,-0.18314796371755346,0.09738430260911397
slow,2.338,0.9923168633793271,-0.1092393189325843,0.05808626216377494
slow,2.388,0.9999950320089501,0.0027841479666426932,-0.0014779978073891553
slow,2.439,0.9961448118772039,0.07745674002692376,-0.04118212226842516
slow,2.489,0.9885868780617736,0.1330186187164556,-0.07072504223287812
slow,2.54,0.9885868780617736,0.1330186187164556,-0.07072504223287812
slow,2.59,0.9885868780617736,0.1330186187164556,-0.07072504223287812
slow,2.64,0.9885868780617736,0.1330186187164556,-0.07072504223287812
slow,2.69,0.9104394306290844,0.3652252075952527,-0.1941921494108173
slow,2.741,0.8718210936242394,0.4324898355933772,-0.22995765440673788
slow,2.791,0.8021474529558832,0.5272312979999614,-0.28033305571349426
slow,2.841,0.7483879225773887,0.5856251973581853,-0.31138183241718986
slow,2.891,0.6415804884515123,0.6772700855747096,-0.3601106885722006
slow,2.942,0.5565400067937,0.7335711833839508,-0.39004684301598735
slow,2.992,0.5025832072518267,0.7633335327127708,-0.4058719473241637
slow,3.042,0.5025832072518267,0.7633335327127708,-0.4058719473241637
slow,3.092,0.5025832072518267,0.7633335327127708,-0.4058719473241637
slow,3.142,0.5025832072518267,0.7633335327127708,-0.4058719473241637
slow,3.193,0.26840150425248394,0.8505494121077833,-0.4522458734782528
slow,3.243,0.14383384202445684,0.8737661032159637,-0.4645908121769882
slow,3.293,0.017126773329819035,0.8828175004515181,-0.46940380753871486
slow,3.344,-0.025233536073355507,0.8826657223955247,-0.46932343982079283
slow,3.394,-0.1306276597599528,0.8753813567867831,-0.46545020646226887
slow,3.444,-0.1306276597599528,0.8753813567867831,-0.46545020646226887
slow,3.494,-0.1306276597599528,0.8753813567867831,-0.46545020646226887
slow,3.544,-0.1306276597599528,0.8753813567867831,-0.46545020646226887
slow,3.594,-0.3953899986357624,0.8109981935802458,-0.4312176700790331
slow,3.644,-0.5092096812736444,0.7599012381904277,-0.40404901768702334
slow,3.695,-0.6146085873298012,0.6964964366951696,-0.37033633099035523
slow,3.745,-0.6475735623151888,0.6728076094689478,-0.35774069104743467
slow,3.795,-0.7246428766140702,0.6084598143649699,-0.32352643736707504
slow,3.845,-0.7246428766140702,0.6084598143649699,-0.32352643736707504
slow,3.895,-0.7246428766140702,0.6084598143649699,-0.32352643736707504
slow,3.946,-0.7246428766140702,0.6084598143649699,-0.32352643736707504
slow,4.0,-0.8948032879220578,0.39420026288722865,-0.2096025492772329
slow,4.05,-0.9371976061971167,0.3079700993685502,-0.16375306053115327
slow,4.1,-0.9739646105616616,0.20016331274041113,-0.10643113081357014
slow,4.151,-0.9925182516704475,0.1078037923584182,-0.057322442849038695
slow,4.201,-0.9998661518865883,0.014444979973920849,-0.007682503827448022
slow,4.252,-0.999988574147902,-0.004221603854607207,0.0022426846725771095
slow,4.302,-0.999988574147902,-0.004221603854607207,0.0022426846725771095
slow,4.352,-0.999988574147902,-0.004221603854607207,0.0022426846725771095
slow,4.402,-0.999988574147902,-0.004221603854607207,0.0022426846725771095
slow,4.454,-0.9481592609187346,-0.28059728776173093,0.1491951005723691
slow,4.504,-0.8998604949330586,-0.3851225220144059,0.20477239241678594
slow,4.554,-0.8483542366290391,-0.4674583762955424,0.24855131386636348
slow,4.605,-0.8002653758276345,-0.5294561807103555,0.281516395542175
slow,4.655,-0.7740407763904767,-0.5590258203543885,0.2972389756777044
slow,4.705,-0.7320686741889714,-0.6014912262488834,0.31981832501721374
slow,4.755,-0.7320686741889714,-0.6014912262488834,0.31981832501721374
slow,4.805,-0.7320686741889714,-0.6014912262488834,0.31981832501721374
slow,4.855,-0.7320686741889714,-0.6014912262488834,0.31981832501721374
slow,4.905,-0.5000347671416738,-0.7646370203731946,0.4065654421177173
slow,4.956,-0.38571043654168863,-0.8146245270401747,0.43314470917626546
slow,5.033,-0.3059761515320789,-0.8406001527732009,0.44695634893274494
slow,5.083,-0.14067269192255813,-0.8741670164828578,0.46480449765543375
slow,5.136,-0.11971066366716597,-0.876597475120388,0.46609679640277224
slow,5.186,-0.11971066366716597,-0.876597475120388,0.46609679640277224
slow,5.236,-0.11971066366716597,-0.876597475120388,0.46609679640277224
slow,5.286,0.09210780811437987,-0.8791932987194956,0.4674775878810623
slow,5.336,0.1552569076145395,-0.8722401249754417,0.46378061302818196
slow,5.389,0.29980078422712286,-0.8423325684075889,0.4478787045358116
slow,5.439,0.39908806765876,-0.8095847039629167,0.43046639980569157
slow,5.49,0.4751133264531701,-0.7769262478123317,0.4131016006829976
slow,5.542,0.4751133264531701,-0.7769262478123317,0.4131016006829976
slow,5.592,0.4751133264531701,-0.7769262478123317,0.4131016006829976
slow,5.642,0.4751133264531701,-0.7769262478123317,0.4131016006829976
slow,5.692,0.696657860237904,-0.633428595248907,0.3368026729254701
slow,5.742,0.726585020550654,-0.6066514667740671,0.3225650411502751
slow,5.792,0.8325182828011221,-0.48914972660411055,0.2600881653689665
slow,5.843,0.8765739353060135,-0.4249327255756417,0.22594316691811042
slow,5.893,0.9054260508840364,-0.37481374091028163,0.19929457093804306
slow,5.943,0.9054260508840364,-0.37481374091028163,0.19929457093804306
slow,5.993,0.9054260508840364,-0.37481374091028163,0.19929457093804306
slow,6.043,0.9054260508840364,-0.37481374091028163,0.19929457093804306
slow,6.093,0.9868879110680581,-0.14251307214027348,0.07577780187407064
slow,6.144,0.9928589520370625,-0.10532958640717122,0.056006960167108814
slow,6.194,0.9995721898785164,0.025825160128774418,-0.013729469246492699
slow,6.244,0.9934893887944055,0.10059024435508387,-0.05348305426490678
slow,6.294,0.9538232020213261,0.26521033194280885,-0.14101340048580407
slow,6.344,0.947267673727074,0.2829352443494437,-0.1504380331452729
slow,6.394,0.947267673727074,0.2829352443494437,-0.1504380331452729
slow,6.445,0.947267673727074,0.2829352443494437,-0.1504380331452729
slow,6.495,0.947267673727074,0.2829352443494437,-0.1504380331452729
slow,6.545,0.8243733791338322,0.4997895512364342,-0.2657422364818033
slow,6.597,0.7593203746728908,0.5745491212947682,-0.30549284087524925
slow,6.647,0.7010074410559842,0.6296776548998042,-0.3348053441987208
slow,6.697,0.6041754101078993,0.7035779205024607,-0.37409916279294836
slow,6.747,0.5340870381020223,0.7464697028629991,-0.39690555355025536
slow,6.797,0.4025055990782129,0.8082653740061208,-0.4297631067151235
slow,6.847,0.3433573357356595,0.8292682687272306,-0.44093069577729704
slow,6.898,0.3433573357356595,0.8292682687272306,-0.44093069577729704
slow,6.948,0.3433573357356595,0.8292682687272306,-0.44093069577729704
slow,6.999,0.3433573357356595,0.8292682687272306,-0.44093069577729704
slow,7.049,0.09503184681410931,0.8789508919606488,-0.46734813320765445
slow,7.1,-0.03242949378753749,0.8824823690120825,-0.4692261675519672
slow,7.15,-0.07486618489555856,0.8804688348729269,-0.46815562068258304
slow,7.202,-0.2217573682314415,0.8609628101781774,-0.4577845662810842
slow,7.253,-0.3436636683706333,0.8291685841702975,-0.44087950969291334
slow,7.306,-0.3436636683706333,0.8291685841702975,-0.44087950969291334
slow,7.356,-0.3436636683706333,0.8291685841702975,-0.44087950969291334
slow,7.406,-0.3436636683706333,0.8291685841702975,-0.44087950969291334
slow,7.456,-0.5335192585826919,0.7467851744734487,-0.3970756904017614
slow,7.506,-0.5863848618861591,0.715215075832045,-0.38028961207652284
slow,7.557,-0.6691599892298212,0.6561333325626291,-0.3488752767311034
slow,7.607,-0.7582631988698701,0.5756351874374445,-0.30607360589160554
slow,7.657,-0.8108505756823166,0.51674664977568,-0.27476215871416254
slow,7.707,-0.8575526461274808,0.4541837039893854,-0.24149662968711988
slow,7.757,-0.8575526461274808,0.4541837039893854,-0.24149662968711988
slow,7.808,-0.8575526461274808,0.4541837039893854,-0.24149662968711988
slow,7.859,-0.8575526461274808,0.4541837039893854,-0.24149662968711988
slow,7.909,-0.9532867456950477,0.2667081367420545,-0.1418137873329921
slow,7.959,-0.9755224624568912,0.19415891248194872,-0.10323876183813074
fast,0.031,-0.9183790521746182,-0.3493842945716818,0.1857701031745906
fast,0.081,-0.9181941875656858,-0.34976292144045307,0.18597132226778823
fast,0.131,-0.9157256739103099,-0.35477222000318137,0.18863499690015914
fast,0.181,-0.9149015400332507,-0.3564260247285592,0.18951427635136814
fast,0.231,-0.9149015400332507,-0.3564260247285592,0.18951427635136814
fast,0.282,-0.9149015400332507,-0.3564260247285592,0.18951427635136814
fast,0.334,-0.886987130221704,-0.40774025376731704,0.21679879215260833
fast,0.392,-0.874422882615109,-0.42837502256975,0.22777063550301968
fast,0.442,-0.8391761714215903,-0.4801996653842019,0.2553265256159302
fast,0.492,-0.8087011271707248,-0.5193672154489234,0.27615246229144985
fast,0.542,-0.7639193320090165,-0.5697763250541364,0.3029557617717493
fast,0.592,-0.7142788381999624,-0.6179405632697418,0.3285653687861613
fast,0.644,-0.7056326965418199,-0.6256368844308748,0.3326574610778302
fast,0.694,-0.7056326965418199,-0.6256368844308748,0.3326574610778302
fast,0.761,-0.7056326965418199,-0.6256368844308748,0.3326574610778302
fast,0.811,-0.6045554154137983,-0.703323001692553,0.37396457717814224
fast,0.861,-0.5641123049229769,-0.7290475533490074,0.38764284127313964
fast,0.911,-0.5010910596413976,-0.7640973590830287,0.4062794306752468
fast,0.961,-0.4574254856752507,-0.7851585926980168,0.4174780345925168
fast,1.011,-0.40119022065553167,-0.8087745891735626,0.43003496457555734
fast,1.062,-0.40119022065553167,-0.8087745891735626,0.43003496457555734
fast,1.112,-0.40119022065553167,-0.8087745891735626,0.43003496457555734
fast,1.162,-0.40119022065553167,-0.8087745891735626,0.43003496457555734
fast,1.213,-0.2732721277804909,-0.8493387726086905,0.4516038014918455
fast,1.263,-0.24847333019197224,-0.8552561875978043,0.45475032463867526
fast,1.314,-0.13690544128361162,-0.8746327174969611,0.46505323311511404
fast,1.364,-0.11190820705598208,-0.8774002355189958,0.46652479023598115
fast,1.414,-0.04853388875408303,-0.8819058319940255,0.46892063842118525
fast,1.464,-0.023325922091828814,-0.8827061212913064,0.4693461460302229
fast,1.52,-0.023325922091828814,-0.8827061212913064,0.4693461460302229
fast,1.57,-0.023325922091828814,-0.8827061212913064,0.4693461460302229
fast,1.623,0.11590445397311018,-0.8769955308131724,0.4663099789656202
fast,1.674,0.16796962344551228,-0.8704014300065923,0.46280401493726464
fast,1.724,0.2673695301474367,-0.8508015956107015,0.4523827795739172
fast,1.776,0.3040082366636887,-0.8411556467255445,0.44725403298613803
fast,1.826,0.34060203879357387,-0.8301524613755806,0.44140360447296506
fast,1.876,0.34060203879357387,-0.8301524613755806,0.44140360447296506
fast,1.926,0.34060203879357387,-0.8301524613755806,0.44140360447296506
fast,1.976,0.34060203879357387,-0.8301524613755806,0.44140360447296506
fast,2.026,0.4800222448487086,-0.7745698100484196,0.41184979520689524
fast,2.077,0.5027716590432529,-0.7632352767416622,0.4058233251058559
fast,2.162,0.567685165746978,-0.726881238602736,0.3864934896711436
fast,2.213,0.60896099881303,-0.7003525641308903,0.37238795340333464
fast,2.263,0.60896099881303,-0.7003525641308903,0.37238795340333464
fast,2.313,0.60896099881303,-0.7003525641308903,0.37238795340333464
fast,2.363,0.60896099881303,-0.7003525641308903,0.37238795340333464
fast,2.415,0.7138914376865056,-0.6182880840720885,0.3287534947226572
fast,2.465,0.7492325438071801,-0.584780749889073,0.31093740505026973
fast,2.515,0.7980625863701071,-0.5320401745258126,0.28289461098931906
fast,2.566,0.8280000832233713,-0.4950917864992449,0.2632489033653826
fast,2.618,0.8351255264037815,-0.48567212818960787,0.2582400802520477
fast,2.669,0.8351255264037815,-0.48567212818960787,0.2582400802520477
fast,2.719,0.8351255264037815,-0.48567212818960787,0.2582400802520477
fast,2.769,0.8351255264037815,-0.48567212818960787,0.2582400802520477
fast,2.82,0.9093870336730951,-0.36726148601053504,0.1952798604070126
fast,2.871,0.9203632924764715,-0.3452879583192104,0.18359639348750836
fast,2.921,0.9600488101430662,-0.247076202859695,0.13137591911502494
fast,2.972,0.9669595427173864,-0.2250884627532023,0.1196846969465328
fast,3.022,0.9813959442736294,-0.16952014269323645,0.09013834802422341
fast,3.074,0.9837681894544645,-0.158438487459875,0.08424603912892294
fast,3.124,0.9837681894544645,-0.158438487459875,0.08424603912892294
fast,3.174,0.9837681894544645,-0.158438487459875,0.08424603912892294
fast,3.224,0.9985768344211968,-0.04708834623109012,0.025039836392490022
fast,3.276,0.9999091072744978,0.011905223183064872,-0.006327942041318827
fast,3.326,0.9958087405962524,0.08075529499181068,-0.04293640044171679
fast,3.376,0.9931046463689198,0.10350980586946733,-0.05503527459119239
fast,3.426,0.9725948196320136,0.20529173779377843,-0.10915410765784948
fast,3.476,0.9662434406366642,0.22747505904204074,-0.12094920810175326
fast,3.526,0.9554895457575009,0.26049211070264017,-0.13850483099808442
fast,3.577,0.9554895457575009,0.26049211070264017,-0.13850483099808442
fast,3.627,0.9554895457575009,0.26049211070264017,-0.13850483099808442
fast,3.677,0.9554895457575009,0.26049211070264017,-0.13850483099808442
fast,3.727,0.8909286923979324,0.4009849131652504,-0.21320685841681314
fast,3.778,0.8640929736842651,0.44441621107211554,-0.23629973374041036
fast,3.829,0.8128494133306493,0.5142939755758894,-0.27345481881723305
fast,3.879,0.7814528720839342,0.5509276830126654,-0.2929336047674737
fast,3.929,0.7211597970721555,0.611678327920411,-0.3252355611542772
fast,3.979,0.6841778570037976,0.6439468055268214,-0.34239329963872395
fast,4.029,0.6746720278390272,0.65171893206941,-0.34652573992978153
fast,4.082,0.6746720278390272,0.65171893206941,-0.34652573992978153
fast,4.133,0.6746720278390272,0.65171893206941,-0.34652573992978153
fast,4.183,0.6746720278390272,0.65171893206941,-0.34652573992978153
fast,4.233,0.5182188187016136,0.7551386081987147,-0.4015158008736547
fast,4.284,0.47114018545956854,0.7788105659042874,-0.41410267818618
fast,4.335,0.37644461942850993,0.8179963583095251,-0.4349383936785522
fast,4.385,0.32771191712873915,0.8341882735212928,-0.44354799480030493
fast,4.435,0.22775844025010583,0.8597406189563827,-0.4571347296053267
fast,4.485,0.20235015483807314,0.864681197867618,-0.4597617218638685
fast,4.536,0.18963344038093657,0.8669254276051488,-0.4609549449359662
fast,4.586,0.18963344038093657,0.8669254276051488,-0.4609549449359662
fast,4.636,0.18963344038093657,0.8669254276051488,-0.4609549449359662
fast,4.686,0.0616702782462941,0.8812657670818295,-0.46858022210791117
fast,4.742,-0.033265594992281614,0.8824576094559936,-0.4692142023671305
fast,4.793,-0.08561358744104564,0.8797044474697407,-0.46775035943057547
fast,4.861,-0.16311988058380167,0.8711202450018558,-0.46318616484760533
fast,4.911,-0.2647679339679234,0.8514356989074474,-0.4527197717886242
fast,4.962,-0.31438943728704216,0.8381755148966445,-0.4456692584754773
fast,5.012,-0.31438943728704216,0.8381755148966445,-0.4456692584754773
fast,5.062,-0.31438943728704216,0.8381755148966445,-0.4456692584754773
fast,5.112,-0.31438943728704216,0.8381755148966445,-0.4456692584754773
fast,5.163,-0.4463483290724788,0.7901123971308208,-0.42011375725438266
fast,5.213,-0.505148005766188,0.7620111594970173,-0.40517216719865473
fast,5.263,-0.5274613820707995,0.7501322143205744,-0.3988560535612739
fast,5.313,-0.6235599606983542,0.6902653205120604,-0.36702419908263495
fast,5.364,-0.6535579280284671,0.6682807541755503,-0.3553348678496027
fast,5.414,-0.6535579280284671,0.6682807541755503,-0.3553348678496027
fast,5.464,-0.6535579280284671,0.6682807541755503,-0.3553348678496027
fast,5.514,-0.6535579280284671,0.6682807541755503,-0.3553348678496027
fast,5.564,-0.7542996656095252,0.5796803289795648,-0.3082251298247795
fast,5.615,-0.8053480118610813,0.5234118913151391,-0.2783066147638474
fast,5.665,-0.835317794193117,0.4854144024411218,-0.25810277140525667
fast,5.715,-0.8756811392589173,0.4263650045332836,-0.22670559158419007
fast,5.765,-0.8879541369536935,0.4060944713229071,-0.21592760598818767
fast,5.816,-0.8938471875490723,0.3958873769547781,-0.21050033272771532
fast,5.867,-0.8938471875490723,0.3958873769547781,-0.21050033272771532
fast,5.917,-0.8938471875490723,0.3958873769547781,-0.21050033272771532
fast,5.967,-0.8938471875490723,0.3958873769547781,-0.21050033272771532
fast,6.017,-0.9568362261302265,0.2566077577804137,-0.1364437430290401
fast,6.067,-0.9711494705384393,0.21055675115725614,-0.11195785106463185
fast,6.118,-0.9868689841435945,0.1426150745455621,-0.07583237203037746
fast,6.168,-0.9907414896934681,0.11986964152412082,-0.06373829022531322
fast,6.218,-0.9974727159739508,0.06273297303862826,-0.03335798227238545
fast,6.27,-0.9974727159739508,0.06273297303862826,-0.03335798227238545
fast,6.321,-0.9974727159739508,0.06273297303862826,-0.03335798227238545
fast,6.371,-0.9974727159739508,0.06273297303862826,-0.03335798227238545
fast,6.421,-0.9962961796573708,-0.0759235377258525,0.04036754661010212
fast,6.471,-0.9935876720124013,-0.09983054395307195,0.053079191016920685
fast,6.521,-0.98151891503074,-0.1689659788258626,0.0898393980183376
fast,6.572,-0.9761981791370964,-0.19149456258495987,0.1018182083412009
fast,6.622,-0.9600279771648162,-0.24714097112937958,0.13140632956619028
fast,6.673,-0.9600279771648162,-0.24714097112937958,0.13140632956619028
fast,6.723,-0.9600279771648162,-0.24714097112937958,0.13140632956619028
fast,6.773,-0.9600279771648162,-0.24714097112937958,0.13140632956619028
fast,6.823,-0.9600279771648162,-0.24714097112937958,0.13140632956619028
fast,6.874,-0.8987677690425633,-0.3871064780875767,0.20582777254997944
fast,6.924,-0.8670890034724157,-0.43984325215975256,0.23386871014897564
fast,6.974,-0.8537120733075257,-0.4597908235105943,0.24447514087206346
fast,7.024,-0.7865457418615867,-0.545248184091142,0.2899141488522395
fast,7.074,-0.7533129809628684,-0.5806809342120418,0.3087542798982184
fast,7.127,-0.7447100018154831,-0.5892684722773185,0.31332041231930347
fast,7.179,-0.7447100018154831,-0.5892684722773185,0.31332041231930347
fast,7.229,-0.7447100018154831,-0.5892684722773185,0.31332041231930347
fast,7.279,-0.7447100018154831,-0.5892684722773185,0.31332041231930347
fast,7.329,-0.5992280106837283,-0.7068679873070793,0.3758502889881291
fast,7.379,-0.5443899367788374,-0.7406440829377567,0.3938095213973664
fast,7.431,-0.4771420994818272,-0.7759564582613324,0.4125857387072451
fast,7.481,-0.41846538807715317,-0.801920794933833,0.42639155436538256
fast,7.531,-0.35845204323781216,-0.8242729196805756,0.43827649558229453
fast,7.581,-0.35845204323781216,-0.8242729196805756,0.43827649558229453
fast,7.631,-0.35845204323781216,-0.8242729196805756,0.43827649558229453
fast,7.681,-0.35845204323781216,-0.8242729196805756,0.43827649558229453
fast,7.732,-0.23477000507402776,-0.8582687461538578,0.4563527189499649
fast,7.783,-0.20781325308245005,-0.8636701935950999,0.4592248344097825
fast,7.861,-0.10263756227815277,-0.8782831695934015,0.4669948659445483
fast,7.911,-0.02463647965351885,-0.8826781186805318,0.4693318470686588
fast,7.962,0.001224726571744081,-0.8829453951924657,0.4694740984902627
1 phase t fx fy fz
2 slow 0.022 -0.9999999999976801 -5.364418029772711e-07 -2.0861625671338324e-06
3 slow 0.072 -0.9999999999976801 -5.364418029772711e-07 -2.0861625671338324e-06
4 slow 0.138 -0.9999999999976801 -5.364418029772711e-07 -2.0861625671338324e-06
5 slow 0.188 -0.9999999999976801 -5.364418029772711e-07 -2.0861625671338324e-06
6 slow 0.238 -0.9999996503301273 -0.000739351008976433 0.00039076810084039696
7 slow 0.288 -0.9995667500505145 -0.025989011351613873 0.013816058859813869
8 slow 0.338 -0.9991424233572718 -0.03655991231151712 0.01943683769373226
9 slow 0.388 -0.9974614922372212 -0.06287386978474002 0.03342825155743701
10 slow 0.441 -0.9974614922372212 -0.06287386978474002 0.03342825155743701
11 slow 0.491 -0.9974614922372212 -0.06287386978474002 0.03342825155743701
12 slow 0.542 -0.9974614922372212 -0.06287386978474002 0.03342825155743701
13 slow 0.592 -0.9756937705208446 -0.19348862930198532 0.10287767735352636
14 slow 0.642 -0.9599895265779043 -0.24725777991348272 0.13146748317735063
15 slow 0.692 -0.9065968643570531 -0.3726025922234667 0.19811469861247516
16 slow 0.742 -0.8880690175394421 -0.405900585102419 0.215819681910719
17 slow 0.792 -0.8231976038572328 -0.5012983450542031 0.2665439443124295
18 slow 0.845 -0.8111180643235866 -0.5164209971100269 0.2745848493122731
19 slow 0.895 -0.8111180643235866 -0.5164209971100269 0.2745848493122731
20 slow 0.946 -0.8111180643235866 -0.5164209971100269 0.2745848493122731
21 slow 0.996 -0.8111180643235866 -0.5164209971100269 0.2745848493122731
22 slow 1.047 -0.6225347328753619 -0.6909879300492386 0.3674046636749054
23 slow 1.098 -0.4995761468930651 -0.7648708472261829 0.40668939071357624
24 slow 1.148 -0.42441628069163945 -0.7994799112461082 0.425091392759005
25 slow 1.198 -0.34635895158661695 -0.8282947460891245 0.440412636350244
26 slow 1.249 -0.26597407096587283 -0.8511436226859083 0.4525619594430681
27 slow 1.3 -0.22508987440157757 -0.8602890836759516 0.45742457405551984
28 slow 1.35 -0.22508987440157757 -0.8602890836759516 0.45742457405551984
29 slow 1.4 -0.22508987440157757 -0.8602890836759516 0.45742457405551984
30 slow 1.45 0.0050435963756794286 -0.8829357634414114 0.4694667184920898
31 slow 1.5 0.1113271185026686 -0.8774582682112876 0.4665546701443904
32 slow 1.551 0.19530088938670107 -0.8659441420087264 0.46043273724349176
33 slow 1.601 0.35806279594948665 -0.8244050055782095 0.4383462340826355
34 slow 1.651 0.4357105639703388 -0.7947284845866424 0.4225670837053784
35 slow 1.701 0.4357105639703388 -0.7947284845866424 0.4225670837053784
36 slow 1.751 0.4357105639703388 -0.7947284845866424 0.4225670837053784
37 slow 1.801 0.581059227173933 -0.7185957552011922 0.38208679003972373
38 slow 1.854 0.5981621070188505 -0.707571139880663 0.3762249004714446
39 slow 1.933 0.7102092219298712 -0.6215856943388454 0.3305058027918156
40 slow 1.983 0.7936818073741404 -0.5371251153693617 0.28559726728869045
41 slow 2.034 0.8306115980329357 -0.491670162790673 0.2614284304251665
42 slow 2.085 0.8306115980329357 -0.491670162790673 0.2614284304251665
43 slow 2.136 0.8306115980329357 -0.491670162790673 0.2614284304251665
44 slow 2.186 0.8306115980329357 -0.491670162790673 0.2614284304251665
45 slow 2.236 0.9439254674422402 -0.29151154402331125 0.15500236003072188
46 slow 2.288 0.9782500298959619 -0.18314796371755346 0.09738430260911397
47 slow 2.338 0.9923168633793271 -0.1092393189325843 0.05808626216377494
48 slow 2.388 0.9999950320089501 0.0027841479666426932 -0.0014779978073891553
49 slow 2.439 0.9961448118772039 0.07745674002692376 -0.04118212226842516
50 slow 2.489 0.9885868780617736 0.1330186187164556 -0.07072504223287812
51 slow 2.54 0.9885868780617736 0.1330186187164556 -0.07072504223287812
52 slow 2.59 0.9885868780617736 0.1330186187164556 -0.07072504223287812
53 slow 2.64 0.9885868780617736 0.1330186187164556 -0.07072504223287812
54 slow 2.69 0.9104394306290844 0.3652252075952527 -0.1941921494108173
55 slow 2.741 0.8718210936242394 0.4324898355933772 -0.22995765440673788
56 slow 2.791 0.8021474529558832 0.5272312979999614 -0.28033305571349426
57 slow 2.841 0.7483879225773887 0.5856251973581853 -0.31138183241718986
58 slow 2.891 0.6415804884515123 0.6772700855747096 -0.3601106885722006
59 slow 2.942 0.5565400067937 0.7335711833839508 -0.39004684301598735
60 slow 2.992 0.5025832072518267 0.7633335327127708 -0.4058719473241637
61 slow 3.042 0.5025832072518267 0.7633335327127708 -0.4058719473241637
62 slow 3.092 0.5025832072518267 0.7633335327127708 -0.4058719473241637
63 slow 3.142 0.5025832072518267 0.7633335327127708 -0.4058719473241637
64 slow 3.193 0.26840150425248394 0.8505494121077833 -0.4522458734782528
65 slow 3.243 0.14383384202445684 0.8737661032159637 -0.4645908121769882
66 slow 3.293 0.017126773329819035 0.8828175004515181 -0.46940380753871486
67 slow 3.344 -0.025233536073355507 0.8826657223955247 -0.46932343982079283
68 slow 3.394 -0.1306276597599528 0.8753813567867831 -0.46545020646226887
69 slow 3.444 -0.1306276597599528 0.8753813567867831 -0.46545020646226887
70 slow 3.494 -0.1306276597599528 0.8753813567867831 -0.46545020646226887
71 slow 3.544 -0.1306276597599528 0.8753813567867831 -0.46545020646226887
72 slow 3.594 -0.3953899986357624 0.8109981935802458 -0.4312176700790331
73 slow 3.644 -0.5092096812736444 0.7599012381904277 -0.40404901768702334
74 slow 3.695 -0.6146085873298012 0.6964964366951696 -0.37033633099035523
75 slow 3.745 -0.6475735623151888 0.6728076094689478 -0.35774069104743467
76 slow 3.795 -0.7246428766140702 0.6084598143649699 -0.32352643736707504
77 slow 3.845 -0.7246428766140702 0.6084598143649699 -0.32352643736707504
78 slow 3.895 -0.7246428766140702 0.6084598143649699 -0.32352643736707504
79 slow 3.946 -0.7246428766140702 0.6084598143649699 -0.32352643736707504
80 slow 4.0 -0.8948032879220578 0.39420026288722865 -0.2096025492772329
81 slow 4.05 -0.9371976061971167 0.3079700993685502 -0.16375306053115327
82 slow 4.1 -0.9739646105616616 0.20016331274041113 -0.10643113081357014
83 slow 4.151 -0.9925182516704475 0.1078037923584182 -0.057322442849038695
84 slow 4.201 -0.9998661518865883 0.014444979973920849 -0.007682503827448022
85 slow 4.252 -0.999988574147902 -0.004221603854607207 0.0022426846725771095
86 slow 4.302 -0.999988574147902 -0.004221603854607207 0.0022426846725771095
87 slow 4.352 -0.999988574147902 -0.004221603854607207 0.0022426846725771095
88 slow 4.402 -0.999988574147902 -0.004221603854607207 0.0022426846725771095
89 slow 4.454 -0.9481592609187346 -0.28059728776173093 0.1491951005723691
90 slow 4.504 -0.8998604949330586 -0.3851225220144059 0.20477239241678594
91 slow 4.554 -0.8483542366290391 -0.4674583762955424 0.24855131386636348
92 slow 4.605 -0.8002653758276345 -0.5294561807103555 0.281516395542175
93 slow 4.655 -0.7740407763904767 -0.5590258203543885 0.2972389756777044
94 slow 4.705 -0.7320686741889714 -0.6014912262488834 0.31981832501721374
95 slow 4.755 -0.7320686741889714 -0.6014912262488834 0.31981832501721374
96 slow 4.805 -0.7320686741889714 -0.6014912262488834 0.31981832501721374
97 slow 4.855 -0.7320686741889714 -0.6014912262488834 0.31981832501721374
98 slow 4.905 -0.5000347671416738 -0.7646370203731946 0.4065654421177173
99 slow 4.956 -0.38571043654168863 -0.8146245270401747 0.43314470917626546
100 slow 5.033 -0.3059761515320789 -0.8406001527732009 0.44695634893274494
101 slow 5.083 -0.14067269192255813 -0.8741670164828578 0.46480449765543375
102 slow 5.136 -0.11971066366716597 -0.876597475120388 0.46609679640277224
103 slow 5.186 -0.11971066366716597 -0.876597475120388 0.46609679640277224
104 slow 5.236 -0.11971066366716597 -0.876597475120388 0.46609679640277224
105 slow 5.286 0.09210780811437987 -0.8791932987194956 0.4674775878810623
106 slow 5.336 0.1552569076145395 -0.8722401249754417 0.46378061302818196
107 slow 5.389 0.29980078422712286 -0.8423325684075889 0.4478787045358116
108 slow 5.439 0.39908806765876 -0.8095847039629167 0.43046639980569157
109 slow 5.49 0.4751133264531701 -0.7769262478123317 0.4131016006829976
110 slow 5.542 0.4751133264531701 -0.7769262478123317 0.4131016006829976
111 slow 5.592 0.4751133264531701 -0.7769262478123317 0.4131016006829976
112 slow 5.642 0.4751133264531701 -0.7769262478123317 0.4131016006829976
113 slow 5.692 0.696657860237904 -0.633428595248907 0.3368026729254701
114 slow 5.742 0.726585020550654 -0.6066514667740671 0.3225650411502751
115 slow 5.792 0.8325182828011221 -0.48914972660411055 0.2600881653689665
116 slow 5.843 0.8765739353060135 -0.4249327255756417 0.22594316691811042
117 slow 5.893 0.9054260508840364 -0.37481374091028163 0.19929457093804306
118 slow 5.943 0.9054260508840364 -0.37481374091028163 0.19929457093804306
119 slow 5.993 0.9054260508840364 -0.37481374091028163 0.19929457093804306
120 slow 6.043 0.9054260508840364 -0.37481374091028163 0.19929457093804306
121 slow 6.093 0.9868879110680581 -0.14251307214027348 0.07577780187407064
122 slow 6.144 0.9928589520370625 -0.10532958640717122 0.056006960167108814
123 slow 6.194 0.9995721898785164 0.025825160128774418 -0.013729469246492699
124 slow 6.244 0.9934893887944055 0.10059024435508387 -0.05348305426490678
125 slow 6.294 0.9538232020213261 0.26521033194280885 -0.14101340048580407
126 slow 6.344 0.947267673727074 0.2829352443494437 -0.1504380331452729
127 slow 6.394 0.947267673727074 0.2829352443494437 -0.1504380331452729
128 slow 6.445 0.947267673727074 0.2829352443494437 -0.1504380331452729
129 slow 6.495 0.947267673727074 0.2829352443494437 -0.1504380331452729
130 slow 6.545 0.8243733791338322 0.4997895512364342 -0.2657422364818033
131 slow 6.597 0.7593203746728908 0.5745491212947682 -0.30549284087524925
132 slow 6.647 0.7010074410559842 0.6296776548998042 -0.3348053441987208
133 slow 6.697 0.6041754101078993 0.7035779205024607 -0.37409916279294836
134 slow 6.747 0.5340870381020223 0.7464697028629991 -0.39690555355025536
135 slow 6.797 0.4025055990782129 0.8082653740061208 -0.4297631067151235
136 slow 6.847 0.3433573357356595 0.8292682687272306 -0.44093069577729704
137 slow 6.898 0.3433573357356595 0.8292682687272306 -0.44093069577729704
138 slow 6.948 0.3433573357356595 0.8292682687272306 -0.44093069577729704
139 slow 6.999 0.3433573357356595 0.8292682687272306 -0.44093069577729704
140 slow 7.049 0.09503184681410931 0.8789508919606488 -0.46734813320765445
141 slow 7.1 -0.03242949378753749 0.8824823690120825 -0.4692261675519672
142 slow 7.15 -0.07486618489555856 0.8804688348729269 -0.46815562068258304
143 slow 7.202 -0.2217573682314415 0.8609628101781774 -0.4577845662810842
144 slow 7.253 -0.3436636683706333 0.8291685841702975 -0.44087950969291334
145 slow 7.306 -0.3436636683706333 0.8291685841702975 -0.44087950969291334
146 slow 7.356 -0.3436636683706333 0.8291685841702975 -0.44087950969291334
147 slow 7.406 -0.3436636683706333 0.8291685841702975 -0.44087950969291334
148 slow 7.456 -0.5335192585826919 0.7467851744734487 -0.3970756904017614
149 slow 7.506 -0.5863848618861591 0.715215075832045 -0.38028961207652284
150 slow 7.557 -0.6691599892298212 0.6561333325626291 -0.3488752767311034
151 slow 7.607 -0.7582631988698701 0.5756351874374445 -0.30607360589160554
152 slow 7.657 -0.8108505756823166 0.51674664977568 -0.27476215871416254
153 slow 7.707 -0.8575526461274808 0.4541837039893854 -0.24149662968711988
154 slow 7.757 -0.8575526461274808 0.4541837039893854 -0.24149662968711988
155 slow 7.808 -0.8575526461274808 0.4541837039893854 -0.24149662968711988
156 slow 7.859 -0.8575526461274808 0.4541837039893854 -0.24149662968711988
157 slow 7.909 -0.9532867456950477 0.2667081367420545 -0.1418137873329921
158 slow 7.959 -0.9755224624568912 0.19415891248194872 -0.10323876183813074
159 fast 0.031 -0.9183790521746182 -0.3493842945716818 0.1857701031745906
160 fast 0.081 -0.9181941875656858 -0.34976292144045307 0.18597132226778823
161 fast 0.131 -0.9157256739103099 -0.35477222000318137 0.18863499690015914
162 fast 0.181 -0.9149015400332507 -0.3564260247285592 0.18951427635136814
163 fast 0.231 -0.9149015400332507 -0.3564260247285592 0.18951427635136814
164 fast 0.282 -0.9149015400332507 -0.3564260247285592 0.18951427635136814
165 fast 0.334 -0.886987130221704 -0.40774025376731704 0.21679879215260833
166 fast 0.392 -0.874422882615109 -0.42837502256975 0.22777063550301968
167 fast 0.442 -0.8391761714215903 -0.4801996653842019 0.2553265256159302
168 fast 0.492 -0.8087011271707248 -0.5193672154489234 0.27615246229144985
169 fast 0.542 -0.7639193320090165 -0.5697763250541364 0.3029557617717493
170 fast 0.592 -0.7142788381999624 -0.6179405632697418 0.3285653687861613
171 fast 0.644 -0.7056326965418199 -0.6256368844308748 0.3326574610778302
172 fast 0.694 -0.7056326965418199 -0.6256368844308748 0.3326574610778302
173 fast 0.761 -0.7056326965418199 -0.6256368844308748 0.3326574610778302
174 fast 0.811 -0.6045554154137983 -0.703323001692553 0.37396457717814224
175 fast 0.861 -0.5641123049229769 -0.7290475533490074 0.38764284127313964
176 fast 0.911 -0.5010910596413976 -0.7640973590830287 0.4062794306752468
177 fast 0.961 -0.4574254856752507 -0.7851585926980168 0.4174780345925168
178 fast 1.011 -0.40119022065553167 -0.8087745891735626 0.43003496457555734
179 fast 1.062 -0.40119022065553167 -0.8087745891735626 0.43003496457555734
180 fast 1.112 -0.40119022065553167 -0.8087745891735626 0.43003496457555734
181 fast 1.162 -0.40119022065553167 -0.8087745891735626 0.43003496457555734
182 fast 1.213 -0.2732721277804909 -0.8493387726086905 0.4516038014918455
183 fast 1.263 -0.24847333019197224 -0.8552561875978043 0.45475032463867526
184 fast 1.314 -0.13690544128361162 -0.8746327174969611 0.46505323311511404
185 fast 1.364 -0.11190820705598208 -0.8774002355189958 0.46652479023598115
186 fast 1.414 -0.04853388875408303 -0.8819058319940255 0.46892063842118525
187 fast 1.464 -0.023325922091828814 -0.8827061212913064 0.4693461460302229
188 fast 1.52 -0.023325922091828814 -0.8827061212913064 0.4693461460302229
189 fast 1.57 -0.023325922091828814 -0.8827061212913064 0.4693461460302229
190 fast 1.623 0.11590445397311018 -0.8769955308131724 0.4663099789656202
191 fast 1.674 0.16796962344551228 -0.8704014300065923 0.46280401493726464
192 fast 1.724 0.2673695301474367 -0.8508015956107015 0.4523827795739172
193 fast 1.776 0.3040082366636887 -0.8411556467255445 0.44725403298613803
194 fast 1.826 0.34060203879357387 -0.8301524613755806 0.44140360447296506
195 fast 1.876 0.34060203879357387 -0.8301524613755806 0.44140360447296506
196 fast 1.926 0.34060203879357387 -0.8301524613755806 0.44140360447296506
197 fast 1.976 0.34060203879357387 -0.8301524613755806 0.44140360447296506
198 fast 2.026 0.4800222448487086 -0.7745698100484196 0.41184979520689524
199 fast 2.077 0.5027716590432529 -0.7632352767416622 0.4058233251058559
200 fast 2.162 0.567685165746978 -0.726881238602736 0.3864934896711436
201 fast 2.213 0.60896099881303 -0.7003525641308903 0.37238795340333464
202 fast 2.263 0.60896099881303 -0.7003525641308903 0.37238795340333464
203 fast 2.313 0.60896099881303 -0.7003525641308903 0.37238795340333464
204 fast 2.363 0.60896099881303 -0.7003525641308903 0.37238795340333464
205 fast 2.415 0.7138914376865056 -0.6182880840720885 0.3287534947226572
206 fast 2.465 0.7492325438071801 -0.584780749889073 0.31093740505026973
207 fast 2.515 0.7980625863701071 -0.5320401745258126 0.28289461098931906
208 fast 2.566 0.8280000832233713 -0.4950917864992449 0.2632489033653826
209 fast 2.618 0.8351255264037815 -0.48567212818960787 0.2582400802520477
210 fast 2.669 0.8351255264037815 -0.48567212818960787 0.2582400802520477
211 fast 2.719 0.8351255264037815 -0.48567212818960787 0.2582400802520477
212 fast 2.769 0.8351255264037815 -0.48567212818960787 0.2582400802520477
213 fast 2.82 0.9093870336730951 -0.36726148601053504 0.1952798604070126
214 fast 2.871 0.9203632924764715 -0.3452879583192104 0.18359639348750836
215 fast 2.921 0.9600488101430662 -0.247076202859695 0.13137591911502494
216 fast 2.972 0.9669595427173864 -0.2250884627532023 0.1196846969465328
217 fast 3.022 0.9813959442736294 -0.16952014269323645 0.09013834802422341
218 fast 3.074 0.9837681894544645 -0.158438487459875 0.08424603912892294
219 fast 3.124 0.9837681894544645 -0.158438487459875 0.08424603912892294
220 fast 3.174 0.9837681894544645 -0.158438487459875 0.08424603912892294
221 fast 3.224 0.9985768344211968 -0.04708834623109012 0.025039836392490022
222 fast 3.276 0.9999091072744978 0.011905223183064872 -0.006327942041318827
223 fast 3.326 0.9958087405962524 0.08075529499181068 -0.04293640044171679
224 fast 3.376 0.9931046463689198 0.10350980586946733 -0.05503527459119239
225 fast 3.426 0.9725948196320136 0.20529173779377843 -0.10915410765784948
226 fast 3.476 0.9662434406366642 0.22747505904204074 -0.12094920810175326
227 fast 3.526 0.9554895457575009 0.26049211070264017 -0.13850483099808442
228 fast 3.577 0.9554895457575009 0.26049211070264017 -0.13850483099808442
229 fast 3.627 0.9554895457575009 0.26049211070264017 -0.13850483099808442
230 fast 3.677 0.9554895457575009 0.26049211070264017 -0.13850483099808442
231 fast 3.727 0.8909286923979324 0.4009849131652504 -0.21320685841681314
232 fast 3.778 0.8640929736842651 0.44441621107211554 -0.23629973374041036
233 fast 3.829 0.8128494133306493 0.5142939755758894 -0.27345481881723305
234 fast 3.879 0.7814528720839342 0.5509276830126654 -0.2929336047674737
235 fast 3.929 0.7211597970721555 0.611678327920411 -0.3252355611542772
236 fast 3.979 0.6841778570037976 0.6439468055268214 -0.34239329963872395
237 fast 4.029 0.6746720278390272 0.65171893206941 -0.34652573992978153
238 fast 4.082 0.6746720278390272 0.65171893206941 -0.34652573992978153
239 fast 4.133 0.6746720278390272 0.65171893206941 -0.34652573992978153
240 fast 4.183 0.6746720278390272 0.65171893206941 -0.34652573992978153
241 fast 4.233 0.5182188187016136 0.7551386081987147 -0.4015158008736547
242 fast 4.284 0.47114018545956854 0.7788105659042874 -0.41410267818618
243 fast 4.335 0.37644461942850993 0.8179963583095251 -0.4349383936785522
244 fast 4.385 0.32771191712873915 0.8341882735212928 -0.44354799480030493
245 fast 4.435 0.22775844025010583 0.8597406189563827 -0.4571347296053267
246 fast 4.485 0.20235015483807314 0.864681197867618 -0.4597617218638685
247 fast 4.536 0.18963344038093657 0.8669254276051488 -0.4609549449359662
248 fast 4.586 0.18963344038093657 0.8669254276051488 -0.4609549449359662
249 fast 4.636 0.18963344038093657 0.8669254276051488 -0.4609549449359662
250 fast 4.686 0.0616702782462941 0.8812657670818295 -0.46858022210791117
251 fast 4.742 -0.033265594992281614 0.8824576094559936 -0.4692142023671305
252 fast 4.793 -0.08561358744104564 0.8797044474697407 -0.46775035943057547
253 fast 4.861 -0.16311988058380167 0.8711202450018558 -0.46318616484760533
254 fast 4.911 -0.2647679339679234 0.8514356989074474 -0.4527197717886242
255 fast 4.962 -0.31438943728704216 0.8381755148966445 -0.4456692584754773
256 fast 5.012 -0.31438943728704216 0.8381755148966445 -0.4456692584754773
257 fast 5.062 -0.31438943728704216 0.8381755148966445 -0.4456692584754773
258 fast 5.112 -0.31438943728704216 0.8381755148966445 -0.4456692584754773
259 fast 5.163 -0.4463483290724788 0.7901123971308208 -0.42011375725438266
260 fast 5.213 -0.505148005766188 0.7620111594970173 -0.40517216719865473
261 fast 5.263 -0.5274613820707995 0.7501322143205744 -0.3988560535612739
262 fast 5.313 -0.6235599606983542 0.6902653205120604 -0.36702419908263495
263 fast 5.364 -0.6535579280284671 0.6682807541755503 -0.3553348678496027
264 fast 5.414 -0.6535579280284671 0.6682807541755503 -0.3553348678496027
265 fast 5.464 -0.6535579280284671 0.6682807541755503 -0.3553348678496027
266 fast 5.514 -0.6535579280284671 0.6682807541755503 -0.3553348678496027
267 fast 5.564 -0.7542996656095252 0.5796803289795648 -0.3082251298247795
268 fast 5.615 -0.8053480118610813 0.5234118913151391 -0.2783066147638474
269 fast 5.665 -0.835317794193117 0.4854144024411218 -0.25810277140525667
270 fast 5.715 -0.8756811392589173 0.4263650045332836 -0.22670559158419007
271 fast 5.765 -0.8879541369536935 0.4060944713229071 -0.21592760598818767
272 fast 5.816 -0.8938471875490723 0.3958873769547781 -0.21050033272771532
273 fast 5.867 -0.8938471875490723 0.3958873769547781 -0.21050033272771532
274 fast 5.917 -0.8938471875490723 0.3958873769547781 -0.21050033272771532
275 fast 5.967 -0.8938471875490723 0.3958873769547781 -0.21050033272771532
276 fast 6.017 -0.9568362261302265 0.2566077577804137 -0.1364437430290401
277 fast 6.067 -0.9711494705384393 0.21055675115725614 -0.11195785106463185
278 fast 6.118 -0.9868689841435945 0.1426150745455621 -0.07583237203037746
279 fast 6.168 -0.9907414896934681 0.11986964152412082 -0.06373829022531322
280 fast 6.218 -0.9974727159739508 0.06273297303862826 -0.03335798227238545
281 fast 6.27 -0.9974727159739508 0.06273297303862826 -0.03335798227238545
282 fast 6.321 -0.9974727159739508 0.06273297303862826 -0.03335798227238545
283 fast 6.371 -0.9974727159739508 0.06273297303862826 -0.03335798227238545
284 fast 6.421 -0.9962961796573708 -0.0759235377258525 0.04036754661010212
285 fast 6.471 -0.9935876720124013 -0.09983054395307195 0.053079191016920685
286 fast 6.521 -0.98151891503074 -0.1689659788258626 0.0898393980183376
287 fast 6.572 -0.9761981791370964 -0.19149456258495987 0.1018182083412009
288 fast 6.622 -0.9600279771648162 -0.24714097112937958 0.13140632956619028
289 fast 6.673 -0.9600279771648162 -0.24714097112937958 0.13140632956619028
290 fast 6.723 -0.9600279771648162 -0.24714097112937958 0.13140632956619028
291 fast 6.773 -0.9600279771648162 -0.24714097112937958 0.13140632956619028
292 fast 6.823 -0.9600279771648162 -0.24714097112937958 0.13140632956619028
293 fast 6.874 -0.8987677690425633 -0.3871064780875767 0.20582777254997944
294 fast 6.924 -0.8670890034724157 -0.43984325215975256 0.23386871014897564
295 fast 6.974 -0.8537120733075257 -0.4597908235105943 0.24447514087206346
296 fast 7.024 -0.7865457418615867 -0.545248184091142 0.2899141488522395
297 fast 7.074 -0.7533129809628684 -0.5806809342120418 0.3087542798982184
298 fast 7.127 -0.7447100018154831 -0.5892684722773185 0.31332041231930347
299 fast 7.179 -0.7447100018154831 -0.5892684722773185 0.31332041231930347
300 fast 7.229 -0.7447100018154831 -0.5892684722773185 0.31332041231930347
301 fast 7.279 -0.7447100018154831 -0.5892684722773185 0.31332041231930347
302 fast 7.329 -0.5992280106837283 -0.7068679873070793 0.3758502889881291
303 fast 7.379 -0.5443899367788374 -0.7406440829377567 0.3938095213973664
304 fast 7.431 -0.4771420994818272 -0.7759564582613324 0.4125857387072451
305 fast 7.481 -0.41846538807715317 -0.801920794933833 0.42639155436538256
306 fast 7.531 -0.35845204323781216 -0.8242729196805756 0.43827649558229453
307 fast 7.581 -0.35845204323781216 -0.8242729196805756 0.43827649558229453
308 fast 7.631 -0.35845204323781216 -0.8242729196805756 0.43827649558229453
309 fast 7.681 -0.35845204323781216 -0.8242729196805756 0.43827649558229453
310 fast 7.732 -0.23477000507402776 -0.8582687461538578 0.4563527189499649
311 fast 7.783 -0.20781325308245005 -0.8636701935950999 0.4592248344097825
312 fast 7.861 -0.10263756227815277 -0.8782831695934015 0.4669948659445483
313 fast 7.911 -0.02463647965351885 -0.8826781186805318 0.4693318470686588
314 fast 7.962 0.001224726571744081 -0.8829453951924657 0.4694740984902627

View File

@@ -0,0 +1,314 @@
phase,t,fx,fy,fz
slow,0.046,5.36441810913306e-07,0.8829469811387421,-0.4694727132621171
slow,0.124,-0.0037028938908542333,0.8829408973863202,-0.4694695520472787
slow,0.175,-0.029433192564468726,0.8825644180942943,-0.4692693630414654
slow,0.225,-0.047907995026344505,0.8819330671344229,-0.46893377902154315
slow,0.276,-0.05494452988794276,0.8816131314630001,-0.4687636772056853
slow,0.327,-0.05494452988794276,0.8816131314630001,-0.4687636772056853
slow,0.377,-0.05494452988794276,0.8816131314630001,-0.4687636772056853
slow,0.427,-0.05494452988794276,0.8816131314630001,-0.4687636772056853
slow,0.478,-0.2805405845010285,0.8474894135274412,-0.4506203217862406
slow,0.529,-0.3464401476183601,0.828267481843762,-0.440400048408674
slow,0.579,-0.4933270963841563,0.7680254218881261,-0.4083691066997395
slow,0.629,-0.5646325672888053,0.7287328660233411,-0.3874770624621025
slow,0.679,-0.663984471662157,0.6602195443081346,-0.35104810881855686
slow,0.729,-0.6795143538879752,0.6477839998044589,-0.3444359627819725
slow,0.782,-0.6795143538879752,0.6477839998044589,-0.3444359627819725
slow,0.832,-0.6795143538879752,0.6477839998044589,-0.3444359627819725
slow,0.883,-0.6795143538879752,0.6477839998044589,-0.3444359627819725
slow,0.933,-0.8636404059341753,0.44509990979031433,-0.23666710701427646
slow,0.983,-0.9034235025038042,0.37856180077666735,-0.20128819666459757
slow,1.033,-0.9208475303349151,0.34428010688112226,-0.18306019196431236
slow,1.084,-0.9823258963987413,0.1652676638242847,-0.08787737227792251
slow,1.134,-0.9946318488171882,0.09136350259329508,-0.048581845502070904
slow,1.188,-0.9965908416220451,0.07284426607901787,-0.03873509125422061
slow,1.238,-0.9965908416220451,0.07284426607901787,-0.03873509125422061
slow,1.288,-0.9965908416220451,0.07284426607901787,-0.03873509125422061
slow,1.338,-0.9965908416220451,0.07284426607901787,-0.03873509125422061
slow,1.388,-0.9887775514835899,-0.13190930729666128,0.0701347868794932
slow,1.438,-0.9556714469692192,-0.2599717478297875,0.13822726134190855
slow,1.489,-0.8922483691415248,-0.39869133958378805,0.21198599837058513
slow,1.539,-0.8508838444950022,-0.46386065972493185,0.24663732794724316
slow,1.589,-0.7907927164969744,-0.5404386826976731,0.28735502393266027
slow,1.64,-0.7777418936805442,-0.5550070379438635,0.29510122779646286
slow,1.691,-0.7777418936805442,-0.5550070379438635,0.29510122779646286
slow,1.741,-0.7777418936805442,-0.5550070379438635,0.29510122779646286
slow,1.791,-0.5952358692207049,-0.7094937017300517,0.377243882917219
slow,1.841,-0.5604049203743158,-0.7312739567343891,0.38882480042081646
slow,1.892,-0.45017479352935263,-0.7884196750580088,0.4192100562393852
slow,1.942,-0.3527042657551637,-0.8262047790273792,0.4393009947979067
slow,1.993,-0.2515210843607131,-0.8545622769363128,0.454379201724106
slow,2.048,-0.21020554253366847,-0.8632198721332542,0.4589826600672126
slow,2.098,-0.21020554253366847,-0.8632198721332542,0.4589826600672126
slow,2.148,-0.21020554253366847,-0.8632198721332542,0.4589826600672126
slow,2.199,-0.21020554253366847,-0.8632198721332542,0.4589826600672126
slow,2.249,0.06423144170165734,-0.8811238583231025,0.46850300766455694
slow,2.3,0.12787323617667282,-0.8756985100693347,0.46561846498184756
slow,2.35,0.2327336093496518,-0.858701653919306,0.45658135817763307
slow,2.423,0.3547279040834424,-0.8255283263615021,0.43894315855170307
slow,2.479,0.5260315144840211,-0.7509151987562808,0.3992708479797423
slow,2.529,0.5961056688939317,-0.7089229256787852,0.3769433869423229
slow,2.581,0.5961056688939317,-0.7089229256787852,0.3769433869423229
slow,2.631,0.5961056688939317,-0.7089229256787852,0.3769433869423229
slow,2.681,0.5961056688939317,-0.7089229256787852,0.3769433869423229
slow,2.732,0.5961056688939317,-0.7089229256787852,0.3769433869423229
slow,2.782,0.8295924682130262,-0.4930097696572142,0.26214061819328877
slow,2.832,0.8741827941510458,-0.4287555674072037,0.22797610801923318
slow,2.882,0.9439064628362973,-0.29155959525346875,0.15502771310802138
slow,2.932,0.9571066736003423,-0.25582037216180104,0.1360248232371042
slow,2.982,0.9861968747582776,-0.14619466320861924,0.07773573609560003
slow,3.032,0.9966905224322332,-0.07177339798264935,0.03816519141555759
slow,3.083,0.9992422961997571,-0.03436404433766335,0.01827418786692905
slow,3.133,0.9992422961997571,-0.03436404433766335,0.01827418786692905
slow,3.184,0.9992422961997571,-0.03436404433766335,0.01827418786692905
slow,3.234,0.9992422961997571,-0.03436404433766335,0.01827418786692905
slow,3.286,0.9667885938062846,0.22566239526859874,-0.11998457504073406
slow,3.336,0.9415539672577656,0.2974325173987048,-0.15814557956209666
slow,3.386,0.8910494227865149,0.4007762840154738,-0.21309457131181636
slow,3.437,0.8493271610881868,0.46607942161808097,-0.24781716280765573
slow,3.487,0.761860256786668,0.5719223062697806,-0.30409509157499987
slow,3.537,0.748009652602088,0.586002088637891,-0.3115816293142661
slow,3.587,0.748009652602088,0.586002088637891,-0.3115816293142661
slow,3.637,0.748009652602088,0.586002088637891,-0.3115816293142661
slow,3.688,0.591663947524308,0.7118191730405439,-0.3784801686902885
slow,3.738,0.539041368473937,0.7436887413829951,-0.3954256681273002
slow,3.789,0.40803721926756004,0.8061006144181252,-0.4286110441030633
slow,3.839,0.36886970856393964,0.8206831516383724,-0.4363648733810532
slow,3.89,0.24776263895916018,0.8554178600934551,-0.4548339910001527
slow,3.94,0.16475926423798679,0.8708809062626716,-0.46305597065027154
slow,3.992,0.14387633165971442,0.8737609544059406,-0.46458733919873835
slow,4.042,0.14387633165971442,0.8737609544059406,-0.46458733919873835
slow,4.093,0.14387633165971442,0.8737609544059406,-0.46458733919873835
slow,4.143,0.14387633165971442,0.8737609544059406,-0.46458733919873835
slow,4.196,-0.1733023236078747,0.869586949506304,-0.46236872934967393
slow,4.247,-0.21515127447977428,0.86226908085857,-0.4584778743680502
slow,4.297,-0.3579950095311995,0.8244282743035451,-0.4383578374794213
slow,4.347,-0.3974270950667179,0.8102218773848151,-0.43080414751236507
slow,4.397,-0.5648254471144367,0.7286167551161777,-0.3874142982079373
slow,4.448,-0.6161812577464959,0.6954125799901635,-0.36975938283344584
slow,4.498,-0.6161812577464959,0.6954125799901635,-0.36975938283344584
slow,4.55,-0.6161812577464959,0.6954125799901635,-0.36975938283344584
slow,4.6,-0.6161812577464959,0.6954125799901635,-0.36975938283344584
slow,4.65,-0.7949436150360499,0.5356686009745564,-0.2848223987740045
slow,4.706,-0.8320602692300713,0.4897569720337153,-0.26041086135787
slow,4.756,-0.9052591628184888,0.37512792417883484,-0.1994614966213956
slow,4.824,-0.9519766029552919,0.2703318015873179,-0.14374026741403262
slow,4.874,-0.983175920401433,0.1612793283684674,-0.08575597812287565
slow,4.925,-0.992798606527993,0.10577208861815067,-0.05624226298282666
slow,4.975,-0.992798606527993,0.10577208861815067,-0.05624226298282666
slow,5.025,-0.992798606527993,0.10577208861815067,-0.05624226298282666
slow,5.075,-0.992798606527993,0.10577208861815067,-0.05624226298282666
slow,5.125,-0.9909352442124001,-0.11861635420392577,0.06306744241746298
slow,5.177,-0.971089850817662,-0.21077290020723444,0.11206822108502636
slow,5.227,-0.9473137584186095,-0.2828150426309014,0.15037385002881865
slow,5.278,-0.8692337732689488,-0.43653100062660777,0.23210629655517379
slow,5.329,-0.8474958640779253,-0.4686708632974702,0.24919546999657635
slow,5.379,-0.7866667561433955,-0.5451126777938068,0.2898406170420097
slow,5.43,-0.7734621510586307,-0.5596500718853581,0.29757032432430053
slow,5.48,-0.7734621510586307,-0.5596500718853581,0.29757032432430053
slow,5.531,-0.7734621510586307,-0.5596500718853581,0.29757032432430053
slow,5.581,-0.6062043205372735,-0.7022162337138214,0.3733747217886052
slow,5.632,-0.5541510145645213,-0.734979908569316,0.39079558218658444
slow,5.682,-0.42418330732008847,-0.7995763915406578,0.42514246539461586
slow,5.732,-0.3852348981801229,-0.8148002884614528,0.4332373058120499
slow,5.783,-0.243946035449459,-0.8562723940695657,0.45528883024171124
slow,5.833,-0.16070912377840446,-0.8714704720337134,0.4633700399332204
slow,5.883,-0.0975990723650993,-0.8787317852366855,0.4672310677686361
slow,5.934,-0.0975990723650993,-0.8787317852366855,0.4672310677686361
slow,5.984,-0.0975990723650993,-0.8787317852366855,0.4672310677686361
slow,6.034,-0.0975990723650993,-0.8787317852366855,0.4672310677686361
slow,6.085,0.1775602464395945,-0.8689168079517865,0.46201292161928603
slow,6.135,0.2607328887465965,-0.8524065164179079,0.45323447738906825
slow,6.185,0.36194842063416144,-0.8230812569371999,0.4376420743931222
slow,6.235,0.4398997578876258,-0.7929274597606337,0.4216091158501638
slow,6.285,0.5682409772730201,-0.7265432946265349,0.38631209246025844
slow,6.336,0.6359981125758746,-0.6813614183433645,0.36228858440895406
slow,6.386,0.7140739082487315,-0.6181244196428086,0.32866495919039396
slow,6.436,0.7140739082487315,-0.6181244196428086,0.32866495919039396
slow,6.487,0.7140739082487315,-0.6181244196428086,0.32866495919039396
slow,6.539,0.7140739082487315,-0.6181244196428086,0.32866495919039396
slow,6.589,0.7140739082487315,-0.6181244196428086,0.32866495919039396
slow,6.639,0.9065680252911018,-0.37265567940138744,0.1981468145837393
slow,6.691,0.9392685544638382,-0.3030117042642596,0.16111638549285018
slow,6.741,0.965104771584189,-0.2312113232646016,0.12293943167130032
slow,6.792,0.9973294370055789,-0.06448454199620153,0.034289035064803325
slow,6.842,0.9999278161305012,0.010609508165090861,-0.005639225565755396
slow,6.892,0.9930188796365541,0.1041492959551682,-0.055375345031933365
slow,6.943,0.9930188796365541,0.1041492959551682,-0.055375345031933365
slow,6.993,0.9930188796365541,0.1041492959551682,-0.055375345031933365
slow,7.043,0.9930188796365541,0.1041492959551682,-0.055375345031933365
slow,7.093,0.9386688966024551,0.30445842560916364,-0.16188196201775823
slow,7.144,0.9311374675345754,0.32198368527382176,-0.17120024232104936
slow,7.223,0.8558381442539132,0.4566995610987047,-0.24283035587065402
slow,7.273,0.7831408512856074,0.5490564200014606,-0.29193741572952536
slow,7.324,0.7560444192777931,0.5779075266990185,-0.30727793064834297
slow,7.374,0.6509683314574719,0.6702500769547218,-0.3563777010163019
slow,7.425,0.6509683314574719,0.6702500769547218,-0.3563777010163019
slow,7.475,0.6509683314574719,0.6702500769547218,-0.3563777010163019
slow,7.525,0.6509683314574719,0.6702500769547218,-0.3563777010163019
slow,7.576,0.4196485397802218,0.8014397844240222,-0.42613304847512623
slow,7.626,0.3806332297410603,0.8164846784795214,-0.43413259981839836
slow,7.676,0.23917773281080557,0.8573206036655484,-0.4558458014044032
slow,7.727,0.13481190457623585,0.8748870865403633,-0.46518634566100775
slow,7.777,0.007896542705130004,0.8829196865934407,-0.4694576356169389
slow,7.828,-0.055613100836188686,0.8815807152851224,-0.46874580046412767
slow,7.878,-0.055613100836188686,0.8815807152851224,-0.46874580046412767
slow,7.934,-0.055613100836188686,0.8815807152851224,-0.46874580046412767
slow,7.984,-0.055613100836188686,0.8815807152851224,-0.46874580046412767
fast,0.044,-0.468564632951404,0.7800211366930896,-0.4147459596658374
fast,0.094,-0.468564632951404,0.7800211366930896,-0.4147459596658374
fast,0.147,-0.6532919035228096,0.6684843531374839,-0.3554410758507007
fast,0.197,-0.6740804102157376,0.6521956099667656,-0.346780170862553
fast,0.253,-0.7406633321896331,0.593230936921181,-0.31542809613185546
fast,0.303,-0.8067414530300762,0.521736964591286,-0.27741443318975423
fast,0.354,-0.8364927453434133,0.4838350279608412,-0.25726164250811173
fast,0.404,-0.8572846408021899,0.4545782991663938,-0.24170563620165925
fast,0.454,-0.8572846408021899,0.4545782991663938,-0.24170563620165925
fast,0.505,-0.8572846408021899,0.4545782991663938,-0.24170563620165925
fast,0.555,-0.8572846408021899,0.4545782991663938,-0.24170563620165925
fast,0.605,-0.9267948315707897,0.33160599382699485,-0.17632017760790408
fast,0.656,-0.9368960066831657,0.30868477952212847,-0.16413281071288688
fast,0.706,-0.9657135503823218,0.22922111730247924,-0.12188116339522719
fast,0.756,-0.9779586730613649,0.18435730681493703,-0.09802661479413445
fast,0.807,-0.9943971478546243,0.09333425614443461,-0.04962891262715385
fast,0.857,-0.9977694134078435,0.058940059911640835,-0.031341139184466044
fast,0.907,-0.9977694134078435,0.058940059911640835,-0.031341139184466044
fast,0.957,-0.9977694134078435,0.058940059911640835,-0.031341139184466044
fast,1.007,-0.9977694134078435,0.058940059911640835,-0.031341139184466044
fast,1.057,-0.9960740012037427,-0.0781633335984552,0.041558120827859354
fast,1.108,-0.9915869770276278,-0.11429142880777064,0.06076788864432451
fast,1.158,-0.9830488997220782,-0.16188358013218335,0.08607303433014432
fast,1.208,-0.9654882699749504,-0.22996141302144335,0.12227080216453375
fast,1.258,-0.9421438137516855,-0.2959725872352957,0.15736982498139357
fast,1.308,-0.9183006336633192,-0.3495452280775043,0.1858549965478247
fast,1.359,-0.9183006336633192,-0.3495452280775043,0.1858549965478247
fast,1.409,-0.9183006336633192,-0.3495452280775043,0.1858549965478247
fast,1.459,-0.9183006336633192,-0.3495452280775043,0.1858549965478247
fast,1.509,-0.852788869570223,-0.4611250554621998,0.24518325220561926
fast,1.561,-0.8457836830587759,-0.47107600317640114,0.25047427153877355
fast,1.611,-0.7990683904573951,-0.5308639797392242,0.28226431298919213
fast,1.661,-0.7576916738262323,-0.5762231745752734,0.30638240892191654
fast,1.712,-0.7039218688816332,-0.6271380249228601,0.3334544949555229
fast,1.763,-0.6851467559103143,-0.6431437685849701,0.34196493357637503
fast,1.813,-0.6560905528050488,-0.6663450550269401,0.3543013606537654
fast,1.863,-0.6560905528050488,-0.6663450550269401,0.3543013606537654
fast,1.913,-0.6560905528050488,-0.6663450550269401,0.3543013606537654
fast,1.964,-0.6560905528050488,-0.6663450550269401,0.3543013606537654
fast,2.014,-0.5163993954213524,-0.7561103236758572,0.40203089786638574
fast,2.064,-0.4546015920025061,-0.7864369179669822,0.4181559118407643
fast,2.142,-0.3807299710798536,-0.8164494585717856,0.4341140065920148
fast,2.193,-0.2820279695634007,-0.8471052048351421,0.45041424969150085
fast,2.244,-0.23157561174253732,-0.8589461445197458,0.4567102548232671
fast,2.294,-0.1805137900613878,-0.8684427065467883,0.46175971786564723
fast,2.344,-0.1805137900613878,-0.8684427065467883,0.46175971786564723
fast,2.395,-0.1805137900613878,-0.8684427065467883,0.46175971786564723
fast,2.445,-0.1805137900613878,-0.8684427065467883,0.46175971786564723
fast,2.496,-0.024830674288472077,-0.8826749954107264,0.46932748703975774
fast,2.55,0.016627909997720097,-0.8828251361547534,0.4694073833914936
fast,2.6,0.111726663405662,-0.8774189869035709,0.46653303645652927
fast,2.651,0.13780214292537876,-0.874523580821017,0.4649936300565413
fast,2.701,0.2656103428096974,-0.8512318793390828,0.45260958163672177
fast,2.751,0.31554354506824306,-0.8378380863926662,0.4454880606207544
fast,2.801,0.34018885207653954,-0.8302853882293821,0.4414722177166199
fast,2.851,0.34018885207653954,-0.8302853882293821,0.4414722177166199
fast,2.901,0.34018885207653954,-0.8302853882293821,0.4414722177166199
fast,2.952,0.34018885207653954,-0.8302853882293821,0.4414722177166199
fast,3.003,0.4940800181283668,-0.7676483628437457,0.4081677678474743
fast,3.053,0.5530560650928253,-0.7356216755844609,0.39113902806336104
fast,3.103,0.5974397882275826,-0.7080469991770619,0.3764772853691691
fast,3.154,0.6185047351113914,-0.6938025932733614,0.3689035838968582
fast,3.206,0.6881042365676635,-0.6406762784960411,0.34065593461746135
fast,3.256,0.7514898864756772,-0.5825188958027513,0.3097332506488721
fast,3.306,0.7931845845529396,-0.5376975001965116,0.2859014045261112
fast,3.357,0.8009798300561773,-0.5286119824350076,0.28107060299737585
fast,3.407,0.8009798300561773,-0.5286119824350076,0.28107060299737585
fast,3.458,0.8009798300561773,-0.5286119824350076,0.28107060299737585
fast,3.508,0.8009798300561773,-0.5286119824350076,0.28107060299737585
fast,3.566,0.9079615585910537,-0.37000119040604634,0.19673567856139682
fast,3.618,0.9289873638512246,-0.3267879327407989,0.1737588122074601
fast,3.668,0.951171266364975,-0.27253270223930237,0.14491082862158244
fast,3.718,0.97558673482976,-0.1939070387891802,0.10310471925289769
fast,3.768,0.9897808982513759,-0.1259042544228822,0.06694693551550773
fast,3.819,0.9931410372296491,-0.10323546390051833,0.05489370786949623
fast,3.869,0.9931410372296491,-0.10323546390051833,0.05489370786949623
fast,3.943,0.9931410372296491,-0.10323546390051833,0.05489370786949623
fast,3.993,0.9999376400959273,0.009861411882843249,-0.005241037594265275
fast,4.045,0.998654861608302,0.04578216735335978,-0.024340512289846263
fast,4.095,0.992907801560002,0.10497188750958387,-0.05581218893717397
fast,4.145,0.9853453521738103,0.15060635068109599,-0.08007661383945096
fast,4.195,0.9656808627762835,0.22933012769607466,-0.12193508026222302
fast,4.245,0.9584524128068335,0.25186373612958607,-0.13391650685261142
fast,4.295,0.9422656297525576,0.295670151705548,-0.15720891952250804
fast,4.346,0.9422656297525576,0.295670151705548,-0.15720891952250804
fast,4.396,0.9422656297525576,0.295670151705548,-0.15720891952250804
fast,4.446,0.9422656297525576,0.295670151705548,-0.15720891952250804
fast,4.496,0.872076362854367,0.43208850957625344,-0.22974406900477443
fast,4.547,0.8580093568921251,0.45351256088827063,-0.24113544036935863
fast,4.598,0.8132252153454199,0.5138310229603692,-0.2732076663819958
fast,4.648,0.7815435931024417,0.5508278891839419,-0.29287923889836937
fast,4.699,0.7210023605142103,0.6118235759463857,-0.32531140165864775
fast,4.752,0.7119253398407421,0.6200549034607505,-0.32968807559104
fast,4.802,0.7119253398407421,0.6200549034607505,-0.32968807559104
fast,4.852,0.7119253398407421,0.6200549034607505,-0.32968807559104
fast,4.902,0.7119253398407421,0.6200549034607505,-0.32968807559104
fast,4.952,0.5717137662325098,0.7244172953808695,-0.38517911632551577
fast,5.003,0.5489901411529138,0.7379931951737293,-0.392397590199244
fast,5.053,0.4917898196021908,0.7687948374153668,-0.40877533107946273
fast,5.104,0.42168183785580987,0.8006073549916201,-0.42569036958318496
fast,5.154,0.37379846714844805,0.8189426822227043,-0.43543953563193305
fast,5.204,0.33726198026341786,0.8312163487333023,-0.44196576594491466
fast,5.255,0.33726198026341786,0.8312163487333023,-0.44196576594491466
fast,5.306,0.33726198026341786,0.8312163487333023,-0.44196576594491466
fast,5.357,0.33726198026341786,0.8312163487333023,-0.44196576594491466
fast,5.407,0.33726198026341786,0.8312163487333023,-0.44196576594491466
fast,5.459,0.13407634499561424,0.8749752241040766,-0.46523315758513817
fast,5.509,0.1067327874409669,0.8779037141803553,-0.4667902962931195
fast,5.561,0.02627950826709677,0.8826423614597066,-0.46930997134311153
fast,5.611,-0.05263072139273397,0.8817235042090142,-0.4688215751125975
fast,5.662,-0.10470500798344481,0.8780938562969806,-0.46689189416468185
fast,5.712,-0.14352498907655858,0.8738056992414621,-0.46461185680491773
fast,5.762,-0.14352498907655858,0.8738056992414621,-0.46461185680491773
fast,5.812,-0.14352498907655858,0.8738056992414621,-0.46461185680491773
fast,5.862,-0.14352498907655858,0.8738056992414621,-0.46461185680491773
fast,5.912,-0.295103523640452,0.843625197837987,-0.4485648625425387
fast,5.962,-0.33420756849144506,0.8321770526698412,-0.44247785726832983
fast,6.013,-0.4219355057458717,0.8005024328118661,-0.42563632839932636
fast,6.063,-0.44551813189673,0.790478394286142,-0.42030643858743166
fast,6.113,-0.5364964099008817,0.7451210147911475,-0.396189696332547
fast,6.163,-0.5798139907491607,0.719379824283596,-0.38250281638863076
fast,6.213,-0.6213904831858549,0.6917895911437915,-0.3678328818786537
fast,6.265,-0.6213904831858549,0.6917895911437915,-0.3678328818786537
fast,6.316,-0.6213904831858549,0.6917895911437915,-0.3678328818786537
fast,6.366,-0.6213904831858549,0.6917895911437915,-0.3678328818786537
fast,6.416,-0.6213904831858549,0.6917895911437915,-0.3678328818786537
fast,6.467,-0.7697685939313547,0.5636049336495432,-0.2996761427989206
fast,6.517,-0.8188294015799512,0.5068436537072459,-0.26949568049397077
fast,6.567,-0.8407379772940358,0.4780642012631092,-0.2541933771879171
fast,6.618,-0.8928806068283204,0.39758464497224594,-0.21140168408076437
fast,6.668,-0.904333371419307,0.3768648333400775,-0.20038475672801448
fast,6.719,-0.9150935727512862,0.35604033442654803,-0.18931200007056712
fast,6.769,-0.9150935727512862,0.35604033442654803,-0.18931200007056712
fast,6.819,-0.9150935727512862,0.35604033442654803,-0.18931200007056712
fast,6.87,-0.9150935727512862,0.35604033442654803,-0.18931200007056712
fast,6.92,-0.9695072843499856,0.21637647177545588,-0.11505150174735601
fast,6.97,-0.9840519374844526,0.15705915122674283,-0.08351171983039263
fast,7.021,-0.9950416541582717,0.08781629148940584,-0.04669481169271156
fast,7.071,-0.9994288190771032,0.029837554381306492,-0.015866819047602072
fast,7.122,-0.9990051683116948,-0.03937536594069818,0.020934522768823672
fast,7.172,-0.9983402523657028,-0.05085064211870806,0.027036136974427062
fast,7.222,-0.9983402523657028,-0.05085064211870806,0.027036136974427062
fast,7.272,-0.9983402523657028,-0.05085064211870806,0.027036136974427062
fast,7.322,-0.9983402523657028,-0.05085064211870806,0.027036136974427062
fast,7.372,-0.9773662273888087,-0.18679204232103552,0.09931762424315102
fast,7.423,-0.9642049478456077,-0.23412130178924356,0.12448306952577433
fast,7.473,-0.9484068324824643,-0.27994440727138714,0.14884760306451283
fast,7.545,-0.9099733991029075,-0.36612944116866886,0.194673175436727
fast,7.595,-0.8747228862138969,-0.42789759461639953,0.22751597934019752
fast,7.646,-0.8618665613775525,-0.44777421714659554,0.23808460857011965
fast,7.696,-0.8618665613775525,-0.44777421714659554,0.23808460857011965
fast,7.746,-0.8618665613775525,-0.44777421714659554,0.23808460857011965
fast,7.796,-0.8618665613775525,-0.44777421714659554,0.23808460857011965
fast,7.847,-0.7556758579959296,-0.5782831810950133,0.3074777392019586
fast,7.897,-0.7097083644940697,-0.6220330202188311,0.3307400174224341
fast,7.948,-0.6909634215042433,-0.6382740408720933,0.3393756014977489
fast,7.998,-0.6322370482773051,-0.6840859490030367,0.3637344211952114
1 phase t fx fy fz
2 slow 0.046 5.36441810913306e-07 0.8829469811387421 -0.4694727132621171
3 slow 0.124 -0.0037028938908542333 0.8829408973863202 -0.4694695520472787
4 slow 0.175 -0.029433192564468726 0.8825644180942943 -0.4692693630414654
5 slow 0.225 -0.047907995026344505 0.8819330671344229 -0.46893377902154315
6 slow 0.276 -0.05494452988794276 0.8816131314630001 -0.4687636772056853
7 slow 0.327 -0.05494452988794276 0.8816131314630001 -0.4687636772056853
8 slow 0.377 -0.05494452988794276 0.8816131314630001 -0.4687636772056853
9 slow 0.427 -0.05494452988794276 0.8816131314630001 -0.4687636772056853
10 slow 0.478 -0.2805405845010285 0.8474894135274412 -0.4506203217862406
11 slow 0.529 -0.3464401476183601 0.828267481843762 -0.440400048408674
12 slow 0.579 -0.4933270963841563 0.7680254218881261 -0.4083691066997395
13 slow 0.629 -0.5646325672888053 0.7287328660233411 -0.3874770624621025
14 slow 0.679 -0.663984471662157 0.6602195443081346 -0.35104810881855686
15 slow 0.729 -0.6795143538879752 0.6477839998044589 -0.3444359627819725
16 slow 0.782 -0.6795143538879752 0.6477839998044589 -0.3444359627819725
17 slow 0.832 -0.6795143538879752 0.6477839998044589 -0.3444359627819725
18 slow 0.883 -0.6795143538879752 0.6477839998044589 -0.3444359627819725
19 slow 0.933 -0.8636404059341753 0.44509990979031433 -0.23666710701427646
20 slow 0.983 -0.9034235025038042 0.37856180077666735 -0.20128819666459757
21 slow 1.033 -0.9208475303349151 0.34428010688112226 -0.18306019196431236
22 slow 1.084 -0.9823258963987413 0.1652676638242847 -0.08787737227792251
23 slow 1.134 -0.9946318488171882 0.09136350259329508 -0.048581845502070904
24 slow 1.188 -0.9965908416220451 0.07284426607901787 -0.03873509125422061
25 slow 1.238 -0.9965908416220451 0.07284426607901787 -0.03873509125422061
26 slow 1.288 -0.9965908416220451 0.07284426607901787 -0.03873509125422061
27 slow 1.338 -0.9965908416220451 0.07284426607901787 -0.03873509125422061
28 slow 1.388 -0.9887775514835899 -0.13190930729666128 0.0701347868794932
29 slow 1.438 -0.9556714469692192 -0.2599717478297875 0.13822726134190855
30 slow 1.489 -0.8922483691415248 -0.39869133958378805 0.21198599837058513
31 slow 1.539 -0.8508838444950022 -0.46386065972493185 0.24663732794724316
32 slow 1.589 -0.7907927164969744 -0.5404386826976731 0.28735502393266027
33 slow 1.64 -0.7777418936805442 -0.5550070379438635 0.29510122779646286
34 slow 1.691 -0.7777418936805442 -0.5550070379438635 0.29510122779646286
35 slow 1.741 -0.7777418936805442 -0.5550070379438635 0.29510122779646286
36 slow 1.791 -0.5952358692207049 -0.7094937017300517 0.377243882917219
37 slow 1.841 -0.5604049203743158 -0.7312739567343891 0.38882480042081646
38 slow 1.892 -0.45017479352935263 -0.7884196750580088 0.4192100562393852
39 slow 1.942 -0.3527042657551637 -0.8262047790273792 0.4393009947979067
40 slow 1.993 -0.2515210843607131 -0.8545622769363128 0.454379201724106
41 slow 2.048 -0.21020554253366847 -0.8632198721332542 0.4589826600672126
42 slow 2.098 -0.21020554253366847 -0.8632198721332542 0.4589826600672126
43 slow 2.148 -0.21020554253366847 -0.8632198721332542 0.4589826600672126
44 slow 2.199 -0.21020554253366847 -0.8632198721332542 0.4589826600672126
45 slow 2.249 0.06423144170165734 -0.8811238583231025 0.46850300766455694
46 slow 2.3 0.12787323617667282 -0.8756985100693347 0.46561846498184756
47 slow 2.35 0.2327336093496518 -0.858701653919306 0.45658135817763307
48 slow 2.423 0.3547279040834424 -0.8255283263615021 0.43894315855170307
49 slow 2.479 0.5260315144840211 -0.7509151987562808 0.3992708479797423
50 slow 2.529 0.5961056688939317 -0.7089229256787852 0.3769433869423229
51 slow 2.581 0.5961056688939317 -0.7089229256787852 0.3769433869423229
52 slow 2.631 0.5961056688939317 -0.7089229256787852 0.3769433869423229
53 slow 2.681 0.5961056688939317 -0.7089229256787852 0.3769433869423229
54 slow 2.732 0.5961056688939317 -0.7089229256787852 0.3769433869423229
55 slow 2.782 0.8295924682130262 -0.4930097696572142 0.26214061819328877
56 slow 2.832 0.8741827941510458 -0.4287555674072037 0.22797610801923318
57 slow 2.882 0.9439064628362973 -0.29155959525346875 0.15502771310802138
58 slow 2.932 0.9571066736003423 -0.25582037216180104 0.1360248232371042
59 slow 2.982 0.9861968747582776 -0.14619466320861924 0.07773573609560003
60 slow 3.032 0.9966905224322332 -0.07177339798264935 0.03816519141555759
61 slow 3.083 0.9992422961997571 -0.03436404433766335 0.01827418786692905
62 slow 3.133 0.9992422961997571 -0.03436404433766335 0.01827418786692905
63 slow 3.184 0.9992422961997571 -0.03436404433766335 0.01827418786692905
64 slow 3.234 0.9992422961997571 -0.03436404433766335 0.01827418786692905
65 slow 3.286 0.9667885938062846 0.22566239526859874 -0.11998457504073406
66 slow 3.336 0.9415539672577656 0.2974325173987048 -0.15814557956209666
67 slow 3.386 0.8910494227865149 0.4007762840154738 -0.21309457131181636
68 slow 3.437 0.8493271610881868 0.46607942161808097 -0.24781716280765573
69 slow 3.487 0.761860256786668 0.5719223062697806 -0.30409509157499987
70 slow 3.537 0.748009652602088 0.586002088637891 -0.3115816293142661
71 slow 3.587 0.748009652602088 0.586002088637891 -0.3115816293142661
72 slow 3.637 0.748009652602088 0.586002088637891 -0.3115816293142661
73 slow 3.688 0.591663947524308 0.7118191730405439 -0.3784801686902885
74 slow 3.738 0.539041368473937 0.7436887413829951 -0.3954256681273002
75 slow 3.789 0.40803721926756004 0.8061006144181252 -0.4286110441030633
76 slow 3.839 0.36886970856393964 0.8206831516383724 -0.4363648733810532
77 slow 3.89 0.24776263895916018 0.8554178600934551 -0.4548339910001527
78 slow 3.94 0.16475926423798679 0.8708809062626716 -0.46305597065027154
79 slow 3.992 0.14387633165971442 0.8737609544059406 -0.46458733919873835
80 slow 4.042 0.14387633165971442 0.8737609544059406 -0.46458733919873835
81 slow 4.093 0.14387633165971442 0.8737609544059406 -0.46458733919873835
82 slow 4.143 0.14387633165971442 0.8737609544059406 -0.46458733919873835
83 slow 4.196 -0.1733023236078747 0.869586949506304 -0.46236872934967393
84 slow 4.247 -0.21515127447977428 0.86226908085857 -0.4584778743680502
85 slow 4.297 -0.3579950095311995 0.8244282743035451 -0.4383578374794213
86 slow 4.347 -0.3974270950667179 0.8102218773848151 -0.43080414751236507
87 slow 4.397 -0.5648254471144367 0.7286167551161777 -0.3874142982079373
88 slow 4.448 -0.6161812577464959 0.6954125799901635 -0.36975938283344584
89 slow 4.498 -0.6161812577464959 0.6954125799901635 -0.36975938283344584
90 slow 4.55 -0.6161812577464959 0.6954125799901635 -0.36975938283344584
91 slow 4.6 -0.6161812577464959 0.6954125799901635 -0.36975938283344584
92 slow 4.65 -0.7949436150360499 0.5356686009745564 -0.2848223987740045
93 slow 4.706 -0.8320602692300713 0.4897569720337153 -0.26041086135787
94 slow 4.756 -0.9052591628184888 0.37512792417883484 -0.1994614966213956
95 slow 4.824 -0.9519766029552919 0.2703318015873179 -0.14374026741403262
96 slow 4.874 -0.983175920401433 0.1612793283684674 -0.08575597812287565
97 slow 4.925 -0.992798606527993 0.10577208861815067 -0.05624226298282666
98 slow 4.975 -0.992798606527993 0.10577208861815067 -0.05624226298282666
99 slow 5.025 -0.992798606527993 0.10577208861815067 -0.05624226298282666
100 slow 5.075 -0.992798606527993 0.10577208861815067 -0.05624226298282666
101 slow 5.125 -0.9909352442124001 -0.11861635420392577 0.06306744241746298
102 slow 5.177 -0.971089850817662 -0.21077290020723444 0.11206822108502636
103 slow 5.227 -0.9473137584186095 -0.2828150426309014 0.15037385002881865
104 slow 5.278 -0.8692337732689488 -0.43653100062660777 0.23210629655517379
105 slow 5.329 -0.8474958640779253 -0.4686708632974702 0.24919546999657635
106 slow 5.379 -0.7866667561433955 -0.5451126777938068 0.2898406170420097
107 slow 5.43 -0.7734621510586307 -0.5596500718853581 0.29757032432430053
108 slow 5.48 -0.7734621510586307 -0.5596500718853581 0.29757032432430053
109 slow 5.531 -0.7734621510586307 -0.5596500718853581 0.29757032432430053
110 slow 5.581 -0.6062043205372735 -0.7022162337138214 0.3733747217886052
111 slow 5.632 -0.5541510145645213 -0.734979908569316 0.39079558218658444
112 slow 5.682 -0.42418330732008847 -0.7995763915406578 0.42514246539461586
113 slow 5.732 -0.3852348981801229 -0.8148002884614528 0.4332373058120499
114 slow 5.783 -0.243946035449459 -0.8562723940695657 0.45528883024171124
115 slow 5.833 -0.16070912377840446 -0.8714704720337134 0.4633700399332204
116 slow 5.883 -0.0975990723650993 -0.8787317852366855 0.4672310677686361
117 slow 5.934 -0.0975990723650993 -0.8787317852366855 0.4672310677686361
118 slow 5.984 -0.0975990723650993 -0.8787317852366855 0.4672310677686361
119 slow 6.034 -0.0975990723650993 -0.8787317852366855 0.4672310677686361
120 slow 6.085 0.1775602464395945 -0.8689168079517865 0.46201292161928603
121 slow 6.135 0.2607328887465965 -0.8524065164179079 0.45323447738906825
122 slow 6.185 0.36194842063416144 -0.8230812569371999 0.4376420743931222
123 slow 6.235 0.4398997578876258 -0.7929274597606337 0.4216091158501638
124 slow 6.285 0.5682409772730201 -0.7265432946265349 0.38631209246025844
125 slow 6.336 0.6359981125758746 -0.6813614183433645 0.36228858440895406
126 slow 6.386 0.7140739082487315 -0.6181244196428086 0.32866495919039396
127 slow 6.436 0.7140739082487315 -0.6181244196428086 0.32866495919039396
128 slow 6.487 0.7140739082487315 -0.6181244196428086 0.32866495919039396
129 slow 6.539 0.7140739082487315 -0.6181244196428086 0.32866495919039396
130 slow 6.589 0.7140739082487315 -0.6181244196428086 0.32866495919039396
131 slow 6.639 0.9065680252911018 -0.37265567940138744 0.1981468145837393
132 slow 6.691 0.9392685544638382 -0.3030117042642596 0.16111638549285018
133 slow 6.741 0.965104771584189 -0.2312113232646016 0.12293943167130032
134 slow 6.792 0.9973294370055789 -0.06448454199620153 0.034289035064803325
135 slow 6.842 0.9999278161305012 0.010609508165090861 -0.005639225565755396
136 slow 6.892 0.9930188796365541 0.1041492959551682 -0.055375345031933365
137 slow 6.943 0.9930188796365541 0.1041492959551682 -0.055375345031933365
138 slow 6.993 0.9930188796365541 0.1041492959551682 -0.055375345031933365
139 slow 7.043 0.9930188796365541 0.1041492959551682 -0.055375345031933365
140 slow 7.093 0.9386688966024551 0.30445842560916364 -0.16188196201775823
141 slow 7.144 0.9311374675345754 0.32198368527382176 -0.17120024232104936
142 slow 7.223 0.8558381442539132 0.4566995610987047 -0.24283035587065402
143 slow 7.273 0.7831408512856074 0.5490564200014606 -0.29193741572952536
144 slow 7.324 0.7560444192777931 0.5779075266990185 -0.30727793064834297
145 slow 7.374 0.6509683314574719 0.6702500769547218 -0.3563777010163019
146 slow 7.425 0.6509683314574719 0.6702500769547218 -0.3563777010163019
147 slow 7.475 0.6509683314574719 0.6702500769547218 -0.3563777010163019
148 slow 7.525 0.6509683314574719 0.6702500769547218 -0.3563777010163019
149 slow 7.576 0.4196485397802218 0.8014397844240222 -0.42613304847512623
150 slow 7.626 0.3806332297410603 0.8164846784795214 -0.43413259981839836
151 slow 7.676 0.23917773281080557 0.8573206036655484 -0.4558458014044032
152 slow 7.727 0.13481190457623585 0.8748870865403633 -0.46518634566100775
153 slow 7.777 0.007896542705130004 0.8829196865934407 -0.4694576356169389
154 slow 7.828 -0.055613100836188686 0.8815807152851224 -0.46874580046412767
155 slow 7.878 -0.055613100836188686 0.8815807152851224 -0.46874580046412767
156 slow 7.934 -0.055613100836188686 0.8815807152851224 -0.46874580046412767
157 slow 7.984 -0.055613100836188686 0.8815807152851224 -0.46874580046412767
158 fast 0.044 -0.468564632951404 0.7800211366930896 -0.4147459596658374
159 fast 0.094 -0.468564632951404 0.7800211366930896 -0.4147459596658374
160 fast 0.147 -0.6532919035228096 0.6684843531374839 -0.3554410758507007
161 fast 0.197 -0.6740804102157376 0.6521956099667656 -0.346780170862553
162 fast 0.253 -0.7406633321896331 0.593230936921181 -0.31542809613185546
163 fast 0.303 -0.8067414530300762 0.521736964591286 -0.27741443318975423
164 fast 0.354 -0.8364927453434133 0.4838350279608412 -0.25726164250811173
165 fast 0.404 -0.8572846408021899 0.4545782991663938 -0.24170563620165925
166 fast 0.454 -0.8572846408021899 0.4545782991663938 -0.24170563620165925
167 fast 0.505 -0.8572846408021899 0.4545782991663938 -0.24170563620165925
168 fast 0.555 -0.8572846408021899 0.4545782991663938 -0.24170563620165925
169 fast 0.605 -0.9267948315707897 0.33160599382699485 -0.17632017760790408
170 fast 0.656 -0.9368960066831657 0.30868477952212847 -0.16413281071288688
171 fast 0.706 -0.9657135503823218 0.22922111730247924 -0.12188116339522719
172 fast 0.756 -0.9779586730613649 0.18435730681493703 -0.09802661479413445
173 fast 0.807 -0.9943971478546243 0.09333425614443461 -0.04962891262715385
174 fast 0.857 -0.9977694134078435 0.058940059911640835 -0.031341139184466044
175 fast 0.907 -0.9977694134078435 0.058940059911640835 -0.031341139184466044
176 fast 0.957 -0.9977694134078435 0.058940059911640835 -0.031341139184466044
177 fast 1.007 -0.9977694134078435 0.058940059911640835 -0.031341139184466044
178 fast 1.057 -0.9960740012037427 -0.0781633335984552 0.041558120827859354
179 fast 1.108 -0.9915869770276278 -0.11429142880777064 0.06076788864432451
180 fast 1.158 -0.9830488997220782 -0.16188358013218335 0.08607303433014432
181 fast 1.208 -0.9654882699749504 -0.22996141302144335 0.12227080216453375
182 fast 1.258 -0.9421438137516855 -0.2959725872352957 0.15736982498139357
183 fast 1.308 -0.9183006336633192 -0.3495452280775043 0.1858549965478247
184 fast 1.359 -0.9183006336633192 -0.3495452280775043 0.1858549965478247
185 fast 1.409 -0.9183006336633192 -0.3495452280775043 0.1858549965478247
186 fast 1.459 -0.9183006336633192 -0.3495452280775043 0.1858549965478247
187 fast 1.509 -0.852788869570223 -0.4611250554621998 0.24518325220561926
188 fast 1.561 -0.8457836830587759 -0.47107600317640114 0.25047427153877355
189 fast 1.611 -0.7990683904573951 -0.5308639797392242 0.28226431298919213
190 fast 1.661 -0.7576916738262323 -0.5762231745752734 0.30638240892191654
191 fast 1.712 -0.7039218688816332 -0.6271380249228601 0.3334544949555229
192 fast 1.763 -0.6851467559103143 -0.6431437685849701 0.34196493357637503
193 fast 1.813 -0.6560905528050488 -0.6663450550269401 0.3543013606537654
194 fast 1.863 -0.6560905528050488 -0.6663450550269401 0.3543013606537654
195 fast 1.913 -0.6560905528050488 -0.6663450550269401 0.3543013606537654
196 fast 1.964 -0.6560905528050488 -0.6663450550269401 0.3543013606537654
197 fast 2.014 -0.5163993954213524 -0.7561103236758572 0.40203089786638574
198 fast 2.064 -0.4546015920025061 -0.7864369179669822 0.4181559118407643
199 fast 2.142 -0.3807299710798536 -0.8164494585717856 0.4341140065920148
200 fast 2.193 -0.2820279695634007 -0.8471052048351421 0.45041424969150085
201 fast 2.244 -0.23157561174253732 -0.8589461445197458 0.4567102548232671
202 fast 2.294 -0.1805137900613878 -0.8684427065467883 0.46175971786564723
203 fast 2.344 -0.1805137900613878 -0.8684427065467883 0.46175971786564723
204 fast 2.395 -0.1805137900613878 -0.8684427065467883 0.46175971786564723
205 fast 2.445 -0.1805137900613878 -0.8684427065467883 0.46175971786564723
206 fast 2.496 -0.024830674288472077 -0.8826749954107264 0.46932748703975774
207 fast 2.55 0.016627909997720097 -0.8828251361547534 0.4694073833914936
208 fast 2.6 0.111726663405662 -0.8774189869035709 0.46653303645652927
209 fast 2.651 0.13780214292537876 -0.874523580821017 0.4649936300565413
210 fast 2.701 0.2656103428096974 -0.8512318793390828 0.45260958163672177
211 fast 2.751 0.31554354506824306 -0.8378380863926662 0.4454880606207544
212 fast 2.801 0.34018885207653954 -0.8302853882293821 0.4414722177166199
213 fast 2.851 0.34018885207653954 -0.8302853882293821 0.4414722177166199
214 fast 2.901 0.34018885207653954 -0.8302853882293821 0.4414722177166199
215 fast 2.952 0.34018885207653954 -0.8302853882293821 0.4414722177166199
216 fast 3.003 0.4940800181283668 -0.7676483628437457 0.4081677678474743
217 fast 3.053 0.5530560650928253 -0.7356216755844609 0.39113902806336104
218 fast 3.103 0.5974397882275826 -0.7080469991770619 0.3764772853691691
219 fast 3.154 0.6185047351113914 -0.6938025932733614 0.3689035838968582
220 fast 3.206 0.6881042365676635 -0.6406762784960411 0.34065593461746135
221 fast 3.256 0.7514898864756772 -0.5825188958027513 0.3097332506488721
222 fast 3.306 0.7931845845529396 -0.5376975001965116 0.2859014045261112
223 fast 3.357 0.8009798300561773 -0.5286119824350076 0.28107060299737585
224 fast 3.407 0.8009798300561773 -0.5286119824350076 0.28107060299737585
225 fast 3.458 0.8009798300561773 -0.5286119824350076 0.28107060299737585
226 fast 3.508 0.8009798300561773 -0.5286119824350076 0.28107060299737585
227 fast 3.566 0.9079615585910537 -0.37000119040604634 0.19673567856139682
228 fast 3.618 0.9289873638512246 -0.3267879327407989 0.1737588122074601
229 fast 3.668 0.951171266364975 -0.27253270223930237 0.14491082862158244
230 fast 3.718 0.97558673482976 -0.1939070387891802 0.10310471925289769
231 fast 3.768 0.9897808982513759 -0.1259042544228822 0.06694693551550773
232 fast 3.819 0.9931410372296491 -0.10323546390051833 0.05489370786949623
233 fast 3.869 0.9931410372296491 -0.10323546390051833 0.05489370786949623
234 fast 3.943 0.9931410372296491 -0.10323546390051833 0.05489370786949623
235 fast 3.993 0.9999376400959273 0.009861411882843249 -0.005241037594265275
236 fast 4.045 0.998654861608302 0.04578216735335978 -0.024340512289846263
237 fast 4.095 0.992907801560002 0.10497188750958387 -0.05581218893717397
238 fast 4.145 0.9853453521738103 0.15060635068109599 -0.08007661383945096
239 fast 4.195 0.9656808627762835 0.22933012769607466 -0.12193508026222302
240 fast 4.245 0.9584524128068335 0.25186373612958607 -0.13391650685261142
241 fast 4.295 0.9422656297525576 0.295670151705548 -0.15720891952250804
242 fast 4.346 0.9422656297525576 0.295670151705548 -0.15720891952250804
243 fast 4.396 0.9422656297525576 0.295670151705548 -0.15720891952250804
244 fast 4.446 0.9422656297525576 0.295670151705548 -0.15720891952250804
245 fast 4.496 0.872076362854367 0.43208850957625344 -0.22974406900477443
246 fast 4.547 0.8580093568921251 0.45351256088827063 -0.24113544036935863
247 fast 4.598 0.8132252153454199 0.5138310229603692 -0.2732076663819958
248 fast 4.648 0.7815435931024417 0.5508278891839419 -0.29287923889836937
249 fast 4.699 0.7210023605142103 0.6118235759463857 -0.32531140165864775
250 fast 4.752 0.7119253398407421 0.6200549034607505 -0.32968807559104
251 fast 4.802 0.7119253398407421 0.6200549034607505 -0.32968807559104
252 fast 4.852 0.7119253398407421 0.6200549034607505 -0.32968807559104
253 fast 4.902 0.7119253398407421 0.6200549034607505 -0.32968807559104
254 fast 4.952 0.5717137662325098 0.7244172953808695 -0.38517911632551577
255 fast 5.003 0.5489901411529138 0.7379931951737293 -0.392397590199244
256 fast 5.053 0.4917898196021908 0.7687948374153668 -0.40877533107946273
257 fast 5.104 0.42168183785580987 0.8006073549916201 -0.42569036958318496
258 fast 5.154 0.37379846714844805 0.8189426822227043 -0.43543953563193305
259 fast 5.204 0.33726198026341786 0.8312163487333023 -0.44196576594491466
260 fast 5.255 0.33726198026341786 0.8312163487333023 -0.44196576594491466
261 fast 5.306 0.33726198026341786 0.8312163487333023 -0.44196576594491466
262 fast 5.357 0.33726198026341786 0.8312163487333023 -0.44196576594491466
263 fast 5.407 0.33726198026341786 0.8312163487333023 -0.44196576594491466
264 fast 5.459 0.13407634499561424 0.8749752241040766 -0.46523315758513817
265 fast 5.509 0.1067327874409669 0.8779037141803553 -0.4667902962931195
266 fast 5.561 0.02627950826709677 0.8826423614597066 -0.46930997134311153
267 fast 5.611 -0.05263072139273397 0.8817235042090142 -0.4688215751125975
268 fast 5.662 -0.10470500798344481 0.8780938562969806 -0.46689189416468185
269 fast 5.712 -0.14352498907655858 0.8738056992414621 -0.46461185680491773
270 fast 5.762 -0.14352498907655858 0.8738056992414621 -0.46461185680491773
271 fast 5.812 -0.14352498907655858 0.8738056992414621 -0.46461185680491773
272 fast 5.862 -0.14352498907655858 0.8738056992414621 -0.46461185680491773
273 fast 5.912 -0.295103523640452 0.843625197837987 -0.4485648625425387
274 fast 5.962 -0.33420756849144506 0.8321770526698412 -0.44247785726832983
275 fast 6.013 -0.4219355057458717 0.8005024328118661 -0.42563632839932636
276 fast 6.063 -0.44551813189673 0.790478394286142 -0.42030643858743166
277 fast 6.113 -0.5364964099008817 0.7451210147911475 -0.396189696332547
278 fast 6.163 -0.5798139907491607 0.719379824283596 -0.38250281638863076
279 fast 6.213 -0.6213904831858549 0.6917895911437915 -0.3678328818786537
280 fast 6.265 -0.6213904831858549 0.6917895911437915 -0.3678328818786537
281 fast 6.316 -0.6213904831858549 0.6917895911437915 -0.3678328818786537
282 fast 6.366 -0.6213904831858549 0.6917895911437915 -0.3678328818786537
283 fast 6.416 -0.6213904831858549 0.6917895911437915 -0.3678328818786537
284 fast 6.467 -0.7697685939313547 0.5636049336495432 -0.2996761427989206
285 fast 6.517 -0.8188294015799512 0.5068436537072459 -0.26949568049397077
286 fast 6.567 -0.8407379772940358 0.4780642012631092 -0.2541933771879171
287 fast 6.618 -0.8928806068283204 0.39758464497224594 -0.21140168408076437
288 fast 6.668 -0.904333371419307 0.3768648333400775 -0.20038475672801448
289 fast 6.719 -0.9150935727512862 0.35604033442654803 -0.18931200007056712
290 fast 6.769 -0.9150935727512862 0.35604033442654803 -0.18931200007056712
291 fast 6.819 -0.9150935727512862 0.35604033442654803 -0.18931200007056712
292 fast 6.87 -0.9150935727512862 0.35604033442654803 -0.18931200007056712
293 fast 6.92 -0.9695072843499856 0.21637647177545588 -0.11505150174735601
294 fast 6.97 -0.9840519374844526 0.15705915122674283 -0.08351171983039263
295 fast 7.021 -0.9950416541582717 0.08781629148940584 -0.04669481169271156
296 fast 7.071 -0.9994288190771032 0.029837554381306492 -0.015866819047602072
297 fast 7.122 -0.9990051683116948 -0.03937536594069818 0.020934522768823672
298 fast 7.172 -0.9983402523657028 -0.05085064211870806 0.027036136974427062
299 fast 7.222 -0.9983402523657028 -0.05085064211870806 0.027036136974427062
300 fast 7.272 -0.9983402523657028 -0.05085064211870806 0.027036136974427062
301 fast 7.322 -0.9983402523657028 -0.05085064211870806 0.027036136974427062
302 fast 7.372 -0.9773662273888087 -0.18679204232103552 0.09931762424315102
303 fast 7.423 -0.9642049478456077 -0.23412130178924356 0.12448306952577433
304 fast 7.473 -0.9484068324824643 -0.27994440727138714 0.14884760306451283
305 fast 7.545 -0.9099733991029075 -0.36612944116866886 0.194673175436727
306 fast 7.595 -0.8747228862138969 -0.42789759461639953 0.22751597934019752
307 fast 7.646 -0.8618665613775525 -0.44777421714659554 0.23808460857011965
308 fast 7.696 -0.8618665613775525 -0.44777421714659554 0.23808460857011965
309 fast 7.746 -0.8618665613775525 -0.44777421714659554 0.23808460857011965
310 fast 7.796 -0.8618665613775525 -0.44777421714659554 0.23808460857011965
311 fast 7.847 -0.7556758579959296 -0.5782831810950133 0.3074777392019586
312 fast 7.897 -0.7097083644940697 -0.6220330202188311 0.3307400174224341
313 fast 7.948 -0.6909634215042433 -0.6382740408720933 0.3393756014977489
314 fast 7.998 -0.6322370482773051 -0.6840859490030367 0.3637344211952114

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 908 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -0,0 +1,786 @@
phase,t,x,y,z
idle,0.0,-1032.5526123046875,881.9141235351562,1004.4220581054688
idle,0.05,-1038.362548828125,881.9141235351562,1004.4220581054688
idle,0.1,-1038.362548828125,881.9141235351562,1004.4220581054688
idle,0.162,-1038.362548828125,881.9141235351562,1004.4220581054688
idle,0.212,-1090.8275146484375,881.9140625,1004.4219360351562
idle,0.262,-1102.4825439453125,881.9140625,1004.4219360351562
idle,0.312,-1143.2926025390625,881.9140625,1004.4218139648438
idle,0.362,-1166.6025390625,881.9140625,1004.4217529296875
idle,0.413,-1201.5675048828125,881.9140014648438,1004.4216918945312
idle,0.463,-1201.5675048828125,881.9140014648438,1004.4216918945312
idle,0.516,-1201.5675048828125,881.9140014648438,1004.4216918945312
idle,0.566,-1201.5675048828125,881.9140014648438,1004.4216918945312
idle,0.616,-1277.342529296875,881.9140014648438,1004.4215698242188
idle,0.666,-1300.652587890625,881.9139404296875,1004.4215087890625
idle,0.716,-1335.6175537109375,881.9139404296875,1004.4214477539062
idle,0.767,-1358.927490234375,881.9139404296875,1004.42138671875
idle,0.817,-1388.0474853515625,881.9139404296875,1004.4213256835938
idle,0.867,-1388.0474853515625,881.9139404296875,1004.4213256835938
idle,0.917,-1388.0474853515625,881.9139404296875,1004.4213256835938
idle,0.968,-1388.0474853515625,881.9139404296875,1004.4213256835938
idle,1.018,-1458.0125732421875,881.9138793945312,1004.4212036132812
idle,1.068,-1492.9775390625,881.9138793945312,1004.421142578125
idle,1.118,-1527.9425048828125,881.913818359375,1004.4210205078125
idle,1.168,-1539.5975341796875,881.913818359375,1004.4210205078125
idle,1.218,-1551.217529296875,881.913818359375,1004.4210205078125
idle,1.269,-1551.217529296875,881.913818359375,1004.4210205078125
idle,1.319,-1551.217529296875,881.913818359375,1004.4210205078125
idle,1.369,-1603.6824951171875,881.913818359375,1004.4208984375
idle,1.419,-1638.6474609375,881.9137573242188,1004.4208374023438
idle,1.469,-1650.302490234375,881.9137573242188,1004.4207763671875
idle,1.519,-1685.2674560546875,881.9137573242188,1004.4207153320312
idle,1.572,-1691.0775146484375,881.9137573242188,1004.4207153320312
idle,1.622,-1691.0775146484375,881.9137573242188,1004.4207153320312
idle,1.672,-1691.0775146484375,881.9137573242188,1004.4207153320312
idle,1.722,-1749.387451171875,881.9136962890625,1004.4205932617188
idle,1.773,-1761.04248046875,881.9136962890625,1004.4205932617188
idle,1.823,-1807.6624755859375,881.9136962890625,1004.4204711914062
idle,1.873,-1819.3175048828125,881.9136962890625,1004.4204711914062
idle,1.923,-1842.5924072265625,881.9136962890625,1004.42041015625
idle,1.973,-1842.5924072265625,881.9136962890625,1004.42041015625
idle,2.024,-1842.5924072265625,881.9136962890625,1004.42041015625
idle,2.074,-1842.5924072265625,881.9136962890625,1004.42041015625
idle,2.124,-1906.71240234375,881.9136352539062,1004.4202880859375
idle,2.174,-1935.867431640625,881.9136352539062,1004.4202270507812
idle,2.224,-1970.8323974609375,881.91357421875,1004.420166015625
idle,2.275,-1982.4874267578125,881.91357421875,1004.4201049804688
idle,2.325,-1994.107421875,881.91357421875,1004.4201049804688
idle,2.375,-1994.107421875,881.91357421875,1004.4201049804688
idle,2.425,-1994.107421875,881.91357421875,1004.4201049804688
idle,2.475,-2058.262451171875,881.91357421875,1004.4199829101562
idle,2.525,-2075.7275390625,881.91357421875,1004.419921875
idle,2.575,-2116.537353515625,881.9135131835938,1004.4198608398438
idle,2.625,-2151.50244140625,881.9135131835938,1004.4197998046875
idle,2.675,-2169.00244140625,881.9135131835938,1004.4197387695312
idle,2.726,-2174.8125,881.9135131835938,1004.4197387695312
idle,2.776,-2174.8125,881.9135131835938,1004.4197387695312
idle,2.826,-2174.8125,881.9135131835938,1004.4197387695312
idle,2.876,-2238.932373046875,881.9134521484375,1004.4196166992188
idle,2.927,-2279.742431640625,881.9134521484375,1004.4194946289062
idle,2.977,-2291.3974609375,881.9134521484375,1004.4194946289062
idle,3.027,-2320.517333984375,881.9133911132812,1004.41943359375
idle,3.077,-2326.327392578125,881.9133911132812,1004.41943359375
idle,3.128,-2326.327392578125,881.9133911132812,1004.41943359375
idle,3.18,-2326.327392578125,881.9133911132812,1004.41943359375
idle,3.23,-2390.482421875,881.9133911132812,1004.4193115234375
idle,3.28,-2419.602294921875,881.9133911132812,1004.4192504882812
idle,3.361,-2454.5673828125,881.913330078125,1004.419189453125
idle,3.411,-2489.532470703125,881.913330078125,1004.4191284179688
idle,3.464,-2501.15234375,881.913330078125,1004.4190673828125
idle,3.514,-2501.15234375,881.913330078125,1004.4190673828125
idle,3.564,-2501.15234375,881.913330078125,1004.4190673828125
idle,3.615,-2547.7724609375,881.9132690429688,1004.4190063476562
idle,3.665,-2559.427490234375,881.9132690429688,1004.4189453125
idle,3.715,-2600.2373046875,881.9132690429688,1004.4188842773438
idle,3.765,-2629.392333984375,881.9132690429688,1004.4188232421875
idle,3.815,-2658.512451171875,881.9132080078125,1004.4187622070312
idle,3.865,-2664.322265625,881.9132080078125,1004.4187622070312
idle,3.916,-2664.322265625,881.9132080078125,1004.4187622070312
idle,3.968,-2664.322265625,881.9132080078125,1004.4187622070312
idle,4.019,-2728.4423828125,881.9132080078125,1004.4186401367188
idle,4.069,-2740.097412109375,881.9132080078125,1004.4185791015625
idle,4.119,-2792.562255859375,881.9131469726562,1004.41845703125
idle,4.169,-2804.21728515625,881.9131469726562,1004.41845703125
idle,4.221,-2815.83740234375,881.9131469726562,1004.41845703125
idle,4.271,-2815.83740234375,881.9131469726562,1004.41845703125
idle,4.324,-2815.83740234375,881.9131469726562,1004.41845703125
idle,4.374,-2874.147216796875,881.9131469726562,1004.4183349609375
idle,4.424,-2903.267333984375,881.9130859375,1004.4182739257812
idle,4.475,-2938.232421875,881.9130859375,1004.418212890625
idle,4.525,-2973.197265625,881.9130859375,1004.4180908203125
idle,4.575,-2996.50732421875,881.9130249023438,1004.4180908203125
idle,4.627,-3008.162353515625,881.9130249023438,1004.4180297851562
idle,4.677,-3008.162353515625,881.9130249023438,1004.4180297851562
idle,4.727,-3008.162353515625,881.9130249023438,1004.4180297851562
idle,4.778,-3072.2822265625,881.9130249023438,1004.4179077148438
idle,4.863,-3113.09228515625,881.9129638671875,1004.4178466796875
idle,4.913,-3148.057373046875,881.9129638671875,1004.4177856445312
idle,4.963,-3165.522216796875,881.9129638671875,1004.417724609375
idle,5.013,-3165.522216796875,881.9129638671875,1004.417724609375
idle,5.064,-3165.522216796875,881.9129638671875,1004.417724609375
idle,5.114,-3223.832275390625,881.9129028320312,1004.4176025390625
idle,5.164,-3241.29736328125,881.9129028320312,1004.4176025390625
idle,5.214,-3276.26220703125,881.9129028320312,1004.41748046875
idle,5.266,-3299.572265625,881.9129028320312,1004.41748046875
idle,5.316,-3334.537353515625,881.912841796875,1004.4173583984375
idle,5.367,-3340.34716796875,881.912841796875,1004.4173583984375
idle,5.417,-3340.34716796875,881.912841796875,1004.4173583984375
idle,5.467,-3340.34716796875,881.912841796875,1004.4173583984375
idle,5.519,-3416.122314453125,881.912841796875,1004.417236328125
idle,5.569,-3427.77734375,881.912841796875,1004.4171752929688
idle,5.619,-3462.7421875,881.9127807617188,1004.4171142578125
idle,5.669,-3491.897216796875,881.9127807617188,1004.4170532226562
idle,5.719,-3521.017333984375,881.9127807617188,1004.4169921875
idle,5.769,-3521.017333984375,881.9127807617188,1004.4169921875
idle,5.819,-3521.017333984375,881.9127807617188,1004.4169921875
idle,5.87,-3521.017333984375,881.9127807617188,1004.4169921875
idle,5.92,-3585.13720703125,881.9127197265625,1004.4168701171875
idle,5.97,-3608.447265625,881.9127197265625,1004.4168090820312
idle,6.02,-3643.412109375,881.9127197265625,1004.416748046875
idle,6.07,-3655.067138671875,881.9127197265625,1004.416748046875
idle,6.12,-3672.567138671875,881.9126586914062,1004.4166870117188
idle,6.173,-3672.567138671875,881.9126586914062,1004.4166870117188
idle,6.223,-3672.567138671875,881.9126586914062,1004.4166870117188
idle,6.273,-3736.687255859375,881.9126586914062,1004.4165649414062
idle,6.323,-3771.652099609375,881.9126586914062,1004.41650390625
idle,6.374,-3783.30712890625,881.9126586914062,1004.41650390625
idle,6.424,-3829.92724609375,881.91259765625,1004.4163818359375
idle,6.474,-3835.7373046875,881.91259765625,1004.4163818359375
idle,6.531,-3835.7373046875,881.91259765625,1004.4163818359375
idle,6.581,-3835.7373046875,881.91259765625,1004.4163818359375
idle,6.633,-3894.047119140625,881.91259765625,1004.416259765625
idle,6.683,-3905.7021484375,881.9125366210938,1004.416259765625
idle,6.761,-3952.322265625,881.9125366210938,1004.4161376953125
idle,6.811,-3981.442138671875,881.9125366210938,1004.4160766601562
idle,6.863,-3987.252197265625,881.9125366210938,1004.4160766601562
idle,6.913,-3987.252197265625,881.9125366210938,1004.4160766601562
idle,6.963,-3987.252197265625,881.9125366210938,1004.4160766601562
idle,7.013,-4039.71728515625,881.9124755859375,1004.4159545898438
idle,7.064,-4063.027099609375,881.9124755859375,1004.4158935546875
idle,7.114,-4097.9921875,881.9124755859375,1004.4158325195312
idle,7.164,-4109.64697265625,881.9124755859375,1004.4158325195312
idle,7.214,-4150.42236328125,881.9124145507812,1004.415771484375
idle,7.264,-4156.23193359375,881.9124145507812,1004.4157104492188
idle,7.315,-4156.23193359375,881.9124145507812,1004.4157104492188
idle,7.365,-4156.23193359375,881.9124145507812,1004.4157104492188
idle,7.415,-4220.35205078125,881.9124145507812,1004.4155883789062
idle,7.466,-4243.662109375,881.912353515625,1004.41552734375
idle,7.516,-4278.626953125,881.912353515625,1004.4154663085938
idle,7.566,-4307.7822265625,881.912353515625,1004.4154052734375
idle,7.616,-4336.90234375,881.912353515625,1004.4153442382812
idle,7.667,-4336.90234375,881.912353515625,1004.4153442382812
idle,7.717,-4336.90234375,881.912353515625,1004.4153442382812
idle,7.767,-4336.90234375,881.912353515625,1004.4153442382812
idle,7.82,-4401.02197265625,881.9122924804688,1004.4152221679688
idle,7.87,-4424.33203125,881.9122924804688,1004.4152221679688
idle,7.92,-4470.9521484375,881.9122314453125,1004.4151000976562
idle,7.97,-4482.60693359375,881.9122314453125,1004.4151000976562
RT,0.0,-4511.76220703125,881.9122314453125,1004.4150390625
RT,0.05,-4511.76220703125,881.9122314453125,1004.4150390625
RT,0.1,-4511.76220703125,881.9122314453125,1004.4150390625
RT,0.151,-4591.10205078125,881.9121704101562,1004.4148559570312
RT,0.203,-4631.14013671875,881.9121704101562,1004.414794921875
RT,0.253,-4688.6787109375,881.9121704101562,1004.4146728515625
RT,0.303,-4745.97314453125,881.912109375,1004.41455078125
RT,0.353,-4758.11572265625,881.912109375,1004.4144897460938
RT,0.404,-4758.11572265625,881.912109375,1004.4144897460938
RT,0.454,-4758.11572265625,881.912109375,1004.4144897460938
RT,0.504,-4894.6865234375,881.9120483398438,1004.4142456054688
RT,0.554,-4976.0556640625,881.9119873046875,1004.4140625
RT,0.605,-5047.275390625,881.9119262695312,1004.4139404296875
RT,0.655,-5163.5263671875,881.911865234375,1004.4136962890625
RT,0.705,-5203.26416015625,881.911865234375,1004.4136352539062
RT,0.756,-5223.07373046875,881.911865234375,1004.41357421875
RT,0.806,-5223.07373046875,881.911865234375,1004.41357421875
RT,0.857,-5223.07373046875,881.911865234375,1004.41357421875
RT,0.908,-5421.8828125,881.9117431640625,1004.4132080078125
RT,0.989,-5541.0966796875,881.9116821289062,1004.4129638671875
RT,1.039,-5700.048828125,881.91162109375,1004.41259765625
RT,1.09,-5739.78662109375,881.9115600585938,1004.4125366210938
RT,1.14,-5779.52490234375,881.9115600585938,1004.4124755859375
RT,1.19,-5779.52490234375,881.9115600585938,1004.4124755859375
RT,1.24,-5779.52490234375,881.9115600585938,1004.4124755859375
RT,1.29,-5978.333984375,881.9114379882812,1004.4120483398438
RT,1.341,-6097.54833984375,881.911376953125,1004.4118041992188
RT,1.391,-6177.02392578125,881.9113159179688,1004.4116821289062
RT,1.441,-6316.1669921875,881.9112548828125,1004.411376953125
RT,1.491,-6355.90478515625,881.9112548828125,1004.4113159179688
RT,1.541,-6455.3095703125,881.9111938476562,1004.4110717773438
RT,1.591,-6455.3095703125,881.9111938476562,1004.4110717773438
RT,1.641,-6455.3095703125,881.9111938476562,1004.4110717773438
RT,1.691,-6455.3095703125,881.9111938476562,1004.4110717773438
RT,1.742,-6713.666015625,881.9110717773438,1004.4105834960938
RT,1.792,-6793.14208984375,881.9110107421875,1004.410400390625
RT,1.842,-6912.35595703125,881.9109497070312,1004.41015625
RT,1.892,-6952.09423828125,881.9109497070312,1004.4100952148438
RT,1.942,-7011.6416015625,881.910888671875,1004.4099731445312
RT,1.992,-7011.6416015625,881.910888671875,1004.4099731445312
RT,2.042,-7011.6416015625,881.910888671875,1004.4099731445312
RT,2.092,-7011.6416015625,881.910888671875,1004.4099731445312
RT,2.144,-7269.998046875,881.9107666015625,1004.409423828125
RT,2.194,-7369.40283203125,881.9107055664062,1004.4092407226562
RT,2.244,-7488.61669921875,881.91064453125,1004.4089965820312
RT,2.294,-7528.3544921875,881.91064453125,1004.408935546875
RT,2.347,-7587.90185546875,881.9105834960938,1004.4088134765625
RT,2.397,-7587.90185546875,881.9105834960938,1004.4088134765625
RT,2.448,-7587.90185546875,881.9105834960938,1004.4088134765625
RT,2.498,-7587.90185546875,881.9105834960938,1004.4088134765625
RT,2.549,-7826.44921875,881.9104614257812,1004.4083251953125
RT,2.599,-7965.591796875,881.910400390625,1004.4080200195312
RT,2.65,-8084.80615234375,881.9103393554688,1004.4077758789062
RT,2.7,-8124.5439453125,881.9102783203125,1004.40771484375
RT,2.751,-8164.16259765625,881.9102783203125,1004.4076538085938
RT,2.801,-8164.16259765625,881.9102783203125,1004.4076538085938
RT,2.852,-8164.16259765625,881.9102783203125,1004.4076538085938
RT,2.902,-8164.16259765625,881.9102783203125,1004.4076538085938
RT,2.952,-8422.638671875,881.91015625,1004.4071044921875
RT,3.004,-8502.1142578125,881.9100952148438,1004.4069213867188
RT,3.054,-8621.3291015625,881.9100341796875,1004.4066772460938
RT,3.104,-8661.06640625,881.9100341796875,1004.4066162109375
RT,3.155,-8740.4228515625,881.9099731445312,1004.4064331054688
RT,3.205,-8740.4228515625,881.9099731445312,1004.4064331054688
RT,3.29,-8740.4228515625,881.9099731445312,1004.4064331054688
RT,3.34,-8939.232421875,881.9098510742188,1004.4060668945312
RT,3.39,-8998.7802734375,881.9098510742188,1004.4059448242188
RT,3.44,-9137.9228515625,881.9097290039062,1004.4056396484375
RT,3.49,-9177.66015625,881.9097290039062,1004.4055786132812
RT,3.54,-9276.9462890625,881.90966796875,1004.4053955078125
RT,3.592,-9296.7548828125,881.90966796875,1004.4053344726562
RT,3.642,-9296.7548828125,881.90966796875,1004.4053344726562
RT,3.692,-9296.7548828125,881.90966796875,1004.4053344726562
RT,3.747,-9555.1123046875,881.9095458984375,1004.40478515625
RT,3.797,-9614.7783203125,881.9094848632812,1004.4046630859375
RT,3.847,-9733.9921875,881.909423828125,1004.4044189453125
RT,3.898,-9793.6591796875,881.909423828125,1004.404296875
RT,3.948,-9873.015625,881.9093627929688,1004.4041748046875
RT,3.998,-9873.015625,881.9093627929688,1004.4041748046875
RT,4.048,-9873.015625,881.9093627929688,1004.4041748046875
RT,4.098,-9873.015625,881.9093627929688,1004.4041748046875
RT,4.148,-10111.5634765625,881.9092407226562,1004.4036865234375
RT,4.198,-10151.30078125,881.9092407226562,1004.4036254882812
RT,4.249,-10310.2529296875,881.9091186523438,1004.4032592773438
RT,4.3,-10349.9912109375,881.9091186523438,1004.4031982421875
RT,4.35,-10469.205078125,881.9090576171875,1004.4029541015625
RT,4.4,-10469.205078125,881.9090576171875,1004.4029541015625
RT,4.451,-10469.205078125,881.9090576171875,1004.4029541015625
RT,4.501,-10469.205078125,881.9090576171875,1004.4029541015625
RT,4.551,-10727.5615234375,881.9088745117188,1004.4024047851562
RT,4.601,-10727.5615234375,881.9088745117188,1004.4024047851562
RT,4.651,-10906.4423828125,881.9088134765625,1004.4020385742188
RT,4.704,-11005.8466796875,881.9087524414062,1004.40185546875
RT,4.754,-11065.39453125,881.9087524414062,1004.4017333984375
RT,4.804,-11065.39453125,881.9087524414062,1004.4017333984375
RT,4.855,-11065.39453125,881.9087524414062,1004.4017333984375
RT,4.905,-11065.39453125,881.9087524414062,1004.4017333984375
RT,4.957,-11323.7509765625,881.9085693359375,1004.4012451171875
RT,5.007,-11423.15625,881.9085083007812,1004.4010009765625
RT,5.058,-11542.3701171875,881.908447265625,1004.4007568359375
RT,5.108,-11621.845703125,881.908447265625,1004.400634765625
RT,5.158,-11681.3935546875,881.9083862304688,1004.4005126953125
RT,5.208,-11681.3935546875,881.9083862304688,1004.4005126953125
RT,5.259,-11681.3935546875,881.9083862304688,1004.4005126953125
RT,5.309,-11681.3935546875,881.9083862304688,1004.4005126953125
RT,5.36,-11939.75,881.9082641601562,1004.3999633789062
RT,5.41,-12058.9638671875,881.908203125,1004.3997192382812
RT,5.489,-12178.177734375,881.9081420898438,1004.3994750976562
RT,5.539,-12297.3916015625,881.9080810546875,1004.3992309570312
RT,5.59,-12297.3916015625,881.9080810546875,1004.3992309570312
RT,5.64,-12297.3916015625,881.9080810546875,1004.3992309570312
RT,5.69,-12297.3916015625,881.9080810546875,1004.3992309570312
RT,5.743,-12555.748046875,881.9078979492188,1004.3987426757812
RT,5.793,-12595.486328125,881.9078979492188,1004.398681640625
RT,5.844,-12714.7001953125,881.9078369140625,1004.3984375
RT,5.894,-12814.10546875,881.9077758789062,1004.398193359375
RT,5.944,-12913.390625,881.90771484375,1004.3980102539062
RT,5.994,-12913.390625,881.90771484375,1004.3980102539062
RT,6.044,-12913.390625,881.90771484375,1004.3980102539062
RT,6.094,-12913.390625,881.90771484375,1004.3980102539062
RT,6.144,-13132.0087890625,881.9075927734375,1004.3975830078125
RT,6.195,-13171.7470703125,881.9075927734375,1004.3975219726562
RT,6.246,-13350.6279296875,881.907470703125,1004.3971557617188
RT,6.296,-13390.365234375,881.907470703125,1004.3970336914062
RT,6.347,-13489.6513671875,881.9074096679688,1004.3968505859375
RT,6.397,-13489.6513671875,881.9074096679688,1004.3968505859375
RT,6.447,-13489.6513671875,881.9074096679688,1004.3968505859375
RT,6.497,-13489.6513671875,881.9074096679688,1004.3968505859375
RT,6.548,-13728.1982421875,881.9072875976562,1004.3963623046875
RT,6.598,-13807.673828125,881.9072265625,1004.3961791992188
RT,6.649,-13966.6259765625,881.9071655273438,1004.3958740234375
RT,6.701,-14066.03125,881.9071044921875,1004.3956909179688
RT,6.752,-14125.578125,881.9071044921875,1004.3955688476562
RT,6.802,-14125.578125,881.9071044921875,1004.3955688476562
RT,6.852,-14125.578125,881.9071044921875,1004.3955688476562
RT,6.902,-14125.578125,881.9071044921875,1004.3955688476562
RT,6.952,-14383.9345703125,881.9069213867188,1004.39501953125
RT,7.002,-14443.6015625,881.9069213867188,1004.3948974609375
RT,7.052,-14562.8154296875,881.9068603515625,1004.3946533203125
RT,7.102,-14602.5537109375,881.9067993164062,1004.3945922851562
RT,7.152,-14721.767578125,881.90673828125,1004.3943481445312
RT,7.202,-14721.767578125,881.90673828125,1004.3943481445312
RT,7.252,-14721.767578125,881.90673828125,1004.3943481445312
RT,7.302,-14721.767578125,881.90673828125,1004.3943481445312
RT,7.354,-14960.314453125,881.9066162109375,1004.3938598632812
RT,7.404,-15059.7197265625,881.9065551757812,1004.3936767578125
RT,7.455,-15178.93359375,881.906494140625,1004.3934326171875
RT,7.505,-15278.337890625,881.9064331054688,1004.3932495117188
RT,7.555,-15337.8857421875,881.9064331054688,1004.3931274414062
RT,7.605,-15337.8857421875,881.9064331054688,1004.3931274414062
RT,7.656,-15337.8857421875,881.9064331054688,1004.3931274414062
RT,7.706,-15496.95703125,881.9063720703125,1004.3927612304688
RT,7.756,-15596.2421875,881.9063110351562,1004.392578125
RT,7.806,-15655.9091796875,881.90625,1004.3924560546875
RT,7.857,-15775.123046875,881.9061889648438,1004.3922119140625
RT,7.907,-15874.52734375,881.9061279296875,1004.3920288085938
RT,7.957,-15894.3369140625,881.9061279296875,1004.3919677734375
coast,0.0,-15894.3369140625,881.9061279296875,1004.3919677734375
coast,0.05,-15894.3369140625,881.9061279296875,1004.3919677734375
coast,0.1,-16132.259765625,881.906005859375,1004.3914794921875
coast,0.15,-16228.6279296875,881.9059448242188,1004.3912963867188
coast,0.201,-16341.4130859375,881.9058837890625,1004.3910522460938
coast,0.251,-16414.818359375,881.9058837890625,1004.3909301757812
coast,0.302,-16432.935546875,881.9058227539062,1004.390869140625
coast,0.352,-16432.935546875,881.9058227539062,1004.390869140625
coast,0.402,-16432.935546875,881.9058227539062,1004.390869140625
coast,0.453,-16589.41015625,881.90576171875,1004.3905639648438
coast,0.503,-16674.68359375,881.9057006835938,1004.390380859375
coast,0.553,-16741.302734375,881.9057006835938,1004.3902587890625
coast,0.603,-16838.55078125,881.9056396484375,1004.3900756835938
coast,0.653,-16870.25390625,881.9056396484375,1004.3900146484375
coast,0.705,-16885.966796875,881.9055786132812,1004.3899536132812
coast,0.755,-16885.966796875,881.9055786132812,1004.3899536132812
coast,0.805,-16885.966796875,881.9055786132812,1004.3899536132812
coast,0.855,-17035.544921875,881.905517578125,1004.3896484375
coast,0.906,-17122.61328125,881.9054565429688,1004.3894653320312
coast,0.956,-17150.923828125,881.9054565429688,1004.389404296875
coast,1.006,-17233.70703125,881.9053955078125,1004.3892822265625
coast,1.056,-17260.5859375,881.9053955078125,1004.3892211914062
coast,1.107,-17287.109375,881.9053955078125,1004.38916015625
coast,1.157,-17287.109375,881.9053955078125,1004.38916015625
coast,1.207,-17387.55859375,881.9053344726562,1004.3889770507812
coast,1.259,-17424.537109375,881.9053344726562,1004.3888549804688
coast,1.309,-17496.0703125,881.9052734375,1004.3887329101562
coast,1.359,-17541.97265625,881.9052734375,1004.3886108398438
coast,1.409,-17586.4453125,881.9052124023438,1004.3885498046875
coast,1.459,-17629.4921875,881.9052124023438,1004.3884887695312
coast,1.509,-17629.4921875,881.9052124023438,1004.3884887695312
coast,1.559,-17629.4921875,881.9052124023438,1004.3884887695312
coast,1.611,-17718.390625,881.9051513671875,1004.3883056640625
coast,1.661,-17747.33984375,881.9051513671875,1004.3882446289062
coast,1.737,-17802.796875,881.9050903320312,1004.3881225585938
coast,1.787,-17855.041015625,881.9050903320312,1004.3880004882812
coast,1.837,-17871.7421875,881.9050903320312,1004.387939453125
coast,1.889,-17896.01171875,881.905029296875,1004.387939453125
coast,1.942,-17896.01171875,881.905029296875,1004.387939453125
coast,1.992,-17896.01171875,881.905029296875,1004.387939453125
coast,2.042,-17976.451171875,881.905029296875,1004.3877563476562
coast,2.098,-18003.77734375,881.905029296875,1004.3876953125
coast,2.148,-18016.90625,881.9049682617188,1004.3876953125
coast,2.198,-18071.580078125,881.9049682617188,1004.3875732421875
coast,2.248,-18077.390625,881.9049682617188,1004.3875732421875
coast,2.302,-18077.390625,881.9049682617188,1004.3875732421875
coast,2.352,-18077.390625,881.9049682617188,1004.3875732421875
coast,2.402,-18135.69921875,881.9049072265625,1004.387451171875
coast,2.452,-18147.35546875,881.9049072265625,1004.3873901367188
coast,2.537,-18193.974609375,881.9049072265625,1004.3873291015625
coast,2.587,-18228.939453125,881.9049072265625,1004.3872680664062
coast,2.638,-18234.75,881.9049072265625,1004.38720703125
coast,2.688,-18234.75,881.9049072265625,1004.38720703125
coast,2.738,-18234.75,881.9049072265625,1004.38720703125
coast,2.788,-18293.060546875,881.9048461914062,1004.3870849609375
coast,2.84,-18310.525390625,881.9048461914062,1004.3870849609375
coast,2.89,-18345.490234375,881.9048461914062,1004.3870239257812
coast,2.94,-18357.14453125,881.90478515625,1004.386962890625
coast,2.99,-18386.265625,881.90478515625,1004.3869018554688
coast,3.043,-18392.07421875,881.90478515625,1004.3869018554688
coast,3.093,-18392.07421875,881.90478515625,1004.3869018554688
coast,3.143,-18392.07421875,881.90478515625,1004.3869018554688
coast,3.193,-18467.849609375,881.9047241210938,1004.3867797851562
coast,3.243,-18479.505859375,881.9047241210938,1004.38671875
coast,3.293,-18514.470703125,881.9047241210938,1004.3866577148438
coast,3.343,-18537.779296875,881.9047241210938,1004.3865966796875
coast,3.394,-18561.0546875,881.9047241210938,1004.3865966796875
coast,3.445,-18561.0546875,881.9047241210938,1004.3865966796875
coast,3.495,-18561.0546875,881.9047241210938,1004.3865966796875
coast,3.546,-18561.0546875,881.9047241210938,1004.3865966796875
coast,3.596,-18631.01953125,881.9046630859375,1004.3864135742188
coast,3.646,-18654.330078125,881.9046630859375,1004.3863525390625
coast,3.697,-18700.94921875,881.9046020507812,1004.3862915039062
coast,3.747,-18712.60546875,881.9046020507812,1004.3862915039062
coast,3.797,-18747.5703125,881.9046020507812,1004.3861694335938
coast,3.847,-18747.5703125,881.9046020507812,1004.3861694335938
coast,3.897,-18747.5703125,881.9046020507812,1004.3861694335938
coast,3.947,-18747.5703125,881.9046020507812,1004.3861694335938
coast,3.998,-18823.345703125,881.904541015625,1004.3860473632812
coast,4.048,-18846.654296875,881.904541015625,1004.385986328125
coast,4.098,-18881.619140625,881.904541015625,1004.3859252929688
coast,4.148,-18904.9296875,881.904541015625,1004.3858642578125
coast,4.199,-18910.740234375,881.904541015625,1004.3858642578125
coast,4.249,-18910.740234375,881.904541015625,1004.3858642578125
coast,4.299,-18910.740234375,881.904541015625,1004.3858642578125
coast,4.349,-18910.740234375,881.904541015625,1004.3858642578125
coast,4.399,-18980.705078125,881.9044799804688,1004.3857421875
coast,4.449,-19021.515625,881.9044799804688,1004.3856201171875
coast,4.499,-19056.48046875,881.9044189453125,1004.3855590820312
coast,4.549,-19068.134765625,881.9044189453125,1004.3855590820312
coast,4.6,-19073.9453125,881.9044189453125,1004.385498046875
coast,4.65,-19073.9453125,881.9044189453125,1004.385498046875
coast,4.7,-19073.9453125,881.9044189453125,1004.385498046875
coast,4.751,-19138.099609375,881.9044189453125,1004.3853759765625
coast,4.801,-19155.564453125,881.9043579101562,1004.3853759765625
coast,4.851,-19190.529296875,881.9043579101562,1004.3853149414062
coast,4.902,-19225.494140625,881.9043579101562,1004.3851928710938
coast,4.952,-19237.150390625,881.9043579101562,1004.3851928710938
coast,5.005,-19242.958984375,881.9043579101562,1004.3851928710938
coast,5.055,-19242.958984375,881.9043579101562,1004.3851928710938
coast,5.109,-19242.958984375,881.9043579101562,1004.3851928710938
coast,5.159,-19312.92578125,881.904296875,1004.3850708007812
coast,5.209,-19347.890625,881.904296875,1004.3849487304688
coast,5.259,-19377.044921875,881.9042358398438,1004.3848876953125
coast,5.31,-19412.009765625,881.9042358398438,1004.3848266601562
coast,5.36,-19423.6640625,881.9042358398438,1004.3848266601562
coast,5.411,-19423.6640625,881.9042358398438,1004.3848266601562
coast,5.461,-19423.6640625,881.9042358398438,1004.3848266601562
coast,5.537,-19481.974609375,881.9042358398438,1004.3847045898438
coast,5.587,-19522.78515625,881.9041748046875,1004.3846435546875
coast,5.637,-19534.439453125,881.9041748046875,1004.3845825195312
coast,5.687,-19569.404296875,881.9041748046875,1004.384521484375
coast,5.737,-19586.869140625,881.9041748046875,1004.3844604492188
coast,5.787,-19586.869140625,881.9041748046875,1004.3844604492188
coast,5.839,-19586.869140625,881.9041748046875,1004.3844604492188
coast,5.889,-19586.869140625,881.9041748046875,1004.3844604492188
coast,5.939,-19650.990234375,881.9041137695312,1004.3843383789062
coast,5.989,-19685.955078125,881.9041137695312,1004.38427734375
coast,6.039,-19697.609375,881.9041137695312,1004.38427734375
coast,6.09,-19744.23046875,881.904052734375,1004.3841552734375
coast,6.14,-19755.849609375,881.904052734375,1004.3841552734375
coast,6.192,-19755.849609375,881.904052734375,1004.3841552734375
coast,6.242,-19755.849609375,881.904052734375,1004.3841552734375
coast,6.292,-19814.16015625,881.904052734375,1004.384033203125
coast,6.343,-19831.625,881.9039916992188,1004.3839721679688
coast,6.393,-19878.244140625,881.9039916992188,1004.3839111328125
coast,6.443,-19889.900390625,881.9039916992188,1004.3838500976562
coast,6.494,-19913.173828125,881.9039916992188,1004.3838500976562
coast,6.544,-19913.173828125,881.9039916992188,1004.3838500976562
coast,6.594,-19913.173828125,881.9039916992188,1004.3838500976562
coast,6.644,-19913.173828125,881.9039916992188,1004.3838500976562
coast,6.694,-19988.94921875,881.9039306640625,1004.3836669921875
coast,6.744,-20006.44921875,881.9039306640625,1004.3836059570312
coast,6.795,-20041.4140625,881.9039306640625,1004.383544921875
coast,6.846,-20070.5703125,881.9038696289062,1004.3834838867188
coast,6.896,-20088.03515625,881.9038696289062,1004.3834838867188
coast,6.946,-20088.03515625,881.9038696289062,1004.3834838867188
coast,6.996,-20088.03515625,881.9038696289062,1004.3834838867188
coast,7.046,-20088.03515625,881.9038696289062,1004.3834838867188
coast,7.097,-20152.154296875,881.9038696289062,1004.3833618164062
coast,7.147,-20192.96484375,881.90380859375,1004.3832397460938
coast,7.197,-20227.9296875,881.90380859375,1004.3831787109375
coast,7.247,-20245.4296875,881.90380859375,1004.3831787109375
coast,7.298,-20257.083984375,881.90380859375,1004.3831176757812
coast,7.348,-20257.083984375,881.90380859375,1004.3831176757812
coast,7.399,-20257.083984375,881.90380859375,1004.3831176757812
coast,7.449,-20315.39453125,881.9037475585938,1004.3829956054688
coast,7.499,-20344.515625,881.9037475585938,1004.3829345703125
coast,7.55,-20367.82421875,881.9037475585938,1004.3828735351562
coast,7.6,-20414.4453125,881.9036865234375,1004.3828125
coast,7.65,-20426.099609375,881.9036865234375,1004.3828125
coast,7.702,-20437.75390625,881.9036865234375,1004.3827514648438
coast,7.752,-20437.75390625,881.9036865234375,1004.3827514648438
coast,7.802,-20437.75390625,881.9036865234375,1004.3827514648438
coast,7.852,-20507.71875,881.9036865234375,1004.3826293945312
coast,7.902,-20542.685546875,881.9036254882812,1004.382568359375
coast,7.952,-20554.33984375,881.9036254882812,1004.3825073242188
LT,0.0,-20600.958984375,881.9036254882812,1004.3824462890625
LT,0.05,-20600.958984375,881.9036254882812,1004.3824462890625
LT,0.104,-20600.958984375,881.9036254882812,1004.3824462890625
LT,0.175,-20641.892578125,881.903564453125,1004.38232421875
LT,0.225,-20670.3359375,881.903564453125,1004.3822631835938
LT,0.275,-20679.1328125,881.903564453125,1004.3822631835938
LT,0.325,-20703.380859375,881.903564453125,1004.3822021484375
LT,0.376,-20714.333984375,881.903564453125,1004.3822021484375
LT,0.426,-20714.333984375,881.903564453125,1004.3822021484375
LT,0.479,-20714.333984375,881.903564453125,1004.3822021484375
LT,0.529,-20714.333984375,881.903564453125,1004.3822021484375
LT,0.579,-20745.40234375,881.9035034179688,1004.3821411132812
LT,0.629,-20758.935546875,881.9035034179688,1004.3821411132812
LT,0.679,-20762.732421875,881.9035034179688,1004.382080078125
LT,0.729,-20772.962890625,881.9035034179688,1004.382080078125
LT,0.779,-20778.05078125,881.9035034179688,1004.382080078125
LT,0.829,-20778.05078125,881.9035034179688,1004.382080078125
LT,0.88,-20778.05078125,881.9035034179688,1004.382080078125
LT,0.93,-20795.037109375,881.9035034179688,1004.3820190429688
LT,0.981,-20800.125,881.9035034179688,1004.3820190429688
LT,1.031,-20808.619140625,881.9035034179688,1004.3820190429688
LT,1.081,-20817.11328125,881.9035034179688,1004.3820190429688
LT,1.131,-20827.298828125,881.9035034179688,1004.3819580078125
LT,1.183,-20828.990234375,881.9035034179688,1004.3819580078125
LT,1.233,-20828.990234375,881.9035034179688,1004.3819580078125
LT,1.283,-20828.990234375,881.9035034179688,1004.3819580078125
LT,1.335,-20847.669921875,881.9035034179688,1004.3819580078125
LT,1.386,-20854.4609375,881.9034423828125,1004.3818969726562
LT,1.436,-20864.646484375,881.9034423828125,1004.3818969726562
LT,1.486,-20868.041015625,881.9034423828125,1004.3818969726562
LT,1.536,-20874.822265625,881.9034423828125,1004.3818969726562
LT,1.586,-20874.822265625,881.9034423828125,1004.3818969726562
LT,1.636,-20874.822265625,881.9034423828125,1004.3818969726562
LT,1.686,-20874.822265625,881.9034423828125,1004.3818969726562
LT,1.737,-20895.203125,881.9034423828125,1004.3818359375
LT,1.787,-20903.697265625,881.9034423828125,1004.3818359375
LT,1.837,-20913.8828125,881.9034423828125,1004.3817749023438
LT,1.887,-20917.279296875,881.9034423828125,1004.3817749023438
LT,1.937,-20924.068359375,881.9034423828125,1004.3817749023438
LT,1.987,-20924.068359375,881.9034423828125,1004.3817749023438
LT,2.037,-20924.068359375,881.9034423828125,1004.3817749023438
LT,2.088,-20924.068359375,881.9034423828125,1004.3817749023438
LT,2.139,-20946.14453125,881.9034423828125,1004.3817138671875
LT,2.189,-20956.330078125,881.9034423828125,1004.3817138671875
LT,2.239,-20966.515625,881.9034423828125,1004.3817138671875
LT,2.289,-20969.91015625,881.9033813476562,1004.3817138671875
LT,2.34,-20971.603515625,881.9033813476562,1004.3816528320312
LT,2.39,-20971.603515625,881.9033813476562,1004.3816528320312
LT,2.44,-20971.603515625,881.9033813476562,1004.3816528320312
LT,2.492,-20991.974609375,881.9033813476562,1004.3816528320312
LT,2.542,-21002.16015625,881.9033813476562,1004.381591796875
LT,2.592,-21005.556640625,881.9033813476562,1004.381591796875
LT,2.642,-21015.7421875,881.9033813476562,1004.381591796875
LT,2.693,-21017.435546875,881.9033813476562,1004.381591796875
LT,2.775,-21017.435546875,881.9033813476562,1004.381591796875
LT,2.825,-21017.435546875,881.9033813476562,1004.381591796875
LT,2.878,-21037.81640625,881.9033813476562,1004.3815307617188
LT,2.928,-21048.001953125,881.9033813476562,1004.3815307617188
LT,2.978,-21051.3984375,881.9033813476562,1004.3815307617188
LT,3.029,-21061.583984375,881.9033813476562,1004.3814697265625
LT,3.079,-21063.275390625,881.9033813476562,1004.3814697265625
LT,3.129,-21063.275390625,881.9033813476562,1004.3814697265625
LT,3.179,-21063.275390625,881.9033813476562,1004.3814697265625
LT,3.229,-21081.955078125,881.9033203125,1004.3814697265625
LT,3.279,-21090.44921875,881.9033203125,1004.3814697265625
LT,3.329,-21097.240234375,881.9033203125,1004.3814086914062
LT,3.379,-21100.634765625,881.9033203125,1004.3814086914062
LT,3.429,-21110.8203125,881.9033203125,1004.3814086914062
LT,3.48,-21110.8203125,881.9033203125,1004.3814086914062
LT,3.53,-21110.8203125,881.9033203125,1004.3814086914062
LT,3.58,-21110.8203125,881.9033203125,1004.3814086914062
LT,3.631,-21132.89453125,881.9033203125,1004.38134765625
LT,3.681,-21143.080078125,881.9033203125,1004.38134765625
LT,3.731,-21153.267578125,881.9033203125,1004.3812866210938
LT,3.781,-21160.056640625,881.9033203125,1004.3812866210938
LT,3.831,-21163.453125,881.9033203125,1004.3812866210938
LT,3.882,-21163.453125,881.9033203125,1004.3812866210938
LT,3.932,-21163.453125,881.9033203125,1004.3812866210938
LT,3.982,-21177.033203125,881.9033203125,1004.3812866210938
LT,4.035,-21188.921875,881.9033203125,1004.3812255859375
LT,4.085,-21199.107421875,881.9032592773438,1004.3812255859375
LT,4.135,-21205.8984375,881.9032592773438,1004.3812255859375
LT,4.187,-21207.591796875,881.9032592773438,1004.3812255859375
LT,4.237,-21207.591796875,881.9032592773438,1004.3812255859375
LT,4.287,-21207.591796875,881.9032592773438,1004.3812255859375
LT,4.337,-21222.875,881.9032592773438,1004.3811645507812
LT,4.387,-21229.666015625,881.9032592773438,1004.3811645507812
LT,4.437,-21239.8515625,881.9032592773438,1004.3811645507812
LT,4.487,-21244.94921875,881.9032592773438,1004.381103515625
LT,4.537,-21251.73046875,881.9032592773438,1004.381103515625
LT,4.587,-21251.73046875,881.9032592773438,1004.381103515625
LT,4.638,-21251.73046875,881.9032592773438,1004.381103515625
LT,4.688,-21251.73046875,881.9032592773438,1004.381103515625
LT,4.741,-21272.111328125,881.9032592773438,1004.381103515625
LT,4.791,-21284.0,881.9032592773438,1004.3810424804688
LT,4.841,-21290.791015625,881.9032592773438,1004.3810424804688
LT,4.891,-21297.58203125,881.9032592773438,1004.3810424804688
LT,4.942,-21299.275390625,881.9032592773438,1004.3810424804688
LT,4.992,-21299.275390625,881.9032592773438,1004.3810424804688
LT,5.042,-21299.275390625,881.9032592773438,1004.3810424804688
LT,5.092,-21316.26171875,881.9031982421875,1004.3809814453125
LT,5.142,-21324.744140625,881.9031982421875,1004.3809814453125
LT,5.192,-21331.53515625,881.9031982421875,1004.3809814453125
LT,5.242,-21341.720703125,881.9031982421875,1004.3809204101562
LT,5.292,-21346.818359375,881.9031982421875,1004.3809204101562
LT,5.343,-21350.21484375,881.9031982421875,1004.3809204101562
LT,5.393,-21350.21484375,881.9031982421875,1004.3809204101562
LT,5.443,-21362.103515625,881.9031982421875,1004.3809204101562
LT,5.493,-21370.5859375,881.9031982421875,1004.380859375
LT,5.578,-21380.771484375,881.9031982421875,1004.380859375
LT,5.628,-21390.95703125,881.9031982421875,1004.380859375
LT,5.678,-21396.044921875,881.9031982421875,1004.3807983398438
LT,5.728,-21396.044921875,881.9031982421875,1004.3807983398438
LT,5.778,-21396.044921875,881.9031982421875,1004.3807983398438
LT,5.828,-21413.03125,881.9031982421875,1004.3807983398438
LT,5.882,-21418.119140625,881.9031982421875,1004.3807983398438
LT,5.932,-21430.0078125,881.9031372070312,1004.3807373046875
LT,5.983,-21436.798828125,881.9031372070312,1004.3807373046875
LT,6.033,-21443.58984375,881.9031372070312,1004.3807373046875
LT,6.085,-21445.283203125,881.9031372070312,1004.3807373046875
LT,6.135,-21445.283203125,881.9031372070312,1004.3807373046875
LT,6.185,-21445.283203125,881.9031372070312,1004.3807373046875
LT,6.235,-21463.9609375,881.9031372070312,1004.3806762695312
LT,6.285,-21469.060546875,881.9031372070312,1004.3806762695312
LT,6.335,-21479.24609375,881.9031372070312,1004.3806762695312
LT,6.385,-21482.640625,881.9031372070312,1004.3806762695312
LT,6.438,-21489.431640625,881.9031372070312,1004.380615234375
LT,6.488,-21489.431640625,881.9031372070312,1004.380615234375
LT,6.538,-21489.431640625,881.9031372070312,1004.380615234375
LT,6.588,-21506.41796875,881.9031372070312,1004.380615234375
LT,6.638,-21514.900390625,881.9031372070312,1004.3805541992188
LT,6.689,-21525.087890625,881.9031372070312,1004.3805541992188
LT,6.739,-21535.2734375,881.9031372070312,1004.3805541992188
LT,6.789,-21538.66796875,881.903076171875,1004.3805541992188
LT,6.84,-21542.064453125,881.903076171875,1004.3805541992188
LT,6.89,-21542.064453125,881.903076171875,1004.3805541992188
LT,6.94,-21542.064453125,881.903076171875,1004.3805541992188
LT,6.99,-21560.7421875,881.903076171875,1004.3804931640625
LT,7.075,-21570.927734375,881.903076171875,1004.3804931640625
LT,7.125,-21581.115234375,881.903076171875,1004.3804321289062
LT,7.175,-21586.203125,881.903076171875,1004.3804321289062
LT,7.225,-21586.203125,881.903076171875,1004.3804321289062
LT,7.275,-21586.203125,881.903076171875,1004.3804321289062
LT,7.325,-21603.189453125,881.903076171875,1004.3804321289062
LT,7.376,-21608.27734375,881.903076171875,1004.38037109375
LT,7.426,-21620.166015625,881.903076171875,1004.38037109375
LT,7.476,-21620.166015625,881.903076171875,1004.38037109375
LT,7.526,-21632.04296875,881.903076171875,1004.38037109375
LT,7.577,-21633.736328125,881.903076171875,1004.38037109375
LT,7.627,-21633.736328125,881.903076171875,1004.38037109375
LT,7.677,-21633.736328125,881.903076171875,1004.38037109375
LT,7.729,-21652.416015625,881.9030151367188,1004.3803100585938
LT,7.779,-21659.20703125,881.9030151367188,1004.3803100585938
LT,7.829,-21672.787109375,881.9030151367188,1004.3802490234375
LT,7.879,-21676.18359375,881.9030151367188,1004.3802490234375
LT,7.929,-21681.271484375,881.9030151367188,1004.3802490234375
LT,7.979,-21681.271484375,881.9030151367188,1004.3802490234375
coast2,0.0,-21699.958984375,881.9030151367188,1004.3801879882812
coast2,0.05,-21709.087890625,881.9030151367188,1004.3801879882812
coast2,0.1,-21722.490234375,881.9030151367188,1004.3801879882812
coast2,0.15,-21733.17578125,881.9030151367188,1004.380126953125
coast2,0.2,-21748.78125,881.9030151367188,1004.380126953125
coast2,0.25,-21748.78125,881.9030151367188,1004.380126953125
coast2,0.301,-21748.78125,881.9030151367188,1004.380126953125
coast2,0.351,-21780.17578125,881.9029541015625,1004.3800659179688
coast2,0.401,-21797.376953125,881.9029541015625,1004.3800048828125
coast2,0.478,-21826.087890625,881.9029541015625,1004.3799438476562
coast2,0.528,-21858.291015625,881.9029541015625,1004.3798828125
coast2,0.579,-21875.611328125,881.9029541015625,1004.3798828125
coast2,0.629,-21875.611328125,881.9029541015625,1004.3798828125
coast2,0.68,-21875.611328125,881.9029541015625,1004.3798828125
coast2,0.73,-21875.611328125,881.9029541015625,1004.3798828125
coast2,0.78,-21951.38671875,881.9028930664062,1004.3796997070312
coast2,0.83,-21986.3515625,881.9028930664062,1004.379638671875
coast2,0.881,-21998.005859375,881.90283203125,1004.3795776367188
coast2,0.932,-22044.626953125,881.90283203125,1004.3795166015625
coast2,0.982,-22062.091796875,881.90283203125,1004.3794555664062
coast2,1.032,-22062.091796875,881.90283203125,1004.3794555664062
coast2,1.082,-22062.091796875,881.90283203125,1004.3794555664062
coast2,1.132,-22062.091796875,881.90283203125,1004.3794555664062
coast2,1.183,-22143.7109375,881.9027709960938,1004.3793334960938
coast2,1.233,-22178.677734375,881.9027709960938,1004.3792114257812
coast2,1.283,-22190.33203125,881.9027709960938,1004.3792114257812
coast2,1.333,-22236.951171875,881.9027099609375,1004.379150390625
coast2,1.383,-22242.76171875,881.9027099609375,1004.3790893554688
coast2,1.433,-22242.76171875,881.9027099609375,1004.3790893554688
coast2,1.483,-22242.76171875,881.9027099609375,1004.3790893554688
coast2,1.533,-22289.416015625,881.9027099609375,1004.3790283203125
coast2,1.583,-22318.537109375,881.9027099609375,1004.3789672851562
coast2,1.634,-22353.501953125,881.9026489257812,1004.37890625
coast2,1.684,-22365.15625,881.9026489257812,1004.3788452148438
coast2,1.734,-22411.77734375,881.9026489257812,1004.3787841796875
coast2,1.784,-22417.5859375,881.9026489257812,1004.3787841796875
coast2,1.834,-22417.5859375,881.9026489257812,1004.3787841796875
coast2,1.885,-22417.5859375,881.9026489257812,1004.3787841796875
coast2,1.935,-22475.896484375,881.902587890625,1004.378662109375
coast2,1.989,-22493.361328125,881.902587890625,1004.3786010742188
coast2,2.042,-22539.982421875,881.902587890625,1004.3785400390625
coast2,2.092,-22563.291015625,881.9025268554688,1004.3784790039062
coast2,2.143,-22592.412109375,881.9025268554688,1004.37841796875
coast2,2.194,-22598.22265625,881.9025268554688,1004.37841796875
coast2,2.279,-22598.22265625,881.9025268554688,1004.37841796875
coast2,2.329,-22598.22265625,881.9025268554688,1004.37841796875
coast2,2.38,-22662.341796875,881.9025268554688,1004.3782348632812
coast2,2.43,-22708.9609375,881.9024658203125,1004.378173828125
coast2,2.48,-22708.9609375,881.9024658203125,1004.378173828125
coast2,2.531,-22743.92578125,881.9024658203125,1004.3781127929688
coast2,2.581,-22761.392578125,881.9024658203125,1004.3780517578125
coast2,2.631,-22761.392578125,881.9024658203125,1004.3780517578125
coast2,2.681,-22761.392578125,881.9024658203125,1004.3780517578125
coast2,2.731,-22761.392578125,881.9024658203125,1004.3780517578125
coast2,2.781,-22837.166015625,881.9024047851562,1004.3779296875
coast2,2.832,-22872.130859375,881.9024047851562,1004.3778686523438
coast2,2.882,-22883.787109375,881.9024047851562,1004.3778076171875
coast2,2.933,-22930.40625,881.90234375,1004.3777465820312
coast2,2.983,-22942.02734375,881.90234375,1004.377685546875
coast2,3.033,-22942.02734375,881.90234375,1004.377685546875
coast2,3.083,-22942.02734375,881.90234375,1004.377685546875
coast2,3.133,-22994.52734375,881.90234375,1004.3775634765625
coast2,3.183,-23011.9921875,881.90234375,1004.3775634765625
coast2,3.234,-23046.95703125,881.9022827148438,1004.3775024414062
coast2,3.284,-23058.611328125,881.9022827148438,1004.37744140625
coast2,3.334,-23105.232421875,881.9022827148438,1004.3773803710938
coast2,3.384,-23111.041015625,881.9022827148438,1004.3773803710938
coast2,3.435,-23111.041015625,881.9022827148438,1004.3773803710938
coast2,3.485,-23111.041015625,881.9022827148438,1004.3773803710938
coast2,3.535,-23163.541015625,881.9022216796875,1004.3772583007812
coast2,3.587,-23181.005859375,881.9022216796875,1004.377197265625
coast2,3.677,-23221.81640625,881.9022216796875,1004.3771362304688
coast2,3.728,-23256.78125,881.9021606445312,1004.3770751953125
coast2,3.778,-23274.24609375,881.9021606445312,1004.3770141601562
coast2,3.828,-23274.24609375,881.9021606445312,1004.3770141601562
coast2,3.878,-23274.24609375,881.9021606445312,1004.3770141601562
coast2,3.928,-23274.24609375,881.9021606445312,1004.3770141601562
coast2,3.979,-23344.2109375,881.9021606445312,1004.3768920898438
coast2,4.029,-23379.17578125,881.902099609375,1004.3768310546875
coast2,4.079,-23390.83203125,881.902099609375,1004.3767700195312
coast2,4.129,-23437.451171875,881.902099609375,1004.376708984375
coast2,4.18,-23449.072265625,881.902099609375,1004.3766479492188
coast2,4.23,-23449.072265625,881.902099609375,1004.3766479492188
coast2,4.28,-23449.072265625,881.902099609375,1004.3766479492188
coast2,4.33,-23449.072265625,881.902099609375,1004.3766479492188
coast2,4.38,-23524.845703125,881.9020385742188,1004.3765258789062
coast2,4.43,-23559.8125,881.9020385742188,1004.37646484375
coast2,4.48,-23571.466796875,881.9020385742188,1004.3764038085938
coast2,4.53,-23606.431640625,881.9019775390625,1004.3763427734375
coast2,4.58,-23623.896484375,881.9019775390625,1004.3763427734375
coast2,4.631,-23623.896484375,881.9019775390625,1004.3763427734375
coast2,4.681,-23623.896484375,881.9019775390625,1004.3763427734375
coast2,4.731,-23623.896484375,881.9019775390625,1004.3763427734375
coast2,4.781,-23688.015625,881.9019775390625,1004.3761596679688
coast2,4.832,-23722.982421875,881.9019165039062,1004.3760986328125
coast2,4.882,-23746.291015625,881.9019165039062,1004.3760986328125
coast2,4.934,-23781.255859375,881.9019165039062,1004.3759765625
coast2,4.984,-23804.56640625,881.9019165039062,1004.3759765625
coast2,5.034,-23822.06640625,881.90185546875,1004.3759155273438
coast2,5.084,-23822.06640625,881.90185546875,1004.3759155273438
coast2,5.134,-23822.06640625,881.90185546875,1004.3759155273438
coast2,5.184,-23874.56640625,881.90185546875,1004.3757934570312
coast2,5.234,-23915.341796875,881.90185546875,1004.375732421875
coast2,5.284,-23938.65234375,881.9017944335938,1004.3756713867188
coast2,5.334,-23985.271484375,881.9017944335938,1004.3756103515625
coast2,5.385,-23996.92578125,881.9017944335938,1004.3755493164062
coast2,5.438,-24008.546875,881.9017944335938,1004.3755493164062
coast2,5.488,-24008.546875,881.9017944335938,1004.3755493164062
coast2,5.539,-24008.546875,881.9017944335938,1004.3755493164062
coast2,5.589,-24008.546875,881.9017944335938,1004.3755493164062
coast2,5.639,-24095.9765625,881.9017333984375,1004.3753662109375
coast2,5.689,-24125.130859375,881.9017333984375,1004.3753051757812
coast2,5.739,-24160.095703125,881.9016723632812,1004.375244140625
coast2,5.789,-24171.751953125,881.9016723632812,1004.3751831054688
coast2,5.839,-24195.02734375,881.9016723632812,1004.3751831054688
coast2,5.889,-24195.02734375,881.9016723632812,1004.3751831054688
coast2,5.94,-24195.02734375,881.9016723632812,1004.3751831054688
coast2,5.99,-24195.02734375,881.9016723632812,1004.3751831054688
coast2,6.04,-24264.9921875,881.9016723632812,1004.375
coast2,6.091,-24288.30078125,881.901611328125,1004.375
coast2,6.141,-24334.921875,881.901611328125,1004.3748779296875
coast2,6.192,-24358.232421875,881.901611328125,1004.3748168945312
coast2,6.242,-24387.3515625,881.9015502929688,1004.374755859375
coast2,6.292,-24393.162109375,881.9015502929688,1004.374755859375
coast2,6.345,-24393.162109375,881.9015502929688,1004.374755859375
coast2,6.395,-24393.162109375,881.9015502929688,1004.374755859375
coast2,6.446,-24451.470703125,881.9015502929688,1004.3746337890625
coast2,6.496,-24480.591796875,881.9015502929688,1004.3745727539062
coast2,6.578,-24515.556640625,881.9014892578125,1004.37451171875
coast2,6.628,-24568.021484375,881.9014892578125,1004.3743896484375
coast2,6.678,-24579.67578125,881.9014892578125,1004.3743896484375
coast2,6.728,-24591.33203125,881.9014892578125,1004.3743286132812
coast2,6.778,-24591.33203125,881.9014892578125,1004.3743286132812
coast2,6.829,-24591.33203125,881.9014892578125,1004.3743286132812
coast2,6.879,-24655.451171875,881.9014282226562,1004.3742065429688
coast2,6.929,-24690.416015625,881.9014282226562,1004.3741455078125
coast2,6.979,-24702.072265625,881.9014282226562,1004.3741455078125
coast2,7.031,-24737.037109375,881.9013671875,1004.3740844726562
coast2,7.081,-24760.345703125,881.9013671875,1004.3740234375
coast2,7.132,-24772.001953125,881.9013671875,1004.3739624023438
coast2,7.182,-24772.001953125,881.9013671875,1004.3739624023438
coast2,7.232,-24772.001953125,881.9013671875,1004.3739624023438
coast2,7.284,-24830.310546875,881.9013671875,1004.3738403320312
coast2,7.334,-24865.27734375,881.9013061523438,1004.373779296875
coast2,7.384,-24894.431640625,881.9013061523438,1004.3737182617188
coast2,7.434,-24929.396484375,881.9013061523438,1004.3736572265625
coast2,7.484,-24952.70703125,881.9012451171875,1004.3735961914062
coast2,7.534,-24958.515625,881.9012451171875,1004.3735961914062
coast2,7.584,-24958.515625,881.9012451171875,1004.3735961914062
coast2,7.635,-24958.515625,881.9012451171875,1004.3735961914062
coast2,7.685,-24958.515625,881.9012451171875,1004.3735961914062
coast2,7.736,-25028.48046875,881.9012451171875,1004.3734741210938
coast2,7.786,-25057.63671875,881.9012451171875,1004.3734130859375
coast2,7.837,-25092.6015625,881.9011840820312,1004.3733520507812
coast2,7.887,-25104.255859375,881.9011840820312,1004.373291015625
coast2,7.937,-25121.720703125,881.9011840820312,1004.373291015625
coast2,7.987,-25121.720703125,881.9011840820312,1004.373291015625
1 phase t x y z
2 idle 0.0 -1032.5526123046875 881.9141235351562 1004.4220581054688
3 idle 0.05 -1038.362548828125 881.9141235351562 1004.4220581054688
4 idle 0.1 -1038.362548828125 881.9141235351562 1004.4220581054688
5 idle 0.162 -1038.362548828125 881.9141235351562 1004.4220581054688
6 idle 0.212 -1090.8275146484375 881.9140625 1004.4219360351562
7 idle 0.262 -1102.4825439453125 881.9140625 1004.4219360351562
8 idle 0.312 -1143.2926025390625 881.9140625 1004.4218139648438
9 idle 0.362 -1166.6025390625 881.9140625 1004.4217529296875
10 idle 0.413 -1201.5675048828125 881.9140014648438 1004.4216918945312
11 idle 0.463 -1201.5675048828125 881.9140014648438 1004.4216918945312
12 idle 0.516 -1201.5675048828125 881.9140014648438 1004.4216918945312
13 idle 0.566 -1201.5675048828125 881.9140014648438 1004.4216918945312
14 idle 0.616 -1277.342529296875 881.9140014648438 1004.4215698242188
15 idle 0.666 -1300.652587890625 881.9139404296875 1004.4215087890625
16 idle 0.716 -1335.6175537109375 881.9139404296875 1004.4214477539062
17 idle 0.767 -1358.927490234375 881.9139404296875 1004.42138671875
18 idle 0.817 -1388.0474853515625 881.9139404296875 1004.4213256835938
19 idle 0.867 -1388.0474853515625 881.9139404296875 1004.4213256835938
20 idle 0.917 -1388.0474853515625 881.9139404296875 1004.4213256835938
21 idle 0.968 -1388.0474853515625 881.9139404296875 1004.4213256835938
22 idle 1.018 -1458.0125732421875 881.9138793945312 1004.4212036132812
23 idle 1.068 -1492.9775390625 881.9138793945312 1004.421142578125
24 idle 1.118 -1527.9425048828125 881.913818359375 1004.4210205078125
25 idle 1.168 -1539.5975341796875 881.913818359375 1004.4210205078125
26 idle 1.218 -1551.217529296875 881.913818359375 1004.4210205078125
27 idle 1.269 -1551.217529296875 881.913818359375 1004.4210205078125
28 idle 1.319 -1551.217529296875 881.913818359375 1004.4210205078125
29 idle 1.369 -1603.6824951171875 881.913818359375 1004.4208984375
30 idle 1.419 -1638.6474609375 881.9137573242188 1004.4208374023438
31 idle 1.469 -1650.302490234375 881.9137573242188 1004.4207763671875
32 idle 1.519 -1685.2674560546875 881.9137573242188 1004.4207153320312
33 idle 1.572 -1691.0775146484375 881.9137573242188 1004.4207153320312
34 idle 1.622 -1691.0775146484375 881.9137573242188 1004.4207153320312
35 idle 1.672 -1691.0775146484375 881.9137573242188 1004.4207153320312
36 idle 1.722 -1749.387451171875 881.9136962890625 1004.4205932617188
37 idle 1.773 -1761.04248046875 881.9136962890625 1004.4205932617188
38 idle 1.823 -1807.6624755859375 881.9136962890625 1004.4204711914062
39 idle 1.873 -1819.3175048828125 881.9136962890625 1004.4204711914062
40 idle 1.923 -1842.5924072265625 881.9136962890625 1004.42041015625
41 idle 1.973 -1842.5924072265625 881.9136962890625 1004.42041015625
42 idle 2.024 -1842.5924072265625 881.9136962890625 1004.42041015625
43 idle 2.074 -1842.5924072265625 881.9136962890625 1004.42041015625
44 idle 2.124 -1906.71240234375 881.9136352539062 1004.4202880859375
45 idle 2.174 -1935.867431640625 881.9136352539062 1004.4202270507812
46 idle 2.224 -1970.8323974609375 881.91357421875 1004.420166015625
47 idle 2.275 -1982.4874267578125 881.91357421875 1004.4201049804688
48 idle 2.325 -1994.107421875 881.91357421875 1004.4201049804688
49 idle 2.375 -1994.107421875 881.91357421875 1004.4201049804688
50 idle 2.425 -1994.107421875 881.91357421875 1004.4201049804688
51 idle 2.475 -2058.262451171875 881.91357421875 1004.4199829101562
52 idle 2.525 -2075.7275390625 881.91357421875 1004.419921875
53 idle 2.575 -2116.537353515625 881.9135131835938 1004.4198608398438
54 idle 2.625 -2151.50244140625 881.9135131835938 1004.4197998046875
55 idle 2.675 -2169.00244140625 881.9135131835938 1004.4197387695312
56 idle 2.726 -2174.8125 881.9135131835938 1004.4197387695312
57 idle 2.776 -2174.8125 881.9135131835938 1004.4197387695312
58 idle 2.826 -2174.8125 881.9135131835938 1004.4197387695312
59 idle 2.876 -2238.932373046875 881.9134521484375 1004.4196166992188
60 idle 2.927 -2279.742431640625 881.9134521484375 1004.4194946289062
61 idle 2.977 -2291.3974609375 881.9134521484375 1004.4194946289062
62 idle 3.027 -2320.517333984375 881.9133911132812 1004.41943359375
63 idle 3.077 -2326.327392578125 881.9133911132812 1004.41943359375
64 idle 3.128 -2326.327392578125 881.9133911132812 1004.41943359375
65 idle 3.18 -2326.327392578125 881.9133911132812 1004.41943359375
66 idle 3.23 -2390.482421875 881.9133911132812 1004.4193115234375
67 idle 3.28 -2419.602294921875 881.9133911132812 1004.4192504882812
68 idle 3.361 -2454.5673828125 881.913330078125 1004.419189453125
69 idle 3.411 -2489.532470703125 881.913330078125 1004.4191284179688
70 idle 3.464 -2501.15234375 881.913330078125 1004.4190673828125
71 idle 3.514 -2501.15234375 881.913330078125 1004.4190673828125
72 idle 3.564 -2501.15234375 881.913330078125 1004.4190673828125
73 idle 3.615 -2547.7724609375 881.9132690429688 1004.4190063476562
74 idle 3.665 -2559.427490234375 881.9132690429688 1004.4189453125
75 idle 3.715 -2600.2373046875 881.9132690429688 1004.4188842773438
76 idle 3.765 -2629.392333984375 881.9132690429688 1004.4188232421875
77 idle 3.815 -2658.512451171875 881.9132080078125 1004.4187622070312
78 idle 3.865 -2664.322265625 881.9132080078125 1004.4187622070312
79 idle 3.916 -2664.322265625 881.9132080078125 1004.4187622070312
80 idle 3.968 -2664.322265625 881.9132080078125 1004.4187622070312
81 idle 4.019 -2728.4423828125 881.9132080078125 1004.4186401367188
82 idle 4.069 -2740.097412109375 881.9132080078125 1004.4185791015625
83 idle 4.119 -2792.562255859375 881.9131469726562 1004.41845703125
84 idle 4.169 -2804.21728515625 881.9131469726562 1004.41845703125
85 idle 4.221 -2815.83740234375 881.9131469726562 1004.41845703125
86 idle 4.271 -2815.83740234375 881.9131469726562 1004.41845703125
87 idle 4.324 -2815.83740234375 881.9131469726562 1004.41845703125
88 idle 4.374 -2874.147216796875 881.9131469726562 1004.4183349609375
89 idle 4.424 -2903.267333984375 881.9130859375 1004.4182739257812
90 idle 4.475 -2938.232421875 881.9130859375 1004.418212890625
91 idle 4.525 -2973.197265625 881.9130859375 1004.4180908203125
92 idle 4.575 -2996.50732421875 881.9130249023438 1004.4180908203125
93 idle 4.627 -3008.162353515625 881.9130249023438 1004.4180297851562
94 idle 4.677 -3008.162353515625 881.9130249023438 1004.4180297851562
95 idle 4.727 -3008.162353515625 881.9130249023438 1004.4180297851562
96 idle 4.778 -3072.2822265625 881.9130249023438 1004.4179077148438
97 idle 4.863 -3113.09228515625 881.9129638671875 1004.4178466796875
98 idle 4.913 -3148.057373046875 881.9129638671875 1004.4177856445312
99 idle 4.963 -3165.522216796875 881.9129638671875 1004.417724609375
100 idle 5.013 -3165.522216796875 881.9129638671875 1004.417724609375
101 idle 5.064 -3165.522216796875 881.9129638671875 1004.417724609375
102 idle 5.114 -3223.832275390625 881.9129028320312 1004.4176025390625
103 idle 5.164 -3241.29736328125 881.9129028320312 1004.4176025390625
104 idle 5.214 -3276.26220703125 881.9129028320312 1004.41748046875
105 idle 5.266 -3299.572265625 881.9129028320312 1004.41748046875
106 idle 5.316 -3334.537353515625 881.912841796875 1004.4173583984375
107 idle 5.367 -3340.34716796875 881.912841796875 1004.4173583984375
108 idle 5.417 -3340.34716796875 881.912841796875 1004.4173583984375
109 idle 5.467 -3340.34716796875 881.912841796875 1004.4173583984375
110 idle 5.519 -3416.122314453125 881.912841796875 1004.417236328125
111 idle 5.569 -3427.77734375 881.912841796875 1004.4171752929688
112 idle 5.619 -3462.7421875 881.9127807617188 1004.4171142578125
113 idle 5.669 -3491.897216796875 881.9127807617188 1004.4170532226562
114 idle 5.719 -3521.017333984375 881.9127807617188 1004.4169921875
115 idle 5.769 -3521.017333984375 881.9127807617188 1004.4169921875
116 idle 5.819 -3521.017333984375 881.9127807617188 1004.4169921875
117 idle 5.87 -3521.017333984375 881.9127807617188 1004.4169921875
118 idle 5.92 -3585.13720703125 881.9127197265625 1004.4168701171875
119 idle 5.97 -3608.447265625 881.9127197265625 1004.4168090820312
120 idle 6.02 -3643.412109375 881.9127197265625 1004.416748046875
121 idle 6.07 -3655.067138671875 881.9127197265625 1004.416748046875
122 idle 6.12 -3672.567138671875 881.9126586914062 1004.4166870117188
123 idle 6.173 -3672.567138671875 881.9126586914062 1004.4166870117188
124 idle 6.223 -3672.567138671875 881.9126586914062 1004.4166870117188
125 idle 6.273 -3736.687255859375 881.9126586914062 1004.4165649414062
126 idle 6.323 -3771.652099609375 881.9126586914062 1004.41650390625
127 idle 6.374 -3783.30712890625 881.9126586914062 1004.41650390625
128 idle 6.424 -3829.92724609375 881.91259765625 1004.4163818359375
129 idle 6.474 -3835.7373046875 881.91259765625 1004.4163818359375
130 idle 6.531 -3835.7373046875 881.91259765625 1004.4163818359375
131 idle 6.581 -3835.7373046875 881.91259765625 1004.4163818359375
132 idle 6.633 -3894.047119140625 881.91259765625 1004.416259765625
133 idle 6.683 -3905.7021484375 881.9125366210938 1004.416259765625
134 idle 6.761 -3952.322265625 881.9125366210938 1004.4161376953125
135 idle 6.811 -3981.442138671875 881.9125366210938 1004.4160766601562
136 idle 6.863 -3987.252197265625 881.9125366210938 1004.4160766601562
137 idle 6.913 -3987.252197265625 881.9125366210938 1004.4160766601562
138 idle 6.963 -3987.252197265625 881.9125366210938 1004.4160766601562
139 idle 7.013 -4039.71728515625 881.9124755859375 1004.4159545898438
140 idle 7.064 -4063.027099609375 881.9124755859375 1004.4158935546875
141 idle 7.114 -4097.9921875 881.9124755859375 1004.4158325195312
142 idle 7.164 -4109.64697265625 881.9124755859375 1004.4158325195312
143 idle 7.214 -4150.42236328125 881.9124145507812 1004.415771484375
144 idle 7.264 -4156.23193359375 881.9124145507812 1004.4157104492188
145 idle 7.315 -4156.23193359375 881.9124145507812 1004.4157104492188
146 idle 7.365 -4156.23193359375 881.9124145507812 1004.4157104492188
147 idle 7.415 -4220.35205078125 881.9124145507812 1004.4155883789062
148 idle 7.466 -4243.662109375 881.912353515625 1004.41552734375
149 idle 7.516 -4278.626953125 881.912353515625 1004.4154663085938
150 idle 7.566 -4307.7822265625 881.912353515625 1004.4154052734375
151 idle 7.616 -4336.90234375 881.912353515625 1004.4153442382812
152 idle 7.667 -4336.90234375 881.912353515625 1004.4153442382812
153 idle 7.717 -4336.90234375 881.912353515625 1004.4153442382812
154 idle 7.767 -4336.90234375 881.912353515625 1004.4153442382812
155 idle 7.82 -4401.02197265625 881.9122924804688 1004.4152221679688
156 idle 7.87 -4424.33203125 881.9122924804688 1004.4152221679688
157 idle 7.92 -4470.9521484375 881.9122314453125 1004.4151000976562
158 idle 7.97 -4482.60693359375 881.9122314453125 1004.4151000976562
159 RT 0.0 -4511.76220703125 881.9122314453125 1004.4150390625
160 RT 0.05 -4511.76220703125 881.9122314453125 1004.4150390625
161 RT 0.1 -4511.76220703125 881.9122314453125 1004.4150390625
162 RT 0.151 -4591.10205078125 881.9121704101562 1004.4148559570312
163 RT 0.203 -4631.14013671875 881.9121704101562 1004.414794921875
164 RT 0.253 -4688.6787109375 881.9121704101562 1004.4146728515625
165 RT 0.303 -4745.97314453125 881.912109375 1004.41455078125
166 RT 0.353 -4758.11572265625 881.912109375 1004.4144897460938
167 RT 0.404 -4758.11572265625 881.912109375 1004.4144897460938
168 RT 0.454 -4758.11572265625 881.912109375 1004.4144897460938
169 RT 0.504 -4894.6865234375 881.9120483398438 1004.4142456054688
170 RT 0.554 -4976.0556640625 881.9119873046875 1004.4140625
171 RT 0.605 -5047.275390625 881.9119262695312 1004.4139404296875
172 RT 0.655 -5163.5263671875 881.911865234375 1004.4136962890625
173 RT 0.705 -5203.26416015625 881.911865234375 1004.4136352539062
174 RT 0.756 -5223.07373046875 881.911865234375 1004.41357421875
175 RT 0.806 -5223.07373046875 881.911865234375 1004.41357421875
176 RT 0.857 -5223.07373046875 881.911865234375 1004.41357421875
177 RT 0.908 -5421.8828125 881.9117431640625 1004.4132080078125
178 RT 0.989 -5541.0966796875 881.9116821289062 1004.4129638671875
179 RT 1.039 -5700.048828125 881.91162109375 1004.41259765625
180 RT 1.09 -5739.78662109375 881.9115600585938 1004.4125366210938
181 RT 1.14 -5779.52490234375 881.9115600585938 1004.4124755859375
182 RT 1.19 -5779.52490234375 881.9115600585938 1004.4124755859375
183 RT 1.24 -5779.52490234375 881.9115600585938 1004.4124755859375
184 RT 1.29 -5978.333984375 881.9114379882812 1004.4120483398438
185 RT 1.341 -6097.54833984375 881.911376953125 1004.4118041992188
186 RT 1.391 -6177.02392578125 881.9113159179688 1004.4116821289062
187 RT 1.441 -6316.1669921875 881.9112548828125 1004.411376953125
188 RT 1.491 -6355.90478515625 881.9112548828125 1004.4113159179688
189 RT 1.541 -6455.3095703125 881.9111938476562 1004.4110717773438
190 RT 1.591 -6455.3095703125 881.9111938476562 1004.4110717773438
191 RT 1.641 -6455.3095703125 881.9111938476562 1004.4110717773438
192 RT 1.691 -6455.3095703125 881.9111938476562 1004.4110717773438
193 RT 1.742 -6713.666015625 881.9110717773438 1004.4105834960938
194 RT 1.792 -6793.14208984375 881.9110107421875 1004.410400390625
195 RT 1.842 -6912.35595703125 881.9109497070312 1004.41015625
196 RT 1.892 -6952.09423828125 881.9109497070312 1004.4100952148438
197 RT 1.942 -7011.6416015625 881.910888671875 1004.4099731445312
198 RT 1.992 -7011.6416015625 881.910888671875 1004.4099731445312
199 RT 2.042 -7011.6416015625 881.910888671875 1004.4099731445312
200 RT 2.092 -7011.6416015625 881.910888671875 1004.4099731445312
201 RT 2.144 -7269.998046875 881.9107666015625 1004.409423828125
202 RT 2.194 -7369.40283203125 881.9107055664062 1004.4092407226562
203 RT 2.244 -7488.61669921875 881.91064453125 1004.4089965820312
204 RT 2.294 -7528.3544921875 881.91064453125 1004.408935546875
205 RT 2.347 -7587.90185546875 881.9105834960938 1004.4088134765625
206 RT 2.397 -7587.90185546875 881.9105834960938 1004.4088134765625
207 RT 2.448 -7587.90185546875 881.9105834960938 1004.4088134765625
208 RT 2.498 -7587.90185546875 881.9105834960938 1004.4088134765625
209 RT 2.549 -7826.44921875 881.9104614257812 1004.4083251953125
210 RT 2.599 -7965.591796875 881.910400390625 1004.4080200195312
211 RT 2.65 -8084.80615234375 881.9103393554688 1004.4077758789062
212 RT 2.7 -8124.5439453125 881.9102783203125 1004.40771484375
213 RT 2.751 -8164.16259765625 881.9102783203125 1004.4076538085938
214 RT 2.801 -8164.16259765625 881.9102783203125 1004.4076538085938
215 RT 2.852 -8164.16259765625 881.9102783203125 1004.4076538085938
216 RT 2.902 -8164.16259765625 881.9102783203125 1004.4076538085938
217 RT 2.952 -8422.638671875 881.91015625 1004.4071044921875
218 RT 3.004 -8502.1142578125 881.9100952148438 1004.4069213867188
219 RT 3.054 -8621.3291015625 881.9100341796875 1004.4066772460938
220 RT 3.104 -8661.06640625 881.9100341796875 1004.4066162109375
221 RT 3.155 -8740.4228515625 881.9099731445312 1004.4064331054688
222 RT 3.205 -8740.4228515625 881.9099731445312 1004.4064331054688
223 RT 3.29 -8740.4228515625 881.9099731445312 1004.4064331054688
224 RT 3.34 -8939.232421875 881.9098510742188 1004.4060668945312
225 RT 3.39 -8998.7802734375 881.9098510742188 1004.4059448242188
226 RT 3.44 -9137.9228515625 881.9097290039062 1004.4056396484375
227 RT 3.49 -9177.66015625 881.9097290039062 1004.4055786132812
228 RT 3.54 -9276.9462890625 881.90966796875 1004.4053955078125
229 RT 3.592 -9296.7548828125 881.90966796875 1004.4053344726562
230 RT 3.642 -9296.7548828125 881.90966796875 1004.4053344726562
231 RT 3.692 -9296.7548828125 881.90966796875 1004.4053344726562
232 RT 3.747 -9555.1123046875 881.9095458984375 1004.40478515625
233 RT 3.797 -9614.7783203125 881.9094848632812 1004.4046630859375
234 RT 3.847 -9733.9921875 881.909423828125 1004.4044189453125
235 RT 3.898 -9793.6591796875 881.909423828125 1004.404296875
236 RT 3.948 -9873.015625 881.9093627929688 1004.4041748046875
237 RT 3.998 -9873.015625 881.9093627929688 1004.4041748046875
238 RT 4.048 -9873.015625 881.9093627929688 1004.4041748046875
239 RT 4.098 -9873.015625 881.9093627929688 1004.4041748046875
240 RT 4.148 -10111.5634765625 881.9092407226562 1004.4036865234375
241 RT 4.198 -10151.30078125 881.9092407226562 1004.4036254882812
242 RT 4.249 -10310.2529296875 881.9091186523438 1004.4032592773438
243 RT 4.3 -10349.9912109375 881.9091186523438 1004.4031982421875
244 RT 4.35 -10469.205078125 881.9090576171875 1004.4029541015625
245 RT 4.4 -10469.205078125 881.9090576171875 1004.4029541015625
246 RT 4.451 -10469.205078125 881.9090576171875 1004.4029541015625
247 RT 4.501 -10469.205078125 881.9090576171875 1004.4029541015625
248 RT 4.551 -10727.5615234375 881.9088745117188 1004.4024047851562
249 RT 4.601 -10727.5615234375 881.9088745117188 1004.4024047851562
250 RT 4.651 -10906.4423828125 881.9088134765625 1004.4020385742188
251 RT 4.704 -11005.8466796875 881.9087524414062 1004.40185546875
252 RT 4.754 -11065.39453125 881.9087524414062 1004.4017333984375
253 RT 4.804 -11065.39453125 881.9087524414062 1004.4017333984375
254 RT 4.855 -11065.39453125 881.9087524414062 1004.4017333984375
255 RT 4.905 -11065.39453125 881.9087524414062 1004.4017333984375
256 RT 4.957 -11323.7509765625 881.9085693359375 1004.4012451171875
257 RT 5.007 -11423.15625 881.9085083007812 1004.4010009765625
258 RT 5.058 -11542.3701171875 881.908447265625 1004.4007568359375
259 RT 5.108 -11621.845703125 881.908447265625 1004.400634765625
260 RT 5.158 -11681.3935546875 881.9083862304688 1004.4005126953125
261 RT 5.208 -11681.3935546875 881.9083862304688 1004.4005126953125
262 RT 5.259 -11681.3935546875 881.9083862304688 1004.4005126953125
263 RT 5.309 -11681.3935546875 881.9083862304688 1004.4005126953125
264 RT 5.36 -11939.75 881.9082641601562 1004.3999633789062
265 RT 5.41 -12058.9638671875 881.908203125 1004.3997192382812
266 RT 5.489 -12178.177734375 881.9081420898438 1004.3994750976562
267 RT 5.539 -12297.3916015625 881.9080810546875 1004.3992309570312
268 RT 5.59 -12297.3916015625 881.9080810546875 1004.3992309570312
269 RT 5.64 -12297.3916015625 881.9080810546875 1004.3992309570312
270 RT 5.69 -12297.3916015625 881.9080810546875 1004.3992309570312
271 RT 5.743 -12555.748046875 881.9078979492188 1004.3987426757812
272 RT 5.793 -12595.486328125 881.9078979492188 1004.398681640625
273 RT 5.844 -12714.7001953125 881.9078369140625 1004.3984375
274 RT 5.894 -12814.10546875 881.9077758789062 1004.398193359375
275 RT 5.944 -12913.390625 881.90771484375 1004.3980102539062
276 RT 5.994 -12913.390625 881.90771484375 1004.3980102539062
277 RT 6.044 -12913.390625 881.90771484375 1004.3980102539062
278 RT 6.094 -12913.390625 881.90771484375 1004.3980102539062
279 RT 6.144 -13132.0087890625 881.9075927734375 1004.3975830078125
280 RT 6.195 -13171.7470703125 881.9075927734375 1004.3975219726562
281 RT 6.246 -13350.6279296875 881.907470703125 1004.3971557617188
282 RT 6.296 -13390.365234375 881.907470703125 1004.3970336914062
283 RT 6.347 -13489.6513671875 881.9074096679688 1004.3968505859375
284 RT 6.397 -13489.6513671875 881.9074096679688 1004.3968505859375
285 RT 6.447 -13489.6513671875 881.9074096679688 1004.3968505859375
286 RT 6.497 -13489.6513671875 881.9074096679688 1004.3968505859375
287 RT 6.548 -13728.1982421875 881.9072875976562 1004.3963623046875
288 RT 6.598 -13807.673828125 881.9072265625 1004.3961791992188
289 RT 6.649 -13966.6259765625 881.9071655273438 1004.3958740234375
290 RT 6.701 -14066.03125 881.9071044921875 1004.3956909179688
291 RT 6.752 -14125.578125 881.9071044921875 1004.3955688476562
292 RT 6.802 -14125.578125 881.9071044921875 1004.3955688476562
293 RT 6.852 -14125.578125 881.9071044921875 1004.3955688476562
294 RT 6.902 -14125.578125 881.9071044921875 1004.3955688476562
295 RT 6.952 -14383.9345703125 881.9069213867188 1004.39501953125
296 RT 7.002 -14443.6015625 881.9069213867188 1004.3948974609375
297 RT 7.052 -14562.8154296875 881.9068603515625 1004.3946533203125
298 RT 7.102 -14602.5537109375 881.9067993164062 1004.3945922851562
299 RT 7.152 -14721.767578125 881.90673828125 1004.3943481445312
300 RT 7.202 -14721.767578125 881.90673828125 1004.3943481445312
301 RT 7.252 -14721.767578125 881.90673828125 1004.3943481445312
302 RT 7.302 -14721.767578125 881.90673828125 1004.3943481445312
303 RT 7.354 -14960.314453125 881.9066162109375 1004.3938598632812
304 RT 7.404 -15059.7197265625 881.9065551757812 1004.3936767578125
305 RT 7.455 -15178.93359375 881.906494140625 1004.3934326171875
306 RT 7.505 -15278.337890625 881.9064331054688 1004.3932495117188
307 RT 7.555 -15337.8857421875 881.9064331054688 1004.3931274414062
308 RT 7.605 -15337.8857421875 881.9064331054688 1004.3931274414062
309 RT 7.656 -15337.8857421875 881.9064331054688 1004.3931274414062
310 RT 7.706 -15496.95703125 881.9063720703125 1004.3927612304688
311 RT 7.756 -15596.2421875 881.9063110351562 1004.392578125
312 RT 7.806 -15655.9091796875 881.90625 1004.3924560546875
313 RT 7.857 -15775.123046875 881.9061889648438 1004.3922119140625
314 RT 7.907 -15874.52734375 881.9061279296875 1004.3920288085938
315 RT 7.957 -15894.3369140625 881.9061279296875 1004.3919677734375
316 coast 0.0 -15894.3369140625 881.9061279296875 1004.3919677734375
317 coast 0.05 -15894.3369140625 881.9061279296875 1004.3919677734375
318 coast 0.1 -16132.259765625 881.906005859375 1004.3914794921875
319 coast 0.15 -16228.6279296875 881.9059448242188 1004.3912963867188
320 coast 0.201 -16341.4130859375 881.9058837890625 1004.3910522460938
321 coast 0.251 -16414.818359375 881.9058837890625 1004.3909301757812
322 coast 0.302 -16432.935546875 881.9058227539062 1004.390869140625
323 coast 0.352 -16432.935546875 881.9058227539062 1004.390869140625
324 coast 0.402 -16432.935546875 881.9058227539062 1004.390869140625
325 coast 0.453 -16589.41015625 881.90576171875 1004.3905639648438
326 coast 0.503 -16674.68359375 881.9057006835938 1004.390380859375
327 coast 0.553 -16741.302734375 881.9057006835938 1004.3902587890625
328 coast 0.603 -16838.55078125 881.9056396484375 1004.3900756835938
329 coast 0.653 -16870.25390625 881.9056396484375 1004.3900146484375
330 coast 0.705 -16885.966796875 881.9055786132812 1004.3899536132812
331 coast 0.755 -16885.966796875 881.9055786132812 1004.3899536132812
332 coast 0.805 -16885.966796875 881.9055786132812 1004.3899536132812
333 coast 0.855 -17035.544921875 881.905517578125 1004.3896484375
334 coast 0.906 -17122.61328125 881.9054565429688 1004.3894653320312
335 coast 0.956 -17150.923828125 881.9054565429688 1004.389404296875
336 coast 1.006 -17233.70703125 881.9053955078125 1004.3892822265625
337 coast 1.056 -17260.5859375 881.9053955078125 1004.3892211914062
338 coast 1.107 -17287.109375 881.9053955078125 1004.38916015625
339 coast 1.157 -17287.109375 881.9053955078125 1004.38916015625
340 coast 1.207 -17387.55859375 881.9053344726562 1004.3889770507812
341 coast 1.259 -17424.537109375 881.9053344726562 1004.3888549804688
342 coast 1.309 -17496.0703125 881.9052734375 1004.3887329101562
343 coast 1.359 -17541.97265625 881.9052734375 1004.3886108398438
344 coast 1.409 -17586.4453125 881.9052124023438 1004.3885498046875
345 coast 1.459 -17629.4921875 881.9052124023438 1004.3884887695312
346 coast 1.509 -17629.4921875 881.9052124023438 1004.3884887695312
347 coast 1.559 -17629.4921875 881.9052124023438 1004.3884887695312
348 coast 1.611 -17718.390625 881.9051513671875 1004.3883056640625
349 coast 1.661 -17747.33984375 881.9051513671875 1004.3882446289062
350 coast 1.737 -17802.796875 881.9050903320312 1004.3881225585938
351 coast 1.787 -17855.041015625 881.9050903320312 1004.3880004882812
352 coast 1.837 -17871.7421875 881.9050903320312 1004.387939453125
353 coast 1.889 -17896.01171875 881.905029296875 1004.387939453125
354 coast 1.942 -17896.01171875 881.905029296875 1004.387939453125
355 coast 1.992 -17896.01171875 881.905029296875 1004.387939453125
356 coast 2.042 -17976.451171875 881.905029296875 1004.3877563476562
357 coast 2.098 -18003.77734375 881.905029296875 1004.3876953125
358 coast 2.148 -18016.90625 881.9049682617188 1004.3876953125
359 coast 2.198 -18071.580078125 881.9049682617188 1004.3875732421875
360 coast 2.248 -18077.390625 881.9049682617188 1004.3875732421875
361 coast 2.302 -18077.390625 881.9049682617188 1004.3875732421875
362 coast 2.352 -18077.390625 881.9049682617188 1004.3875732421875
363 coast 2.402 -18135.69921875 881.9049072265625 1004.387451171875
364 coast 2.452 -18147.35546875 881.9049072265625 1004.3873901367188
365 coast 2.537 -18193.974609375 881.9049072265625 1004.3873291015625
366 coast 2.587 -18228.939453125 881.9049072265625 1004.3872680664062
367 coast 2.638 -18234.75 881.9049072265625 1004.38720703125
368 coast 2.688 -18234.75 881.9049072265625 1004.38720703125
369 coast 2.738 -18234.75 881.9049072265625 1004.38720703125
370 coast 2.788 -18293.060546875 881.9048461914062 1004.3870849609375
371 coast 2.84 -18310.525390625 881.9048461914062 1004.3870849609375
372 coast 2.89 -18345.490234375 881.9048461914062 1004.3870239257812
373 coast 2.94 -18357.14453125 881.90478515625 1004.386962890625
374 coast 2.99 -18386.265625 881.90478515625 1004.3869018554688
375 coast 3.043 -18392.07421875 881.90478515625 1004.3869018554688
376 coast 3.093 -18392.07421875 881.90478515625 1004.3869018554688
377 coast 3.143 -18392.07421875 881.90478515625 1004.3869018554688
378 coast 3.193 -18467.849609375 881.9047241210938 1004.3867797851562
379 coast 3.243 -18479.505859375 881.9047241210938 1004.38671875
380 coast 3.293 -18514.470703125 881.9047241210938 1004.3866577148438
381 coast 3.343 -18537.779296875 881.9047241210938 1004.3865966796875
382 coast 3.394 -18561.0546875 881.9047241210938 1004.3865966796875
383 coast 3.445 -18561.0546875 881.9047241210938 1004.3865966796875
384 coast 3.495 -18561.0546875 881.9047241210938 1004.3865966796875
385 coast 3.546 -18561.0546875 881.9047241210938 1004.3865966796875
386 coast 3.596 -18631.01953125 881.9046630859375 1004.3864135742188
387 coast 3.646 -18654.330078125 881.9046630859375 1004.3863525390625
388 coast 3.697 -18700.94921875 881.9046020507812 1004.3862915039062
389 coast 3.747 -18712.60546875 881.9046020507812 1004.3862915039062
390 coast 3.797 -18747.5703125 881.9046020507812 1004.3861694335938
391 coast 3.847 -18747.5703125 881.9046020507812 1004.3861694335938
392 coast 3.897 -18747.5703125 881.9046020507812 1004.3861694335938
393 coast 3.947 -18747.5703125 881.9046020507812 1004.3861694335938
394 coast 3.998 -18823.345703125 881.904541015625 1004.3860473632812
395 coast 4.048 -18846.654296875 881.904541015625 1004.385986328125
396 coast 4.098 -18881.619140625 881.904541015625 1004.3859252929688
397 coast 4.148 -18904.9296875 881.904541015625 1004.3858642578125
398 coast 4.199 -18910.740234375 881.904541015625 1004.3858642578125
399 coast 4.249 -18910.740234375 881.904541015625 1004.3858642578125
400 coast 4.299 -18910.740234375 881.904541015625 1004.3858642578125
401 coast 4.349 -18910.740234375 881.904541015625 1004.3858642578125
402 coast 4.399 -18980.705078125 881.9044799804688 1004.3857421875
403 coast 4.449 -19021.515625 881.9044799804688 1004.3856201171875
404 coast 4.499 -19056.48046875 881.9044189453125 1004.3855590820312
405 coast 4.549 -19068.134765625 881.9044189453125 1004.3855590820312
406 coast 4.6 -19073.9453125 881.9044189453125 1004.385498046875
407 coast 4.65 -19073.9453125 881.9044189453125 1004.385498046875
408 coast 4.7 -19073.9453125 881.9044189453125 1004.385498046875
409 coast 4.751 -19138.099609375 881.9044189453125 1004.3853759765625
410 coast 4.801 -19155.564453125 881.9043579101562 1004.3853759765625
411 coast 4.851 -19190.529296875 881.9043579101562 1004.3853149414062
412 coast 4.902 -19225.494140625 881.9043579101562 1004.3851928710938
413 coast 4.952 -19237.150390625 881.9043579101562 1004.3851928710938
414 coast 5.005 -19242.958984375 881.9043579101562 1004.3851928710938
415 coast 5.055 -19242.958984375 881.9043579101562 1004.3851928710938
416 coast 5.109 -19242.958984375 881.9043579101562 1004.3851928710938
417 coast 5.159 -19312.92578125 881.904296875 1004.3850708007812
418 coast 5.209 -19347.890625 881.904296875 1004.3849487304688
419 coast 5.259 -19377.044921875 881.9042358398438 1004.3848876953125
420 coast 5.31 -19412.009765625 881.9042358398438 1004.3848266601562
421 coast 5.36 -19423.6640625 881.9042358398438 1004.3848266601562
422 coast 5.411 -19423.6640625 881.9042358398438 1004.3848266601562
423 coast 5.461 -19423.6640625 881.9042358398438 1004.3848266601562
424 coast 5.537 -19481.974609375 881.9042358398438 1004.3847045898438
425 coast 5.587 -19522.78515625 881.9041748046875 1004.3846435546875
426 coast 5.637 -19534.439453125 881.9041748046875 1004.3845825195312
427 coast 5.687 -19569.404296875 881.9041748046875 1004.384521484375
428 coast 5.737 -19586.869140625 881.9041748046875 1004.3844604492188
429 coast 5.787 -19586.869140625 881.9041748046875 1004.3844604492188
430 coast 5.839 -19586.869140625 881.9041748046875 1004.3844604492188
431 coast 5.889 -19586.869140625 881.9041748046875 1004.3844604492188
432 coast 5.939 -19650.990234375 881.9041137695312 1004.3843383789062
433 coast 5.989 -19685.955078125 881.9041137695312 1004.38427734375
434 coast 6.039 -19697.609375 881.9041137695312 1004.38427734375
435 coast 6.09 -19744.23046875 881.904052734375 1004.3841552734375
436 coast 6.14 -19755.849609375 881.904052734375 1004.3841552734375
437 coast 6.192 -19755.849609375 881.904052734375 1004.3841552734375
438 coast 6.242 -19755.849609375 881.904052734375 1004.3841552734375
439 coast 6.292 -19814.16015625 881.904052734375 1004.384033203125
440 coast 6.343 -19831.625 881.9039916992188 1004.3839721679688
441 coast 6.393 -19878.244140625 881.9039916992188 1004.3839111328125
442 coast 6.443 -19889.900390625 881.9039916992188 1004.3838500976562
443 coast 6.494 -19913.173828125 881.9039916992188 1004.3838500976562
444 coast 6.544 -19913.173828125 881.9039916992188 1004.3838500976562
445 coast 6.594 -19913.173828125 881.9039916992188 1004.3838500976562
446 coast 6.644 -19913.173828125 881.9039916992188 1004.3838500976562
447 coast 6.694 -19988.94921875 881.9039306640625 1004.3836669921875
448 coast 6.744 -20006.44921875 881.9039306640625 1004.3836059570312
449 coast 6.795 -20041.4140625 881.9039306640625 1004.383544921875
450 coast 6.846 -20070.5703125 881.9038696289062 1004.3834838867188
451 coast 6.896 -20088.03515625 881.9038696289062 1004.3834838867188
452 coast 6.946 -20088.03515625 881.9038696289062 1004.3834838867188
453 coast 6.996 -20088.03515625 881.9038696289062 1004.3834838867188
454 coast 7.046 -20088.03515625 881.9038696289062 1004.3834838867188
455 coast 7.097 -20152.154296875 881.9038696289062 1004.3833618164062
456 coast 7.147 -20192.96484375 881.90380859375 1004.3832397460938
457 coast 7.197 -20227.9296875 881.90380859375 1004.3831787109375
458 coast 7.247 -20245.4296875 881.90380859375 1004.3831787109375
459 coast 7.298 -20257.083984375 881.90380859375 1004.3831176757812
460 coast 7.348 -20257.083984375 881.90380859375 1004.3831176757812
461 coast 7.399 -20257.083984375 881.90380859375 1004.3831176757812
462 coast 7.449 -20315.39453125 881.9037475585938 1004.3829956054688
463 coast 7.499 -20344.515625 881.9037475585938 1004.3829345703125
464 coast 7.55 -20367.82421875 881.9037475585938 1004.3828735351562
465 coast 7.6 -20414.4453125 881.9036865234375 1004.3828125
466 coast 7.65 -20426.099609375 881.9036865234375 1004.3828125
467 coast 7.702 -20437.75390625 881.9036865234375 1004.3827514648438
468 coast 7.752 -20437.75390625 881.9036865234375 1004.3827514648438
469 coast 7.802 -20437.75390625 881.9036865234375 1004.3827514648438
470 coast 7.852 -20507.71875 881.9036865234375 1004.3826293945312
471 coast 7.902 -20542.685546875 881.9036254882812 1004.382568359375
472 coast 7.952 -20554.33984375 881.9036254882812 1004.3825073242188
473 LT 0.0 -20600.958984375 881.9036254882812 1004.3824462890625
474 LT 0.05 -20600.958984375 881.9036254882812 1004.3824462890625
475 LT 0.104 -20600.958984375 881.9036254882812 1004.3824462890625
476 LT 0.175 -20641.892578125 881.903564453125 1004.38232421875
477 LT 0.225 -20670.3359375 881.903564453125 1004.3822631835938
478 LT 0.275 -20679.1328125 881.903564453125 1004.3822631835938
479 LT 0.325 -20703.380859375 881.903564453125 1004.3822021484375
480 LT 0.376 -20714.333984375 881.903564453125 1004.3822021484375
481 LT 0.426 -20714.333984375 881.903564453125 1004.3822021484375
482 LT 0.479 -20714.333984375 881.903564453125 1004.3822021484375
483 LT 0.529 -20714.333984375 881.903564453125 1004.3822021484375
484 LT 0.579 -20745.40234375 881.9035034179688 1004.3821411132812
485 LT 0.629 -20758.935546875 881.9035034179688 1004.3821411132812
486 LT 0.679 -20762.732421875 881.9035034179688 1004.382080078125
487 LT 0.729 -20772.962890625 881.9035034179688 1004.382080078125
488 LT 0.779 -20778.05078125 881.9035034179688 1004.382080078125
489 LT 0.829 -20778.05078125 881.9035034179688 1004.382080078125
490 LT 0.88 -20778.05078125 881.9035034179688 1004.382080078125
491 LT 0.93 -20795.037109375 881.9035034179688 1004.3820190429688
492 LT 0.981 -20800.125 881.9035034179688 1004.3820190429688
493 LT 1.031 -20808.619140625 881.9035034179688 1004.3820190429688
494 LT 1.081 -20817.11328125 881.9035034179688 1004.3820190429688
495 LT 1.131 -20827.298828125 881.9035034179688 1004.3819580078125
496 LT 1.183 -20828.990234375 881.9035034179688 1004.3819580078125
497 LT 1.233 -20828.990234375 881.9035034179688 1004.3819580078125
498 LT 1.283 -20828.990234375 881.9035034179688 1004.3819580078125
499 LT 1.335 -20847.669921875 881.9035034179688 1004.3819580078125
500 LT 1.386 -20854.4609375 881.9034423828125 1004.3818969726562
501 LT 1.436 -20864.646484375 881.9034423828125 1004.3818969726562
502 LT 1.486 -20868.041015625 881.9034423828125 1004.3818969726562
503 LT 1.536 -20874.822265625 881.9034423828125 1004.3818969726562
504 LT 1.586 -20874.822265625 881.9034423828125 1004.3818969726562
505 LT 1.636 -20874.822265625 881.9034423828125 1004.3818969726562
506 LT 1.686 -20874.822265625 881.9034423828125 1004.3818969726562
507 LT 1.737 -20895.203125 881.9034423828125 1004.3818359375
508 LT 1.787 -20903.697265625 881.9034423828125 1004.3818359375
509 LT 1.837 -20913.8828125 881.9034423828125 1004.3817749023438
510 LT 1.887 -20917.279296875 881.9034423828125 1004.3817749023438
511 LT 1.937 -20924.068359375 881.9034423828125 1004.3817749023438
512 LT 1.987 -20924.068359375 881.9034423828125 1004.3817749023438
513 LT 2.037 -20924.068359375 881.9034423828125 1004.3817749023438
514 LT 2.088 -20924.068359375 881.9034423828125 1004.3817749023438
515 LT 2.139 -20946.14453125 881.9034423828125 1004.3817138671875
516 LT 2.189 -20956.330078125 881.9034423828125 1004.3817138671875
517 LT 2.239 -20966.515625 881.9034423828125 1004.3817138671875
518 LT 2.289 -20969.91015625 881.9033813476562 1004.3817138671875
519 LT 2.34 -20971.603515625 881.9033813476562 1004.3816528320312
520 LT 2.39 -20971.603515625 881.9033813476562 1004.3816528320312
521 LT 2.44 -20971.603515625 881.9033813476562 1004.3816528320312
522 LT 2.492 -20991.974609375 881.9033813476562 1004.3816528320312
523 LT 2.542 -21002.16015625 881.9033813476562 1004.381591796875
524 LT 2.592 -21005.556640625 881.9033813476562 1004.381591796875
525 LT 2.642 -21015.7421875 881.9033813476562 1004.381591796875
526 LT 2.693 -21017.435546875 881.9033813476562 1004.381591796875
527 LT 2.775 -21017.435546875 881.9033813476562 1004.381591796875
528 LT 2.825 -21017.435546875 881.9033813476562 1004.381591796875
529 LT 2.878 -21037.81640625 881.9033813476562 1004.3815307617188
530 LT 2.928 -21048.001953125 881.9033813476562 1004.3815307617188
531 LT 2.978 -21051.3984375 881.9033813476562 1004.3815307617188
532 LT 3.029 -21061.583984375 881.9033813476562 1004.3814697265625
533 LT 3.079 -21063.275390625 881.9033813476562 1004.3814697265625
534 LT 3.129 -21063.275390625 881.9033813476562 1004.3814697265625
535 LT 3.179 -21063.275390625 881.9033813476562 1004.3814697265625
536 LT 3.229 -21081.955078125 881.9033203125 1004.3814697265625
537 LT 3.279 -21090.44921875 881.9033203125 1004.3814697265625
538 LT 3.329 -21097.240234375 881.9033203125 1004.3814086914062
539 LT 3.379 -21100.634765625 881.9033203125 1004.3814086914062
540 LT 3.429 -21110.8203125 881.9033203125 1004.3814086914062
541 LT 3.48 -21110.8203125 881.9033203125 1004.3814086914062
542 LT 3.53 -21110.8203125 881.9033203125 1004.3814086914062
543 LT 3.58 -21110.8203125 881.9033203125 1004.3814086914062
544 LT 3.631 -21132.89453125 881.9033203125 1004.38134765625
545 LT 3.681 -21143.080078125 881.9033203125 1004.38134765625
546 LT 3.731 -21153.267578125 881.9033203125 1004.3812866210938
547 LT 3.781 -21160.056640625 881.9033203125 1004.3812866210938
548 LT 3.831 -21163.453125 881.9033203125 1004.3812866210938
549 LT 3.882 -21163.453125 881.9033203125 1004.3812866210938
550 LT 3.932 -21163.453125 881.9033203125 1004.3812866210938
551 LT 3.982 -21177.033203125 881.9033203125 1004.3812866210938
552 LT 4.035 -21188.921875 881.9033203125 1004.3812255859375
553 LT 4.085 -21199.107421875 881.9032592773438 1004.3812255859375
554 LT 4.135 -21205.8984375 881.9032592773438 1004.3812255859375
555 LT 4.187 -21207.591796875 881.9032592773438 1004.3812255859375
556 LT 4.237 -21207.591796875 881.9032592773438 1004.3812255859375
557 LT 4.287 -21207.591796875 881.9032592773438 1004.3812255859375
558 LT 4.337 -21222.875 881.9032592773438 1004.3811645507812
559 LT 4.387 -21229.666015625 881.9032592773438 1004.3811645507812
560 LT 4.437 -21239.8515625 881.9032592773438 1004.3811645507812
561 LT 4.487 -21244.94921875 881.9032592773438 1004.381103515625
562 LT 4.537 -21251.73046875 881.9032592773438 1004.381103515625
563 LT 4.587 -21251.73046875 881.9032592773438 1004.381103515625
564 LT 4.638 -21251.73046875 881.9032592773438 1004.381103515625
565 LT 4.688 -21251.73046875 881.9032592773438 1004.381103515625
566 LT 4.741 -21272.111328125 881.9032592773438 1004.381103515625
567 LT 4.791 -21284.0 881.9032592773438 1004.3810424804688
568 LT 4.841 -21290.791015625 881.9032592773438 1004.3810424804688
569 LT 4.891 -21297.58203125 881.9032592773438 1004.3810424804688
570 LT 4.942 -21299.275390625 881.9032592773438 1004.3810424804688
571 LT 4.992 -21299.275390625 881.9032592773438 1004.3810424804688
572 LT 5.042 -21299.275390625 881.9032592773438 1004.3810424804688
573 LT 5.092 -21316.26171875 881.9031982421875 1004.3809814453125
574 LT 5.142 -21324.744140625 881.9031982421875 1004.3809814453125
575 LT 5.192 -21331.53515625 881.9031982421875 1004.3809814453125
576 LT 5.242 -21341.720703125 881.9031982421875 1004.3809204101562
577 LT 5.292 -21346.818359375 881.9031982421875 1004.3809204101562
578 LT 5.343 -21350.21484375 881.9031982421875 1004.3809204101562
579 LT 5.393 -21350.21484375 881.9031982421875 1004.3809204101562
580 LT 5.443 -21362.103515625 881.9031982421875 1004.3809204101562
581 LT 5.493 -21370.5859375 881.9031982421875 1004.380859375
582 LT 5.578 -21380.771484375 881.9031982421875 1004.380859375
583 LT 5.628 -21390.95703125 881.9031982421875 1004.380859375
584 LT 5.678 -21396.044921875 881.9031982421875 1004.3807983398438
585 LT 5.728 -21396.044921875 881.9031982421875 1004.3807983398438
586 LT 5.778 -21396.044921875 881.9031982421875 1004.3807983398438
587 LT 5.828 -21413.03125 881.9031982421875 1004.3807983398438
588 LT 5.882 -21418.119140625 881.9031982421875 1004.3807983398438
589 LT 5.932 -21430.0078125 881.9031372070312 1004.3807373046875
590 LT 5.983 -21436.798828125 881.9031372070312 1004.3807373046875
591 LT 6.033 -21443.58984375 881.9031372070312 1004.3807373046875
592 LT 6.085 -21445.283203125 881.9031372070312 1004.3807373046875
593 LT 6.135 -21445.283203125 881.9031372070312 1004.3807373046875
594 LT 6.185 -21445.283203125 881.9031372070312 1004.3807373046875
595 LT 6.235 -21463.9609375 881.9031372070312 1004.3806762695312
596 LT 6.285 -21469.060546875 881.9031372070312 1004.3806762695312
597 LT 6.335 -21479.24609375 881.9031372070312 1004.3806762695312
598 LT 6.385 -21482.640625 881.9031372070312 1004.3806762695312
599 LT 6.438 -21489.431640625 881.9031372070312 1004.380615234375
600 LT 6.488 -21489.431640625 881.9031372070312 1004.380615234375
601 LT 6.538 -21489.431640625 881.9031372070312 1004.380615234375
602 LT 6.588 -21506.41796875 881.9031372070312 1004.380615234375
603 LT 6.638 -21514.900390625 881.9031372070312 1004.3805541992188
604 LT 6.689 -21525.087890625 881.9031372070312 1004.3805541992188
605 LT 6.739 -21535.2734375 881.9031372070312 1004.3805541992188
606 LT 6.789 -21538.66796875 881.903076171875 1004.3805541992188
607 LT 6.84 -21542.064453125 881.903076171875 1004.3805541992188
608 LT 6.89 -21542.064453125 881.903076171875 1004.3805541992188
609 LT 6.94 -21542.064453125 881.903076171875 1004.3805541992188
610 LT 6.99 -21560.7421875 881.903076171875 1004.3804931640625
611 LT 7.075 -21570.927734375 881.903076171875 1004.3804931640625
612 LT 7.125 -21581.115234375 881.903076171875 1004.3804321289062
613 LT 7.175 -21586.203125 881.903076171875 1004.3804321289062
614 LT 7.225 -21586.203125 881.903076171875 1004.3804321289062
615 LT 7.275 -21586.203125 881.903076171875 1004.3804321289062
616 LT 7.325 -21603.189453125 881.903076171875 1004.3804321289062
617 LT 7.376 -21608.27734375 881.903076171875 1004.38037109375
618 LT 7.426 -21620.166015625 881.903076171875 1004.38037109375
619 LT 7.476 -21620.166015625 881.903076171875 1004.38037109375
620 LT 7.526 -21632.04296875 881.903076171875 1004.38037109375
621 LT 7.577 -21633.736328125 881.903076171875 1004.38037109375
622 LT 7.627 -21633.736328125 881.903076171875 1004.38037109375
623 LT 7.677 -21633.736328125 881.903076171875 1004.38037109375
624 LT 7.729 -21652.416015625 881.9030151367188 1004.3803100585938
625 LT 7.779 -21659.20703125 881.9030151367188 1004.3803100585938
626 LT 7.829 -21672.787109375 881.9030151367188 1004.3802490234375
627 LT 7.879 -21676.18359375 881.9030151367188 1004.3802490234375
628 LT 7.929 -21681.271484375 881.9030151367188 1004.3802490234375
629 LT 7.979 -21681.271484375 881.9030151367188 1004.3802490234375
630 coast2 0.0 -21699.958984375 881.9030151367188 1004.3801879882812
631 coast2 0.05 -21709.087890625 881.9030151367188 1004.3801879882812
632 coast2 0.1 -21722.490234375 881.9030151367188 1004.3801879882812
633 coast2 0.15 -21733.17578125 881.9030151367188 1004.380126953125
634 coast2 0.2 -21748.78125 881.9030151367188 1004.380126953125
635 coast2 0.25 -21748.78125 881.9030151367188 1004.380126953125
636 coast2 0.301 -21748.78125 881.9030151367188 1004.380126953125
637 coast2 0.351 -21780.17578125 881.9029541015625 1004.3800659179688
638 coast2 0.401 -21797.376953125 881.9029541015625 1004.3800048828125
639 coast2 0.478 -21826.087890625 881.9029541015625 1004.3799438476562
640 coast2 0.528 -21858.291015625 881.9029541015625 1004.3798828125
641 coast2 0.579 -21875.611328125 881.9029541015625 1004.3798828125
642 coast2 0.629 -21875.611328125 881.9029541015625 1004.3798828125
643 coast2 0.68 -21875.611328125 881.9029541015625 1004.3798828125
644 coast2 0.73 -21875.611328125 881.9029541015625 1004.3798828125
645 coast2 0.78 -21951.38671875 881.9028930664062 1004.3796997070312
646 coast2 0.83 -21986.3515625 881.9028930664062 1004.379638671875
647 coast2 0.881 -21998.005859375 881.90283203125 1004.3795776367188
648 coast2 0.932 -22044.626953125 881.90283203125 1004.3795166015625
649 coast2 0.982 -22062.091796875 881.90283203125 1004.3794555664062
650 coast2 1.032 -22062.091796875 881.90283203125 1004.3794555664062
651 coast2 1.082 -22062.091796875 881.90283203125 1004.3794555664062
652 coast2 1.132 -22062.091796875 881.90283203125 1004.3794555664062
653 coast2 1.183 -22143.7109375 881.9027709960938 1004.3793334960938
654 coast2 1.233 -22178.677734375 881.9027709960938 1004.3792114257812
655 coast2 1.283 -22190.33203125 881.9027709960938 1004.3792114257812
656 coast2 1.333 -22236.951171875 881.9027099609375 1004.379150390625
657 coast2 1.383 -22242.76171875 881.9027099609375 1004.3790893554688
658 coast2 1.433 -22242.76171875 881.9027099609375 1004.3790893554688
659 coast2 1.483 -22242.76171875 881.9027099609375 1004.3790893554688
660 coast2 1.533 -22289.416015625 881.9027099609375 1004.3790283203125
661 coast2 1.583 -22318.537109375 881.9027099609375 1004.3789672851562
662 coast2 1.634 -22353.501953125 881.9026489257812 1004.37890625
663 coast2 1.684 -22365.15625 881.9026489257812 1004.3788452148438
664 coast2 1.734 -22411.77734375 881.9026489257812 1004.3787841796875
665 coast2 1.784 -22417.5859375 881.9026489257812 1004.3787841796875
666 coast2 1.834 -22417.5859375 881.9026489257812 1004.3787841796875
667 coast2 1.885 -22417.5859375 881.9026489257812 1004.3787841796875
668 coast2 1.935 -22475.896484375 881.902587890625 1004.378662109375
669 coast2 1.989 -22493.361328125 881.902587890625 1004.3786010742188
670 coast2 2.042 -22539.982421875 881.902587890625 1004.3785400390625
671 coast2 2.092 -22563.291015625 881.9025268554688 1004.3784790039062
672 coast2 2.143 -22592.412109375 881.9025268554688 1004.37841796875
673 coast2 2.194 -22598.22265625 881.9025268554688 1004.37841796875
674 coast2 2.279 -22598.22265625 881.9025268554688 1004.37841796875
675 coast2 2.329 -22598.22265625 881.9025268554688 1004.37841796875
676 coast2 2.38 -22662.341796875 881.9025268554688 1004.3782348632812
677 coast2 2.43 -22708.9609375 881.9024658203125 1004.378173828125
678 coast2 2.48 -22708.9609375 881.9024658203125 1004.378173828125
679 coast2 2.531 -22743.92578125 881.9024658203125 1004.3781127929688
680 coast2 2.581 -22761.392578125 881.9024658203125 1004.3780517578125
681 coast2 2.631 -22761.392578125 881.9024658203125 1004.3780517578125
682 coast2 2.681 -22761.392578125 881.9024658203125 1004.3780517578125
683 coast2 2.731 -22761.392578125 881.9024658203125 1004.3780517578125
684 coast2 2.781 -22837.166015625 881.9024047851562 1004.3779296875
685 coast2 2.832 -22872.130859375 881.9024047851562 1004.3778686523438
686 coast2 2.882 -22883.787109375 881.9024047851562 1004.3778076171875
687 coast2 2.933 -22930.40625 881.90234375 1004.3777465820312
688 coast2 2.983 -22942.02734375 881.90234375 1004.377685546875
689 coast2 3.033 -22942.02734375 881.90234375 1004.377685546875
690 coast2 3.083 -22942.02734375 881.90234375 1004.377685546875
691 coast2 3.133 -22994.52734375 881.90234375 1004.3775634765625
692 coast2 3.183 -23011.9921875 881.90234375 1004.3775634765625
693 coast2 3.234 -23046.95703125 881.9022827148438 1004.3775024414062
694 coast2 3.284 -23058.611328125 881.9022827148438 1004.37744140625
695 coast2 3.334 -23105.232421875 881.9022827148438 1004.3773803710938
696 coast2 3.384 -23111.041015625 881.9022827148438 1004.3773803710938
697 coast2 3.435 -23111.041015625 881.9022827148438 1004.3773803710938
698 coast2 3.485 -23111.041015625 881.9022827148438 1004.3773803710938
699 coast2 3.535 -23163.541015625 881.9022216796875 1004.3772583007812
700 coast2 3.587 -23181.005859375 881.9022216796875 1004.377197265625
701 coast2 3.677 -23221.81640625 881.9022216796875 1004.3771362304688
702 coast2 3.728 -23256.78125 881.9021606445312 1004.3770751953125
703 coast2 3.778 -23274.24609375 881.9021606445312 1004.3770141601562
704 coast2 3.828 -23274.24609375 881.9021606445312 1004.3770141601562
705 coast2 3.878 -23274.24609375 881.9021606445312 1004.3770141601562
706 coast2 3.928 -23274.24609375 881.9021606445312 1004.3770141601562
707 coast2 3.979 -23344.2109375 881.9021606445312 1004.3768920898438
708 coast2 4.029 -23379.17578125 881.902099609375 1004.3768310546875
709 coast2 4.079 -23390.83203125 881.902099609375 1004.3767700195312
710 coast2 4.129 -23437.451171875 881.902099609375 1004.376708984375
711 coast2 4.18 -23449.072265625 881.902099609375 1004.3766479492188
712 coast2 4.23 -23449.072265625 881.902099609375 1004.3766479492188
713 coast2 4.28 -23449.072265625 881.902099609375 1004.3766479492188
714 coast2 4.33 -23449.072265625 881.902099609375 1004.3766479492188
715 coast2 4.38 -23524.845703125 881.9020385742188 1004.3765258789062
716 coast2 4.43 -23559.8125 881.9020385742188 1004.37646484375
717 coast2 4.48 -23571.466796875 881.9020385742188 1004.3764038085938
718 coast2 4.53 -23606.431640625 881.9019775390625 1004.3763427734375
719 coast2 4.58 -23623.896484375 881.9019775390625 1004.3763427734375
720 coast2 4.631 -23623.896484375 881.9019775390625 1004.3763427734375
721 coast2 4.681 -23623.896484375 881.9019775390625 1004.3763427734375
722 coast2 4.731 -23623.896484375 881.9019775390625 1004.3763427734375
723 coast2 4.781 -23688.015625 881.9019775390625 1004.3761596679688
724 coast2 4.832 -23722.982421875 881.9019165039062 1004.3760986328125
725 coast2 4.882 -23746.291015625 881.9019165039062 1004.3760986328125
726 coast2 4.934 -23781.255859375 881.9019165039062 1004.3759765625
727 coast2 4.984 -23804.56640625 881.9019165039062 1004.3759765625
728 coast2 5.034 -23822.06640625 881.90185546875 1004.3759155273438
729 coast2 5.084 -23822.06640625 881.90185546875 1004.3759155273438
730 coast2 5.134 -23822.06640625 881.90185546875 1004.3759155273438
731 coast2 5.184 -23874.56640625 881.90185546875 1004.3757934570312
732 coast2 5.234 -23915.341796875 881.90185546875 1004.375732421875
733 coast2 5.284 -23938.65234375 881.9017944335938 1004.3756713867188
734 coast2 5.334 -23985.271484375 881.9017944335938 1004.3756103515625
735 coast2 5.385 -23996.92578125 881.9017944335938 1004.3755493164062
736 coast2 5.438 -24008.546875 881.9017944335938 1004.3755493164062
737 coast2 5.488 -24008.546875 881.9017944335938 1004.3755493164062
738 coast2 5.539 -24008.546875 881.9017944335938 1004.3755493164062
739 coast2 5.589 -24008.546875 881.9017944335938 1004.3755493164062
740 coast2 5.639 -24095.9765625 881.9017333984375 1004.3753662109375
741 coast2 5.689 -24125.130859375 881.9017333984375 1004.3753051757812
742 coast2 5.739 -24160.095703125 881.9016723632812 1004.375244140625
743 coast2 5.789 -24171.751953125 881.9016723632812 1004.3751831054688
744 coast2 5.839 -24195.02734375 881.9016723632812 1004.3751831054688
745 coast2 5.889 -24195.02734375 881.9016723632812 1004.3751831054688
746 coast2 5.94 -24195.02734375 881.9016723632812 1004.3751831054688
747 coast2 5.99 -24195.02734375 881.9016723632812 1004.3751831054688
748 coast2 6.04 -24264.9921875 881.9016723632812 1004.375
749 coast2 6.091 -24288.30078125 881.901611328125 1004.375
750 coast2 6.141 -24334.921875 881.901611328125 1004.3748779296875
751 coast2 6.192 -24358.232421875 881.901611328125 1004.3748168945312
752 coast2 6.242 -24387.3515625 881.9015502929688 1004.374755859375
753 coast2 6.292 -24393.162109375 881.9015502929688 1004.374755859375
754 coast2 6.345 -24393.162109375 881.9015502929688 1004.374755859375
755 coast2 6.395 -24393.162109375 881.9015502929688 1004.374755859375
756 coast2 6.446 -24451.470703125 881.9015502929688 1004.3746337890625
757 coast2 6.496 -24480.591796875 881.9015502929688 1004.3745727539062
758 coast2 6.578 -24515.556640625 881.9014892578125 1004.37451171875
759 coast2 6.628 -24568.021484375 881.9014892578125 1004.3743896484375
760 coast2 6.678 -24579.67578125 881.9014892578125 1004.3743896484375
761 coast2 6.728 -24591.33203125 881.9014892578125 1004.3743286132812
762 coast2 6.778 -24591.33203125 881.9014892578125 1004.3743286132812
763 coast2 6.829 -24591.33203125 881.9014892578125 1004.3743286132812
764 coast2 6.879 -24655.451171875 881.9014282226562 1004.3742065429688
765 coast2 6.929 -24690.416015625 881.9014282226562 1004.3741455078125
766 coast2 6.979 -24702.072265625 881.9014282226562 1004.3741455078125
767 coast2 7.031 -24737.037109375 881.9013671875 1004.3740844726562
768 coast2 7.081 -24760.345703125 881.9013671875 1004.3740234375
769 coast2 7.132 -24772.001953125 881.9013671875 1004.3739624023438
770 coast2 7.182 -24772.001953125 881.9013671875 1004.3739624023438
771 coast2 7.232 -24772.001953125 881.9013671875 1004.3739624023438
772 coast2 7.284 -24830.310546875 881.9013671875 1004.3738403320312
773 coast2 7.334 -24865.27734375 881.9013061523438 1004.373779296875
774 coast2 7.384 -24894.431640625 881.9013061523438 1004.3737182617188
775 coast2 7.434 -24929.396484375 881.9013061523438 1004.3736572265625
776 coast2 7.484 -24952.70703125 881.9012451171875 1004.3735961914062
777 coast2 7.534 -24958.515625 881.9012451171875 1004.3735961914062
778 coast2 7.584 -24958.515625 881.9012451171875 1004.3735961914062
779 coast2 7.635 -24958.515625 881.9012451171875 1004.3735961914062
780 coast2 7.685 -24958.515625 881.9012451171875 1004.3735961914062
781 coast2 7.736 -25028.48046875 881.9012451171875 1004.3734741210938
782 coast2 7.786 -25057.63671875 881.9012451171875 1004.3734130859375
783 coast2 7.837 -25092.6015625 881.9011840820312 1004.3733520507812
784 coast2 7.887 -25104.255859375 881.9011840820312 1004.373291015625
785 coast2 7.937 -25121.720703125 881.9011840820312 1004.373291015625
786 coast2 7.987 -25121.720703125 881.9011840820312 1004.373291015625

View File

@@ -0,0 +1,15 @@
file offset vcount candidate claimed by our decode our resources with that vcount
0x38788 181 NO — NOBODY — none
0x4b8b8 93 NO — NOBODY — none
0xb6574 41 NO — NOBODY n042_bdy_m e007_bdy_01 @ -0x24864
0xdbbac 77 NO — NOBODY — none _rou_e010_break @ -0x5050
0x133da0 76 NO — NOBODY e303_wep_01_m, n041_bdy_l _rou_e010_break @ -0x407bc
0x162840 60 NO — NOBODY — none _rou_e010_break @ -0x6f25c
0x3b3ee8 119 yes e106_bdy_01_l(119), e106_bdy_02_l(119) e106_bdy_01_l, e106_bdy_02_l e106_bdy_01_l @ -0x0
0x3c55d8 119 yes — NOBODY e106_bdy_01_l, e106_bdy_02_l e106_bdy_01_m @ -0x104e8
0x3dd2c4 146 yes e106_bdy_03_l(146) e106_bdy_03_l e106_bdy_03_l @ -0x0
0x40763c 179 yes e106_bdy_04_l(179) e106_bdy_04_l e106_bdy_04_l @ -0x0
0x40e418 51 yes — NOBODY e106_brg_01_b_02, e106_brg_01_l e106_brg_01_b_02 @ -0x5d0
0x444ccc 58 yes e106_eng_01_l(58) e106_eng_01_l e106_eng_01_l @ -0x0
0x44a32c 44 yes — NOBODY e106_eng_02_l e106_eng_02 @ -0x35b8
0x45705c 82 yes e106_wep_02_01_l(82) e106_wep_02_01_l e106_wep_02_01_l @ -0x0

View File

@@ -0,0 +1,47 @@
file offset vcount candidate claimed by our decode our resources with that vcount
0x135036c 240 yes _rou_f101(240) — none _rou_f101 @ -0x0
0x13519ec 240 NO _rou_f101(240) — none _rou_f101 @ -0x0
0x13fd6e8 25448 yes f101_bdy_01(25448) f101_bdy_01 f101_bdy_01 @ -0x0
0x192961c 13172 yes f101_bdy_02(13172) f101_bdy_02 f101_bdy_02 @ -0x0
0x1a0befc 2296 yes f101_bdy_03(2296) f101_bdy_03 f101_bdy_03 @ -0x0
0x1a22c1c 7694 yes f101_eng_01(7694) f101_eng_01 f101_eng_01 @ -0x0
0x1be5df4 628 yes f101_wep_01_m(628) f101_wep_01_m f101_wep_01_m @ -0x0
0x1bf40f4 261 yes e_rob_f001(24), e_rou_f003_Near(24), e_rou_f101_wep_01(24), e_rou_f105(24), _rou_f105_break(261), e_rou_f106(24), e_rou_f302_barrel(24), e_rou_f302_base(24), e_rou_f303_barrel(24), e_rou_f303_base(24), e_rou_e007_Far(24), e_rou_e007_Near(24), e_rou_e010_Far(24), e_rou_e010_Near(24), e_rou_e105(24), e_rou_e105_wep_01(24), e_rou_e106(24), e_rou_e106_eng(24), e_rou_e106_wep_02_01(24), e_rou_e106_wep_02_joint(24), e_rou_e108_Missile_open(24), e_rou_e201(24), e_rou_e302_barrel(24), e_rou_e302_base(24), e_rou_e303_barrel_Near(24), e_rou_e303_base_Near(24), e_rou_e501(24) f106_eng_01_l e_rob_f001 @ -0x0
0x1bf596c 2446 NO _rou_f105_break(2446) f105_bdy_01_m _rou_f105_break @ -0x0
0x1c03ebc 1960 NO _rou_f105_break(1960) f105_bdy_02_m _rou_f105_break @ -0x0
0x1c0f67c 82 NO _rou_f105_break(82) e106_wep_02_01_l _rou_f105_break @ -0x0
0x1c0fe2c 2336 NO _rou_f105_break(2336) f105_bdy_03_m _rou_f105_break @ -0x0
0x1c1d92c 220 NO _rou_f105_break(220) — none _rou_f105_break @ -0x0
0x1c1edcc 80 NO _rou_f105_break(80) f001_bdy_24_m _rou_f105_break @ -0x0
0x1c1f54c 148 NO _rou_f105_break(148) — none _rou_f105_break @ -0x0
0x1c2032c 156 NO _rou_f105_break(156) e105_bdy_01_l _rou_f105_break @ -0x0
0x1c211cc 1402 NO _rou_f105_break(1402) f105_eng_01_m _rou_f105_break @ -0x0
0x1c2953c 84 NO _rou_f105_break(84) — none _rou_f105_break @ -0x0
0x1c29d1c 192 NO _rou_f105_break(192) f105_sld_01_b01 _rou_f105_break @ -0x0
0x1c2af1c 122 NO _rou_f105_break(122) e106_eng_02_m _rou_f105_break @ -0x0
0x1c2ba8c 24 NO _rou_f105_break(24) e_rob_f001, e_rou_f003_Far, e_rou_f003_Near, e_rou_f101_wep_01, e_rou_f105, f105_sld_01_l, e_rou_f106, e_rou_f302_barrel, e_rou_f302_base, f302_01_l, e_rou_f303_barrel, e_rou_f303_base, _rou_f402_dead, e_rou_e007_Far, e_rou_e007_Near, e_rou_e010_Far, e_rou_e010_Near, e_rou_e105, e_rou_e105_wep_01, e_rou_e106, e_rou_e106_eng, e_rou_e106_wep_02_01, e_rou_e106_wep_02_joint, e_rou_e108_Missile_open, e_rou_e201, e201_bdy_03_m, e_rou_e302_barrel, e_rou_e302_base, e_rou_e303_barrel_Near, e_rou_e303_base_Near, e303_wep_02_l, e_rou_e501 _rou_f105_break @ -0x0
0x227ac94 1692 yes f106_bdy_02_l(1692) f106_bdy_02_l f106_bdy_02_l @ -0x0
0x22c2ef0 686 yes f106_bdy_03_l(686) f106_bdy_03_l f106_bdy_03_l @ -0x0
0x22ed420 261 yes f106_eng_01_l(261) f106_eng_01_l f106_eng_01_l @ -0x0
0x2326c9c 254 yes f106_sld_01_l(254) f106_sld_01_l, f106_sld_02_l, e303_wep_02_m f106_sld_01_l @ -0x0
0x233b3fc 254 yes f106_sld_02_l(254) f106_sld_01_l, f106_sld_02_l, e303_wep_02_m f106_sld_02_l @ -0x0
0x24ce5f4 32 yes f303_body_l(32) f303_body_l, e302_barrel_l f303_body_l @ -0x0
0x24fa1c8 128 yes _rou_f402(128) _rou_f402 _rou_f402 @ -0x0
0x28ea1d4 156 yes e105_bdy_01_l(156) e105_bdy_01_l e105_bdy_01_l @ -0x0
0x28f7514 107 yes e105_bdy_02_l(107) e105_bdy_02_l, e105_brg_m e105_bdy_02_l @ -0x0
0x291e1e8 185 yes e105_bdy_03_l(185) e105_bdy_03_l e105_bdy_03_l @ -0x0
0x29a4788 181 yes e105_bdy_04_l(181) e105_bdy_04_l e105_bdy_04_l @ -0x0
0x29b78b8 93 yes e105_bdy_05_l(93) e105_bdy_05_l e105_bdy_05_l @ -0x0
0x2a22574 41 yes e105_bdy_06_l(41) e105_bdy_06_l e105_bdy_06_l @ -0x0
0x2a47bac 77 yes e105_brg_l(77) e105_brg_l e105_brg_l @ -0x0
0x2a9fda0 76 yes e105_eng_01_l(76) e105_eng_01_l, e303_wep_01_m e105_eng_01_l @ -0x0
0x2ace840 60 yes e105_wep_01_l(60) e105_wep_01_l e105_wep_01_l @ -0x0
0x2d1fee8 119 yes e106_bdy_01_l(119) e106_bdy_01_l, e106_bdy_02_l e106_bdy_01_l @ -0x0
0x2d315d8 119 yes e106_bdy_02_l(119) e106_bdy_01_l, e106_bdy_02_l e106_bdy_02_l @ -0x0
0x2d492c4 146 yes e106_bdy_03_l(146) e106_bdy_03_l e106_bdy_03_l @ -0x0
0x2d7363c 179 yes e106_bdy_04_l(179) e106_bdy_04_l e106_bdy_04_l @ -0x0
0x2d7a418 51 yes e106_brg_01_l(51) e106_brg_01_b_02, e106_brg_01_l e106_brg_01_l @ -0x0
0x2db0ccc 58 yes e106_eng_01_l(58) e106_eng_01_l e106_eng_01_l @ -0x0
0x2db632c 44 yes e106_eng_02_l(44) e106_eng_02_l, e302_base_m e106_eng_02_l @ -0x0
0x2dc305c 82 yes e106_wep_02_01_l(82) e106_wep_02_01_l e106_wep_02_01_l @ -0x0
0x329077c 6000 yes n006_02(6000) n006_02 n006_02 @ -0x0

View File

@@ -0,0 +1,50 @@
container load constant: vbase - file_offset = 0x17FE3FF4 (93 buffers agree)
decoded 356 resources, 422 distinct vertex offsets
vb 0x13FD6E8 v=25448 batches 8 idx 52077 span 104154 gap 2 decpad 2 cover exact f101_bdy_01(v25448,i52077)
vb 0x192961C v=13172 batches 2 idx 24816 span 49632 gap 0 decpad 0 cover exact f101_bdy_02(v13172,i24816)
vb 0x1BF40F4 v=261 batches 3 idx 498 span 996 gap 41476 decpad 41476 cover exact e_rob_f001(v24,i36) e_rou_f003_Near(v24,i36) e_rou_f101_wep_01(v24,i36) e_rou_f105(v24,i36) _rou_f105_break(v261,i498) e_rou_f106(v24,i36) e_rou_f302_barrel(v24,i36) e_rou_f302_base(v24,i36) e_rou_f303_barrel(v24,i36) e_rou_f303_base(v24,i36) e_rou_e007_Far(v24,i36) e_rou_e007_Near(v24,i36) e_rou_e010_Far(v24,i36) e_rou_e010_Near(v24,i36) e_rou_e105(v24,i36) e_rou_e105_wep_01(v24,i36) e_rou_e106(v24,i36) e_rou_e106_eng(v24,i36) e_rou_e106_wep_02_01(v24,i36) e_rou_e106_wep_02_joint(v24,i36) e_rou_e108_Missile_open(v24,i36) e_rou_e201(v24,i36) e_rou_e302_barrel(v24,i36) e_rou_e302_base(v24,i36) e_rou_e303_barrel_Near(v24,i36) e_rou_e303_base_Near(v24,i36) e_rou_e501(v24,i36)
vb 0x1C0F67C v=82 batches 1 idx 144 span 288 gap 133672 decpad 133672 cover exact _rou_f105_break(v82,i144)
vb 0x1C1D92C v=220 batches 3 idx 384 span 768 gap 179872 decpad 179872 cover exact _rou_f105_break(v220,i384)
vb 0x1C1EDCC v=80 batches 2 idx 132 span 264 gap 184888 decpad 184888 cover exact _rou_f105_break(v80,i132)
vb 0x1C1F54C v=148 batches 3 idx 288 span 576 gap 186232 decpad 186232 cover exact _rou_f105_break(v148,i288)
vb 0x1C2032C v=156 batches 1 idx 246 span 492 gap 189292 decpad 189292 cover exact _rou_f105_break(v156,i246)
vb 0x1C2953C v=84 batches 1 idx 156 span 312 gap 220012 decpad 220012 cover exact _rou_f105_break(v84,i156)
vb 0x1C2AF1C v=122 batches 3 idx 351 span 702 gap 224882 decpad 224882 cover exact _rou_f105_break(v122,i351)
vb 0x1C2BA8C v=24 batches 2 idx 36 span 72 gap 227736 decpad 227736 cover exact _rou_f105_break(v24,i36)
vb 0x1ECB4C0 v=2446 batches 4 idx 5466 span 10932 gap 0 decpad 0 cover exact f105_bdy_01_m(v2446,i5466)
vb 0x227AC94 v=1692 batches 3 idx 3651 span 7302 gap 2 decpad 2 cover exact f106_bdy_02_l(v1692,i3651)
vb 0x22C2EF0 v=686 batches 2 idx 1506 span 3012 gap 0 decpad 0 cover exact f106_bdy_03_l(v686,i1506)
vb 0x22C8F50 v=1558 batches 3 idx 4098 span 8196 gap 0 decpad 0 cover exact f106_bdy_03_m(v1558,i4098)
vb 0x22ED420 v=261 batches 4 idx 561 span 1122 gap 2 decpad 2 cover exact f106_eng_01_l(v261,i561)
vb 0x22F0430 v=1162 batches 4 idx 3018 span 6036 gap 0 decpad 0 cover exact f106_eng_01_m(v1162,i3018)
vb 0x2326C9C v=254 batches 2 idx 495 span 990 gap 2 decpad 2 cover exact f106_sld_01_l(v254,i495)
vb 0x233B3FC v=254 batches 2 idx 495 span 990 gap 2 decpad 2 cover exact f106_sld_02_l(v254,i495)
vb 0x233D700 v=627 batches 3 idx 1434 span 2868 gap 0 decpad 0 cover exact f106_sld_02_m(v627,i1434)
vb 0x24CE5F4 v=32 batches 1 idx 60 span 120 gap 0 decpad 0 cover exact f303_body_l(v32,i60)
vb 0x28EA1D4 v=156 batches 2 idx 228 span 456 gap 0 decpad 0 cover exact e105_bdy_01_l(v156,i228)
vb 0x28F7514 v=107 batches 3 idx 180 span 360 gap 0 decpad 0 cover exact e105_bdy_02_l(v107,i180)
vb 0x291E1E8 v=185 batches 2 idx 285 span 570 gap 2 decpad 2 cover exact e105_bdy_03_l(v185,i285)
vb 0x29A4788 v=181 batches 3 idx 318 span 636 gap 0 decpad 0 cover exact e105_bdy_04_l(v181,i318)
vb 0x29B78B8 v=93 batches 2 idx 117 span 234 gap 2 decpad 2 cover exact e105_bdy_05_l(v93,i117)
vb 0x2A22574 v=41 batches 1 idx 51 span 102 gap 2 decpad 2 cover exact e105_bdy_06_l(v41,i51)
vb 0x2A47BAC v=77 batches 1 idx 111 span 222 gap 2 decpad 2 cover exact e105_brg_l(v77,i111)
vb 0x2A9FDA0 v=76 batches 1 idx 90 span 180 gap 0 decpad 0 cover exact e105_eng_01_l(v76,i90)
vb 0x2ACE840 v=60 batches 1 idx 90 span 180 gap 0 decpad 0 cover exact e105_wep_01_l(v60,i90)
vb 0x2D1FEE8 v=119 batches 2 idx 246 span 492 gap 0 decpad 0 cover exact e106_bdy_01_l(v119,i246)
vb 0x2D315D8 v=119 batches 2 idx 246 span 492 gap 0 decpad 0 cover exact e106_bdy_02_l(v119,i246)
vb 0x2D492C4 v=146 batches 2 idx 324 span 648 gap 0 decpad 0 cover exact e106_bdy_03_l(v146,i324)
vb 0x2D7363C v=179 batches 2 idx 399 span 798 gap 2 decpad 2 cover exact e106_bdy_04_l(v179,i399)
vb 0x2D7A418 v=51 batches 2 idx 126 span 252 gap 0 decpad 0 cover exact e106_brg_01_l(v51,i126)
vb 0x2DB0CCC v=58 batches 2 idx 96 span 192 gap 0 decpad 0 cover exact e106_eng_01_l(v58,i96)
vb 0x2DB632C v=44 batches 2 idx 72 span 144 gap 0 decpad 0 cover exact e106_eng_02_l(v44,i72)
vb 0x2DC305C v=82 batches 2 idx 168 span 336 gap 0 decpad 0 cover exact e106_wep_02_01_l(v82,i168)
vb 0x329077C v=6000 batches 1 idx 6000 span 12000 gap 0 decpad 0 cover exact n006_02(v6000,i6000)
vb 0x3434030 v=4 batches 1 idx 6 span 12 gap 24 decpad 24 cover exact n301_02B(v4,i6)
vb 0x3434090 v=4 batches 1 idx 6 span 12 gap 108 decpad 108 cover exact n301_02B(v4,i6)
vb 0x34340F0 v=4 batches 1 idx 6 span 12 gap 192 decpad 192 cover exact n301_02B(v4,i6)
placed 42 drawn buffers in this container
DECODER layout assumption — whole index buffer at vb - 2*idx_count - pad: pad 0 20 · pad 1..3 10 · elsewhere 12 · not decoded here 0
index extent: our idx_count == sum of captured batches for 42 buffers, differs for 0
vertex-pool coverage by the union of batches: exact 42 · short 0

View File

@@ -0,0 +1,125 @@
map check: 406 fields agree with the disc, 0 disagree
runtime value where the disc record DEFAULTS the field:
AA_AxisMode_Max 0 (10 units)
AA_AxisMode_Min 0, 1.74533 (11 units)
AA_PitchMinus_Max 0, 0.0628319, 0.174533 (8 units)
AA_PitchMinus_Min 0, 0.0628319, 0.261799, 0.349066, 0.698132 (10 units)
AA_PitchPlus_Max 0, 0.0628319 (6 units)
AA_PitchPlus_Min 0, 0.0628319, 1.74533 (8 units)
AA_Roll_Max 0, 0.0628319, 0.174533, 0.523599, 1.0472 (10 units)
AA_Roll_Min 0, 0.0628319, 1.0472 (7 units)
AA_Yaw_Max 0, 0.0628319, 0.0872665 (7 units)
AA_Yaw_Min 0, 0.0628319, 0.261799 (7 units)
AB_AA_PitchMinus 0, 0.174533 (11 units)
AB_AA_PitchPlus 0 (10 units)
AB_AA_Roll 0, 0.523599 (11 units)
AB_AA_Yaw 0, 0.174533 (11 units)
AB_AV_PitchMinus 0 (10 units)
AB_AV_PitchPlus 0, 0.523599 (11 units)
AB_AV_Roll 0, 0.698132 (11 units)
AB_AV_Yaw 0, 0.279253 (11 units)
AB_ConsumeShield 0, 10 (11 units)
AB_ConsumeShield_Begin 0 (10 units)
AV_AxisMode_Max 0, 0.174533 (11 units)
AV_AxisMode_Min 0 (10 units)
AV_PitchMinus_Max 0, 0.0628319, 0.349066 (7 units)
AV_PitchMinus_Min 0, 0.0628319 (6 units)
AV_PitchPlus_Max 0 (1 units)
AV_PitchPlus_Min 0, 0.0628319, 1.74533 (7 units)
AV_Roll_Max 0, 0.0628319, 0.349066, 1.0472, 2.0944 (10 units)
AV_Roll_Min 0, 0.0628319, 1.0472 (7 units)
AV_Yaw_Max 0, 0.0628319, 0.174533 (7 units)
AV_Yaw_Min 0, 0.0628319, 0.349066 (7 units)
AccPitchFactor 0, 30 (5 units)
Acceleration 0 (1 units)
ArterBurner_Acc 0, 2 (10 units)
ArterBurner_Vc 0, 2 (6 units)
AttackCraftPoint 0, 0.1, 0.5, 1 (9 units)
AttackVesselPoint 0, 0.1 (3 units)
BarrelRoll_CountMaximum 0, 5 (11 units)
BarrelRoll_CountMinimum 0, 0.5 (11 units)
BarrelRoll_Radius 0 (7 units)
BarrelRoll_Time 0 (7 units)
BoostAway_Time_Maximum 0, 2 (11 units)
BoostAway_Time_Minimum 0, 1 (11 units)
ChargeDelay 1, 3, 5 (10 units)
ChargeDelay_Break 1, 10 (6 units)
ChargeSpeed 25 (3 units)
Color_B 0, 1 (3 units)
Color_G 1 (1 units)
CruisingVelocity 0 (1 units)
CutoffTimeMax 0, 5 (10 units)
CutoffTimeMin 0 (7 units)
DecPitchFactor 0, 30 (11 units)
Deceleration 0, 50 (2 units)
DefencePoint 0, 0.1, 0.25 (5 units)
Delay 0, 1.5, 3 (8 units)
DelayAdjustment 0, 1, 2 (10 units)
DestroyMotionTime 0 (1 units)
DragFactorThreshold 0, 0.5 (10 units)
DryMass 100, 10000 (8 units)
FCSRange 0, 500000 (3 units)
FiringRange 0 (11 units)
GrossMass 10000, 200 (10 units)
HQRatio 0.2, 1 (9 units)
HoldPosition_BackRatio 0, 0.1, 0.3 (11 units)
HoldPosition_CancelTime 0, 20 (10 units)
HoldPosition_CutoffRatio 0, 0.5 (11 units)
HoldPosition_LengthMax 0, 400 (8 units)
HoldPosition_LengthMin 0, 150 (10 units)
HoldPosition_MaximumTime 0, 10 (10 units)
HoldPosition_MinimumTime 0, 5 (11 units)
HoldPosition_SideRatio 0, 0.3 (11 units)
HomingResistAdjustment 0, 0.5 (11 units)
LowerHPThresholdRatio 0, 0.3 (7 units)
MaxValue 100 (3 units)
MaximumBank_Normal 0, 0.523599, 1.0472 (5 units)
MaximumVelocity 0 (1 units)
MinimumVelocity 0, 100 (7 units)
PitchDragFactor 0, 2, 3 (11 units)
PowerCutConsumeShield 0, 20 (11 units)
PowerCutDeceleration 0, 10 (11 units)
RadarRange 0 (1 units)
ResistanceParalyze 1 (1 units)
ResistanceToExplosion 0.1, 0.5, 1 (9 units)
ResistanceToOptics 0.1, 1 (4 units)
ResistanceToPlayer 0, 1 (10 units)
ResistanceToShell 0.1, 1 (8 units)
ReverseThrust_Acc 0, 0.25, 2 (9 units)
ReverseThrust_Vc 0 (1 units)
RollDragFactor 0, 2, 3 (11 units)
SELength 2000 (11 units)
ShieldRatio 1 (6 units)
SideRoll_Length 0 (7 units)
SideRoll_Time 0, 0.5, 1.5 (11 units)
SideThrustAcceleration 0, 100, 1000 (5 units)
SideThrustVelocity_Max 0, 100, 1000 (3 units)
Size_Radius 10, 50 (4 units)
Size_Y 200, 300, 400, 600, 700 (5 units)
Slalom_CutoffRatio 0 (7 units)
Slalom_TurnCount_Max 0 (11 units)
Slalom_TurnCount_Min 0 (9 units)
SolidCutoff_LengthMax 0 (7 units)
SolidCutoff_LengthMin 0, 500 (9 units)
SolidCutoff_Ratio 0, 0.5 (11 units)
Through_AngleMaximum 0, 1.0472 (11 units)
Through_AngleMinimum 0, 0.523599 (11 units)
Through_CutoffRatio 0, 0.5 (11 units)
Through_LengthMaximum 0, 500 (10 units)
Through_LengthMinimum 0, 250 (11 units)
Through_Time1Max 0, 2 (11 units)
Through_Time1Min 0, 5 (11 units)
Through_Time2Max 0, 1.5 (8 units)
Through_Time2Min 0, 5 (11 units)
ThrusterRatio 0.2, 1 (10 units)
TurnAttack_CutoffRatio 0 (7 units)
TurnAttack_DoubleRatio 0 (7 units)
TurnAttack_DoubleTimeMax 0 (7 units)
TurnAttack_DoubleTimeMin 0 (7 units)
TurnAway_Time_Maximum 0, 2, 5 (11 units)
TurnAway_Time_Minimum 0, 0.5 (11 units)
Turn_AngularVelocity 0, 0.523599 (8 units)
UsingChaffRatio 0 (11 units)
YawDragFactor 0 (1 units)

Some files were not shown because too many files have changed in this diff Show More