Add portable Windows build and update GC runtime

This commit is contained in:
2026-08-15 13:01:11 +02:00
parent cd300cd554
commit 623ef9a733
13 changed files with 580 additions and 60 deletions
+40 -26
View File
@@ -47,10 +47,22 @@ generated samples remain uniform over corners; it is not the normal route
renderer.
The player now mirrors `DrawWay`: it uploads the original authored points plus
the two exact timestamp intersections and draws separate behind/current and
current/ahead line strips with endpoint color gradients. The stage values
`backwardsDrawDist` and `forwardDrawDist` behave as seconds and are converted
to milliseconds before comparison with track and note timestamps.
the two exact timestamp intersections and draws separate past/current and
current/future line strips with endpoint color gradients. Android
`DrawGameStageCharacter` proves that the active `forwardDrawDist` value is a
count of beats, not seconds. If `beat_ms = 60000 / bpm`, it computes:
```text
beat_start = floor(current_ms / beat_ms) * beat_ms
future_ms = forwardDrawDist * beat_ms
first_ms = max(0, beat_start - max(beat_ms, future_ms))
last_ms = min(song_end, beat_start + future_ms)
```
The same active value drives both sides, but only the past side has a minimum
one-beat span. Thus a dynamic value of zero removes the future route while
retaining one past beat. The first `backwardsDrawDist` config float is retained
while parsing but is not consumed by this normal Android rendering path.
Dynamic `TrackDrawDist` records are step changes, not interpolation keys. The
StageConfig forward distance remains active until the timestamp of the first
@@ -64,18 +76,22 @@ For `ac_10pt8tion_hard.dat`:
```text
first track key: 0 ms, (0, 0, 0)
second track key: 6486 ms, (0, 0, 199.985)
draw behind: 10 s
draw ahead: 7 s
first range field: 10
active range: 7 beats
```
Treating 7/10 as world units collapses the visible rail to a tiny fraction of
the first segment; timestamp clipping produces the expected visible range.
The rail brightness is also chart-clock driven. Over a two-beat triangle wave,
`pulse = triangle * 0.6 + 0.4`; the past segment grades from `0.7*pulse` to
`pulse` alpha and the future segment from `pulse` to `0.5*pulse`. Both are
submitted with additive blending.
## Track colors
The stage config stores two RGBA colors directly after the draw-range values.
They are used for the forward and already-travelled portions of the rail. For
`10pt8tion_hard` they are `(255,0,128)` ahead and `(255,255,255)` behind.
Android uses the first for the past/current call and the second for the
current/future call. For `10pt8tion_hard` they are `(255,0,128)` and
`(255,255,255)` respectively; the older ahead/behind field names were inferred
backwards.
## Base background
@@ -88,15 +104,14 @@ rgba top_left
rgba bottom_right
rgba bottom_left
u8 interpolate_to_next
u8 audio_reactive_color
u8 rhythm_reactive_color
```
`FUN_00642390` holds the active colors unless `interpolate_to_next` is set; in
that case it linearly interpolates all four RGBA values to the following key.
`audio_reactive_color` applies `FUN_005d9650` to each active color using the
runtime analyser value. The Linux player now implements the exact hold versus
interpolate selection and keeps the second mode at its neutral color factor
until the analyser feeding `stage renderer +0x24` is ported.
`FUN_00642390` holds the active colors unless `interpolate_to_next` is set.
The transition uses `CalcCrossFadeColor`'s 25% overlap rather than a plain
linear mix. `rhythm_reactive_color` multiplies HSV brightness by a 0.5..0.75
triangle wave derived from chart time and the active BPM in `SetCommonParam`;
it is not sourced from an audio analyser. The Linux player implements both.
`data/stage/2d/<song>_menu.dds` is not the gameplay background. It is a
512x256 UI atlas whose top-left 197x197 cell is the song jacket. The player has
@@ -105,7 +120,7 @@ only an explicit debug comparison layer (`B`). The inherited procedural
blue/black square grid has also been removed: the base layer is now only the
stage-authored color table before particles, visualizers and objects are drawn.
The remaining original scene is produced by the stage `particles`,
The remaining original scene is produced by the stage FlowItem,
`visualizer`, and `objects` sections (plus `.tumo` models), not by a single
background bitmap. These sections are now decoded completely by
`StagePattern`: particle records are 44 bytes, visualizer records are 12 bytes,
@@ -115,14 +130,13 @@ keys, 19 visualizer keys, 46 model names and 316 object instances; 10pt8tion
contains 2, 28, 37 and 352 respectively. The Vectorail level data retains this
decoded scene for the model-rendering pass.
The PSP package now retains all three timelines. The particle constructor at
`FUN_005f0940` creates a 64-instance pool for every configured particle key.
`FUN_005f0130` scales both `repeatMeasure` and `lifespanMeasure` by the active
beat duration. Recovered spawn layouts are: type 1, a deterministic/random
point; type 2, a screen/grid group using `groupShapeSize`; type 3, six points
at 60-degree intervals around a circle. The PSP implementation follows these
timing and layout rules, but substitutes geometry for the original particle
texture resource until that resource binding is mapped.
Android `GameScene::ExecFlowItem` scales both `repeatMeasure` and
`lifespanMeasure` by the active beat duration. Recovered spawn layouts are:
type 1, a random screen point; type 2, a screen/grid group using
`groupShapeSize`; type 3, eight points at 45-degree intervals around a circle.
The player follows those timing/layout rules, unprojects the points to route
depth and applies the authored velocity, but substitutes colored billboards
for original texture selectors 34/35.
The common `.tumo` container is also big-endian. Its outer count is followed,
for each mesh, by resource names, an XYZ vertex table, eight bound floats,