OSDN Git Service

[Qt][General] Fix indent : replace space to ^I.
[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 <SDL2/SDL.h>
14 #include "emu.h"
15 #include "vm/vm.h"
16 #include "fifo.h"
17 #include "fileio.h"
18 #include "qt_input.h"
19 #include "qt_gldraw.h"
20 #include "qt_main.h"
21 #include "menuclasses.h"
22 #include "agar_logger.h"
23
24 #ifndef Ulong
25 #define Ulong unsigned long
26 #endif
27
28 #define KEY_KEEP_FRAMES 3
29
30 extern EMU* emu;
31
32 void EMU::initialize_input()
33 {
34         // initialize status
35         memset(key_status, 0, sizeof(key_status));
36         memset(joy_status, 0, sizeof(joy_status));
37         memset(mouse_status, 0, sizeof(mouse_status));
38         
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
45         }
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);
50                 fio->Fclose();
51         } else {
52                 for(int i = 0; i < 256; i++) {
53                         keycode_conv[i] = i;
54                 }
55         }
56         delete fio;
57         
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;
62 #endif
63 #ifdef USE_AUTO_KEY
64         // initialize autokey
65         autokey_buffer = new FIFO(65536);
66         autokey_buffer->clear();
67         autokey_phase = autokey_shift = 0;
68 #endif
69         lost_focus = false;
70 }
71
72 void EMU::release_input()
73 {
74         // release mouse
75         if(mouse_enabled) {
76                 disenable_mouse();
77         }
78         
79 #ifdef USE_AUTO_KEY
80         // release autokey buffer
81         if(autokey_buffer) {
82                 autokey_buffer->release();
83                 delete autokey_buffer;
84         }
85 #endif
86 }
87
88
89 void EMU::update_input()
90 {
91
92         int *keystat;
93         int i_c = 0;;
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);
102 # endif
103                 }
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);
110 # endif
111                         // check l/r 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;
114                 }
115         }
116         key_shift_pressed = key_shift_released = false;
117 #endif
118             
119         // release keys
120 #ifdef USE_AUTO_KEY
121         if(lost_focus && autokey_phase == 0) {
122 #else
123         if(lost_focus) {
124 #endif
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
130                                 if(!key_status[i]) {
131                                         vm->key_up(i);
132                                 }
133 #endif
134                         }
135                 }
136         } else {
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
141                                 if(!key_status[i]) {
142                                         vm->key_up(i);
143                                 }
144 #endif
145                         }
146                 }
147         }
148         lost_focus = false;
149 #if 1   
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;
159 #endif
160 #ifdef KEY_TO_JOY_BUTTON_D
161         if(key_status[KEY_TO_JOY_BUTTON_D]) joy_status[0] |= 0x02;
162 #endif
163 #ifdef KEY_TO_JOY_BUTTON_L
164         if(key_status[KEY_TO_JOY_BUTTON_L]) joy_status[0] |= 0x04;
165 #endif
166 #ifdef KEY_TO_JOY_BUTTON_R
167         if(key_status[KEY_TO_JOY_BUTTON_R]) joy_status[0] |= 0x08;
168 #endif
169 #ifdef KEY_TO_JOY_BUTTON_1
170         if(key_status[KEY_TO_JOY_BUTTON_1]) joy_status[0] |= 0x10;
171 #endif
172 #ifdef KEY_TO_JOY_BUTTON_2
173         if(key_status[KEY_TO_JOY_BUTTON_2]) joy_status[0] |= 0x20;
174 #endif
175 #ifdef KEY_TO_JOY_BUTTON_3
176         if(key_status[KEY_TO_JOY_BUTTON_3]) joy_status[0] |= 0x40;
177 #endif
178 #ifdef KEY_TO_JOY_BUTTON_4
179         if(key_status[KEY_TO_JOY_BUTTON_4]) joy_status[0] |= 0x80;
180 #endif
181 #endif
182
183 #endif
184         // update mouse status
185         memset(mouse_status, 0, sizeof(mouse_status));
186 #if 0
187            if(mouse_enabled) {
188                 // get current status
189                 POINT pt;
190                 GetCursorPos(&pt);
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);
203                 }
204         }
205 #endif
206         
207 #ifdef USE_AUTO_KEY
208         // auto key
209         switch(autokey_phase) {
210         case 1:
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) {
217                                 key_up(VK_SHIFT);
218                         }
219                         autokey_shift = shift;
220                         autokey_phase++;
221                         break;
222                 }
223         case 3:
224                 if(autokey_buffer && !autokey_buffer->empty()) {
225                         key_down(autokey_buffer->read_not_remove(0) & 0xff, false);
226                 }
227                 autokey_phase++;
228                 break;
229         case USE_AUTO_KEY:
230                 if(autokey_buffer && !autokey_buffer->empty()) {
231                         key_up(autokey_buffer->read_not_remove(0) & 0xff);
232                 }
233                 autokey_phase++;
234                 break;
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) {
239                                 autokey_phase++;
240                                 break;
241                         }
242                 }
243         case 30:
244                 if(autokey_buffer && !autokey_buffer->empty()) {
245                         autokey_phase = 1;
246                 } else {
247                         stop_auto_key();
248                 }
249                 break;
250         default:
251                 if(autokey_phase) {
252                         autokey_phase++;
253                 }
254         }
255 #endif
256 }
257
258
259
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
279 };
280 #endif
281
282 void EMU::key_down(int sym, bool repeat)
283 {
284         bool keep_frames = false;
285         uint8 code = sym;
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;
292 #endif
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;
298 #endif
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;
304 #endif
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) {
314                 code = VK_CAPITAL;
315                 keep_frames = true;
316         } else if(code == 0xf2) {
317                 code = VK_KANA;
318                 keep_frames = true;
319         } else if(code == 0xf3 || code == 0xf4) {
320                 code = VK_KANJI;
321                 keep_frames = true;
322         }
323
324 # ifdef USE_SHIFT_NUMPAD_KEY
325         if(code == VK_SHIFT) {
326                 key_shift_pressed = true;
327                 key_shift_released = false;
328                 return;
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];
335                 }
336         }
337 #endif
338
339         if(!(code == VK_CONTROL || code == VK_MENU || code == VK_SHIFT)) {
340                 code = keycode_conv[code];
341         }
342         
343 #ifdef DONT_KEEEP_KEY_PRESSED
344         if(!(code == VK_CONTROL || code == VK_MENU || code == VK_SHIFT)) {
345                 key_status[code] = KEY_KEEP_FRAMES;
346         } else
347 #endif
348      
349         key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80;
350 #ifdef NOTIFY_KEY_DOWN
351         if(keep_frames) {
352                 repeat = false;
353         }
354         vm->key_down(code, repeat);
355 #endif
356
357 }
358
359         
360 void EMU::key_up(int sym)
361 {
362         uint8 code = 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;
367 #endif
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;
372 #endif
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;
377 #endif
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;
384         } else {
385                 key_status[code] &= 0x7f;
386 #ifdef NOTIFY_KEY_DOWN
387                 vm->key_up(code);
388 #endif
389         }
390
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;
395                 return;
396         } else if(key_converted[code] != 0) {
397                 key_converted[code] = 0;
398                 code = numpad_table[code];
399         }
400    
401 #endif
402         if(!(code == VK_SHIFT || code == VK_CONTROL || code == VK_MENU)) {
403                 code = keycode_conv[code];
404         }
405         if(key_status[code]) {
406                 key_status[code] &= 0x7f;
407 #ifdef NOTIFY_KEY_DOWN
408                 if(!key_status[code]) {
409                         vm->key_up(code);
410                 }
411 #endif
412         }
413
414 }
415
416 #ifdef USE_BUTTON
417 void EMU::press_button(int num)
418 {
419         int code = buttons[num].code;
420         
421         if(code) {
422                 key_down(code, false);
423                 key_status[code] = KEY_KEEP_FRAMES;
424         } else {
425                 // code=0: reset virtual machine
426                 vm->reset();
427         }
428 }
429 #endif
430
431
432 void EMU::enable_mouse()
433 {
434         // enable mouse emulation
435         if(!mouse_enabled) {
436 #if 0
437                  // hide mouse cursor
438                 ShowCursor(FALSE);
439                 // move mouse cursor to the center of window
440                 POINT pt;
441                 pt.x = display_width / 2;
442                 pt.y = display_height / 2;
443                 ClientToScreen(main_window_handle, &pt);
444                 SetCursorPos(pt.x, pt.y);
445 #endif
446         }
447         mouse_enabled = true;
448
449 }
450
451
452
453 void EMU::disenable_mouse()
454 {
455 #if 0
456         // disenable mouse emulation
457         if(mouse_enabled) {
458                 ShowCursor(TRUE);
459         }
460 #endif
461       mouse_enabled = false;
462 }
463
464 void EMU::toggle_mouse()
465 {
466         // toggle mouse enable / disenable
467         if(mouse_enabled) {
468                 disenable_mouse();
469         } else {
470                 enable_mouse();
471         }
472 }
473
474 #ifdef USE_AUTO_KEY
475 static const int autokey_table[256] = {
476         // 0x100: shift
477         // 0x200: kana
478         // 0x400: alphabet
479         // 0x800: ALPHABET
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,
490         // kana -->
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,
495         // <--- kana
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
498 };
499
500 void EMU::start_auto_key()
501 {
502 #if 0
503          stop_auto_key();
504         
505         if(OpenClipboard(NULL)) {
506                 HANDLE hClip = GetClipboardData(CF_TEXT);
507                 if(hClip) {
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) {
514                                         i++;    // kanji ?
515                                         continue;
516                                 } else if(code == 0xa) {
517                                         continue;       // cr-lf
518                                 }
519                                 if((code = autokey_table[code]) != 0) {
520                                         int kana = code & 0x200;
521                                         if(prev_kana != kana) {
522                                                 autokey_buffer->write(0xf2);
523                                         }
524                                         prev_kana = kana;
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)) {
529 #else
530                                         if(code & (0x100 | 0x400)) {
531 #endif
532                                                 autokey_buffer->write((code & 0xff) | 0x100);
533                                         } else {
534                                                 autokey_buffer->write(code & 0xff);
535                                         }
536                                 }
537                         }
538                         if(prev_kana) {
539                                 autokey_buffer->write(0xf2);
540                         }
541                         GlobalUnlock(hClip);
542                         
543                         autokey_phase = 1;
544                         autokey_shift = 0;
545                 }
546                 CloseClipboard();
547         }
548 #endif
549 }
550
551 void EMU::stop_auto_key()
552 {
553 #if 1
554          if(autokey_shift) {
555                 key_up(VK_SHIFT);
556         }
557         autokey_phase = autokey_shift = 0;
558 #endif
559 }
560 #endif
561
562  
563 JoyThreadClass::JoyThreadClass(QObject *parent) : QThread(parent)
564 {
565         int i;
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.");
569         bRunThread = true;
570 }
571  
572 JoyThreadClass::~JoyThreadClass()
573 {
574         int i;
575         for(i = 0; i < 2; i++) {
576                 if(joyhandle[i] != NULL) SDL_JoystickClose(joyhandle[i]);
577         }
578         AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : EXIT");
579 }
580  
581 void JoyThreadClass::x_axis_changed(int index, int value)
582 {
583         if(p_emu == NULL) return;
584         p_emu->LockVM();
585         uint32_t *joy_status = p_emu->getJoyStatPtr();
586    
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;
592                 }  else { // center
593                         joy_status[index] &= ~0x0c;
594                 }
595         }
596         p_emu->UnlockVM();
597 }
598            
599 void JoyThreadClass::y_axis_changed(int index, int value)
600 {
601         if(p_emu == NULL) return;
602         p_emu->LockVM();
603         uint32_t *joy_status = p_emu->getJoyStatPtr();
604    
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;
610                 } else {
611                         joy_status[index] &= ~0x03;
612                 }
613         }
614         p_emu->UnlockVM();
615 }
616
617 void JoyThreadClass::button_down(int index, unsigned int button)
618 {
619         if(p_emu == NULL) return;
620         p_emu->LockVM();
621         uint32_t *joy_status = p_emu->getJoyStatPtr();
622         if(joy_status != NULL) {
623                 joy_status[index] |= (1 << (button + 4));
624         }
625         p_emu->UnlockVM();
626 }
627
628 void JoyThreadClass::button_up(int index, unsigned int button)
629 {
630         if(p_emu == NULL) return;
631    
632         p_emu->LockVM();
633         uint32_t *joy_status = p_emu->getJoyStatPtr();
634         if(joy_status != NULL) {
635                 joy_status[index] &= ~(1 << (button + 4));
636         }
637         p_emu->UnlockVM();
638 }
639            
640 // SDL Event Handler
641 bool  JoyThreadClass::EventSDL(SDL_Event *eventQueue)
642 {
643         //      SDL_Surface *p;
644         Sint16 value;
645         unsigned int button;
646         int vk;
647         uint32_t sym;
648         uint32_t mod;
649         int i;
650         if(eventQueue == NULL) return false;
651         /*
652          * JoyStickなどはSDLが管理する
653          */
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;
659                         
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);
664                         }
665                         break;
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);
671                         break;
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);
677                         break;
678                 default:
679                         break;
680    }
681    return true;
682 }
683
684
685 void JoyThreadClass::doWork(const QString &params)
686 {
687         do {
688                 if(bRunThread == false) {
689                         return;
690                 }
691                 while(SDL_PollEvent(&event) == 1) {
692                         EventSDL(&event);
693                 }
694                 msleep(10);
695         } while(1);
696         //timer.setInterval(5);
697         return;
698 }
699
700 void JoyThreadClass::doExit(void)
701 {
702         bRunThread = false;
703 }
704
705
706 void Ui_MainWindow::LaunchJoyThread(void)
707 {
708         hRunJoy = new JoyThreadClass(this);
709         hRunJoy->SetEmu(emu);
710         connect(this, SIGNAL(quit_joy_thread()), hRunJoy, SLOT(doExit()));
711         hRunJoy->setObjectName("JoyThread");
712         hRunJoy->start();
713 }
714 void Ui_MainWindow::StopJoyThread(void)
715 {
716         emit quit_joy_thread();
717 }
718
719 void Ui_MainWindow::delete_joy_thread(void)
720 {
721         //    delete hRunJoyThread;
722         //  delete hRunJoy;
723 }