Entry 150
The travellers' hum: tobjSeLoopStart and tobjSeLoop
Filescrates/piney-stream/src/draw.rsdocs/engine/stream.mdcrates/piney-audio/src/se3d.rscrates/piney-audio/src/driver.rscrates/piney-audio/src/lib.rscrates/piney-world/src/field_ambient.rscrates/piney-world/src/field_world.rscrates/piney-world/src/field_area.rscrates/piney-data/src/field/render.rscrates/piney-game/src/area.rstools/test_sound3d_rs.pytools/test_field_ambient_rs.pydocs/engine/sound.mddocs/engine/field.md
Half of a GAPS field item. Δ's airship and Λ's whale, the servers' travellers that now and then cross a field (TOBJ), hum as they pass. The port drew them in silence.
What the game does
Two functions of main, called only by TOBJ, speak to the synthesizer
directly rather than through ccSeOn3DLoop:
tobjSeLoopStart(pos)(0x0017bf20), fromTOBJ::Initfor servers 0 and 2. UnlessccSnd +0x133is already set, it takes the first freeloopIDslot, keeps it inlooptest(0x003789dc), and startsseData[44](program 31, channel 15, note 60) with a note on at 127 followed at once by expression 0: the loop runs silent.+0x133is set.tobjSeLoop(pos, rate)(0x0017c0d0), fromTOBJ::Drawwhile the traveller's transparency is not 0, sets the loop's pan and volume. The volume iscalcVel's arithmetic with a reach of 15,000 per 256 of decay (7,500 here) instead of 5,500, clamped to 0-127 (never -1), then scaled by the transparency, so the hum fades with the picture. Behind the camera it also bends the note asccSeOn3Ddoes.- The end. Nothing turns the note off.
+0x133is cleared byinitBeforeLoad, so the nextccSndSQLoad(whose sound off silences the note) stops the updates, and by the desktop'sccSndChangeData. - Ω's sleigh (server 4) calls
tobjSeLooptoo, but no hum was started for it, so it stays silent.
The port
- piney-audio.
se3d::tobj_se_loop_startandse3d::tobj_se_loopbuild the messages.Drivergainstobj_loop(+0x133, cleared insq_loadanddesktop) andlooptest.Audio::tobj_se_loop_startandAudio::tobj_se_loopsend them on port 0. - piney-world.
Ambient::generatemarkstobj_se_startfor servers 0 and 2.Tobj::drawemitsOp::SeLoop(pos, alpha)before its far test, asDrawcalls it. The field runtime sendsOp::SeLoopStartonce, on the first drawn frame, which comes after the area'sccSndSQLoadas inccSetupGameCtrl. - piney-game. The ops become
Event::TobjSeLoopStartandEvent::TobjSeLoop, heard from the active camera.
A crash found on the way
A 300-frame run of the ambient sweep panicked in cell_height.
FIREFLY2::SetBasePosition2 asks the height at its rotated offset (the
game's slip). The harness's camera turn had drifted to -8.4 radians, where
the game's sine no longer holds (matrix entries near -25), so the offset
landed 58,000 away. FIELD::GetHeight wraps only once and read past the
map. The game reads whatever memory lies there; the port indexed out of
bounds. A real camera's turn is a 16-bit angle, so play stays within -pi
to pi. Still, cell_height now gives 0 outside the map instead of
panicking, and the harness keeps its turns within -pi to pi.
Checks
tools/test_sound3d_rs.py's newtest_tobj: 1,510 calls oftobjSeLoopStartandtobjSeLoopmixed withccSeOn3DLoop, random cameras, points and transparencies, run in eemu against the probe: 0 mismatches.test_loopstill has 0 in 1,506.tools/test_field_ambient_rs.py: TOBJ's calls are now recorded (the starts afterGenerate, each frame'stobjSeLoopwith its place and rate) instead of stubbed. 124 cases of 1,000 frames: 0 mismatches, with 8,463 calls oftobjSeLoopamong them.the_airship_hums(piney-world): a type 10 field of seed 1 on Δ has the airship; the start is asked; 120 frames each send one hum, the rate rising by 0.01 from 0.01 to 0.8.tobj_hum_starts_silent_and_follows_distance_and_fade(piney-audio).
Also: the streams' fog by depth
The streams' models still took one fog value at their centre. They now
carry piney_draw::DepthFog like every other model since worklog 0145,
so VU1's per-vertex fog is drawn in the streams too (stream.md).
the hum was not listened to against the game. TOBJ's shadow (ccShadowModel) is still not drawn.