OSDN Git Service

[UI][Qt][VM][FM7] Fixup keycode tables.
[csp-qt/common_source_project-fm7.git] / source / src / qt / common / emu_input.cpp
1 /*
2  *      Skelton for retropc emulator
3  *
4  *      Author : Takeda.Toshiya
5  *      Date   : 2006.08.18 -
6  *      Converted to QT by (C) 2015 K.Ohta
7  *        History:
8  *           Jan 12, 2015 (maybe) : Initial
9  *      [ SDL input -> Keyboard]
10 */
11
12 #include <Qt>
13 #include <QApplication>
14 #include <SDL2/SDL.h>
15 #include "emu.h"
16 #include "vm/vm.h"
17 #include "fifo.h"
18 #include "fileio.h"
19 #include "qt_input.h"
20 #include "qt_gldraw.h"
21 #include "qt_main.h"
22 //#include "menuclasses.h"
23 //#include "commonclasses.h"
24 #include "mainwidget.h"
25 #include "agar_logger.h"
26
27 #ifndef Ulong
28 #define Ulong unsigned long
29 #endif
30
31 #define KEY_KEEP_FRAMES 3
32
33 extern EMU* emu;
34
35 void EMU::initialize_input()
36 {
37         // initialize status
38         memset(key_status, 0, sizeof(key_status));
39         memset(joy_status, 0, sizeof(joy_status));
40         memset(mouse_status, 0, sizeof(mouse_status));
41         
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
50         }
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);
55                 fio->Fclose();
56         } else {
57                 for(int i = 0; i < 256; i++) {
58                         keycode_conv[i] = i;
59                 }
60         }
61         delete fio;
62         
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;
67 #endif
68 #ifdef USE_AUTO_KEY
69         // initialize autokey
70         autokey_buffer = new FIFO(65536);
71         autokey_buffer->clear();
72         autokey_phase = autokey_shift = 0;
73 #endif
74         lost_focus = false;
75 }
76
77 void EMU::release_input()
78 {
79         // release mouse
80         if(mouse_enabled) {
81                 disenable_mouse();
82         }
83         
84 #ifdef USE_AUTO_KEY
85         // release autokey buffer
86         if(autokey_buffer) {
87                 autokey_buffer->release();
88                 delete autokey_buffer;
89         }
90 #endif
91 }
92
93
94 void EMU::update_input()
95 {
96         int *keystat;
97         int i_c = 0;;
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);
108 # endif
109                 }
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);
116 # endif
117                         // check l/r 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;
120                 }
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);
126 # endif
127                         // check l/r shift
128                         if(!(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
129                 }
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);
135 # endif
136                         // check l/r shift
137                         if(!(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
138                 }
139         }
140         key_shift_pressed = key_shift_released = false;
141 #endif
142             
143         // release keys
144 #ifdef USE_AUTO_KEY
145         if(lost_focus && autokey_phase == 0) {
146 #else
147         if(lost_focus) {
148 #endif
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;
153                                 release_flag = true;
154 #ifdef NOTIFY_KEY_DOWN
155                                 if(!key_status[i]) {
156                                         vm->key_up(i);
157                                 }
158 #endif
159                         }
160                 }
161         } else {
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);
165                                 press_flag = true;
166 #ifdef NOTIFY_KEY_DOWN
167                                 if(!key_status[i]) {
168                                         vm->key_up(i);
169                                 }
170 #endif
171                         }
172                 }
173         }
174         lost_focus = false;
175 #if 1   
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;
185 #endif
186 #ifdef KEY_TO_JOY_BUTTON_D
187         if(key_status[KEY_TO_JOY_BUTTON_D]) joy_status[0] |= 0x02;
188 #endif
189 #ifdef KEY_TO_JOY_BUTTON_L
190         if(key_status[KEY_TO_JOY_BUTTON_L]) joy_status[0] |= 0x04;
191 #endif
192 #ifdef KEY_TO_JOY_BUTTON_R
193         if(key_status[KEY_TO_JOY_BUTTON_R]) joy_status[0] |= 0x08;
194 #endif
195 #ifdef KEY_TO_JOY_BUTTON_1
196         if(key_status[KEY_TO_JOY_BUTTON_1]) joy_status[0] |= 0x10;
197 #endif
198 #ifdef KEY_TO_JOY_BUTTON_2
199         if(key_status[KEY_TO_JOY_BUTTON_2]) joy_status[0] |= 0x20;
200 #endif
201 #ifdef KEY_TO_JOY_BUTTON_3
202         if(key_status[KEY_TO_JOY_BUTTON_3]) joy_status[0] |= 0x40;
203 #endif
204 #ifdef KEY_TO_JOY_BUTTON_4
205         if(key_status[KEY_TO_JOY_BUTTON_4]) joy_status[0] |= 0x80;
206 #endif
207 #endif
208
209 #endif
210 #if defined(USE_BUTTON)
211         if(!press_flag && !release_flag) {
212                 int ii;
213                 ii = 0;
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);
218                                 }
219                         }
220                 }
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);
224                         }
225                 }
226                 mouse_ptrx = mouse_ptry = 0;
227         }
228         //return;
229 #endif                  
230                 
231         // update mouse status
232         if(mouse_enabled) {
233                 bool hid = false;
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;
241                 
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;
247         }
248         
249 #ifdef USE_AUTO_KEY
250         // auto key
251         switch(autokey_phase) {
252         case 1:
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) {
260                                 key_up(VK_SHIFT);
261                         }
262 # endif            
263                         autokey_shift = shift;
264                         autokey_phase++;
265                         break;
266                 }
267         case 3:
268 # ifdef NOTIFY_KEY_DOWN
269                 if(autokey_buffer && !autokey_buffer->empty()) {
270                         key_down(autokey_buffer->read_not_remove(0) & 0xff, false);
271                 }
272 # endif    
273                 autokey_phase++;
274                 break;
275         case USE_AUTO_KEY:
276 # ifdef NOTIFY_KEY_DOWN
277                 if(autokey_buffer && !autokey_buffer->empty()) {
278                         key_up(autokey_buffer->read_not_remove(0) & 0xff);
279                 }
280 # endif    
281                 autokey_phase++;
282                 break;
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) {
287                                 autokey_phase++;
288                                 break;
289                         }
290                 }
291         case 30:
292                 if(autokey_buffer && !autokey_buffer->empty()) {
293                         autokey_phase = 1;
294                 } else {
295                         stop_auto_key();
296                 }
297                 break;
298         default:
299                 if(autokey_phase) {
300                         autokey_phase++;
301                 }
302         }
303 #endif
304 }
305
306
307
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
327 };
328 #endif
329
330 void EMU::key_down(int sym, bool repeat)
331 {
332         bool keep_frames = false;
333         uint8 code = sym;
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;
340                 }
341 #endif
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;
345 #endif
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;
349 #endif
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;
355                 }
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;
365                 }
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) {
371                 code = VK_CAPITAL;
372                 keep_frames = true;
373         } else if(code == 0xf2) {
374                 code = VK_KANA;
375                 keep_frames = true;
376         } else if(code == 0xf3 || code == 0xf4) {
377                 code = VK_KANJI;
378                 keep_frames = true;
379         }
380
381 # ifdef USE_SHIFT_NUMPAD_KEY
382         if(code == VK_SHIFT) {
383                 key_shift_pressed = true;
384                 key_shift_released = false;
385                 return;
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];
392                 }
393         }
394 #endif
395
396         if(!(code == VK_CONTROL || code == VK_MENU || code == VK_SHIFT || code == VK_LSHIFT || code == VK_RSHIFT)) {
397                 code = keycode_conv[code];
398         }
399         
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;
403         } else
404 #endif
405      
406         key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80;
407 #ifdef NOTIFY_KEY_DOWN
408         if(keep_frames) {
409                 repeat = false;
410         }
411         vm->key_down(code, repeat);
412 #endif
413
414 }
415
416         
417 void EMU::key_up(int sym)
418 {
419         uint8 code = 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;
426                 }
427 #endif
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;
431 #endif
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;
435 #endif
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;
441                 }
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;
451                 }
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;
456         }
457
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;
462                 return;
463         } else if(key_converted[code] != 0) {
464                 key_converted[code] = 0;
465                 code = numpad_table[code];
466         }
467    
468 #endif
469         if(!(code == VK_CONTROL || code == VK_MENU || code == VK_SHIFT || code == VK_LSHIFT || code == VK_RSHIFT)) {
470                 code = keycode_conv[code];
471         }
472         key_status[code] &= 0x7f;
473 #ifdef NOTIFY_KEY_DOWN
474                         vm->key_up(code);
475 #endif
476 }
477
478 #ifdef USE_BUTTON
479 void EMU::press_button(int num)
480 {
481         int code = buttons[num].code;
482         
483         if(code) {
484                 key_down(code, false);
485                 key_status[code] = KEY_KEEP_FRAMES;
486         } else {
487                 // code=0: reset virtual machine
488                 vm->reset();
489         }
490 }
491 #endif
492
493
494 void EMU::enable_mouse()
495 {
496         // enable mouse emulation
497         if(!mouse_enabled) {
498                 QCursor cursor;
499                 QPoint pos;
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);
509                 mouse_status[0] = 0;
510                 mouse_status[1] = 0;
511                 mouse_status[2] = mouse_button;
512         }
513         instance_handle->setMouseTracking(true);
514         mouse_enabled = true;
515
516 }
517
518
519
520 void EMU::disenable_mouse()
521 {
522         // disenable mouse emulation
523         if(mouse_enabled) {
524                 QCursor cursor;
525                 cursor = instance_handle->cursor();
526                 if(QApplication::overrideCursor() != NULL) QApplication::restoreOverrideCursor();
527                 //QApplication::restoreOverrideCursor();
528                 instance_handle->setMouseTracking(false);
529         }
530         mouse_enabled = false;
531 }
532
533 void EMU::toggle_mouse()
534 {
535         // toggle mouse enable / disenable
536         if(mouse_enabled) {
537                 disenable_mouse();
538         } else {
539                 enable_mouse();
540         }
541 }
542
543 #ifdef USE_AUTO_KEY
544 static const int autokey_table[256] = {
545         // 0x100: shift
546         // 0x200: kana
547         // 0x400: alphabet
548         // 0x800: ALPHABET
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,
559         // kana -->
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,
564         // <--- kana
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
567 };
568
569 void EMU::start_auto_key()
570 {
571 #if 0
572          stop_auto_key();
573         
574         if(OpenClipboard(NULL)) {
575                 HANDLE hClip = GetClipboardData(CF_TEXT);
576                 if(hClip) {
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) {
583                                         i++;    // kanji ?
584                                         continue;
585                                 } else if(code == 0xa) {
586                                         continue;       // cr-lf
587                                 }
588                                 if((code = autokey_table[code]) != 0) {
589                                         int kana = code & 0x200;
590                                         if(prev_kana != kana) {
591                                                 autokey_buffer->write(0xf2);
592                                         }
593                                         prev_kana = kana;
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)) {
598 #else
599                                         if(code & (0x100 | 0x400)) {
600 #endif
601                                                 autokey_buffer->write((code & 0xff) | 0x100);
602                                         } else {
603                                                 autokey_buffer->write(code & 0xff);
604                                         }
605                                 }
606                         }
607                         if(prev_kana) {
608                                 autokey_buffer->write(0xf2);
609                         }
610                         GlobalUnlock(hClip);
611                         
612                         autokey_phase = 1;
613                         autokey_shift = 0;
614                 }
615                 CloseClipboard();
616         }
617 #endif
618 }
619   
620 void EMU::stop_auto_key()
621 {
622 #if 1
623          if(autokey_shift) {
624                 key_up(VK_SHIFT);
625         }
626         autokey_phase = autokey_shift = 0;
627 #endif
628 }
629 #endif
630
631  
632 JoyThreadClass::JoyThreadClass(QObject *parent) : QThread(parent)
633 {
634         int i;
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.");
638         bRunThread = true;
639 }
640  
641 JoyThreadClass::~JoyThreadClass()
642 {
643         int i;
644         for(i = 0; i < 2; i++) {
645                 if(joyhandle[i] != NULL) SDL_JoystickClose(joyhandle[i]);
646         }
647         AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : EXIT");
648 }
649  
650 void JoyThreadClass::x_axis_changed(int index, int value)
651 {
652         if(p_emu == NULL) return;
653         p_emu->LockVM();
654         uint32_t *joy_status = p_emu->getJoyStatPtr();
655    
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;
661                 }  else { // center
662                         joy_status[index] &= ~0x0c;
663                 }
664         }
665         p_emu->UnlockVM();
666 }
667            
668 void JoyThreadClass::y_axis_changed(int index, int value)
669 {
670         if(p_emu == NULL) return;
671         p_emu->LockVM();
672         uint32_t *joy_status = p_emu->getJoyStatPtr();
673    
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;
679                 } else {
680                         joy_status[index] &= ~0x03;
681                 }
682         }
683         p_emu->UnlockVM();
684 }
685
686 void JoyThreadClass::button_down(int index, unsigned int button)
687 {
688         if(p_emu == NULL) return;
689         p_emu->LockVM();
690         uint32_t *joy_status = p_emu->getJoyStatPtr();
691         if(joy_status != NULL) {
692                 joy_status[index] |= (1 << (button + 4));
693         }
694         p_emu->UnlockVM();
695 }
696
697 void JoyThreadClass::button_up(int index, unsigned int button)
698 {
699         if(p_emu == NULL) return;
700    
701         p_emu->LockVM();
702         uint32_t *joy_status = p_emu->getJoyStatPtr();
703         if(joy_status != NULL) {
704                 joy_status[index] &= ~(1 << (button + 4));
705         }
706         p_emu->UnlockVM();
707 }
708            
709 // SDL Event Handler
710 bool  JoyThreadClass::EventSDL(SDL_Event *eventQueue)
711 {
712         //      SDL_Surface *p;
713         Sint16 value;
714         unsigned int button;
715         int vk;
716         uint32_t sym;
717         uint32_t mod;
718         int i;
719         if(eventQueue == NULL) return false;
720         /*
721          * JoyStickなどはSDLが管理する
722          */
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;
728                         
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);
733                         }
734                         break;
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);
740                         break;
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);
746                         break;
747                 default:
748                         break;
749         }
750         return true;
751 }
752
753
754 void JoyThreadClass::doWork(const QString &params)
755 {
756         do {
757                 if(bRunThread == false) {
758                         break;
759                 }
760                 while(SDL_PollEvent(&event) == 1) {
761                         EventSDL(&event);
762                 }
763                 msleep(10);
764         } while(1);
765         this->quit();
766 }
767            
768
769 void JoyThreadClass::doExit(void)
770 {
771         bRunThread = false;
772         //this->quit();
773 }
774
775
776 void Ui_MainWindow::LaunchJoyThread(void)
777 {
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");
784         hRunJoy->start();
785 }
786 void Ui_MainWindow::StopJoyThread(void)
787 {
788         emit quit_joy_thread();
789 }
790
791 void Ui_MainWindow::delete_joy_thread(void)
792 {
793         //    delete hRunJoyThread;
794         //  delete hRunJoy;
795 }