2 * Skelton for retropc emulator
4 * Author : Takeda.Toshiya
6 * Converted to QT by (C) 2015 K.Ohta
8 * Jan 12, 2015 (maybe) : Initial
9 * [ SDL input -> Keyboard]
19 #include "qt_gldraw.h"
21 #include "menuclasses.h"
22 #include "agar_logger.h"
25 #define Ulong unsigned long
28 #define KEY_KEEP_FRAMES 3
32 void EMU::initialize_input()
35 memset(key_status, 0, sizeof(key_status));
36 memset(joy_status, 0, sizeof(joy_status));
37 memset(mouse_status, 0, sizeof(mouse_status));
39 // initialize joysticks
40 // mouse emulation is disenabled
41 mouse_enabled = false;
42 joy_num = SDL_NumJoysticks();
43 for(int i = 0; i < joy_num && i < 2; i++) {
44 joy_mask[i] = 0x0f; // 4buttons
46 // initialize keycode convert table
47 FILEIO* fio = new FILEIO();
48 if(fio->Fopen(bios_path(_T("keycode.cfg")), FILEIO_READ_BINARY)) {
49 fio->Fread(keycode_conv, sizeof(keycode_conv), 1);
52 for(int i = 0; i < 256; i++) {
58 #ifdef USE_SHIFT_NUMPAD_KEY
59 // initialize shift+numpad conversion
60 memset(key_converted, 0, sizeof(key_converted));
61 key_shift_pressed = key_shift_released = false;
65 autokey_buffer = new FIFO(65536);
66 autokey_buffer->clear();
67 autokey_phase = autokey_shift = 0;
72 void EMU::release_input()
80 // release autokey buffer
82 autokey_buffer->release();
83 delete autokey_buffer;
89 void EMU::update_input()
94 #ifdef USE_SHIFT_NUMPAD_KEY
95 //update numpad key status
96 if(key_shift_pressed && !key_shift_released) {
97 if(key_status[VK_SHIFT] == 0) {
98 // shift key is newly pressed
99 key_status[VK_SHIFT] = 0x80;
100 # ifdef NOTIFY_KEY_DOWN
101 vm->key_down(VK_SHIFT, false);
104 } else if(!key_shift_pressed && key_shift_released) {
105 if(key_status[VK_SHIFT] != 0) {
106 // shift key is newly released
107 key_status[VK_SHIFT] = 0;
108 # ifdef NOTIFY_KEY_DOWN
109 vm->key_up(VK_SHIFT);
112 if(!(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
113 if(!(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
116 key_shift_pressed = key_shift_released = false;
121 if(lost_focus && autokey_phase == 0) {
125 // we lost key focus so release all pressed keys
126 for(int i = 0; i < 256; i++) {
127 if(key_status[i] & 0x80) {
128 key_status[i] &= 0x7f;
129 #ifdef NOTIFY_KEY_DOWN
137 for(int i = 0; i < 256; i++) {
138 if(key_status[i] & 0x7f) {
139 key_status[i] = (key_status[i] & 0x80) | ((key_status[i] & 0x7f) - 1);
140 #ifdef NOTIFY_KEY_DOWN
150 // update joystick status
151 #ifdef USE_KEY_TO_JOY
152 // emulate joystick #1 with keyboard
153 if(key_status[0x26]) joy_status[0] |= 0x01; // up
154 if(key_status[0x28]) joy_status[0] |= 0x02; // down
155 if(key_status[0x25]) joy_status[0] |= 0x04; // left
156 if(key_status[0x27]) joy_status[0] |= 0x08; // right
157 #ifdef KEY_TO_JOY_BUTTON_U
158 if(key_status[KEY_TO_JOY_BUTTON_U]) joy_status[0] |= 0x01;
160 #ifdef KEY_TO_JOY_BUTTON_D
161 if(key_status[KEY_TO_JOY_BUTTON_D]) joy_status[0] |= 0x02;
163 #ifdef KEY_TO_JOY_BUTTON_L
164 if(key_status[KEY_TO_JOY_BUTTON_L]) joy_status[0] |= 0x04;
166 #ifdef KEY_TO_JOY_BUTTON_R
167 if(key_status[KEY_TO_JOY_BUTTON_R]) joy_status[0] |= 0x08;
169 #ifdef KEY_TO_JOY_BUTTON_1
170 if(key_status[KEY_TO_JOY_BUTTON_1]) joy_status[0] |= 0x10;
172 #ifdef KEY_TO_JOY_BUTTON_2
173 if(key_status[KEY_TO_JOY_BUTTON_2]) joy_status[0] |= 0x20;
175 #ifdef KEY_TO_JOY_BUTTON_3
176 if(key_status[KEY_TO_JOY_BUTTON_3]) joy_status[0] |= 0x40;
178 #ifdef KEY_TO_JOY_BUTTON_4
179 if(key_status[KEY_TO_JOY_BUTTON_4]) joy_status[0] |= 0x80;
184 // update mouse status
185 memset(mouse_status, 0, sizeof(mouse_status));
188 // get current status
191 ScreenToClient(main_window_handle, &pt);
192 mouse_status[0] = pt.x - display_width / 2;
193 mouse_status[1] = pt.y - display_height / 2;
194 mouse_status[2] = (GetAsyncKeyState(VK_LBUTTON, modkey_status) & 0x8000) ? 1 : 0;
195 mouse_status[2] |= (GetAsyncKeyState(VK_RBUTTON, modkey_status) & 0x8000) ? 2 : 0;
196 mouse_status[2] |= (GetAsyncKeyState(VK_MBUTTON, modkey_status) & 0x8000) ? 4 : 0;
197 // move mouse cursor to the center of window
198 if(!(mouse_status[0] == 0 && mouse_status[1] == 0)) {
199 pt.x = display_width / 2;
200 pt.y = display_height / 2;
201 // ClientToScreen(main_window_handle, &pt);
202 // SetCursorPos(pt.x, pt.y);
209 switch(autokey_phase) {
211 if(autokey_buffer && !autokey_buffer->empty()) {
212 // update shift key status
213 int shift = autokey_buffer->read_not_remove(0) & 0x100;
214 if(shift && !autokey_shift) {
215 key_down(VK_SHIFT, false);
216 } else if(!shift && autokey_shift) {
219 autokey_shift = shift;
224 if(autokey_buffer && !autokey_buffer->empty()) {
225 key_down(autokey_buffer->read_not_remove(0) & 0xff, false);
230 if(autokey_buffer && !autokey_buffer->empty()) {
231 key_up(autokey_buffer->read_not_remove(0) & 0xff);
235 case USE_AUTO_KEY_RELEASE:
236 if(autokey_buffer && !autokey_buffer->empty()) {
237 // wait enough while vm analyzes one line
238 if(autokey_buffer->read() == 0xd) {
244 if(autokey_buffer && !autokey_buffer->empty()) {
260 #ifdef USE_SHIFT_NUMPAD_KEY
261 static const int numpad_table[256] = {
262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264 // 0x00, 0x69, 0x63, 0x61, 0x67, 0x64, 0x68, 0x66, 0x62, 0x00, 0x00, 0x00, 0x00, 0x60, 0x6e, 0x00,
265 0x00, 0x69, 0x63, 0x61, 0x67, 0x64, 0x68, 0x66, 0x62, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, // remove shift + period
266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
282 void EMU::key_down(int sym, bool repeat)
284 bool keep_frames = false;
286 if(code == VK_SHIFT){
287 #ifndef USE_SHIFT_NUMPAD_KEY
288 if(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000) key_status[VK_LSHIFT] = 0x80;
289 if(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000) key_status[VK_RSHIFT] = 0x80;
290 if(GetAsyncKeyState(VK_SHIFT, modkey_status) & 0x8000) key_status[VK_LSHIFT] = 0x80;
291 if(!(key_status[VK_LSHIFT] || key_status[VK_RSHIFT])) key_status[VK_LSHIFT] = 0x80;
293 } else if(code == VK_LSHIFT){
294 #ifndef USE_SHIFT_NUMPAD_KEY
295 if(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000) key_status[VK_LSHIFT] = 0x80;
296 // if(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000) key_status[VK_RSHIFT] = 0x80;
297 if(!(key_status[VK_LSHIFT] || key_status[VK_RSHIFT])) key_status[VK_LSHIFT] = 0x80;
299 } else if(code == VK_RSHIFT){
300 #ifndef USE_SHIFT_NUMPAD_KEY
301 // if(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000) key_status[VK_LSHIFT] = 0x80;
302 if(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000) key_status[VK_RSHIFT] = 0x80;
303 if(!(key_status[VK_LSHIFT] || key_status[VK_RSHIFT])) key_status[VK_LSHIFT] = 0x80;
305 } else if(code == VK_CONTROL) {
306 if(GetAsyncKeyState(VK_LCONTROL, modkey_status) & 0x8000) key_status[VK_LCONTROL] = 0x80;
307 if(GetAsyncKeyState(VK_RCONTROL, modkey_status) & 0x8000) key_status[VK_RCONTROL] = 0x80;
308 if(!(key_status[VK_LCONTROL] || key_status[VK_RCONTROL])) key_status[VK_LCONTROL] = 0x80;
309 } else if(code == VK_MENU) {
310 if(GetAsyncKeyState(VK_LMENU, modkey_status) & 0x8000) key_status[VK_LMENU] = 0x80;
311 if(GetAsyncKeyState(VK_RMENU, modkey_status) & 0x8000) key_status[VK_RMENU] = 0x80;
312 if(!(key_status[VK_LMENU] || key_status[VK_RMENU])) key_status[VK_LMENU] = 0x80;
313 } else if(code == 0xf0) {
316 } else if(code == 0xf2) {
319 } else if(code == 0xf3 || code == 0xf4) {
324 # ifdef USE_SHIFT_NUMPAD_KEY
325 if(code == VK_SHIFT) {
326 key_shift_pressed = true;
327 key_shift_released = false;
329 } else if(numpad_table[code] != 0) {
330 if(key_shift_pressed || key_shift_released) {
331 key_converted[code] = 1;
332 key_shift_pressed = true;
333 key_shift_released = false;
334 code = numpad_table[code];
339 if(!(code == VK_CONTROL || code == VK_MENU || code == VK_SHIFT)) {
340 code = keycode_conv[code];
343 #ifdef DONT_KEEEP_KEY_PRESSED
344 if(!(code == VK_CONTROL || code == VK_MENU || code == VK_SHIFT)) {
345 key_status[code] = KEY_KEEP_FRAMES;
349 key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80;
350 #ifdef NOTIFY_KEY_DOWN
354 vm->key_down(code, repeat);
360 void EMU::key_up(int sym)
363 if(code == VK_SHIFT) {
364 #ifndef USE_SHIFT_NUMPAD_KEY
365 if(!(GetAsyncKeyState(VK_SHIFT, modkey_status) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
366 // if(!(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
368 } else if(code == VK_LSHIFT) {
369 #ifndef USE_SHIFT_NUMPAD_KEY
370 if(!(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
371 // if(!(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
373 } else if(code == VK_RSHIFT) {
374 #ifndef USE_SHIFT_NUMPAD_KEY
375 // if(!(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
376 if(!(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
378 } else if(code == VK_CONTROL) {
379 if(!(GetAsyncKeyState(VK_LCONTROL, modkey_status) & 0x8000)) key_status[VK_LCONTROL] &= 0x7f;
380 if(!(GetAsyncKeyState(VK_RCONTROL, modkey_status) & 0x8000)) key_status[VK_RCONTROL] &= 0x7f;
381 } else if(code == VK_MENU) {
382 if(!(GetAsyncKeyState(VK_LMENU, modkey_status) & 0x8000)) key_status[VK_LMENU] &= 0x7f;
383 if(!(GetAsyncKeyState(VK_RMENU, modkey_status) & 0x8000)) key_status[VK_RMENU] &= 0x7f;
385 key_status[code] &= 0x7f;
386 #ifdef NOTIFY_KEY_DOWN
391 #ifdef USE_SHIFT_NUMPAD_KEY
392 if((code == VK_SHIFT) || (code == VK_RSHIFT) || (code == VK_LSHIFT)) {
393 key_shift_pressed = false;
394 key_shift_released = true;
396 } else if(key_converted[code] != 0) {
397 key_converted[code] = 0;
398 code = numpad_table[code];
402 if(!(code == VK_SHIFT || code == VK_CONTROL || code == VK_MENU)) {
403 code = keycode_conv[code];
405 if(key_status[code]) {
406 key_status[code] &= 0x7f;
407 #ifdef NOTIFY_KEY_DOWN
408 if(!key_status[code]) {
417 void EMU::press_button(int num)
419 int code = buttons[num].code;
422 key_down(code, false);
423 key_status[code] = KEY_KEEP_FRAMES;
425 // code=0: reset virtual machine
432 void EMU::enable_mouse()
434 // enable mouse emulation
439 // move mouse cursor to the center of window
441 pt.x = display_width / 2;
442 pt.y = display_height / 2;
443 ClientToScreen(main_window_handle, &pt);
444 SetCursorPos(pt.x, pt.y);
447 mouse_enabled = true;
453 void EMU::disenable_mouse()
456 // disenable mouse emulation
461 mouse_enabled = false;
464 void EMU::toggle_mouse()
466 // toggle mouse enable / disenable
475 static const int autokey_table[256] = {
480 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x00d,0x000,0x000,0x00d,0x000,0x000,
481 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
482 0x020,0x131,0x132,0x133,0x134,0x135,0x136,0x137,0x138,0x139,0x1ba,0x1bb,0x0bc,0x0bd,0x0be,0x0bf,
483 0x030,0x031,0x032,0x033,0x034,0x035,0x036,0x037,0x038,0x039,0x0ba,0x0bb,0x1bc,0x1bd,0x1be,0x1bf,
484 0x0c0,0x441,0x442,0x443,0x444,0x445,0x446,0x447,0x448,0x449,0x44a,0x44b,0x44c,0x44d,0x44e,0x44f,
485 0x450,0x451,0x452,0x453,0x454,0x455,0x456,0x457,0x458,0x459,0x45a,0x0db,0x0dc,0x0dd,0x0de,0x1e2,
486 0x1c0,0x841,0x842,0x843,0x844,0x845,0x846,0x847,0x848,0x849,0x84a,0x84b,0x84c,0x84d,0x84e,0x84f,
487 0x850,0x851,0x852,0x853,0x854,0x855,0x856,0x857,0x858,0x859,0x85a,0x1db,0x1dc,0x1dd,0x1de,0x000,
488 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
489 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
491 0x000,0x3be,0x3db,0x3dd,0x3bc,0x3bf,0x330,0x333,0x345,0x334,0x335,0x336,0x337,0x338,0x339,0x35a,
492 0x2dc,0x233,0x245,0x234,0x235,0x236,0x254,0x247,0x248,0x2ba,0x242,0x258,0x244,0x252,0x250,0x243,
493 0x251,0x241,0x25a,0x257,0x253,0x255,0x249,0x231,0x2bc,0x24b,0x246,0x256,0x232,0x2de,0x2bd,0x24a,
494 0x24e,0x2dd,0x2bf,0x24d,0x237,0x238,0x239,0x24f,0x24c,0x2be,0x2bb,0x2e2,0x230,0x259,0x2c0,0x2db,
496 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
497 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000
500 void EMU::start_auto_key()
505 if(OpenClipboard(NULL)) {
506 HANDLE hClip = GetClipboardData(CF_TEXT);
508 autokey_buffer->clear();
509 char* buf = (char*)GlobalLock(hClip);
510 int size = strlen(buf), prev_kana = 0;
511 for(int i = 0; i < size; i++) {
512 int code = buf[i] & 0xff;
513 if((0x81 <= code && code <= 0x9f) || 0xe0 <= code) {
516 } else if(code == 0xa) {
519 if((code = autokey_table[code]) != 0) {
520 int kana = code & 0x200;
521 if(prev_kana != kana) {
522 autokey_buffer->write(0xf2);
525 #if defined(USE_AUTO_KEY_NO_CAPS)
526 if((code & 0x100) && !(code & (0x400 | 0x800))) {
527 #elif defined(USE_AUTO_KEY_CAPS)
528 if(code & (0x100 | 0x800)) {
530 if(code & (0x100 | 0x400)) {
532 autokey_buffer->write((code & 0xff) | 0x100);
534 autokey_buffer->write(code & 0xff);
539 autokey_buffer->write(0xf2);
551 void EMU::stop_auto_key()
557 autokey_phase = autokey_shift = 0;
563 JoyThreadClass::JoyThreadClass(QObject *parent) : QThread(parent)
566 for(i = 0; i < 2; i++) joyhandle[i] = SDL_JoystickOpen(i);
567 joy_num = SDL_NumJoysticks();
568 AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : Start.");
572 JoyThreadClass::~JoyThreadClass()
575 for(i = 0; i < 2; i++) {
576 if(joyhandle[i] != NULL) SDL_JoystickClose(joyhandle[i]);
578 AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : EXIT");
581 void JoyThreadClass::x_axis_changed(int index, int value)
583 if(p_emu == NULL) return;
585 uint32_t *joy_status = p_emu->getJoyStatPtr();
587 if(joy_status != NULL) {
588 if(value < -8192) { // left
589 joy_status[index] |= 0x04; joy_status[index] &= ~0x08;
590 } else if(value > 8192) { // right
591 joy_status[index] |= 0x08; joy_status[index] &= ~0x04;
593 joy_status[index] &= ~0x0c;
599 void JoyThreadClass::y_axis_changed(int index, int value)
601 if(p_emu == NULL) return;
603 uint32_t *joy_status = p_emu->getJoyStatPtr();
605 if(joy_status != NULL) {
606 if(value < -8192) {// up
607 joy_status[index] |= 0x01; joy_status[index] &= ~0x02;
608 } else if(value > 8192) {// down
609 joy_status[index] |= 0x02; joy_status[index] &= ~0x01;
611 joy_status[index] &= ~0x03;
617 void JoyThreadClass::button_down(int index, unsigned int button)
619 if(p_emu == NULL) return;
621 uint32_t *joy_status = p_emu->getJoyStatPtr();
622 if(joy_status != NULL) {
623 joy_status[index] |= (1 << (button + 4));
628 void JoyThreadClass::button_up(int index, unsigned int button)
630 if(p_emu == NULL) return;
633 uint32_t *joy_status = p_emu->getJoyStatPtr();
634 if(joy_status != NULL) {
635 joy_status[index] &= ~(1 << (button + 4));
641 bool JoyThreadClass::EventSDL(SDL_Event *eventQueue)
650 if(eventQueue == NULL) return false;
652 * JoyStickなどはSDLが管理する
654 switch (eventQueue->type){
655 case SDL_JOYAXISMOTION:
656 value = eventQueue->jaxis.value;
657 i = eventQueue->jaxis.which;
658 if((i < 0) || (i > 1)) break;
660 if(eventQueue->jaxis.axis == 0) { // X
661 x_axis_changed(i, value);
662 } else if(eventQueue->jaxis.axis == 1) { // Y
663 y_axis_changed(i, value);
666 case SDL_JOYBUTTONDOWN:
667 button = eventQueue->jbutton.button;
668 i = eventQueue->jbutton.which;
669 if((i < 0) || (i > 1)) break;
670 button_down(i, button);
672 case SDL_JOYBUTTONUP:
673 button = eventQueue->jbutton.button;
674 i = eventQueue->jbutton.which;
675 if((i < 0) || (i > 1)) break;
676 button_up(i, button);
685 void JoyThreadClass::doWork(const QString ¶ms)
688 if(bRunThread == false) {
691 while(SDL_PollEvent(&event) == 1) {
696 //timer.setInterval(5);
700 void JoyThreadClass::doExit(void)
706 void Ui_MainWindow::LaunchJoyThread(void)
708 hRunJoy = new JoyThreadClass(this);
709 hRunJoy->SetEmu(emu);
710 connect(this, SIGNAL(quit_joy_thread()), hRunJoy, SLOT(doExit()));
711 hRunJoy->setObjectName("JoyThread");
714 void Ui_MainWindow::StopJoyThread(void)
716 emit quit_joy_thread();
719 void Ui_MainWindow::delete_joy_thread(void)
721 // delete hRunJoyThread;