2 * Skelton for retropc emulator
4 * Author : Takeda.Toshiya
6 * Converted to QT by (C) 2015 K.Ohta
8 * Jan 12, 2015 (maybe) : Initial
9 * [ SDL input -> Keyboard]
19 #include "qt_gldraw.h"
21 #include "menuclasses.h"
22 #include "agar_logger.h"
25 #define Ulong unsigned long
28 #define KEY_KEEP_FRAMES 3
32 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},//_\
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 },
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 },
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 },
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?
149 { VK_PRINT, SDL_SCANCODE_PRINTSCREEN },
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 },
170 { 0xF0, SDL_SCANCODE_CAPSLOCK },
172 { 0xF2, SDL_SCANCODE_LANG3 },
173 { 0xF2, SDL_SCANCODE_LANG4 },
175 { 0xF3, SDL_SCANCODE_LANG5 },
176 // { 0xF4, SDL_SCANCODE_Hankaku },
178 { 0xffffffff, 0xffffffff}
184 uint32_t convert_SDLKey2VK(uint32_t sym)
189 if(SDLKeyMappings[i].sdlkey == sym) {
190 n = SDLKeyMappings[i].vk;
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;
202 void EMU::initialize_input()
205 memset(key_status, 0, sizeof(key_status));
206 memset(joy_status, 0, sizeof(joy_status));
207 memset(mouse_status, 0, sizeof(mouse_status));
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);
219 joy_mask[i] = 0x0f; // 4buttons
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);
231 for(int i = 0; i < 256; i++) {
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;
243 // initialize autokey
244 autokey_buffer = new FIFO(65536);
245 autokey_buffer->clear();
246 autokey_phase = autokey_shift = 0;
251 void EMU::release_input()
259 // release autokey buffer
261 autokey_buffer->release();
262 delete autokey_buffer;
268 void EMU::update_input()
276 if(lost_focus && autokey_phase == 0) {
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
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
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;
315 #ifdef KEY_TO_JOY_BUTTON_D
316 if(key_status[KEY_TO_JOY_BUTTON_D]) joy_status[0] |= 0x02;
318 #ifdef KEY_TO_JOY_BUTTON_L
319 if(key_status[KEY_TO_JOY_BUTTON_L]) joy_status[0] |= 0x04;
321 #ifdef KEY_TO_JOY_BUTTON_R
322 if(key_status[KEY_TO_JOY_BUTTON_R]) joy_status[0] |= 0x08;
324 #ifdef KEY_TO_JOY_BUTTON_1
325 if(key_status[KEY_TO_JOY_BUTTON_1]) joy_status[0] |= 0x10;
327 #ifdef KEY_TO_JOY_BUTTON_2
328 if(key_status[KEY_TO_JOY_BUTTON_2]) joy_status[0] |= 0x20;
330 #ifdef KEY_TO_JOY_BUTTON_3
331 if(key_status[KEY_TO_JOY_BUTTON_3]) joy_status[0] |= 0x40;
333 #ifdef KEY_TO_JOY_BUTTON_4
334 if(key_status[KEY_TO_JOY_BUTTON_4]) joy_status[0] |= 0x80;
339 // update mouse status
340 memset(mouse_status, 0, sizeof(mouse_status));
343 // get current status
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);
365 switch(autokey_phase) {
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) {
375 autokey_shift = shift;
380 if(autokey_buffer && !autokey_buffer->empty()) {
381 key_down(autokey_buffer->read_not_remove(0) & 0xff, false);
386 if(autokey_buffer && !autokey_buffer->empty()) {
387 key_up(autokey_buffer->read_not_remove(0) & 0xff);
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) {
400 if(autokey_buffer && !autokey_buffer->empty()) {
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
439 void EMU::key_down(int sym, bool repeat)
441 bool keep_frames = false;
443 // code = convert_AGKey2VK(sym);
445 //printf("Key down %08x\n", sym);
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;
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) {
465 } else if(code == 0xf2) {
468 } else if(code == 0xf3 || code == 0xf4) {
476 } else if(code == 0xf2) {
479 } else if(code == 0xf3 || code == 0xf4) {
485 # ifdef USE_SHIFT_NUMPAD_KEY
486 if(code == VK_SHIFT) {
487 key_shift_pressed = true;
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];
498 if(!(code == VK_CONTROL || code == VK_MENU)) {
499 code = keycode_conv[code];
502 #ifdef DONT_KEEEP_KEY_PRESSED
503 if(!(code == VK_CONTROL || code == VK_MENU)) {
504 key_status[code] = KEY_KEEP_FRAMES;
508 key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80;
509 #ifdef NOTIFY_KEY_DOWN
513 vm->key_down(code, repeat);
519 void EMU::key_up(int sym)
522 // code = convert_AGKey2VK(sym);
523 //printf("Key up %03x %03x\n", sym, code);
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;
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;
539 key_status[code] &= 0x7f;
540 #ifdef NOTIFY_KEY_DOWN
546 #ifdef USE_SHIFT_NUMPAD_KEY
547 if(code == VK_SHIFT) {
548 key_shift_pressed = false;
549 key_shift_released = true;
551 } else if(key_converted[code] != 0) {
552 key_converted[code] = 0;
553 code = numpad_table[code];
557 if(!(code == VK_SHIFT || code == VK_CONTROL || code == VK_MENU)) {
558 code = keycode_conv[code];
560 if(key_status[code]) {
561 key_status[code] &= 0x7f;
562 #ifdef NOTIFY_KEY_DOWN
563 if(!key_status[code]) {
572 void EMU::press_button(int num)
575 int code = buttons[num].code;
578 key_down(code, false);
579 key_status[code] = KEY_KEEP_FRAMES;
581 // code=0: reset virtual machine
588 void EMU::enable_mouse()
590 // enable mouse emulation
595 // move mouse cursor to the center of window
597 pt.x = display_width / 2;
598 pt.y = display_height / 2;
599 ClientToScreen(main_window_handle, &pt);
600 SetCursorPos(pt.x, pt.y);
603 mouse_enabled = true;
609 void EMU::disenable_mouse()
612 // disenable mouse emulation
617 mouse_enabled = false;
620 void EMU::toggle_mouse()
622 // toggle mouse enable / disenable
631 static const int autokey_table[256] = {
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,
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,
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
656 void EMU::start_auto_key()
661 if(OpenClipboard(NULL)) {
662 HANDLE hClip = GetClipboardData(CF_TEXT);
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) {
672 } else if(code == 0xa) {
675 if((code = autokey_table[code]) != 0) {
676 int kana = code & 0x200;
677 if(prev_kana != kana) {
678 autokey_buffer->write(0xf2);
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)) {
686 if(code & (0x100 | 0x400)) {
688 autokey_buffer->write((code & 0xff) | 0x100);
690 autokey_buffer->write(code & 0xff);
695 autokey_buffer->write(0xf2);
707 void EMU::stop_auto_key()
713 autokey_phase = autokey_shift = 0;
718 void Ui_MainWindow::msleep_joy(unsigned long int ticks)
720 hRunJoyThread->msleep(ticks);
723 JoyThreadClass::JoyThreadClass(QObject *parent) : QObject(parent)
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.");
732 JoyThreadClass::~JoyThreadClass()
735 for(i = 0; i < 2; i++) {
736 if(joyhandle[i] != NULL) SDL_JoystickClose(joyhandle[i]);
738 AGAR_DebugLog(AGAR_LOG_DEBUG, "JoyThread : EXIT");
741 void JoyThreadClass::x_axis_changed(int index, int value)
743 if(p_emu == NULL) return;
745 uint32_t *joy_status = p_emu->getJoyStatPtr();
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;
753 joy_status[index] &= ~0x0c;
760 void JoyThreadClass::y_axis_changed(int index, int value)
762 if(p_emu == NULL) return;
764 uint32_t *joy_status = p_emu->getJoyStatPtr();
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;
772 joy_status[index] &= ~0x03;
779 void JoyThreadClass::button_down(int index, unsigned int button)
781 if(p_emu == NULL) return;
783 uint32_t *joy_status = p_emu->getJoyStatPtr();
784 if(joy_status != NULL) {
785 joy_status[index] |= (1 << (button + 4));
790 void JoyThreadClass::button_up(int index, unsigned int button)
792 if(p_emu == NULL) return;
795 uint32_t *joy_status = p_emu->getJoyStatPtr();
796 if(joy_status != NULL) {
797 joy_status[index] &= ~(1 << (button + 4));
803 bool JoyThreadClass::EventSDL(SDL_Event *eventQueue)
811 if(eventQueue == NULL) return;
813 * JoyStickなどはSDLが管理する
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;
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);
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);
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);
846 void JoyThreadClass::doWork(void)
848 if(bRunThread == false) {
851 while(SDL_PollEvent(&event) == 1) {
854 timer.setInterval(10);
858 void JoyThreadClass::doExit(void)
865 void Ui_MainWindow::LaunchJoyThread(void)
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()));
872 hRunJoy->timer.setInterval(10);
873 hRunJoy->timer.setSingleShot(false);
874 hRunJoy->timer.start(10);
877 void Ui_MainWindow::StopJoyThread(void) {
878 emit quit_joy_thread();
881 void Ui_MainWindow::delete_joy_thread(void)
883 // delete hRunJoyThread;