1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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;
}
|