root / lab4 / state_machine.c @ 360
History | View | Annotate | Download (4.68 KB)
1 |
#include <lcom/lcf.h> |
---|---|
2 |
|
3 |
#include "state_machine.h" |
4 |
#include "mouse_macros.h" |
5 |
#include "mouse.h" |
6 |
#include "errors.h" |
7 |
#include "utils.h" |
8 |
|
9 |
struct mouse_ev* mouse_get_event(struct packet *pp) { |
10 |
static struct mouse_ev event; |
11 |
static uint8_t last = 0; |
12 |
|
13 |
if (pp == NULL) |
14 |
return &event;
|
15 |
|
16 |
// current button presses
|
17 |
uint8_t button_presses = pp->bytes[0] & (LEFT_BUTTON | RIGHT_BUTTON | MIDDLE_BUTTON);
|
18 |
int16_t delta_x = pp->delta_x; |
19 |
int16_t delta_y = pp->delta_y; |
20 |
|
21 |
if ((button_presses ^ last) == LEFT_BUTTON && !(last & LEFT_BUTTON)) {
|
22 |
event.type = LB_PRESSED; |
23 |
last |= LEFT_BUTTON; |
24 |
|
25 |
} else if ((button_presses ^ last) == RIGHT_BUTTON && !(last & RIGHT_BUTTON)) { |
26 |
event.type = RB_PRESSED; |
27 |
last |= RIGHT_BUTTON; |
28 |
|
29 |
} else if ((button_presses ^ last) == LEFT_BUTTON && (last & LEFT_BUTTON)) { |
30 |
event.type = LB_RELEASED; |
31 |
last &= ~LEFT_BUTTON; |
32 |
|
33 |
} else if ((button_presses ^ last) == RIGHT_BUTTON && (last & RIGHT_BUTTON)) { |
34 |
event.type = RB_RELEASED; |
35 |
last &= ~RIGHT_BUTTON; |
36 |
|
37 |
} else if ((delta_x || delta_y) && (button_presses == last)) { |
38 |
event.type = MOUSE_MOV; |
39 |
|
40 |
} else
|
41 |
event.type = BUTTON_EV; |
42 |
|
43 |
event.delta_x = delta_x; |
44 |
event.delta_y = delta_y; |
45 |
return &event;
|
46 |
} |
47 |
|
48 |
int state_machine(struct mouse_ev* event, uint8_t x_len, uint8_t tolerance) { |
49 |
|
50 |
static enum states state = INITIAL; |
51 |
static int response = OTHER_ERROR; |
52 |
static int x_length = 0; |
53 |
static int y_length = 0; |
54 |
|
55 |
if (event == NULL) |
56 |
return response;
|
57 |
|
58 |
switch (state) {
|
59 |
case INITIAL:
|
60 |
if (event->type == LB_PRESSED)
|
61 |
state = DRAG_UP; |
62 |
break;
|
63 |
case DRAG_UP:
|
64 |
if (event->type == MOUSE_MOV) {
|
65 |
if (event->delta_x < -tolerance || event->delta_y < -tolerance) {
|
66 |
state = INITIAL; |
67 |
x_length = 0;
|
68 |
y_length = 0;
|
69 |
break;
|
70 |
} |
71 |
|
72 |
x_length += event->delta_x; |
73 |
y_length += event->delta_y; |
74 |
} else if (event->type == LB_RELEASED) { |
75 |
if (y_length < x_length || x_length < x_len) {
|
76 |
state = INITIAL; |
77 |
x_length = 0;
|
78 |
y_length = 0;
|
79 |
break;
|
80 |
} |
81 |
|
82 |
state = VERTEX; |
83 |
x_length = 0;
|
84 |
y_length = 0;
|
85 |
} else {
|
86 |
state = INITIAL; |
87 |
x_length = 0;
|
88 |
y_length = 0;
|
89 |
} |
90 |
break;
|
91 |
case VERTEX:
|
92 |
if (event->type == MOUSE_MOV) {
|
93 |
x_length += event->delta_x; |
94 |
y_length += event->delta_y; |
95 |
if (abs(x_length) > tolerance || abs(y_length) > tolerance) {
|
96 |
state = INITIAL; |
97 |
x_length = 0;
|
98 |
y_length = 0;
|
99 |
} |
100 |
} else if (event->type == RB_PRESSED) { |
101 |
state = DRAG_DOWN; |
102 |
x_length = 0;
|
103 |
y_length = 0;
|
104 |
} else if (event->type == LB_PRESSED) { |
105 |
state = DRAG_UP; |
106 |
x_length = 0;
|
107 |
y_length = 0;
|
108 |
} else {
|
109 |
state = INITIAL; |
110 |
x_length = 0;
|
111 |
y_length = 0;
|
112 |
} |
113 |
break;
|
114 |
case DRAG_DOWN:
|
115 |
if (event->type == MOUSE_MOV) {
|
116 |
if (event->delta_x < -tolerance || event->delta_y > tolerance) {
|
117 |
state = INITIAL; |
118 |
x_length = 0;
|
119 |
y_length = 0;
|
120 |
break;
|
121 |
} |
122 |
|
123 |
x_length += event->delta_x; |
124 |
y_length += event->delta_y; |
125 |
} else if (event->type == RB_RELEASED) { |
126 |
if (x_length == 0 || y_length == 0) { |
127 |
state = INITIAL; |
128 |
break;
|
129 |
} |
130 |
|
131 |
if (y_length > -x_length || x_length < x_len) {
|
132 |
state = INITIAL; |
133 |
x_length = 0;
|
134 |
y_length = 0;
|
135 |
break;
|
136 |
} |
137 |
|
138 |
state = FINAL; |
139 |
response = SUCCESS; |
140 |
x_length = 0;
|
141 |
y_length = 0;
|
142 |
} else {
|
143 |
state = INITIAL; |
144 |
x_length = 0;
|
145 |
y_length = 0;
|
146 |
} |
147 |
break;
|
148 |
case FINAL: // acception state |
149 |
response = SUCCESS; |
150 |
default: // invalid state / dead state |
151 |
response = INVALID_STATE; |
152 |
} |
153 |
return response;
|
154 |
} |