Commit | Line | Data |
---|---|---|
cf76e892 JPM |
1 | // |
2 | // controllerwidget.cpp: A widget for changing "Controller" configuration | |
3 | // | |
4 | // Part of the Virtual Jaguar Project | |
5 | // (C) 2011 Underground Software | |
6 | // See the README and GPLv3 files for licensing and warranty information | |
7 | // | |
8 | // JLH = James Hammons <jlhamm@acm.org> | |
9 | // | |
10 | // WHO WHEN WHAT | |
11 | // --- ---------- ------------------------------------------------------------ | |
12 | // JLH 07/20/2011 Created this file | |
13 | // | |
14 | ||
15 | #include "controllerwidget.h" | |
16 | ||
17 | #include "joystick.h" | |
18 | #include "gamepad.h" | |
19 | #include "keygrabber.h" | |
20 | ||
21 | ||
22 | // These tables are used to convert Qt keycodes into human readable form. Note | |
23 | // that a lot of these are just filler. | |
24 | char ControllerWidget::keyName1[96][16] = { | |
25 | "Space", | |
26 | "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", | |
27 | "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", | |
28 | "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", | |
29 | "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", | |
30 | "[", "\\", "]", "^", "_", "`", | |
31 | "$61", "$62", "$63", "$64", "$65", "$66", "$67", "$68", "$69", "$6A", "$6B", "$6C", "$6D", | |
32 | "$6E", "$6F", "$70", "$71", "$72", "$73", "$74", "$75", "$76", "$77", "$78", "$79", "$7A", | |
33 | "{", "|", "}", "~" | |
34 | }; | |
35 | ||
36 | char ControllerWidget::keyName2[64][16] = { | |
37 | "Esc", "Tab", "BTab", "BS", "Ret", "Ent", "Ins", "Del", "Pause", "Prt", "SRq", "Clr", | |
38 | "$C", "$D", "$E", "$F", "Hm", "End", "Lf", "Up", "Rt", "Dn", "PgU", "PgD", "$18", | |
39 | "$19", "$1A", "$1B", "$1C", "$1D", "$1E", "$1F", "Shf", "Ctl", "Mta", "Alt", | |
40 | "Cap", "Num", "ScL", "$27", "$28", "$29", "$2A", "$2B", "$2C", "$2D", "$2E", "$2F", | |
41 | "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", | |
42 | "F14", "F15", "F16" | |
43 | }; | |
44 | ||
45 | char ControllerWidget::hatName[4][16] = { "Up", "Rt", "Dn", "Lf" }; | |
46 | ||
47 | char ControllerWidget::axisName[2][8] = { "+", "-" }; | |
48 | ||
49 | // This is hard-coded crap. It's crap-tastic! | |
50 | // These are the positions to draw the button names at, ordered by the BUTTON_* | |
51 | // sequence found in joystick.h. | |
52 | int ControllerWidget::buttonPos[21][2] = { { 74, 32 }, { 71, 67 }, { 53, 49 }, { 93, 49 }, | |
53 | { 110, 200 }, { 110, 175 }, { 110, 151 }, { 110, 126 }, | |
54 | { 148, 200 }, { 148, 175 }, { 148, 151 }, { 148, 126 }, | |
55 | { 186, 200 }, { 186, 175 }, { 186, 151 }, { 186, 126 }, | |
56 | { 234, 31 }, { 216, 51 }, { 199, 71 }, { 164-11, 101-30 }, { 141-11, 108+13-30 } | |
57 | }; | |
58 | ||
59 | ||
60 | ControllerWidget::ControllerWidget(QWidget * parent/*= 0*/): QWidget(parent), | |
61 | controllerPic(":/res/controller.png"), widgetSize(controllerPic.size()), | |
62 | keyToHighlight(-1), mouseDown(false) | |
63 | { | |
64 | // Seems we have to pad this stuff, otherwise it clips on the right side | |
65 | widgetSize += QSize(4, 4); | |
66 | // We want to know when the mouse is moving over our widget... | |
67 | setMouseTracking(true); | |
68 | //nope | |
69 | //setFixedSize(widgetSize); | |
70 | } | |
71 | ||
72 | ||
73 | ControllerWidget::~ControllerWidget() | |
74 | { | |
75 | } | |
76 | ||
77 | ||
78 | QSize ControllerWidget::sizeHint(void) const | |
79 | { | |
80 | return widgetSize; | |
81 | } | |
82 | ||
83 | ||
84 | QSizePolicy ControllerWidget::sizePolicy(void) const | |
85 | { | |
86 | return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); | |
87 | } | |
88 | ||
89 | ||
90 | void ControllerWidget::paintEvent(QPaintEvent * /*event*/) | |
91 | { | |
92 | QPainter painter(this); | |
93 | painter.setRenderHint(QPainter::Antialiasing); | |
94 | painter.drawImage(QPoint(0, 0), controllerPic); | |
95 | ||
96 | // Bump up the size of the default font... | |
97 | QFont font = painter.font(); | |
98 | font.setPixelSize(15); | |
99 | font.setBold(true); | |
100 | painter.setFont(font); | |
101 | // painter.setPen(QColor(48, 255, 255, 255)); // This is R,G,B,A | |
102 | painter.setPen(QColor(0, 0, 0, 255)); // This is R,G,B,A | |
103 | painter.setBrush(QBrush(QColor(48, 255, 255, 255))); | |
104 | ||
105 | // First, draw black oversize line, then dot, then colored line | |
106 | QPen blackPen(QColor(0, 0, 0, 255)); | |
107 | blackPen.setWidth(4); | |
108 | QPen colorPen(QColor(48, 255, 255, 255)); | |
109 | colorPen.setWidth(2); | |
110 | QLine line(QPoint(141-11, 100-30), QPoint(141-11, 108+5-30)); | |
111 | ||
112 | painter.setPen(blackPen); | |
113 | painter.drawLine(line); | |
114 | blackPen.setWidth(1); | |
115 | painter.setPen(blackPen); | |
116 | painter.drawEllipse(QPoint(141-11, 100-30), 4, 4); | |
117 | painter.setPen(colorPen); | |
118 | painter.drawLine(line); | |
119 | ||
120 | //#define DEBUG_CWPAINT | |
121 | #ifdef DEBUG_CWPAINT | |
122 | printf("------------------------------\n"); | |
123 | #endif | |
124 | for(int i=BUTTON_FIRST; i<=BUTTON_LAST; i++) | |
125 | { | |
126 | if (keyToHighlight == i) | |
127 | { | |
128 | painter.setPen(QColor(255, 48, 255, 255)); // This is R,G,B,A | |
129 | font.setPixelSize(mouseDown ? 15 : 18); | |
130 | painter.setFont(font); | |
131 | } | |
132 | else | |
133 | { | |
134 | painter.setPen(QColor(48, 255, 255, 255)); // This is R,G,B,A | |
135 | font.setPixelSize(15); | |
136 | painter.setFont(font); | |
137 | } | |
138 | ||
139 | #ifdef DEBUG_CWPAINT | |
140 | printf("key %02i: ", i); | |
141 | #endif | |
142 | ||
143 | if (keys[i] < 0x80) | |
144 | #ifdef DEBUG_CWPAINT | |
145 | { | |
146 | printf("Drawing a key < 0x80 [keys[i]=%X, keyname=%s]...\n", keys[i], keyName1[keys[i] - 0x20]); | |
147 | #endif | |
148 | DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1], | |
149 | QString(keyName1[keys[i] - 0x20])); | |
150 | #ifdef DEBUG_CWPAINT | |
151 | } | |
152 | #endif | |
153 | else if ((keys[i] & 0xFFFFFF00) == 0x01000000) | |
154 | { | |
155 | #ifdef DEBUG_CWPAINT | |
156 | printf("Drawing a key with bit 48 set...\n"); | |
157 | #endif | |
158 | DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1], | |
159 | QString(keyName2[keys[i] & 0x3F])); | |
160 | } | |
161 | #if 1 | |
162 | else if (keys[i] & JOY_BUTTON) | |
163 | { | |
164 | #ifdef DEBUG_CWPAINT | |
165 | printf("Drawing a joystick button...\n"); | |
166 | #endif | |
167 | DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1], | |
168 | QString("JB%1").arg(keys[i] & JOY_BUTTON_MASK)); | |
169 | } | |
170 | else if (keys[i] & JOY_HAT) | |
171 | { | |
172 | #ifdef DEBUG_CWPAINT | |
173 | printf("Drawing a joystick hat...\n"); | |
174 | #endif | |
175 | DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1], | |
176 | QString("j%1").arg(hatName[keys[i] & JOY_BUTTON_MASK])); | |
177 | } | |
178 | else if (keys[i] & JOY_AXIS) | |
179 | { | |
180 | #ifdef DEBUG_CWPAINT | |
181 | printf("Drawing a joystick axis...\n"); | |
182 | #endif | |
183 | DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1], | |
184 | QString("JA%1%2").arg((keys[i] & JOY_AXISNUM_MASK) >> 1).arg(axisName[keys[i] & JOY_AXISDIR_MASK])); | |
185 | } | |
186 | #endif | |
187 | else | |
188 | #ifdef DEBUG_CWPAINT | |
189 | { | |
190 | printf("Drawing ???...\n"); | |
191 | #endif | |
192 | DrawBorderedText(painter, buttonPos[i][0], buttonPos[i][1], QString("???")); | |
193 | #ifdef DEBUG_CWPAINT | |
194 | } | |
195 | #endif | |
196 | } | |
197 | } | |
198 | ||
199 | ||
200 | void ControllerWidget::mousePressEvent(QMouseEvent * /*event*/) | |
201 | { | |
202 | mouseDown = true; | |
203 | update(); | |
204 | } | |
205 | ||
206 | ||
207 | void ControllerWidget::mouseReleaseEvent(QMouseEvent * /*event*/) | |
208 | { | |
209 | mouseDown = false; | |
210 | // Spawning the keygrabber causes leaveEvent() to be called, so we need to | |
211 | // save this | |
212 | int keyToHighlightSave = keyToHighlight; | |
213 | ||
214 | KeyGrabber keyGrab(this); | |
215 | keyGrab.SetKeyText(keyToHighlightSave); | |
216 | keyGrab.exec(); | |
217 | int key = keyGrab.key; | |
218 | ||
219 | if (key != Qt::Key_Escape) | |
220 | { | |
221 | keys[keyToHighlightSave] = key; | |
222 | emit(KeyDefined(keyToHighlightSave, key)); | |
223 | } | |
224 | ||
225 | keyToHighlight = keyToHighlightSave; | |
226 | update(); | |
227 | } | |
228 | ||
229 | ||
230 | void ControllerWidget::mouseMoveEvent(QMouseEvent * event) | |
231 | { | |
232 | if (mouseDown) | |
233 | return; | |
234 | ||
235 | // Save the current closest item | |
236 | int keyToHighlightOld = keyToHighlight; | |
237 | // Set up closest distance (this should be large enough) | |
238 | double closest = 1e9; | |
239 | ||
240 | for(int i=BUTTON_FIRST; i<=BUTTON_LAST; i++) | |
241 | { | |
242 | // We loop through the button text positions, to see which one is | |
243 | // closest. | |
244 | double distX = (double)(event->x() - buttonPos[i][0]); | |
245 | double distY = (double)(event->y() - buttonPos[i][1]); | |
246 | double currentDistance = sqrt((distX * distX) + (distY * distY)); | |
247 | ||
248 | if (currentDistance < closest) | |
249 | { | |
250 | closest = currentDistance; | |
251 | keyToHighlight = i; | |
252 | } | |
253 | } | |
254 | ||
255 | if (keyToHighlightOld != keyToHighlight) | |
256 | update(); | |
257 | } | |
258 | ||
259 | ||
260 | void ControllerWidget::leaveEvent(QEvent * /*event*/) | |
261 | { | |
262 | keyToHighlight = -1; | |
263 | update(); | |
264 | } | |
265 | ||
266 | ||
267 | void ControllerWidget::DrawBorderedText(QPainter & painter, int x, int y, QString text) | |
268 | { | |
269 | // Text is drawn centered at (x, y) as well, using a bounding rect for the | |
270 | // purpose. | |
271 | QRect rect(0, 0, 60, 30); | |
272 | QPen oldPen = painter.pen(); | |
273 | painter.setPen(QColor(0, 0, 0, 255)); // This is R,G,B,A | |
274 | ||
275 | for(int i=-1; i<=1; i++) | |
276 | { | |
277 | for(int j=-1; j<=1; j++) | |
278 | { | |
279 | rect.moveCenter(QPoint(x + i, y + j)); | |
280 | painter.drawText(rect, Qt::AlignCenter, text); | |
281 | } | |
282 | } | |
283 | ||
284 | painter.setPen(oldPen); | |
285 | rect.moveCenter(QPoint(x, y)); | |
286 | painter.drawText(rect, Qt::AlignCenter, text); | |
287 | } | |
288 |