Consume libakgl 0.3.0: every workaround deleted, two capabilities gained

0.3.0 closed all ten API gaps this port had filed. The four workarounds go
with them: the CMake block that declared libakgl's vendored dependencies by
hand, the akgl/actor.h include in three files, and the six vtable pointers
assigned by hand in two more, now akgl_render_bind2d().

Two gaps were capabilities rather than inconveniences, and both are now real:

The line editor takes the composed UTF-8 text the ring carries in preference
to the keycode, so shifted characters, keyboard layouts, compose keys and dead
keys all work. A double quote can be typed, which means a BASIC string literal
can be typed -- the sharp end of the old limitation. Letters are no longer
folded to upper case.

SOUND's dir/min/step reach akgl_audio_sweep instead of being refused. dir 3
sweeps once rather than oscillating and TODO.md section 5 says so. A backend
with no sweep still refuses the swept note and plays the held one.

The adaptors now carry an AKGL_VERSION_AT_LEAST(0, 3, 0) floor, verified by
temporarily demanding 0.4.0 and watching it fire.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-31 13:25:14 -04:00
parent 583c0abbd2
commit fca9ad4a89
16 changed files with 495 additions and 265 deletions

View File

@@ -60,6 +60,26 @@ static akerr_ErrorContext *snd_tone(akbasic_AudioBackend *self, int voice, doubl
SUCCEED_RETURN(errctx);
}
/**
* @brief A note whose pitch moves, for SOUND's dir/min/step arguments.
*
* New in libakgl 0.3.0, which is why the record's entry may be NULL and why
* SOUND checks before using it. The sweep is advanced on the mixer's own frame
* counter -- doing it from akbasic_runtime_step() instead would tie audible
* pitch to how often a host happens to call us, which is the reason this was
* filed upstream rather than faked here.
*/
static akerr_ErrorContext *snd_sweep(akbasic_AudioBackend *self, int voice, double from_hz, double to_hz, double step_hz, int ms)
{
PREPARE_ERROR(errctx);
(void)self;
FAIL_ZERO_RETURN(errctx, (ms >= 0), AKERR_VALUE, "Negative note duration %d", ms);
PASS(errctx, akgl_audio_sweep(voice, (float32_t)from_hz, (float32_t)to_hz,
(float32_t)step_hz, (uint32_t)ms));
SUCCEED_RETURN(errctx);
}
static akerr_ErrorContext *snd_stop(akbasic_AudioBackend *self, int voice)
{
PREPARE_ERROR(errctx);
@@ -128,6 +148,7 @@ akerr_ErrorContext *akbasic_audio_init_akgl(akbasic_AudioBackend *obj)
obj->self = NULL; /* the voice table is libakgl's, not ours */
obj->tone = snd_tone;
obj->sweep = snd_sweep;
obj->stop = snd_stop;
obj->waveform = snd_waveform;
obj->envelope = snd_envelope;