Files
akbasic/src/input_akgl.c
Andrew Kesterson fca9ad4a89 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>
2026-07-31 13:25:14 -04:00

61 lines
1.9 KiB
C

/**
* @file input_akgl.c
* @brief Wires the input backend record to libakgl's keystroke ring.
*
* The thinnest of the four adaptors, and the one whose *shape* carries the
* design: akgl_controller_poll_key() reads a ring that
* akgl_controller_handle_event() fills as the **host** pumps SDL events. The
* interpreter therefore answers "is there a key waiting" without owning an event
* loop, which is the whole of goal 3 for input.
*
* The caveat a host needs, repeated here because this is the file that causes
* it: that ring is process-global and the host's own control maps read the same
* events. A script sitting in a GET loop drains keystrokes the game will then
* never see. Withhold the backend, or supply a filtered one.
*/
#include <akerror.h>
#include <akgl/controller.h>
#include <akgl/error.h>
#include <akbasic/akgl.h>
#include <akbasic/error.h>
static akerr_ErrorContext *in_poll_key(akbasic_InputBackend *self, int *keycode, bool *available)
{
PREPARE_ERROR(errctx);
(void)self;
/*
* An empty ring comes back as success with available false, both here and
* upstream. Passed through unchanged: GET reports it as the empty string,
* which is ordinary BASIC rather than a failure.
*/
PASS(errctx, akgl_controller_poll_key(keycode, available));
SUCCEED_RETURN(errctx);
}
static akerr_ErrorContext *in_flush_keys(akbasic_InputBackend *self)
{
PREPARE_ERROR(errctx);
(void)self;
PASS(errctx, akgl_controller_flush_keys());
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akbasic_input_init_akgl(akbasic_InputBackend *obj)
{
PREPARE_ERROR(errctx);
FAIL_ZERO_RETURN(errctx, (obj != NULL), AKERR_NULLPOINTER,
"NULL backend in input_init_akgl");
PASS(errctx, akgl_error_init());
obj->self = NULL; /* the ring is libakgl's, not ours */
obj->poll_key = in_poll_key;
obj->flush_keys = in_flush_keys;
SUCCEED_RETURN(errctx);
}