aboutsummaryrefslogtreecommitdiff
path: root/src/joy.c
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-07-22 13:58:05 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-07-22 13:58:22 +0100
commit9ecd65467232071b18a7c6f782a22264046ebf45 (patch)
tree1a6110a495069900ac70b53d9d2746152aab1202 /src/joy.c
parentd6f7ac4c09ffb0717467790d9acc27df75e25b21 (diff)
downloadgold-mine-run-9ecd65467232071b18a7c6f782a22264046ebf45.tar.gz
gold-mine-run-9ecd65467232071b18a7c6f782a22264046ebf45.zip
Joystick support
Diffstat (limited to 'src/joy.c')
-rw-r--r--src/joy.c123
1 files changed, 123 insertions, 0 deletions
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 <stdint.h>
+#include <stdio.h>
+#include <pc.h>
+#include <dos.h>
+
+#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;
+}