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>
61 lines
1.9 KiB
C
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);
|
|
}
|