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;
719 void JoyThreadClass::x_axis_changed(int index, int value)
721 if(p_emu == NULL) return;
723 uint32_t *joy_status = p_emu->getJoyStatPtr();
725 if(joy_status != NULL) {
726 if(value < -8192) { // left
727 joy_status[index] |= 0x04; joy_status[index] &= ~0x08;
728 } else if(value > 8192) { // right
729 joy_status[index] |= 0x08; joy_status[index] &= ~0x04;
731 joy_status[index] &= ~0x0c;
738 void JoyThreadClass::y_axis_changed(int index, int value)
740 if(p_emu == NULL) return;
742 uint32_t *joy_status = p_emu->getJoyStatPtr();
744 if(joy_status != NULL) {
745 if(value < -8192) {// up
746 joy_status[index] |= 0x01; joy_status[index] &= ~0x02;
747 } else if(value > 8192) {// down
748 joy_status[index] |= 0x02; joy_status[index] &= ~0x01;
750 joy_status[index] &= ~0x03;
757 void JoyThreadClass::button_down(int index, unsigned int button)
759 if(p_emu == NULL) return;
761 uint32_t *joy_status = p_emu->getJoyStatPtr();
762 if(joy_status != NULL) {
763 joy_status[index] |= (1 << (button + 4));
768 void JoyThreadClass::button_up(int index, unsigned int button)
770 if(p_emu == NULL) return;
773 uint32_t *joy_status = p_emu->getJoyStatPtr();
774 if(joy_status != NULL) {
775 joy_status[index] &= ~(1 << (button + 4));
781 bool JoyThreadClass::EventSDL(SDL_Event *eventQueue)
789 if(eventQueue == NULL) return;
791 * JoyStickなどはSDLが管理する
793 switch (eventQueue->type){
794 case SDL_JOYAXISMOTION:
795 value = eventQueue->jaxis.value;
796 i = eventQueue->jaxis.which;
797 if((i < 0) || (i > 1)) break;
799 if(eventQueue->jaxis.axis == 0) { // X
800 x_axis_changed(i, value);
801 } else if(eventQueue->jaxis.axis == 1) { // Y
802 y_axis_changed(i, value);
805 case SDL_JOYBUTTONDOWN:
806 button = eventQueue->jbutton.button;
807 i = eventQueue->jbutton.which;
808 if((i < 0) || (i > 1)) break;
809 button_down(i, button);
811 case SDL_JOYBUTTONUP:
812 button = eventQueue->jbutton.button;
813 i = eventQueue->jbutton.which;
814 if((i < 0) || (i > 1)) break;
815 button_up(i, button);
824 void JoyThreadClass::doWork(EMU *e)
828 SDL_Joystick *joyhandle[2] = {NULL, NULL};
831 for(i = 0; i < 2; i++) joyhandle[i] = SDL_JoystickOpen(i);
832 joy_num = SDL_NumJoysticks();
834 if(rMainWindow->GetJoyThreadEnabled() != true) {
835 for(i = 0; i < 2; i++) {
836 if(joyhandle[i] != NULL) SDL_JoystickClose(joyhandle[i]);
841 if(SDL_WaitEventTimeout(&event, 15) == 1) {
849 void Ui_MainWindow::LaunchJoyThread(void)
851 // bRunEmuThread = true;
852 //hRunEmuThread = SDL_CreateThread(fn, "CSP_EmuThread", (void *)this);
853 bRunJoyThread = true;
854 hRunJoy = new JoyThreadClass();
855 hRunJoyThread = new JoyThreadCore();
856 hRunJoy->moveToThread(hRunJoyThread);
858 connect(this, SIGNAL(call_joy_thread(EMU *)), hRunJoy, SLOT(doWork(EMU *)));
859 connect(this, SIGNAL(quit_joy_thread()), hRunJoyThread, SLOT(quit()));
860 // connect(hRunJoy, SIGNAL(x_axis_changed(int, int)), hRunEmu, SLOT(x_axis_changed(int, int)));
861 // connect(hRunJoy, SIGNAL(y_axis_changed(int, int)), hRunEmu, SLOT(y_axis_changed(int, int)));
862 // connect(hRunJoy, SIGNAL(button_down(int, unsigned int)), hRunEmu, SLOT(button_down(int, unsigned int)));
863 // connect(hRunJoy, SIGNAL(button_up(int, unsigned int)), hRunEmu, SLOT(button_up(int, unsigned int)));
864 hRunJoyThread->start();
865 emit call_joy_thread(emu);
867 void Ui_MainWindow::StopJoyThread(void) {
868 bRunJoyThread = false;
869 emit quit_joy_thread();
872 } while(!hRunJoyThread->wait());
873 delete hRunJoyThread;