From 9ecd65467232071b18a7c6f782a22264046ebf45 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Sat, 22 Jul 2023 13:58:05 +0100 Subject: Joystick support --- src/joy.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/joy.c (limited to 'src/joy.c') diff --git a/src/joy.c b/src/joy.c new file mode 100644 index 0000000..cda2fcf --- /dev/null +++ b/src/joy.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include + +#include "vga.h" +#include "keyb.h" +#include "control.h" + +#include "joy.h" + +#define PORT 0x201 + +#define BUTTON1 0x10 +#define BUTTON2 0x20 +#define AXISX 1 +#define AXISY 2 + +#define TIMEOUT 16000 + +static uint16_t j_up, j_down, j_left, j_right; + +static uint16_t read_axis(uint8_t axis) +{ + uint16_t i; + + disable(); + outportb(PORT, 0xff); + for (i = 0; i < TIMEOUT; i++) + if (!(inportb(PORT) & axis)) + break; + enable(); + + return i; +} + +static uint8_t calibrate(uint16_t *v, uint16_t *h) +{ + while (1) + { + if (keys[KEY_ESC]) + { + while (keys[KEY_ESC]) + wait_vsync(); + return 0; + } + + *v = read_axis(AXISY); + *h = read_axis(AXISX); + + if (!(inportb(PORT) & BUTTON1)) + { + while (!(inportb(PORT) & BUTTON1)) + wait_vsync(); + return 1; + } + + wait_vsync(); + } +} + +uint8_t joy_detect() +{ + if (read_axis(AXISX) == TIMEOUT) + return 0; + + printf("Joystick detected!\n"); + + printf("Please move UP + LEFT and press BUTTON 1 (ESC to abort)\n"); + if (!calibrate(&j_up, &j_left)) + return 0; + printf("Please move DOWN + RIGHT and press BUTTON 1 (ESC to abort)\n"); + if (!calibrate(&j_down, &j_right)) + return 0; + +#ifdef DEBUG + printf("Joystick reads: up=%04d, down=%04d, left=%04d, right=%04d\n", + j_up, j_down, j_left, j_right); +#endif + + j_up += j_up >> 4; + j_down -= j_down >> 4; + j_left += j_left >> 4; + j_right -= j_right >> 4; + +#ifdef DEBUG + printf(" Adjusted: up=%04d, down=%04d, left=%04d, right=%04d\n", + j_up, j_down, j_left, j_right); + + printf("(press X to continue)\n"); + while (!keys[KEY_X]) + wait_vsync(); +#endif + + return 1; +} + +uint8_t joy_read() +{ + uint8_t r = CTL_NONE; + uint8_t b; + uint16_t v; + + b = inportb(PORT); + if (!(b & BUTTON1)) + r |= CTL_FIRE1; + if (!(b & BUTTON2)) + r |= CTL_FIRE2; + + v = read_axis(AXISY); + if (v <= j_up) + r |= CTL_UP; + if (v >= j_down) + r |= CTL_DOWN; + + v = read_axis(AXISX); + if (v <= j_left) + r |= CTL_LEFT; + if (v >= j_right) + r |= CTL_RIGHT; + + return r; +} -- cgit v1.2.3