-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInputManager.c
176 lines (154 loc) · 5.78 KB
/
InputManager.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
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//
// Created by jamie on 15/10/17.
//
#include "Joystick.h"
#include "Potentiometer.h"
#include "Accelerometer.h"
#include "InputManager.h"
#include "Buttons.h"
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#define ACCELEROMETER_THRESHOLD 750
#define POTENTIOMETER_THRESHOLD 250
#define MILLISECONDS_PER_SECOND 1000
#define MICROSECONDS_PER_MILLISECOND 1000
#define EXTRA_TIME_FOR_BUTTON 400
#define EXTRA_TIME_FOR_VOICE 750
static int timeoutInMilliseconds;
static Input getJoystickInput(Direction joystickInput);
static Input getAccelerometerInput(Acceleration initialOrientation, Acceleration currentOrientation);
static char* inputStrings[NUMBER_OF_INPUTS];
void InputManager_init(int specifiedTimeoutInMilliseconds)
{
timeoutInMilliseconds = specifiedTimeoutInMilliseconds + (EXTRA_TIME_FOR_VOICE);
Joystick_init();
Potentiometer_init();
Accelerometer_init();
inputStrings[JOYSTICK_UP] = "Push UP on the joystick";
inputStrings[JOYSTICK_DOWN] = "Push DOWN on the joystick";
inputStrings[JOYSTICK_LEFT] = "Push LEFT on the joystick";
inputStrings[JOYSTICK_RIGHT] = "Push RIGHT on the joystick";
inputStrings[JOYSTICK_CENTER] = "Push the CENTER on the joystick";
inputStrings[ACCELEROMETER_TILT_LEFT] = "Tilt the board LEFT";
inputStrings[ACCELEROMETER_TILT_RIGHT] = "Tilt the board RIGHT";
inputStrings[ACCELEROMETER_PITCH_UP] = "Pitch the board UP";
inputStrings[ACCELEROMETER_PITCH_DOWN] = "Pitch the board DOWN";
inputStrings[POTENTIOMETER_TURN] = "Turn the potentiometer";
inputStrings[BUTTON_SEQUENCE] = "Push the buttons in the order the lights flash";
}
void InputManager_cleanup(void){
Joystick_cleanup();
Potentiometer_cleanup();
Accelerometer_cleanup();
return;
}
char* InputManager_getInputString(Input input){
return inputStrings[input];
}
Input InputManager_waitForInput(int* inputTimeMilliseconds){
struct timeval startTime;
struct timeval currentTime;
gettimeofday(&startTime, NULL);
Acceleration initialOrientation = Accelerometer_getAcceleration();
int initialVoltage = Potentiometer_getValue();
int millisecondsSinceStart = 0;
*inputTimeMilliseconds = 0;
while(millisecondsSinceStart < timeoutInMilliseconds){
Direction joystickInput = Joystick_getDirection();
if(joystickInput != NEUTRAL){
return getJoystickInput(joystickInput);
}
Acceleration currentOrientation = Accelerometer_getAcceleration();
if(abs(initialOrientation.x - currentOrientation.x) > (ACCELEROMETER_THRESHOLD) ||
abs(initialOrientation.y - currentOrientation.y) > (ACCELEROMETER_THRESHOLD)){
return getAccelerometerInput(initialOrientation, currentOrientation);
}
int currentVoltage = Potentiometer_getValue();
if(abs(initialVoltage - currentVoltage) > (POTENTIOMETER_THRESHOLD)){
return POTENTIOMETER_TURN;
}
gettimeofday(¤tTime, NULL);
millisecondsSinceStart = (currentTime.tv_sec - startTime.tv_sec) * (MILLISECONDS_PER_SECOND);
millisecondsSinceStart += (currentTime.tv_usec - startTime.tv_usec) / (MICROSECONDS_PER_MILLISECOND);
*inputTimeMilliseconds = millisecondsSinceStart;
}
*inputTimeMilliseconds = timeoutInMilliseconds;
return NO_INPUT;
}
static Input getJoystickInput(Direction joystickInput){
switch(joystickInput){
case UP:
return JOYSTICK_UP;
case DOWN:
return JOYSTICK_DOWN;
case LEFT:
return JOYSTICK_LEFT;
case RIGHT:
return JOYSTICK_RIGHT;
case CENTER:
return JOYSTICK_CENTER;
default:
return NO_INPUT;
}
}
static Input getAccelerometerInput(Acceleration initialOrientation, Acceleration currentOrientation){
if(currentOrientation.x - initialOrientation.x > (ACCELEROMETER_THRESHOLD)){
return ACCELEROMETER_TILT_RIGHT;
}
else if(currentOrientation.x - initialOrientation.x < (-ACCELEROMETER_THRESHOLD)){
return ACCELEROMETER_TILT_LEFT;
}
else if(currentOrientation.y - initialOrientation.y > (ACCELEROMETER_THRESHOLD)){
return ACCELEROMETER_PITCH_DOWN;
}
else if(currentOrientation.y - initialOrientation.y < (-ACCELEROMETER_THRESHOLD)){
return ACCELEROMETER_PITCH_UP;
}
return NO_INPUT;
}
int InputManager_readButtonSequence(int* inputTimeMilliseconds, LED *ledFlashes, int ledFlashCount)
{
struct timeval startTime;
struct timeval currentTime;
gettimeofday(&startTime, NULL);
int millisecondsSinceStart = 0;
int buttonTimeoutInMilliseconds = timeoutInMilliseconds + (ledFlashCount * (EXTRA_TIME_FOR_BUTTON));
printf("LED flash count: %d\n", ledFlashCount);
for(int i = 0;i < ledFlashCount && millisecondsSinceStart < buttonTimeoutInMilliseconds;i++)
{
printf("LED flash expected: %d\n", ledFlashes[i]);
int button;
do
{
button = Buttons_getButton();
gettimeofday(¤tTime, NULL);
millisecondsSinceStart = (currentTime.tv_sec - startTime.tv_sec) * (MILLISECONDS_PER_SECOND);
millisecondsSinceStart += (currentTime.tv_usec - startTime.tv_usec) / (MICROSECONDS_PER_MILLISECOND);
*inputTimeMilliseconds = millisecondsSinceStart;
if(millisecondsSinceStart >= buttonTimeoutInMilliseconds)
{
return 0;
}
}
while(button != -1);
do
{
button = Buttons_getButton();
gettimeofday(¤tTime, NULL);
millisecondsSinceStart = (currentTime.tv_sec - startTime.tv_sec) * (MILLISECONDS_PER_SECOND);
millisecondsSinceStart += (currentTime.tv_usec - startTime.tv_usec) / (MICROSECONDS_PER_MILLISECOND);
*inputTimeMilliseconds = millisecondsSinceStart;
if(millisecondsSinceStart >= buttonTimeoutInMilliseconds)
{
return 0;
}
}
while(button == -1);
if(button != ledFlashes[i])
{
return 0;
}
}
return 1;
}