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:
@@ -30,6 +30,22 @@
|
||||
#include <akerror.h>
|
||||
|
||||
#include <akgl/renderer.h>
|
||||
#include <akgl/version.h>
|
||||
|
||||
/*
|
||||
* Everything in this target now depends on APIs that arrived in libakgl 0.3.0:
|
||||
* akgl_render_bind2d(), akgl_audio_sweep(), and akgl_Keystroke with
|
||||
* akgl_controller_poll_keystroke(). Refused here rather than at link time,
|
||||
* because a missing symbol names a function and this names the release.
|
||||
*
|
||||
* The soname carries MAJOR.MINOR while the major is 0, so 0.2 and 0.3 are
|
||||
* different ABIs and a mismatch is normally caught at load. This catches the
|
||||
* case the soname cannot: a build against 0.2 headers that happens to find a
|
||||
* 0.3 library, or the reverse.
|
||||
*/
|
||||
#if !AKGL_VERSION_AT_LEAST(0, 3, 0)
|
||||
#error "akbasic's libakgl adaptors require libakgl 0.3.0 or later"
|
||||
#endif
|
||||
|
||||
#include <akbasic/audio.h>
|
||||
#include <akbasic/graphics.h>
|
||||
@@ -164,16 +180,21 @@ akerr_ErrorContext AKERR_NOIGNORE *akbasic_sink_akgl_render(akbasic_TextSink *ob
|
||||
* collects keystrokes from libakgl's ring -- the one the host's own event pump
|
||||
* fills -- echoes them into the grid, and returns the line on Return.
|
||||
*
|
||||
* **What the editor cannot do, and why.** akgl_controller_poll_key() reports a
|
||||
* keycode and nothing else: no modifier state and no composed text. So the
|
||||
* editor cannot see Shift, which puts every shifted character out of reach and
|
||||
* makes lowercase unreachable. Letters are folded to upper case, which is what a
|
||||
* C128 does anyway and what the C64 font is drawn for. Filed upstream against
|
||||
* libakgl; when the ring carries modifiers this becomes a real keyboard.
|
||||
* **It is a real keyboard as of libakgl 0.3.0.** The ring carries the composed
|
||||
* UTF-8 text SDL worked out from the keystroke, so shifted characters, a
|
||||
* keyboard layout, a compose key and a dead key all do what the person typing
|
||||
* expects -- including the double quote, without which a BASIC string literal
|
||||
* cannot be typed at all. Until 0.3.0 the ring reported a keycode and nothing
|
||||
* else, so none of that was reachable and letters were folded to upper case;
|
||||
* that was libakgl API-gap item 10, filed from here.
|
||||
*
|
||||
* Composed text is taken over the keycode wherever there is any, which is what
|
||||
* makes the layout work: on an AZERTY keyboard the key SDL calls `SDLK_Q`
|
||||
* composes to "a", and "a" is what the program should see.
|
||||
*
|
||||
* Editing is Backspace to erase one character and Escape to abandon the line.
|
||||
* There is no cursor movement within the line, for the same reason: the ring
|
||||
* reports the arrow keys, but a script's own GET loop wants them.
|
||||
* There is no cursor movement within the line: the ring reports the arrow keys,
|
||||
* but a script's own GET loop wants them.
|
||||
*
|
||||
* @param obj The sink to give an editor to.
|
||||
* @param pump One frame of the host's loop, or NULL to take the editor away.
|
||||
|
||||
@@ -67,6 +67,16 @@ typedef struct akbasic_AudioBackend
|
||||
|
||||
/** Start a note on a voice, for a bounded duration. */
|
||||
akerr_ErrorContext AKERR_NOIGNORE *(*tone)(struct akbasic_AudioBackend *self, int voice, double hz, int ms);
|
||||
/**
|
||||
* Start a note whose pitch moves, which is what SOUND's `dir`, `min` and
|
||||
* `step` arguments ask for -- a siren, a laser, a falling bomb.
|
||||
*
|
||||
* May be NULL, and a host that leaves it so gets `SOUND` refused with
|
||||
* AKBASIC_ERR_DEVICE for a swept note and served normally for a held one.
|
||||
* That is deliberate: this arrived in libakgl 0.3.0, and a backend written
|
||||
* against an older one is still a valid backend for everything else.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *(*sweep)(struct akbasic_AudioBackend *self, int voice, double from_hz, double to_hz, double step_hz, int ms);
|
||||
/** Silence a voice immediately. */
|
||||
akerr_ErrorContext AKERR_NOIGNORE *(*stop)(struct akbasic_AudioBackend *self, int voice);
|
||||
/** Select the waveform a voice synthesises. */
|
||||
|
||||
Reference in New Issue
Block a user