// Internal input state shared between core and per-port HAL.
//
// Per-port jlpInputPoll() writes directly into the public state
// globals: gKeyState[] for keyboard, gMouse* for mouse, gJoy* for
// joysticks. The core compares against the matching *Prev shadow
// each jlInputPoll to derive edge events for keys/buttons. Mouse
// position and joystick axes have no edge semantics, so no shadow.

#ifndef JOEYLIB_INPUT_INTERNAL_H
#define JOEYLIB_INPUT_INTERNAL_H

#include "joey/input.h"
#include "joey/types.h"

// Stored as uint8_t (not bool) because a _Bool wider than one byte
// would break the IIgs asm fast path (iigsInputSnapshot), which walks
// these arrays one byte per element; with a 2-byte bool element k
// would sit at byte offset 2*k and the asm's per-byte clear would
// never reach the live half. uint8_t pins the storage to one byte per
// element on every port. Public predicates still return bool via
// implicit coercion.
extern uint8_t gKeyState[KEY_COUNT];
extern uint8_t gKeyPrev [KEY_COUNT];

extern bool    gMouseAttached;
extern int16_t gMouseX;
extern int16_t gMouseY;
extern uint8_t gMouseButtonState[MOUSE_BUTTON_COUNT];
extern uint8_t gMouseButtonPrev [MOUSE_BUTTON_COUNT];

extern uint8_t gJoyConnected[JOYSTICK_COUNT];
extern int8_t  gJoyAxisX    [JOYSTICK_COUNT];
extern int8_t  gJoyAxisY    [JOYSTICK_COUNT];
extern uint8_t gJoyButtonState[JOYSTICK_COUNT][JOY_BUTTON_COUNT];
extern uint8_t gJoyButtonPrev [JOYSTICK_COUNT][JOY_BUTTON_COUNT];

// Per-stick analog calibration. Set by jlJoystickReset on platforms
// with analog paddles (IIgs); ignored on digital-stick platforms.
extern uint8_t gJoyDeadZone  [JOYSTICK_COUNT];

// Typed-character FIFO backing jlInputGetChar. Ports feed it with
// jlInputCharPush from jlpInputPoll; the pop side is jlInputGetChar.
// NOT interrupt-safe: ports whose keyboard handling runs at interrupt
// time (DOS INT 9, ST ikbd) buffer translated characters in their own
// volatile ring and drain it into this queue at poll time.
extern uint8_t gCharQueue    [JL_CHAR_QUEUE_SIZE];
extern uint8_t gCharQueueHead;
extern uint8_t gCharQueueTail;

// Append one translated character to the typed-character queue.
// Filters to the documented set (printable 0x20..0x7E plus
// JL_CHAR_BACKSPACE/TAB/RETURN/ESCAPE); anything else is discarded,
// so ports may push every translated byte without pre-filtering.
// Drops the character when the queue is full (drop-newest).
void jlInputCharPush(uint8_t ch);

// Empty the typed-character queue. Called by jlInit so a re-init
// never hands the app characters typed before/during a previous run.
void jlInputCharReset(void);

// (jlpJoystickReset hook -- called from jlJoystickReset to clear any auto-
//  disconnect state and arm a fresh center capture -- is declared with the
//  other platform-only services in src/core/port.h.)

#endif
