OSDN Git Service

[VM][Thread] QThread is too weird to use (-_-#) , I discard QThread, using SDL_Thread.
[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 struct SDLKeyTable  SDLKeyMappings[] = {
33         { '0',                  SDL_SCANCODE_0 },
34         { '1',                  SDL_SCANCODE_1 },
35         { '2',                  SDL_SCANCODE_2 },
36         { '3',                  SDL_SCANCODE_3 },
37         { '4',                  SDL_SCANCODE_4 },
38         { '5',                  SDL_SCANCODE_5 },
39         { '6',                  SDL_SCANCODE_6 },
40         { '7',                  SDL_SCANCODE_7 },
41         { '8',                  SDL_SCANCODE_8 },
42         { '9',                  SDL_SCANCODE_9 },
43         { 'A',                  SDL_SCANCODE_A },
44         { 'B',                  SDL_SCANCODE_B },
45         { 'C',                  SDL_SCANCODE_C },
46         { 'D',                  SDL_SCANCODE_D },
47         { 'E',                  SDL_SCANCODE_E },
48         { 'F',                  SDL_SCANCODE_F },
49         { 'G',                  SDL_SCANCODE_G },
50         { 'H',                  SDL_SCANCODE_H },
51         { 'I',                  SDL_SCANCODE_I },
52         { 'J',                  SDL_SCANCODE_J },
53         { 'K',                  SDL_SCANCODE_K },
54         { 'L',                  SDL_SCANCODE_L },
55         { 'M',                  SDL_SCANCODE_M },
56         { 'N',                  SDL_SCANCODE_N },
57         { 'O',                  SDL_SCANCODE_O },
58         { 'P',                  SDL_SCANCODE_P },
59         { 'Q',                  SDL_SCANCODE_Q },
60         { 'R',                  SDL_SCANCODE_R },
61         { 'S',                  SDL_SCANCODE_S },
62         { 'T',                  SDL_SCANCODE_T },
63         { 'U',                  SDL_SCANCODE_U },
64         { 'V',                  SDL_SCANCODE_V },
65         { 'W',                  SDL_SCANCODE_W },
66         { 'X',                  SDL_SCANCODE_X },
67         { 'Y',                  SDL_SCANCODE_Y },
68         { 'Z',                  SDL_SCANCODE_Z },
69         // Start Qt's workaround: Qt returns character directry when keyin/out.
70         // Excepts(maybe) 'a' to 'z'?
71         // So, you should change keycode, using other than 109 / 106 Keyboard.
72 //        {0xBA,                        SDL_SCANCODE_ASTERISK}, // $2a
73 //        {0xBB,                        SDL_SCANCODE_PLUS}, // $2b
74 //        {0xBC,                  SDL_SCANCODE_LESS}, // ,
75 //        {0xBD,                  SDL_SCANCODE_CARET}, // ^~
76 //        {0xBE,                  SDL_SCANCODE_GREATER}, //$2e
77 //        {0xBF,                  SDL_SCANCODE_QUSETION}, //$2f
78         //{0xC0,                  SDL_SCANCODE_BACKQUOTE}, //`
79 //        {0xE2,                        SDL_SCANCODE_UNDERSCORE},//_\
80         {0xE2,                  SDL_SCANCODE_INTERNATIONAL3},//_\
81         // End.
82         { VK_F1,                SDL_SCANCODE_F1 },
83         { VK_F2,                SDL_SCANCODE_F2 },
84         { VK_F3,                SDL_SCANCODE_F3 },
85         { VK_F4,                SDL_SCANCODE_F4 },
86         { VK_F5,                SDL_SCANCODE_F5 },
87         { VK_F6,                SDL_SCANCODE_F6 },
88         { VK_F7,                SDL_SCANCODE_F7 },
89         { VK_F8,                SDL_SCANCODE_F8 },
90         { VK_F9,                SDL_SCANCODE_F9 },
91         { VK_F10,               SDL_SCANCODE_F10 },
92         { VK_F11,               SDL_SCANCODE_F11 },
93         { VK_F12,               SDL_SCANCODE_F12 },
94         { VK_F13,               SDL_SCANCODE_F13 },
95         { VK_F14,               SDL_SCANCODE_F14 },
96         { VK_F15,               SDL_SCANCODE_F15 },
97         { VK_BACK,              SDL_SCANCODE_BACKSPACE },
98         { VK_TAB,               SDL_SCANCODE_TAB },
99         { VK_CLEAR,             SDL_SCANCODE_CLEAR },
100         { VK_RETURN,            SDL_SCANCODE_RETURN },
101         { VK_PAUSE,             SDL_SCANCODE_PAUSE },
102         { VK_ESCAPE,            SDL_SCANCODE_ESCAPE },
103         { VK_SPACE,             SDL_SCANCODE_SPACE },
104         { VK_DELETE,            SDL_SCANCODE_DELETE },
105         { VK_UP,                SDL_SCANCODE_UP },
106         { VK_DOWN,              SDL_SCANCODE_DOWN},
107         { VK_RIGHT,             SDL_SCANCODE_RIGHT },
108         { VK_LEFT,              SDL_SCANCODE_LEFT },
109         { VK_INSERT,            SDL_SCANCODE_INSERT },
110         { VK_HOME,              SDL_SCANCODE_HOME },
111         { VK_END,               SDL_SCANCODE_END },
112         { VK_PRIOR,             SDL_SCANCODE_PAGEUP },
113         { VK_NEXT,              SDL_SCANCODE_PAGEDOWN },
114
115         { VK_NUMPAD0,           SDL_SCANCODE_KP_0 },
116         { VK_NUMPAD1,           SDL_SCANCODE_KP_1 },
117         { VK_NUMPAD2,           SDL_SCANCODE_KP_2 },
118         { VK_NUMPAD3,           SDL_SCANCODE_KP_3 },
119         { VK_NUMPAD4,           SDL_SCANCODE_KP_4 },
120         { VK_NUMPAD5,           SDL_SCANCODE_KP_5 },
121         { VK_NUMPAD6,           SDL_SCANCODE_KP_6 },
122         { VK_NUMPAD7,           SDL_SCANCODE_KP_7 },
123         { VK_NUMPAD8,           SDL_SCANCODE_KP_8 },
124         { VK_NUMPAD9,           SDL_SCANCODE_KP_9 },
125
126         { VK_DECIMAL,           SDL_SCANCODE_KP_PERIOD },
127         { VK_DIVIDE,            SDL_SCANCODE_KP_DIVIDE},
128         { VK_MULTIPLY,          SDL_SCANCODE_KP_MULTIPLY },
129         { VK_SUBTRACT,          SDL_SCANCODE_KP_MINUS },
130         { VK_ADD,               SDL_SCANCODE_KP_PLUS },
131
132         { VK_NUMLOCK,           SDL_SCANCODE_NUMLOCKCLEAR },
133 //      { VK_CAPITAL,           SDL_SCANCODE_Henkan }, // Need check
134         { VK_CAPITAL,           SDL_SCANCODE_CAPSLOCK}, // Need check
135         { VK_SCROLL,            SDL_SCANCODE_SCROLLLOCK },
136 //      { VK_SHIFT,             SDL_SCANCODE_LSHIFT }, // Left
137         { VK_RSHIFT,            SDL_SCANCODE_RSHIFT }, // Right
138         { VK_LSHIFT,            SDL_SCANCODE_LSHIFT }, // Right
139 //      { VK_CONTROL,           SDL_SCANCODE_CTRL }, // Right
140         { VK_RCONTROL,          SDL_SCANCODE_RCTRL }, // Right
141         { VK_LCONTROL,          SDL_SCANCODE_LCTRL }, // Left
142         { VK_RMENU,             SDL_SCANCODE_RALT },  // Right
143         { VK_LMENU,             SDL_SCANCODE_LALT },  // Left
144         { VK_MENU,              SDL_SCANCODE_MENU },  // Right
145         { VK_RWIN,              SDL_SCANCODE_RGUI },
146         { VK_LWIN,              SDL_SCANCODE_LGUI },
147         { VK_HELP,              SDL_SCANCODE_HELP }, // Right?
148 #ifdef VK_PRINT
149         { VK_PRINT,             SDL_SCANCODE_PRINTSCREEN },
150 #endif
151         { VK_SNAPSHOT,          SDL_SCANCODE_PRINTSCREEN },
152         { VK_CANCEL,            SDL_SCANCODE_PAUSE },
153         { VK_APPS,              SDL_SCANCODE_APPLICATION },
154         { 0xBA,                 SDL_SCANCODE_KP_COLON },
155         { 0xBB,                 SDL_SCANCODE_SEMICOLON },
156 //        { 0xBB,                       SDL_SCANCODE_KP_SEMICOLON },
157         { 0xBC,                 SDL_SCANCODE_COMMA },
158         { 0xBD,                 SDL_SCANCODE_MINUS },//
159         { 0xBE,                 SDL_SCANCODE_PERIOD },//
160         { 0xBF,                 SDL_SCANCODE_SLASH },//
161         { 0xBB,                 SDL_SCANCODE_EQUALS },//
162         { 0xC0,                 SDL_SCANCODE_KP_AT },
163         { 0xDB,                 SDL_SCANCODE_LEFTBRACKET },//]
164         { 0xDC,                 SDL_SCANCODE_BACKSLASH },  // Okay?
165         { 0xDD,                 SDL_SCANCODE_RIGHTBRACKET }, //[
166         { 0xDE,                 SDL_SCANCODE_NONUSBACKSLASH }, // ^
167 //      { 0xDF,                 SDL_SCANCODE_QuoteLeft },
168
169         // VK_CAPITAL 
170         { 0xF0,                 SDL_SCANCODE_CAPSLOCK },
171         // VK_KANA 
172         { 0xF2,                 SDL_SCANCODE_LANG3 },
173         { 0xF2,                 SDL_SCANCODE_LANG4 },
174         // VK_KANJI 
175         { 0xF3,                 SDL_SCANCODE_LANG5 },
176 //      { 0xF4,                 SDL_SCANCODE_Hankaku },
177    
178         { 0xffffffff, 0xffffffff}
179 };
180
181
182
183
184 uint32_t convert_SDLKey2VK(uint32_t sym)
185 {
186    uint32 n = 0;
187    int i = 0;
188    do {
189       if(SDLKeyMappings[i].sdlkey == sym) {
190            n = SDLKeyMappings[i].vk;
191            break;
192       }
193       
194       i++;
195    } while(QtKeyMappings[i].vk != 0xffffffff);
196    //if((n == VK_LSHIFT) || (n == VK_RSHIFT)) n = VK_SHIFT;
197    //if((n == VK_LCTRL) || (n == VK_RCTRL)) n = VK_CONTROL;
198    //if((n == VL_RMENU) || (n == VK_RMENU)) n = VK_MENU;
199    return n;
200 }
201
202 void EMU::initialize_input()
203 {
204         // initialize status
205         memset(key_status, 0, sizeof(key_status));
206         memset(joy_status, 0, sizeof(joy_status));
207         memset(mouse_status, 0, sizeof(mouse_status));
208         
209         // initialize joysticks
210         // mouse emulation is disenabled
211         mouse_enabled = false;
212         joy_num = SDL_NumJoysticks();
213         for(int i = 0; i < joy_num && i < 2; i++) {
214            //SDL_Joystick *joycaps = SDL_JoystickOpen(i);
215            //if(joycaps != NULL) {
216            //   joy_mask[i] = (1 << SDL_JoystickNumButtons(joycaps)) - 1;
217            //   SDL_JoystickClose(joycaps);
218            //} else {
219               joy_mask[i] = 0x0f; // 4buttons
220            //}
221   
222         }
223
224         
225         // initialize keycode convert table
226         FILEIO* fio = new FILEIO();
227         if(fio->Fopen(bios_path(_T("keycode.cfg")), FILEIO_READ_BINARY)) {
228                 fio->Fread(keycode_conv, sizeof(keycode_conv), 1);
229                 fio->Fclose();
230         } else {
231                 for(int i = 0; i < 256; i++) {
232                         keycode_conv[i] = i;
233                 }
234         }
235         delete fio;
236         
237 #ifdef USE_SHIFT_NUMPAD_KEY
238         // initialize shift+numpad conversion
239         memset(key_converted, 0, sizeof(key_converted));
240         key_shift_pressed = key_shift_released = false;
241 #endif
242 #ifdef USE_AUTO_KEY
243         // initialize autokey
244         autokey_buffer = new FIFO(65536);
245         autokey_buffer->clear();
246         autokey_phase = autokey_shift = 0;
247 #endif
248         lost_focus = false;
249 }
250
251 void EMU::release_input()
252 {
253         // release mouse
254         if(mouse_enabled) {
255                 disenable_mouse();
256         }
257         
258 #ifdef USE_AUTO_KEY
259         // release autokey buffer
260         if(autokey_buffer) {
261                 autokey_buffer->release();
262                 delete autokey_buffer;
263         }
264 #endif
265 }
266
267
268 void EMU::update_input()
269 {
270
271     int *keystat;
272     int i_c = 0;;
273    
274         // release keys
275 #ifdef USE_AUTO_KEY
276         if(lost_focus && autokey_phase == 0) {
277 #else
278         if(lost_focus) {
279 #endif
280                 // we lost key focus so release all pressed keys
281                 for(int i = 0; i < 256; i++) {
282                         if(key_status[i] & 0x80) {
283                                 key_status[i] &= 0x7f;
284 #ifdef NOTIFY_KEY_DOWN
285                                 if(!key_status[i]) {
286                                         vm->key_up(i);
287                                 }
288 #endif
289                         }
290                 }
291         } else {
292                 for(int i = 0; i < 256; i++) {
293                         if(key_status[i] & 0x7f) {
294                                 key_status[i] = (key_status[i] & 0x80) | ((key_status[i] & 0x7f) - 1);
295 #ifdef NOTIFY_KEY_DOWN
296                                 if(!key_status[i]) {
297                                         vm->key_up(i);
298                                 }
299 #endif
300                         }
301                 }
302         }
303         lost_focus = false;
304 #if 1   
305         // update joystick status
306 #ifdef USE_KEY_TO_JOY
307         // emulate joystick #1 with keyboard
308         if(key_status[0x26]) joy_status[0] |= 0x01;     // up
309         if(key_status[0x28]) joy_status[0] |= 0x02;     // down
310         if(key_status[0x25]) joy_status[0] |= 0x04;     // left
311         if(key_status[0x27]) joy_status[0] |= 0x08;     // right
312 #ifdef KEY_TO_JOY_BUTTON_U
313         if(key_status[KEY_TO_JOY_BUTTON_U]) joy_status[0] |= 0x01;
314 #endif
315 #ifdef KEY_TO_JOY_BUTTON_D
316         if(key_status[KEY_TO_JOY_BUTTON_D]) joy_status[0] |= 0x02;
317 #endif
318 #ifdef KEY_TO_JOY_BUTTON_L
319         if(key_status[KEY_TO_JOY_BUTTON_L]) joy_status[0] |= 0x04;
320 #endif
321 #ifdef KEY_TO_JOY_BUTTON_R
322         if(key_status[KEY_TO_JOY_BUTTON_R]) joy_status[0] |= 0x08;
323 #endif
324 #ifdef KEY_TO_JOY_BUTTON_1
325         if(key_status[KEY_TO_JOY_BUTTON_1]) joy_status[0] |= 0x10;
326 #endif
327 #ifdef KEY_TO_JOY_BUTTON_2
328         if(key_status[KEY_TO_JOY_BUTTON_2]) joy_status[0] |= 0x20;
329 #endif
330 #ifdef KEY_TO_JOY_BUTTON_3
331         if(key_status[KEY_TO_JOY_BUTTON_3]) joy_status[0] |= 0x40;
332 #endif
333 #ifdef KEY_TO_JOY_BUTTON_4
334         if(key_status[KEY_TO_JOY_BUTTON_4]) joy_status[0] |= 0x80;
335 #endif
336 #endif
337
338 #endif
339         // update mouse status
340         memset(mouse_status, 0, sizeof(mouse_status));
341 #if 0
342            if(mouse_enabled) {
343                 // get current status
344                 POINT pt;
345                 GetCursorPos(&pt);
346                 ScreenToClient(main_window_handle, &pt);
347                 mouse_status[0]  = pt.x - display_width / 2;
348                 mouse_status[1]  = pt.y - display_height / 2;
349                 mouse_status[2]  = (GetAsyncKeyState(VK_LBUTTON, modkey_status) & 0x8000) ? 1 : 0;
350                 mouse_status[2] |= (GetAsyncKeyState(VK_RBUTTON, modkey_status) & 0x8000) ? 2 : 0;
351                 mouse_status[2] |= (GetAsyncKeyState(VK_MBUTTON, modkey_status) & 0x8000) ? 4 : 0;
352                  move mouse cursor to the center of window
353                 if(!(mouse_status[0] == 0 && mouse_status[1] == 0)) {
354                         pt.x = display_width / 2;
355                         pt.y = display_height / 2;
356                 //      ClientToScreen(main_window_handle, &pt);
357                 //      SetCursorPos(pt.x, pt.y);
358                 }
359         }
360 #endif
361
362 #if 0
363 #ifdef USE_AUTO_KEY
364         // auto key
365         switch(autokey_phase) {
366         case 1:
367                 if(autokey_buffer && !autokey_buffer->empty()) {
368                         // update shift key status
369                         int shift = autokey_buffer->read_not_remove(0) & 0x100;
370                         if(shift && !autokey_shift) {
371                                 key_down(VK_SHIFT, false);
372                         } else if(!shift && autokey_shift) {
373                                 key_up(VK_SHIFT);
374                         }
375                         autokey_shift = shift;
376                         autokey_phase++;
377                         break;
378                 }
379         case 3:
380                 if(autokey_buffer && !autokey_buffer->empty()) {
381                         key_down(autokey_buffer->read_not_remove(0) & 0xff, false);
382                 }
383                 autokey_phase++;
384                 break;
385         case USE_AUTO_KEY:
386                 if(autokey_buffer && !autokey_buffer->empty()) {
387                         key_up(autokey_buffer->read_not_remove(0) & 0xff);
388                 }
389                 autokey_phase++;
390                 break;
391         case USE_AUTO_KEY_RELEASE:
392                 if(autokey_buffer && !autokey_buffer->empty()) {
393                         // wait enough while vm analyzes one line
394                         if(autokey_buffer->read() == 0xd) {
395                                 autokey_phase++;
396                                 break;
397                         }
398                 }
399         case 30:
400                 if(autokey_buffer && !autokey_buffer->empty()) {
401                         autokey_phase = 1;
402                 } else {
403                         stop_auto_key();
404                 }
405                 break;
406         default:
407                 if(autokey_phase) {
408                         autokey_phase++;
409                 }
410         }
411 #endif
412 #endif
413         }
414
415
416
417 #ifdef USE_SHIFT_NUMPAD_KEY
418 static const int numpad_table[256] = {
419         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
420         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421 //      0x00, 0x69, 0x63, 0x61, 0x67, 0x64, 0x68, 0x66, 0x62, 0x00, 0x00, 0x00, 0x00, 0x60, 0x6e, 0x00,
422         0x00, 0x69, 0x63, 0x61, 0x67, 0x64, 0x68, 0x66, 0x62, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, // remove shift + period
423         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
431         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
432         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
436 };
437 #endif
438
439 void EMU::key_down(int sym, bool repeat)
440 {
441         bool keep_frames = false;
442         uint8 code = sym;
443 //        code = convert_AGKey2VK(sym);
444
445          //printf("Key down %08x\n", sym);
446
447 #if 1  // No needed with SDL?
448        if(code == VK_SHIFT) {
449 #ifndef USE_SHIFT_NUMPAD_KEY
450 //              if(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000) key_status[VK_LSHIFT] = 0x80;
451 //              if(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000) key_status[VK_RSHIFT] = 0x80;
452 //              if(!(key_status[VK_LSHIFT] || key_status[VK_RSHIFT])) key_status[VK_LSHIFT] = 0x80;
453 #endif
454         } else if(code == VK_CONTROL) {
455                 if(GetAsyncKeyState(VK_LCONTROL, modkey_status) & 0x8000) key_status[VK_LCONTROL] = 0x80;
456                 if(GetAsyncKeyState(VK_RCONTROL, modkey_status) & 0x8000) key_status[VK_RCONTROL] = 0x80;
457                 if(!(key_status[VK_LCONTROL] || key_status[VK_RCONTROL])) key_status[VK_LCONTROL] = 0x80;
458         } else if(code == VK_MENU) {
459                 if(GetAsyncKeyState(VK_LMENU, modkey_status) & 0x8000) key_status[VK_LMENU] = 0x80;
460                 if(GetAsyncKeyState(VK_RMENU, modkey_status) & 0x8000) key_status[VK_RMENU] = 0x80;
461                 if(!(key_status[VK_LMENU] || key_status[VK_RMENU])) key_status[VK_LMENU] = 0x80;
462         } else if(code == 0xf0) {
463                 code = VK_CAPITAL;
464                 keep_frames = true;
465         } else if(code == 0xf2) {
466                 code = VK_KANA;
467                 keep_frames = true;
468         } else if(code == 0xf3 || code == 0xf4) {
469                 code = VK_KANJI;
470                 keep_frames = true;
471         }
472 #else  //SDL
473        if(code == 0xf0) {
474                 code = VK_CAPITAL;
475                 keep_frames = true;
476         } else if(code == 0xf2) {
477                 code = VK_KANA;
478                 keep_frames = true;
479         } else if(code == 0xf3 || code == 0xf4) {
480                 code = VK_KANJI;
481                 keep_frames = true;
482         }
483 #endif
484    
485 # ifdef USE_SHIFT_NUMPAD_KEY
486         if(code == VK_SHIFT) {
487                 key_shift_pressed = true;
488                 return;
489         } else if(numpad_table[code] != 0) {
490                 if(key_shift_pressed || key_shift_released) {
491                         key_converted[code] = 1;
492                         key_shift_pressed = true;
493                         code = numpad_table[code];
494                 }
495         }
496 #endif
497
498        if(!(code == VK_CONTROL || code == VK_MENU)) {
499                 code = keycode_conv[code];
500         }
501         
502 #ifdef DONT_KEEEP_KEY_PRESSED
503         if(!(code == VK_CONTROL || code == VK_MENU)) {
504                 key_status[code] = KEY_KEEP_FRAMES;
505         } else
506 #endif
507      
508         key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80;
509 #ifdef NOTIFY_KEY_DOWN
510         if(keep_frames) {
511                 repeat = false;
512         }
513         vm->key_down(code, repeat);
514 #endif
515
516 }
517
518         
519 void EMU::key_up(int sym)
520 {
521         uint8 code = sym;
522 //        code = convert_AGKey2VK(sym);
523    //printf("Key up %03x %03x\n", sym, code);
524 #if 1
525    if(code == VK_SHIFT) {
526 #ifndef USE_SHIFT_NUMPAD_KEY
527 //              if(!(GetAsyncKeyState(VK_LSHIFT, modkey_status) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
528 //              if(!(GetAsyncKeyState(VK_RSHIFT, modkey_status) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
529 #endif
530         } else if(code == VK_CONTROL) {
531                 if(!(GetAsyncKeyState(VK_LCONTROL, modkey_status) & 0x8000)) key_status[VK_LCONTROL] &= 0x7f;
532                 if(!(GetAsyncKeyState(VK_RCONTROL, modkey_status) & 0x8000)) key_status[VK_RCONTROL] &= 0x7f;
533         } else if(code == VK_MENU) {
534                 if(!(GetAsyncKeyState(VK_LMENU, modkey_status) & 0x8000)) key_status[VK_LMENU] &= 0x7f;
535                 if(!(GetAsyncKeyState(VK_RMENU, modkey_status) & 0x8000)) key_status[VK_RMENU] &= 0x7f;
536         } else
537 #endif
538      {
539            key_status[code] &= 0x7f;
540 #ifdef NOTIFY_KEY_DOWN
541            vm->key_up(code);
542 #endif
543         }
544
545
546 #ifdef USE_SHIFT_NUMPAD_KEY
547         if(code == VK_SHIFT) {
548                 key_shift_pressed = false;
549                 key_shift_released = true;
550                 return;
551         } else if(key_converted[code] != 0) {
552                 key_converted[code] = 0;
553                 code = numpad_table[code];
554         }
555    
556 #endif
557         if(!(code == VK_SHIFT || code == VK_CONTROL || code == VK_MENU)) {
558                 code = keycode_conv[code];
559         }
560         if(key_status[code]) {
561                 key_status[code] &= 0x7f;
562 #ifdef NOTIFY_KEY_DOWN
563                 if(!key_status[code]) {
564                         vm->key_up(code);
565                 }
566 #endif
567         }
568
569 }
570
571 #ifdef USE_BUTTON
572 void EMU::press_button(int num)
573 {
574 #if 1
575         int code = buttons[num].code;
576         
577         if(code) {
578                 key_down(code, false);
579                 key_status[code] = KEY_KEEP_FRAMES;
580         } else {
581                 // code=0: reset virtual machine
582                 vm->reset();
583         }
584 #endif
585 }
586 #endif
587
588 void EMU::enable_mouse()
589 {
590         // enable mouse emulation
591         if(!mouse_enabled) {
592 #if 0
593                 // hide mouse cursor
594                 ShowCursor(FALSE);
595                 // move mouse cursor to the center of window
596                 POINT pt;
597                 pt.x = display_width / 2;
598                 pt.y = display_height / 2;
599                 ClientToScreen(main_window_handle, &pt);
600                 SetCursorPos(pt.x, pt.y);
601 #endif
602         }
603         mouse_enabled = true;
604
605 }
606
607
608
609 void EMU::disenable_mouse()
610 {
611 #if 0
612         // disenable mouse emulation
613         if(mouse_enabled) {
614                 ShowCursor(TRUE);
615         }
616 #endif
617       mouse_enabled = false;
618 }
619
620 void EMU::toggle_mouse()
621 {
622         // toggle mouse enable / disenable
623         if(mouse_enabled) {
624                 disenable_mouse();
625         } else {
626                 enable_mouse();
627         }
628 }
629
630 #ifdef USE_AUTO_KEY
631 static const int autokey_table[256] = {
632         // 0x100: shift
633         // 0x200: kana
634         // 0x400: alphabet
635         // 0x800: ALPHABET
636         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x00d,0x000,0x000,0x00d,0x000,0x000,
637         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
638         0x020,0x131,0x132,0x133,0x134,0x135,0x136,0x137,0x138,0x139,0x1ba,0x1bb,0x0bc,0x0bd,0x0be,0x0bf,
639         0x030,0x031,0x032,0x033,0x034,0x035,0x036,0x037,0x038,0x039,0x0ba,0x0bb,0x1bc,0x1bd,0x1be,0x1bf,
640         0x0c0,0x441,0x442,0x443,0x444,0x445,0x446,0x447,0x448,0x449,0x44a,0x44b,0x44c,0x44d,0x44e,0x44f,
641         0x450,0x451,0x452,0x453,0x454,0x455,0x456,0x457,0x458,0x459,0x45a,0x0db,0x0dc,0x0dd,0x0de,0x1e2,
642         0x1c0,0x841,0x842,0x843,0x844,0x845,0x846,0x847,0x848,0x849,0x84a,0x84b,0x84c,0x84d,0x84e,0x84f,
643         0x850,0x851,0x852,0x853,0x854,0x855,0x856,0x857,0x858,0x859,0x85a,0x1db,0x1dc,0x1dd,0x1de,0x000,
644         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
645         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
646         // kana -->
647         0x000,0x3be,0x3db,0x3dd,0x3bc,0x3bf,0x330,0x333,0x345,0x334,0x335,0x336,0x337,0x338,0x339,0x35a,
648         0x2dc,0x233,0x245,0x234,0x235,0x236,0x254,0x247,0x248,0x2ba,0x242,0x258,0x244,0x252,0x250,0x243,
649         0x251,0x241,0x25a,0x257,0x253,0x255,0x249,0x231,0x2bc,0x24b,0x246,0x256,0x232,0x2de,0x2bd,0x24a,
650         0x24e,0x2dd,0x2bf,0x24d,0x237,0x238,0x239,0x24f,0x24c,0x2be,0x2bb,0x2e2,0x230,0x259,0x2c0,0x2db,
651         // <--- kana
652         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
653         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000
654 };
655
656 void EMU::start_auto_key()
657 {
658 #if 0
659         stop_auto_key();
660         
661         if(OpenClipboard(NULL)) {
662                 HANDLE hClip = GetClipboardData(CF_TEXT);
663                 if(hClip) {
664                         autokey_buffer->clear();
665                         char* buf = (char*)GlobalLock(hClip);
666                         int size = strlen(buf), prev_kana = 0;
667                         for(int i = 0; i < size; i++) {
668                                 int code = buf[i] & 0xff;
669                                 if((0x81 <= code && code <= 0x9f) || 0xe0 <= code) {
670                                         i++;    // kanji ?
671                                         continue;
672                                 } else if(code == 0xa) {
673                                         continue;       // cr-lf
674                                 }
675                                 if((code = autokey_table[code]) != 0) {
676                                         int kana = code & 0x200;
677                                         if(prev_kana != kana) {
678                                                 autokey_buffer->write(0xf2);
679                                         }
680                                         prev_kana = kana;
681 #if defined(USE_AUTO_KEY_NO_CAPS)
682                                         if((code & 0x100) && !(code & (0x400 | 0x800))) {
683 #elif defined(USE_AUTO_KEY_CAPS)
684                                         if(code & (0x100 | 0x800)) {
685 #else
686                                         if(code & (0x100 | 0x400)) {
687 #endif
688                                                 autokey_buffer->write((code & 0xff) | 0x100);
689                                         } else {
690                                                 autokey_buffer->write(code & 0xff);
691                                         }
692                                 }
693                         }
694                         if(prev_kana) {
695                                 autokey_buffer->write(0xf2);
696                         }
697                         GlobalUnlock(hClip);
698                         
699                         autokey_phase = 1;
700                         autokey_shift = 0;
701                 }
702                 CloseClipboard();
703         }
704 #endif
705 }
706
707 void EMU::stop_auto_key()
708 {
709 #if 1
710         if(autokey_shift) {
711                 key_up(VK_SHIFT);
712         }
713         autokey_phase = autokey_shift = 0;
714 #endif
715 }
716 #endif
717
718  void Ui_MainWindow::msleep_joy(unsigned long int ticks)
719  {
720      hRunJoyThread->msleep(ticks);
721  }
722  
723  JoyThreadClass::JoyThreadClass(QObject *parent) : QObject(parent)
724  {
725    int i;
726    for(i = 0; i < 2; i++) joyhandle[i] = SDL_JoystickOpen(i);
727      joy_num = SDL_NumJoysticks();
728      AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : Start.");
729      bRunThread = true;
730  }
731  
732  JoyThreadClass::~JoyThreadClass()
733  {
734   int i;
735     for(i = 0; i < 2; i++) {
736       if(joyhandle[i] != NULL) SDL_JoystickClose(joyhandle[i]);
737     }
738     AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : EXIT");
739  }
740  
741 void JoyThreadClass::x_axis_changed(int index, int value)
742 {
743    if(p_emu == NULL) return;
744    p_emu->LockVM();
745    uint32_t *joy_status = p_emu->getJoyStatPtr();
746    
747    if(joy_status != NULL) {
748       if(value < -8192) { // left
749          joy_status[index] |= 0x04; joy_status[index] &= ~0x08;
750       } else if(value > 8192)  { // right
751          joy_status[index] |= 0x08; joy_status[index] &= ~0x04;
752       }  else { // center
753          joy_status[index] &= ~0x0c;
754       }
755    }
756    
757    p_emu->UnlockVM();
758 }
759            
760 void JoyThreadClass::y_axis_changed(int index, int value)
761 {
762    if(p_emu == NULL) return;
763    p_emu->LockVM();
764    uint32_t *joy_status = p_emu->getJoyStatPtr();
765    
766    if(joy_status != NULL) {
767       if(value < -8192) {// up
768          joy_status[index] |= 0x01; joy_status[index] &= ~0x02;
769       } else if(value > 8192)  {// down 
770          joy_status[index] |= 0x02; joy_status[index] &= ~0x01;
771       } else {
772          joy_status[index] &= ~0x03;
773       }
774    }
775    
776    p_emu->UnlockVM();
777 }
778
779 void JoyThreadClass::button_down(int index, unsigned int button)
780 {
781       if(p_emu == NULL) return;
782       p_emu->LockVM();
783       uint32_t *joy_status = p_emu->getJoyStatPtr();
784       if(joy_status != NULL) {
785          joy_status[index] |= (1 << (button + 4));
786       }
787       p_emu->UnlockVM();
788 }
789
790 void JoyThreadClass::button_up(int index, unsigned int button)
791 {
792    if(p_emu == NULL) return;
793    
794    p_emu->LockVM();
795    uint32_t *joy_status = p_emu->getJoyStatPtr();
796       if(joy_status != NULL) {
797          joy_status[index] &= ~(1 << (button + 4));
798       }
799    p_emu->UnlockVM();
800 }
801            
802 // SDL Event Handler
803 bool  JoyThreadClass::EventSDL(SDL_Event *eventQueue)
804 {
805    //   SDL_Surface *p;
806    Sint16 value;
807    unsigned int button;
808    int vk;
809    uint32_t sym;
810    int i;
811    if(eventQueue == NULL) return;
812         /*
813          * JoyStickなどはSDLが管理する
814          */
815    switch (eventQueue->type){
816     case SDL_JOYAXISMOTION:
817       value = eventQueue->jaxis.value;
818       i = eventQueue->jaxis.which;
819       if((i < 0) || (i > 1)) break;
820
821       if(eventQueue->jaxis.axis == 0) { // X
822          x_axis_changed(i, value);
823       } else if(eventQueue->jaxis.axis == 1) { // Y
824          y_axis_changed(i, value);
825       }
826       break;
827     case SDL_JOYBUTTONDOWN:
828       button = eventQueue->jbutton.button;
829       i = eventQueue->jbutton.which;
830       if((i < 0) || (i > 1)) break;
831       button_down(i, button);
832       break;
833     case SDL_JOYBUTTONUP:
834       button = eventQueue->jbutton.button;
835       i = eventQueue->jbutton.which;
836       if((i < 0) || (i > 1)) break;
837       button_up(i, button);
838       break;
839     default:
840       break;
841    }
842    return TRUE;
843 }
844
845
846 void JoyThreadClass::doWork(void)
847 {
848   if(bRunThread == false) {
849     return;
850   }
851   while(SDL_PollEvent(&event) == 1) {
852     EventSDL(&event);
853   }
854   timer.setInterval(10);
855   return;
856 }
857
858 void JoyThreadClass::doExit(void)
859 {
860     bRunThread = false;
861     timer.stop();
862 }
863
864
865 void Ui_MainWindow::LaunchJoyThread(void)
866 {
867     hRunJoy = new JoyThreadClass();
868     hRunJoy->p_emu = emu;
869     connect(&(hRunJoy->timer), SIGNAL(timeout()), hRunJoy, SLOT(doWork()));
870     connect(this, SIGNAL(quit_joy_thread()), hRunJoy, SLOT(doExit()));
871    
872     hRunJoy->timer.setInterval(10);
873     hRunJoy->timer.setSingleShot(false);
874     hRunJoy->timer.start(10);
875    
876 }
877 void Ui_MainWindow::StopJoyThread(void) {
878     emit quit_joy_thread();
879 }
880
881 void Ui_MainWindow::delete_joy_thread(void)
882 {
883   //    delete hRunJoyThread;
884   //  delete hRunJoy;
885 }