-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathcontroller.c
91 lines (77 loc) · 3.25 KB
/
controller.c
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
#include "controller.h"
#include <string.h>
static void Controller_DoMicroseconds(Controller* const controller, const cc_u16f microseconds)
{
if (controller->countdown >= microseconds)
{
controller->countdown -= microseconds;
}
else
{
controller->countdown = 0;
controller->strobes = 0;
}
}
static cc_bool Controller_GetButtonBit(Controller* const controller, const void *user_data, const Controller_Button button)
{
return !controller->callback((void*)user_data, button);
}
void Controller_Initialise(Controller* const controller, const Controller_Callback callback)
{
memset(controller, 0, sizeof(*controller));
controller->callback = callback;
}
cc_u8f Controller_Read(Controller* const controller, const cc_u16f microseconds, const void *user_data)
{
Controller_DoMicroseconds(controller, microseconds);
if (controller->th_bit)
{
switch (controller->strobes)
{
default:
return (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_C) << 5)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_B) << 4)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_RIGHT) << 3)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_LEFT) << 2)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_DOWN) << 1)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_UP) << 0);
case 3:
return (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_C) << 5)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_B) << 4)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_MODE) << 3)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_X) << 2)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_Y) << 1)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_Z) << 0);
}
}
else
{
switch (controller->strobes)
{
default:
return (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_START) << 5)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_A) << 4)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_DOWN) << 1)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_UP) << 0);
case 2:
return (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_START) << 5)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_A) << 4);
case 3:
return (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_START) << 5)
| (Controller_GetButtonBit(controller, user_data, CONTROLLER_BUTTON_A) << 4)
| 0xF;
}
}
}
void Controller_Write(Controller* const controller, const cc_u8f value, const cc_u16f microseconds)
{
const cc_bool new_th_bit = (value & 0x40) != 0;
Controller_DoMicroseconds(controller, microseconds);
/* TODO: The 1us latch time! Doesn't Decap Attack rely on that? */
if (new_th_bit && !controller->th_bit)
{
controller->strobes = (controller->strobes + 1) % 4;
controller->countdown = 1500; /* 1.5ms */
}
controller->th_bit = new_th_bit;
}