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 * [ Qt input -> Keyboard]
23 #include "qt_gldraw.h"
25 #include "menuclasses.h"
26 #include "agar_logger.h"
29 #define Ulong unsigned long
32 #define KEY_KEEP_FRAMES 3
34 const struct NativeScanCode convTable_QTScan106[] = {
49 // Power, Sleep, Wake is not implemented, they are'nt safety.
51 {VK_KANJI, 49}, // Hankaku/Zenkaku
62 {VK_OEM_MINUS, 20}, // - =
64 {VK_OEM_5, 132}, // \|
65 {VK_BACK, 22}, // Backspace
79 {VK_RETURN, 36}, // Enter (Full key)
82 {VK_OEM_ATTN, 66}, // CAPS Lock
92 {VK_OEM_PLUS, 47}, // ;
96 {VK_LSHIFT, 50}, // LShift
104 {VK_OEM_COMMA, 59}, // ,
105 {VK_OEM_PERIOD, 60}, // .
106 {VK_OEM_2, 61}, // /(Slash)
107 {VK_OEM_102, 97}, //\_
113 {VK_NONCONVERT, 102}, // Muhenkan
115 {VK_CONVERT, 100}, // Henkan
116 {VK_OEM_COPY, 101}, // Katakana_Hiragana
148 {VK_DECIMAL, 77}, // NumLock
153 {VK_RETURN, 104}, // Enter(ten Key)
154 {0xffffffff, 0xffffffff}
156 #if defined(Q_OS_WIN32)
157 #else // Linux or Unix
158 const struct NativeVirtualKeyCode convTable_QTKey[] = {
173 // Power, Sleep, Wake is not implemented, they are'nt safety.
175 {VK_KANJI, 0xff2a}, // Hankaku/Zenkaku
176 {VK_OEM_MINUS, 0x002d}, // -=
177 {VK_OEM_MINUS, 0x003d},
178 {VK_OEM_7, 0x005e}, // ^~
180 {VK_OEM_5, 0x005c}, // \|
182 {VK_BACK, 0xff08}, // Backspace
185 {VK_RETURN, 0xff0d}, // Enter (Full key)
186 {VK_OEM_3, 0x0040}, // @
187 {VK_OEM_3, 0x0060}, // @
189 {VK_OEM_4, 0x005b}, // [
190 {VK_OEM_4, 0x007b}, // [
192 {VK_OEM_ATTN, 0xff30}, // CAPS Lock
193 {VK_OEM_PLUS, 0x002b}, // ;
194 {VK_OEM_PLUS, 0x003b}, // ;
195 {VK_OEM_1, 0x002a}, // :
196 {VK_OEM_1, 0x003a}, // :
197 {VK_OEM_6, 0x005d}, // ]
198 {VK_OEM_6, 0x007d}, // ]
200 {VK_LSHIFT, 0xffe1}, // LShift
201 {VK_OEM_COMMA, 0x2c}, // ,
202 {VK_OEM_COMMA, 0x3c}, // ,
203 {VK_OEM_PERIOD, 0x2e}, // .
204 {VK_OEM_PERIOD, 0x3e}, // .
205 {VK_OEM_2, 0x2f}, // /(Slash)
206 {VK_OEM_2, 0x3f}, // /(Slash)
207 {VK_OEM_102, 0x5f}, //\_
211 {VK_LCONTROL, 0xffe3},
214 {VK_NONCONVERT, 0xff22}, // Muhenkan
216 //{VK_OEM_AUTO, 0xff23}, // Henkan
217 {VK_CONVERT, 0xff23}, // Henkan
218 {VK_OEM_COPY, 0xff27}, // Katakana_Hiragana
222 {VK_RCONTROL, 0xffe4},
239 {VK_NUMPAD0, 0xffb0},
240 {VK_NUMPAD1, 0xffb1},
241 {VK_NUMPAD2, 0xffb2},
242 {VK_NUMPAD3, 0xffb3},
243 {VK_NUMPAD4, 0xffb4},
244 {VK_NUMPAD5, 0xffb5},
245 {VK_NUMPAD6, 0xffb6},
246 {VK_NUMPAD7, 0xffb7},
247 {VK_NUMPAD8, 0xffb8},
248 {VK_NUMPAD9, 0xffb9},
250 {VK_DECIMAL, 0xff7f}, // NumLock
252 {VK_MULTIPLY, 0xffaa},
253 {VK_SUBTRACT, 0xffad},
255 {VK_RETURN, 0xff8d}, // Enter(ten Key)
256 {VK_DECIMAL, 0xffae}, // Period(ten Key)
257 {0xffffffff, 0xffffffff}
261 #if defined(Q_OS_WIN32)
262 uint32_t GLDrawClass::getNativeKey2VK(uint32_t data)
265 #if defined(ENABLE_SWAP_KANJI_PAUSE)
266 if(config.swap_kanji_pause) {
269 } else if(vk == VK_PAUSE) {
277 uint32_t GLDrawClass::getNativeKey2VK(uint32_t data)
284 if((data >= 'a') && (data <= 'z')) {
287 if((data >= 'A') && (data <= 'Z')) {
290 if((data >= '0') && (data <= '9')) {
293 if((data > 0x20) && (data <= 0x29)) {
297 while(NativeVirtualKeyCode[i].vk != 0xffffffff) {
298 val = NativeVirtualKeyCode[i].key;
299 if(val == data) break;
302 vk = NativeVirtualKeyCode[i].vk;
304 if(vk == 0xffffffff) return 0;
305 #if defined(ENABLE_SWAP_KANJI_PAUSE)
306 if(config.swap_kanji_pause) {
309 } else if(vk == VK_PAUSE) {
314 #if !defined(_FM8) && !defined(_FM7) && !defined(_FMNEW7) && !defined(_FM77_VARIANTS) && !defined(_FM77AV_VARIANTS)
315 if((vk == VK_LSHIFT) || (vk == VK_RSHIFT)) vk = VK_SHIFT;
316 if((vk == VK_LMENU) || (vk == VK_RMENU)) vk = VK_MENU;
318 if((vk == VK_LCONTROL) || (vk == VK_RCONTROL)) vk = VK_CONTROL;
323 uint32_t GLDrawClass::get106Scancode2VK(uint32_t data)
328 while(NativeScanCode[i].vk != 0xffffffff) {
329 val = NativeScanCode[i].scan;
330 if(val == data) break;
333 vk = NativeScanCode[i].vk;
334 //printf("SCAN=%02x VK=%02x\n", val, vk);
335 if(vk == 0xffffffff) return 0;
336 #if defined(ENABLE_SWAP_KANJI_PAUSE)
337 if(config.swap_kanji_pause) {
340 } else if(vk == VK_PAUSE) {
345 #if !defined(_FM8) && !defined(_FM7) && !defined(_FMNEW7) && !defined(_FM77_VARIANTS) && !defined(_FM77AV_VARIANTS)
346 if((vk == VK_LSHIFT) || (vk == VK_RSHIFT)) vk = VK_SHIFT;
347 if((vk == VK_LMENU) || (vk == VK_RMENU)) vk = VK_MENU;
349 if((vk == VK_LCONTROL) || (vk == VK_RCONTROL)) vk = VK_CONTROL;
353 void GLDrawClass::initKeyCode(void)
356 memset(NativeScanCode, 0x00, sizeof(NativeScanCode));
357 memset(NativeVirtualKeyCode, 0x00, sizeof(NativeVirtualKeyCode));
359 for(i = 0; i < 255; i++) {
360 if(convTable_QTScan106[i].vk == 0xffffffff) break;
361 NativeScanCode[i].vk = convTable_QTScan106[i].vk;
362 NativeScanCode[i].scan = convTable_QTScan106[i].scan;
364 NativeScanCode[i].vk = 0xffffffff;
365 NativeScanCode[i].scan = 0xffffffff;
367 for(i = 0; i < 255; i++) {
368 if(convTable_QTKey[i].vk == 0xffffffff) break;
369 NativeVirtualKeyCode[i].vk = convTable_QTKey[i].vk;
370 NativeVirtualKeyCode[i].key = convTable_QTKey[i].key;
372 NativeVirtualKeyCode[i].vk = 0xffffffff;
373 NativeVirtualKeyCode[i].key = 0xffffffff;
375 // Replace only ScanCode
376 FILEIO *fio = new FILEIO();
377 std::string app_path2;
379 app_path2 = cpp_confdir + "scancode.cfg";
380 if(fio->Fopen(app_path2.c_str(), FILEIO_READ_ASCII)) {
382 memset(buf, 0x00, sizeof(buf));
383 while(fio->Fgets(buf, 512) != NULL) {
387 nstr = QString::fromUtf8(buf);
388 nlist = nstr.split(",", QString::SkipEmptyParts);
389 if(nlist.count() < 2) continue;
390 uint32 vk = nlist.at(0).toULong(&ok1, 16);
391 uint32 scan = nlist.at(1).toULong(&ok2, 16);
392 if((vk == 0) || (vk > 255)) continue;
394 for(i = 0; i < 255; i++) {
395 if(NativeScanCode[i].vk == 0xffffffff) break;
396 if(NativeScanCode[i].scan == scan) {
397 NativeScanCode[i].vk = (uint32)vk;
408 void GLDrawClass::releaseKeyCode(void)
410 // Replace only ScanCode
412 FILEIO *fio = new FILEIO();
413 std::string app_path2;
415 app_path2 = cpp_confdir + "scancode.cfg";
416 if(fio->Fopen(app_path2.c_str(), FILEIO_WRITE_ASCII)) {
417 for(i = 0; i < 255; i++) {
418 if(convTable_QTScan106[i].vk == 0xffffffff) break;
419 fio->Fprintf("%02x,%08x\n", NativeScanCode[i].vk, NativeScanCode[i].scan);
426 void GLDrawClass::keyReleaseEvent(QKeyEvent *event)
428 int key = event->key();
429 uint32 mod = event->modifiers();
432 if(event->isAutoRepeat()) return;
433 //scan = event->nativeVirtualKey();
434 //vk = getNativeKey2VK(scan);
435 scan = event->nativeScanCode();
436 vk = get106Scancode2VK(scan);
438 //printf("Key: UP: VK=%d SCAN=%04x MOD=%08x\n", vk, scan, mod);
441 // Note: Qt4 with 106KEY, event->modifier() don't get Shift key as KEYMOD.
449 void GLDrawClass::keyPressEvent(QKeyEvent *event)
451 int key = event->key();
452 uint32 mod = event->modifiers();;
456 if(event->isAutoRepeat()) return;
457 //scan = event->nativeVirtualKey();
458 //vk = getNativeKey2VK(scan);
459 scan = event->nativeScanCode();
460 vk = get106Scancode2VK(scan);
462 if(vk == VK_APPS) { // Special key : capture/uncapture mouse.
463 emit sig_toggle_mouse();
467 //printf("Key: DOWN: VK=%d SCAN=%04x MOD=%08x\n", vk, scan, mod);
471 emu->key_down(vk, false);
478 uint32_t GetAsyncKeyState(uint32_t vk, uint32_t mod)
480 vk = vk & 0xff; // OK?
481 quint32 modstate = mod;
482 //printf("Mod %d %08x\n", vk, mod);
485 if((modstate & Qt::ShiftModifier) != 0) return 0xffffffff;
488 if((modstate & Qt::ShiftModifier) != 0) return 0xffffffff;
491 if((modstate & Qt::ShiftModifier) != 0) return 0xffffffff;
494 if((modstate & Qt::ControlModifier) != 0) return 0xffffffff;
497 if((modstate & Qt::ControlModifier) != 0) return 0xffffffff;
500 if((modstate & Qt::ControlModifier) != 0) return 0xffffffff;
503 if((modstate & Qt::AltModifier) != 0) return 0xffffffff;
506 if((modstate & Qt::AltModifier) != 0) return 0xffffffff;