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]
13 #include <QApplication>
20 #include "qt_gldraw.h"
22 //#include "menuclasses.h"
23 //#include "commonclasses.h"
24 #include "mainwidget.h"
25 #include "agar_logger.h"
28 #define Ulong unsigned long
31 #define KEY_KEEP_FRAMES 3
35 void EMU::initialize_input()
38 memset(key_status, 0, sizeof(key_status));
39 memset(joy_status, 0, sizeof(joy_status));
40 memset(mouse_status, 0, sizeof(mouse_status));
42 // initialize joysticks
43 // mouse emulation is disenabled
44 mouse_enabled = false;
45 mouse_ptrx = mouse_oldx = SCREEN_WIDTH / 2;
46 mouse_ptry = mouse_oldy = SCREEN_HEIGHT / 2;
47 joy_num = SDL_NumJoysticks();
48 for(int i = 0; i < joy_num && i < 2; i++) {
49 joy_mask[i] = 0x0f; // 4buttons
51 // initialize keycode convert table
52 FILEIO* fio = new FILEIO();
53 if(fio->Fopen(bios_path(_T("keycode.cfg")), FILEIO_READ_BINARY)) {
54 fio->Fread(keycode_conv, sizeof(keycode_conv), 1);
57 for(int i = 0; i < 256; i++) {
63 #ifdef USE_SHIFT_NUMPAD_KEY
64 // initialize shift+numpad conversion
65 memset(key_converted, 0, sizeof(key_converted));
66 key_shift_pressed = key_shift_released = false;
70 autokey_buffer = new FIFO(65536);
71 autokey_buffer->clear();
72 autokey_phase = autokey_shift = 0;
77 void EMU::release_input()
85 // release autokey buffer
87 autokey_buffer->release();
88 delete autokey_buffer;
94 void EMU::update_input()
98 bool press_flag = false;
99 bool release_flag = false;
100 #ifdef USE_SHIFT_NUMPAD_KEY
101 //update numpad key status
102 if(key_shift_pressed && !key_shift_released) {
103 if(key_status[VK_SHIFT] == 0) {
104 // shift key is newly pressed
105 key_status[VK_SHIFT] = 0x80;
106 # ifdef NOTIFY_KEY_DOWN
107 vm->key_down(VK_SHIFT, false);
110 } else if(!key_shift_pressed && key_shift_released) {
111 if(key_status[VK_SHIFT] != 0) {
112 // shift key is newly released
113 key_status[VK_SHIFT] = 0;
114 # ifdef NOTIFY_KEY_DOWN
115 vm->key_up(VK_SHIFT);
118 if(!(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
119 if(!(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
121 if(key_status[VK_LSHIFT] != 0) {
122 // shift key is newly released
123 key_status[VK_LSHIFT] = 0;
124 # ifdef NOTIFY_KEY_DOWN
125 vm->key_up(VK_LSHIFT);
128 if(!(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
130 if(key_status[VK_RSHIFT] != 0) {
131 // shift key is newly released
132 key_status[VK_RSHIFT] = 0;
133 # ifdef NOTIFY_KEY_DOWN
134 vm->key_up(VK_RSHIFT);
137 if(!(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
140 key_shift_pressed = key_shift_released = false;
145 if(lost_focus && autokey_phase == 0) {
149 // we lost key focus so release all pressed keys
150 for(int i = 0; i < 256; i++) {
151 if(key_status[i] & 0x80) {
152 key_status[i] &= 0x7f;
154 #ifdef NOTIFY_KEY_DOWN
162 for(int i = 0; i < 256; i++) {
163 if(key_status[i] & 0x7f) {
164 key_status[i] = (key_status[i] & 0x80) | ((key_status[i] & 0x7f) - 1);
166 #ifdef NOTIFY_KEY_DOWN
176 // update joystick status
177 #ifdef USE_KEY_TO_JOY
178 // emulate joystick #1 with keyboard
179 if(key_status[0x26]) joy_status[0] |= 0x01; // up
180 if(key_status[0x28]) joy_status[0] |= 0x02; // down
181 if(key_status[0x25]) joy_status[0] |= 0x04; // left
182 if(key_status[0x27]) joy_status[0] |= 0x08; // right
183 #ifdef KEY_TO_JOY_BUTTON_U
184 if(key_status[KEY_TO_JOY_BUTTON_U]) joy_status[0] |= 0x01;
186 #ifdef KEY_TO_JOY_BUTTON_D
187 if(key_status[KEY_TO_JOY_BUTTON_D]) joy_status[0] |= 0x02;
189 #ifdef KEY_TO_JOY_BUTTON_L
190 if(key_status[KEY_TO_JOY_BUTTON_L]) joy_status[0] |= 0x04;
192 #ifdef KEY_TO_JOY_BUTTON_R
193 if(key_status[KEY_TO_JOY_BUTTON_R]) joy_status[0] |= 0x08;
195 #ifdef KEY_TO_JOY_BUTTON_1
196 if(key_status[KEY_TO_JOY_BUTTON_1]) joy_status[0] |= 0x10;
198 #ifdef KEY_TO_JOY_BUTTON_2
199 if(key_status[KEY_TO_JOY_BUTTON_2]) joy_status[0] |= 0x20;
201 #ifdef KEY_TO_JOY_BUTTON_3
202 if(key_status[KEY_TO_JOY_BUTTON_3]) joy_status[0] |= 0x40;
204 #ifdef KEY_TO_JOY_BUTTON_4
205 if(key_status[KEY_TO_JOY_BUTTON_4]) joy_status[0] |= 0x80;
210 #if defined(USE_BUTTON)
211 if(!press_flag && !release_flag) {
214 for(ii = 0; buttons[ii].code != 0x00; ii++) {
215 if((mouse_ptrx >= buttons[ii].x) && (mouse_ptrx < (buttons[ii].x + buttons[ii].width))) {
216 if((mouse_ptry >= buttons[ii].y) && (mouse_ptry < (buttons[ii].y + buttons[ii].height))) {
217 if((key_status[buttons[ii].code] & 0x7f) == 0) this->press_button(ii);
221 if((mouse_ptrx >= buttons[ii].x) && (mouse_ptrx < (buttons[ii].x + buttons[ii].width))) {
222 if((mouse_ptry >= buttons[ii].y) && (mouse_ptry < (buttons[ii].y + buttons[ii].height))) {
223 this->press_button(ii);
226 mouse_ptrx = mouse_ptry = 0;
231 // update mouse status
234 memset(mouse_status, 0, sizeof(mouse_status));
235 // get current status
236 // move mouse cursor to the center of window
237 //if(mouse_ptrx < 0) mouse_ptrx = 0;
238 //if(mouse_ptrx >= SCREEN_WIDTH) mouse_ptrx = SCREEN_WIDTH - 1;
239 //if(mouse_ptry < 0) mouse_ptry = 0;
240 //if(mouse_ptry >= SCREEN_HEIGHT) mouse_ptry = SCREEN_HEIGHT - 1;
242 mouse_status[0] = mouse_ptrx - mouse_oldx;
243 mouse_status[1] = mouse_ptry - mouse_oldy;
244 mouse_status[2] = mouse_button;
245 mouse_oldx = mouse_ptrx;
246 mouse_oldy = mouse_ptry;
251 switch(autokey_phase) {
253 if(autokey_buffer && !autokey_buffer->empty()) {
254 // update shift key status
255 int shift = autokey_buffer->read_not_remove(0) & 0x100;
256 # ifdef NOTIFY_KEY_DOWN
257 if(shift && !autokey_shift) {
258 key_down(VK_SHIFT, false);
259 } else if(!shift && autokey_shift) {
263 autokey_shift = shift;
268 # ifdef NOTIFY_KEY_DOWN
269 if(autokey_buffer && !autokey_buffer->empty()) {
270 key_down(autokey_buffer->read_not_remove(0) & 0xff, false);
276 # ifdef NOTIFY_KEY_DOWN
277 if(autokey_buffer && !autokey_buffer->empty()) {
278 key_up(autokey_buffer->read_not_remove(0) & 0xff);
283 case USE_AUTO_KEY_RELEASE:
284 if(autokey_buffer && !autokey_buffer->empty()) {
285 // wait enough while vm analyzes one line
286 if(autokey_buffer->read() == 0xd) {
292 if(autokey_buffer && !autokey_buffer->empty()) {
308 #ifdef USE_SHIFT_NUMPAD_KEY
309 static const int numpad_table[256] = {
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312 // 0x00, 0x69, 0x63, 0x61, 0x67, 0x64, 0x68, 0x66, 0x62, 0x00, 0x00, 0x00, 0x00, 0x60, 0x6e, 0x00,
313 0x00, 0x69, 0x63, 0x61, 0x67, 0x64, 0x68, 0x66, 0x62, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, // remove shift + period
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
330 void EMU::key_down(int sym, bool repeat)
332 bool keep_frames = false;
334 if(code == VK_SHIFT){
335 #ifndef USE_SHIFT_NUMPAD_KEY
336 if(GetAsyncKeyState(VK_SHIFT, modkey_status) & 0x8000) {
337 key_status[VK_LSHIFT] = 0x80;
338 key_status[VK_RSHIFT] = 0x80;
339 key_status[VK_SHIFT] = 0x80;
342 } else if(code == VK_LSHIFT){
343 #ifndef USE_SHIFT_NUMPAD_KEY
344 if(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000) key_status[VK_LSHIFT] = 0x80;
346 } else if(code == VK_RSHIFT){
347 #ifndef USE_SHIFT_NUMPAD_KEY
348 if(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000) key_status[VK_RSHIFT] = 0x80;
350 } else if(code == VK_CONTROL) {
351 if(GetAsyncKeyState(VK_CONTROL, modkey_status) & 0x8000) {
352 key_status[VK_LCONTROL] = 0x80;
353 key_status[VK_RCONTROL] = 0x80;
354 key_status[VK_CONTROL] = 0x80;
356 } else if(code == VK_LCONTROL) {
357 if(GetAsyncKeyState(VK_LCONTROL, modkey_status) & 0x8000) key_status[VK_LCONTROL] = 0x80;
358 } else if(code == VK_RCONTROL) {
359 if(GetAsyncKeyState(VK_RCONTROL, modkey_status) & 0x8000) key_status[VK_RCONTROL] = 0x80;
360 } else if(code == VK_MENU) {
361 if(GetAsyncKeyState(VK_MENU, modkey_status) & 0x8000) {
362 key_status[VK_LMENU] = 0x80;
363 key_status[VK_RMENU] = 0x80;
364 key_status[VK_MENU] = 0x80;
366 } else if(code == VK_LMENU) {
367 if(GetAsyncKeyState(VK_LMENU, modkey_status) & 0x8000) key_status[VK_LMENU] = 0x80;
368 } else if(code == VK_RMENU) {
369 if(GetAsyncKeyState(VK_RMENU, modkey_status) & 0x8000) key_status[VK_RMENU] = 0x80;
370 } else if(code == 0xf0) {
373 } else if(code == 0xf2) {
376 } else if(code == 0xf3 || code == 0xf4) {
381 # ifdef USE_SHIFT_NUMPAD_KEY
382 if(code == VK_SHIFT) {
383 key_shift_pressed = true;
384 key_shift_released = false;
386 } else if(numpad_table[code] != 0) {
387 if(key_shift_pressed || key_shift_released) {
388 key_converted[code] = 1;
389 key_shift_pressed = true;
390 key_shift_released = false;
391 code = numpad_table[code];
396 if(!(code == VK_CONTROL || code == VK_MENU || code == VK_SHIFT || code == VK_LSHIFT || code == VK_RSHIFT)) {
397 code = keycode_conv[code];
400 #ifdef DONT_KEEEP_KEY_PRESSED
401 if(!(code == VK_CONTROL || code == VK_MENU || code == VK_SHIFT || code == VK_LSHIFT || code == VK_RSHIFT)) {
402 key_status[code] = KEY_KEEP_FRAMES;
406 key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80;
407 #ifdef NOTIFY_KEY_DOWN
411 vm->key_down(code, repeat);
417 void EMU::key_up(int sym)
420 if(code == VK_SHIFT) {
421 #ifndef USE_SHIFT_NUMPAD_KEY
422 if(!(GetAsyncKeyState(VK_SHIFT, modkey_status) & 0x8000)) {
423 key_status[VK_LSHIFT] &= 0x7f;
424 key_status[VK_RSHIFT] &= 0x7f;
425 key_status[VK_SHIFT] &= 0x7f;
428 } else if(code == VK_LSHIFT) {
429 #ifndef USE_SHIFT_NUMPAD_KEY
430 if(!(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
432 } else if(code == VK_RSHIFT) {
433 #ifndef USE_SHIFT_NUMPAD_KEY
434 if(!(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
436 } else if(code == VK_CONTROL) {
437 if(!(GetAsyncKeyState(VK_CONTROL, modkey_status) & 0x8000)) {
438 key_status[VK_LCONTROL] &= 0x7f;
439 key_status[VK_RCONTROL] &= 0x7f;
440 key_status[VK_CONTROL] &= 0x7f;
442 } else if(code == VK_LCONTROL) {
443 if(!(GetAsyncKeyState(VK_LCONTROL, modkey_status) & 0x8000)) key_status[VK_LCONTROL] &= 0x7f;
444 } else if(code == VK_RCONTROL) {
445 if(!(GetAsyncKeyState(VK_RCONTROL, modkey_status) & 0x8000)) key_status[VK_RCONTROL] &= 0x7f;
446 } else if(code == VK_MENU) {
447 if(!(GetAsyncKeyState(VK_MENU, modkey_status) & 0x8000)) {
448 key_status[VK_LMENU] &= 0x7f;
449 key_status[VK_RMENU] &= 0x7f;
450 key_status[VK_MENU] &= 0x7f;
452 } else if(code == VK_LMENU) {
453 if(!(GetAsyncKeyState(VK_LMENU, modkey_status) & 0x8000)) key_status[VK_LMENU] &= 0x7f;
454 } else if(code == VK_RMENU) {
455 if(!(GetAsyncKeyState(VK_RMENU, modkey_status) & 0x8000)) key_status[VK_RMENU] &= 0x7f;
458 #ifdef USE_SHIFT_NUMPAD_KEY
459 if((code == VK_SHIFT) || (code == VK_RSHIFT) || (code == VK_LSHIFT)) {
460 key_shift_pressed = false;
461 key_shift_released = true;
463 } else if(key_converted[code] != 0) {
464 key_converted[code] = 0;
465 code = numpad_table[code];
469 if(!(code == VK_CONTROL || code == VK_MENU || code == VK_SHIFT || code == VK_LSHIFT || code == VK_RSHIFT)) {
470 code = keycode_conv[code];
472 key_status[code] &= 0x7f;
473 #ifdef NOTIFY_KEY_DOWN
479 void EMU::press_button(int num)
481 int code = buttons[num].code;
484 key_down(code, false);
485 key_status[code] = KEY_KEEP_FRAMES;
487 // code=0: reset virtual machine
494 void EMU::enable_mouse()
496 // enable mouse emulation
500 mouse_oldx = mouse_ptrx = SCREEN_WIDTH / 2;
501 mouse_oldy = mouse_ptry = SCREEN_HEIGHT / 2;
502 cursor = instance_handle->cursor();
503 pos.setX(instance_handle->width() / 2);
504 pos.setY(instance_handle->height() / 2);
505 cursor.setPos(instance_handle->mapToGlobal(pos));
506 QApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
507 //mouse_shape = cursor.shape();
508 //cursor.setShape(Qt::BlankCursor);
511 mouse_status[2] = mouse_button;
513 instance_handle->setMouseTracking(true);
514 mouse_enabled = true;
520 void EMU::disenable_mouse()
522 // disenable mouse emulation
525 cursor = instance_handle->cursor();
526 if(QApplication::overrideCursor() != NULL) QApplication::restoreOverrideCursor();
527 //QApplication::restoreOverrideCursor();
528 instance_handle->setMouseTracking(false);
530 mouse_enabled = false;
533 void EMU::toggle_mouse()
535 // toggle mouse enable / disenable
544 static const int autokey_table[256] = {
549 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x00d,0x000,0x000,0x00d,0x000,0x000,
550 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
551 0x020,0x131,0x132,0x133,0x134,0x135,0x136,0x137,0x138,0x139,0x1ba,0x1bb,0x0bc,0x0bd,0x0be,0x0bf,
552 0x030,0x031,0x032,0x033,0x034,0x035,0x036,0x037,0x038,0x039,0x0ba,0x0bb,0x1bc,0x1bd,0x1be,0x1bf,
553 0x0c0,0x441,0x442,0x443,0x444,0x445,0x446,0x447,0x448,0x449,0x44a,0x44b,0x44c,0x44d,0x44e,0x44f,
554 0x450,0x451,0x452,0x453,0x454,0x455,0x456,0x457,0x458,0x459,0x45a,0x0db,0x0dc,0x0dd,0x0de,0x1e2,
555 0x1c0,0x841,0x842,0x843,0x844,0x845,0x846,0x847,0x848,0x849,0x84a,0x84b,0x84c,0x84d,0x84e,0x84f,
556 0x850,0x851,0x852,0x853,0x854,0x855,0x856,0x857,0x858,0x859,0x85a,0x1db,0x1dc,0x1dd,0x1de,0x000,
557 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
558 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
560 0x000,0x3be,0x3db,0x3dd,0x3bc,0x3bf,0x330,0x333,0x345,0x334,0x335,0x336,0x337,0x338,0x339,0x35a,
561 0x2dc,0x233,0x245,0x234,0x235,0x236,0x254,0x247,0x248,0x2ba,0x242,0x258,0x244,0x252,0x250,0x243,
562 0x251,0x241,0x25a,0x257,0x253,0x255,0x249,0x231,0x2bc,0x24b,0x246,0x256,0x232,0x2de,0x2bd,0x24a,
563 0x24e,0x2dd,0x2bf,0x24d,0x237,0x238,0x239,0x24f,0x24c,0x2be,0x2bb,0x2e2,0x230,0x259,0x2c0,0x2db,
565 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
566 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000
569 void EMU::start_auto_key()
574 if(OpenClipboard(NULL)) {
575 HANDLE hClip = GetClipboardData(CF_TEXT);
577 autokey_buffer->clear();
578 char* buf = (char*)GlobalLock(hClip);
579 int size = strlen(buf), prev_kana = 0;
580 for(int i = 0; i < size; i++) {
581 int code = buf[i] & 0xff;
582 if((0x81 <= code && code <= 0x9f) || 0xe0 <= code) {
585 } else if(code == 0xa) {
588 if((code = autokey_table[code]) != 0) {
589 int kana = code & 0x200;
590 if(prev_kana != kana) {
591 autokey_buffer->write(0xf2);
594 #if defined(USE_AUTO_KEY_NO_CAPS)
595 if((code & 0x100) && !(code & (0x400 | 0x800))) {
596 #elif defined(USE_AUTO_KEY_CAPS)
597 if(code & (0x100 | 0x800)) {
599 if(code & (0x100 | 0x400)) {
601 autokey_buffer->write((code & 0xff) | 0x100);
603 autokey_buffer->write(code & 0xff);
608 autokey_buffer->write(0xf2);
620 void EMU::stop_auto_key()
626 autokey_phase = autokey_shift = 0;
632 JoyThreadClass::JoyThreadClass(QObject *parent) : QThread(parent)
635 for(i = 0; i < 2; i++) joyhandle[i] = SDL_JoystickOpen(i);
636 joy_num = SDL_NumJoysticks();
637 AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : Start.");
641 JoyThreadClass::~JoyThreadClass()
644 for(i = 0; i < 2; i++) {
645 if(joyhandle[i] != NULL) SDL_JoystickClose(joyhandle[i]);
647 AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : EXIT");
650 void JoyThreadClass::x_axis_changed(int index, int value)
652 if(p_emu == NULL) return;
654 uint32_t *joy_status = p_emu->getJoyStatPtr();
656 if(joy_status != NULL) {
657 if(value < -8192) { // left
658 joy_status[index] |= 0x04; joy_status[index] &= ~0x08;
659 } else if(value > 8192) { // right
660 joy_status[index] |= 0x08; joy_status[index] &= ~0x04;
662 joy_status[index] &= ~0x0c;
668 void JoyThreadClass::y_axis_changed(int index, int value)
670 if(p_emu == NULL) return;
672 uint32_t *joy_status = p_emu->getJoyStatPtr();
674 if(joy_status != NULL) {
675 if(value < -8192) {// up
676 joy_status[index] |= 0x01; joy_status[index] &= ~0x02;
677 } else if(value > 8192) {// down
678 joy_status[index] |= 0x02; joy_status[index] &= ~0x01;
680 joy_status[index] &= ~0x03;
686 void JoyThreadClass::button_down(int index, unsigned int button)
688 if(p_emu == NULL) return;
690 uint32_t *joy_status = p_emu->getJoyStatPtr();
691 if(joy_status != NULL) {
692 joy_status[index] |= (1 << (button + 4));
697 void JoyThreadClass::button_up(int index, unsigned int button)
699 if(p_emu == NULL) return;
702 uint32_t *joy_status = p_emu->getJoyStatPtr();
703 if(joy_status != NULL) {
704 joy_status[index] &= ~(1 << (button + 4));
710 bool JoyThreadClass::EventSDL(SDL_Event *eventQueue)
719 if(eventQueue == NULL) return false;
721 * JoyStickなどはSDLが管理する
723 switch (eventQueue->type){
724 case SDL_JOYAXISMOTION:
725 value = eventQueue->jaxis.value;
726 i = eventQueue->jaxis.which;
727 if((i < 0) || (i > 1)) break;
729 if(eventQueue->jaxis.axis == 0) { // X
730 x_axis_changed(i, value);
731 } else if(eventQueue->jaxis.axis == 1) { // Y
732 y_axis_changed(i, value);
735 case SDL_JOYBUTTONDOWN:
736 button = eventQueue->jbutton.button;
737 i = eventQueue->jbutton.which;
738 if((i < 0) || (i > 1)) break;
739 button_down(i, button);
741 case SDL_JOYBUTTONUP:
742 button = eventQueue->jbutton.button;
743 i = eventQueue->jbutton.which;
744 if((i < 0) || (i > 1)) break;
745 button_up(i, button);
754 void JoyThreadClass::doWork(const QString ¶ms)
757 if(bRunThread == false) {
760 while(SDL_PollEvent(&event) == 1) {
769 void JoyThreadClass::doExit(void)
776 void Ui_MainWindow::LaunchJoyThread(void)
778 hRunJoy = new JoyThreadClass(this);
779 hRunJoy->SetEmu(emu);
780 connect(this, SIGNAL(quit_joy_thread()), hRunJoy, SLOT(doExit()));
781 //connect(this, SIGNAL(quit_joy_thread()), hRunJoy, SLOT(terminate()));
782 //connect(hRunJoy, SIGNAL(finished()), hRunJoy, SLOT(quit()));
783 hRunJoy->setObjectName("JoyThread");
786 void Ui_MainWindow::StopJoyThread(void)
788 emit quit_joy_thread();
791 void Ui_MainWindow::delete_joy_thread(void)
793 // delete hRunJoyThread;