mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-05 14:10:27 -04:00
keyboard mapping
This commit is contained in:
parent
b6c5658b48
commit
bf59962724
7 changed files with 392 additions and 49 deletions
|
@ -24,34 +24,82 @@ void get_ms_event(MS_EVENT *event)
|
||||||
win_mouseEvent.event=0;
|
win_mouseEvent.event=0;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
char cz_table_1[] = { 0x20, 0x31, 0x21, 0x33, 0x34, 0x35, 0x37, 0xad, 0x39,
|
char cz_table_small_normal[] =
|
||||||
0x30, 0x38, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x82, 0x2b, 0x88, 0xa8, 0x87,
|
{ 0x20, 0x31, 0x21, 0x33, 0x34, 0x35, 0x37, 0xad,
|
||||||
0xa9, 0x91, 0x98, 0xa0, 0xa1, 0x5c, 0x22, 0x96, 0x3f, 0x3d, 0x3a, 0x5f,
|
0x39, 0x30, 0x38, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x82, 0x2b, 0x88, 0xa8,
|
||||||
|
0x87, 0xa9, 0x91, 0x98, 0xa0, 0xa1, 0x22, 0x96, 0x3f, 0x3d, 0x3a, 0x5f,
|
||||||
0x32, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
|
0x32, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
|
||||||
0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||||
0x58, 0x59, 0x5a, 0xa3, 0x5c, 0x5c, 0x29, 0x36, 0x3d, 0x3b, 0x61, 0x62,
|
0x58, 0x59, 0x5a, 0xa3, 0x5c, 0x29, 0x36, 0x3d, 0x3b, 0x61, 0x62, 0x63,
|
||||||
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x2f,
|
||||||
0x2f, 0x7c, 0x28, 0x3b, 0x20 };
|
0x7c, 0x28, 0x3b, 0x20 };
|
||||||
char cz_table_2[] = { 0x20, 0x21, 0x5c, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
char cz_table_small_carka[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||||
|
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
|
||||||
|
0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
|
||||||
|
0x8f, 0x42, 0x43, 0x44, 0x90, 0x46, 0x47, 0x48, 0x8b, 0x4a, 0x4b, 0x8a,
|
||||||
|
0x4d, 0x4e, 0x95, 0x50, 0x51, 0xab, 0x53, 0x54, 0x97, 0x56, 0x57, 0x58,
|
||||||
|
0x9d, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0xa0, 0x62, 0x63, 0x64,
|
||||||
|
0x82, 0x66, 0x67, 0x68, 0xa1, 0x6a, 0x6b, 0x8d, 0x6d, 0x6e, 0xa2, 0x70,
|
||||||
|
0x71, 0xaa, 0x73, 0x74, 0xa3, 0x76, 0x77, 0x78, 0x98, 0x7a, 0x7b, 0x7c,
|
||||||
|
0x7d, 0x7e, 0x20 };
|
||||||
|
char cz_table_small_hacek[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||||
|
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
|
||||||
|
0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
|
||||||
|
0x41, 0x42, 0x80, 0x85, 0x89, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x9c,
|
||||||
|
0x4d, 0xa5, 0xa7, 0x50, 0x51, 0x9e, 0x9b, 0x86, 0xa6, 0x56, 0x57, 0x58,
|
||||||
|
0x59, 0x92, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x87, 0x83,
|
||||||
|
0x88, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x8c, 0x6d, 0xa4, 0x93, 0x70,
|
||||||
|
0x71, 0xa9, 0xa8, 0x9f, 0x96, 0x76, 0x77, 0x78, 0x79, 0x91, 0x7b, 0x7c,
|
||||||
|
0x7d, 0x7e, 0x20 };
|
||||||
|
char cz_table_caps_normal[] =
|
||||||
|
{ 0x20, 0x31, 0x21, 0x33, 0x34, 0x35, 0x37, 0xad,
|
||||||
|
0x39, 0x30, 0x38, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||||
|
|
||||||
|
0x90, 0x2b, 0x89, 0x9b, 0x80, 0x9e, 0x92, 0x9d, 0x8f, 0x8b,
|
||||||
|
|
||||||
|
0x22, 0x96, 0x3f, 0x3d, 0x3a, 0x5f,
|
||||||
|
0x32, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||||
|
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||||
|
0x78, 0x79, 0x7a, 0xa3, 0x5c, 0x29, 0x36, 0x3d, 0x3b, 0x41, 0x42, 0x43,
|
||||||
|
0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||||
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x2f,
|
||||||
|
0x7c, 0x28, 0x3b, 0x20 };
|
||||||
|
char cz_table_caps_carka[] =
|
||||||
|
{ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
|
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
|
||||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||||
0x40, 0x8f, 0x42, 0x43, 0x44, 0x90, 0x46, 0x47, 0x48, 0x8b, 0x4a, 0x4b,
|
0x40,
|
||||||
0x8a, 0x4d, 0x4e, 0x95, 0x50, 0x51, 0xab, 0x53, 0x54, 0x97, 0x56, 0x57,
|
|
||||||
0x58, 0x9d, 0x5a, 0x5b, 0x5c, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0xa0, 0x62,
|
0xa0, 0x62, 0x63, 0x64, 0x82, 0x66, 0x67, 0x68, 0xa1, 0x6a,
|
||||||
0x63, 0x64, 0x82, 0x66, 0x67, 0x68, 0xa1, 0x6a, 0x6b, 0x8d, 0x6d, 0x6e,
|
0x6b, 0x8d, 0x6d, 0x6e, 0xa2, 0x70, 0x71, 0xaa, 0x73, 0x74,
|
||||||
0xa2, 0x70, 0x71, 0xaa, 0x73, 0x74, 0xa3, 0x76, 0x77, 0x78, 0x98, 0x7a,
|
0xa3, 0x76, 0x77, 0x78, 0x98, 0x7a,
|
||||||
|
|
||||||
|
0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
|
||||||
|
|
||||||
|
0x8f, 0x42, 0x43, 0x44, 0x90, 0x46, 0x47, 0x48, 0x8b, 0x4a,
|
||||||
|
0x4b, 0x8a, 0x4d, 0x4e, 0x95, 0x50, 0x51, 0xab, 0x53, 0x54,
|
||||||
|
0x97, 0x56, 0x57, 0x58, 0x9d, 0x5a,
|
||||||
|
|
||||||
0x7b, 0x7c, 0x7d, 0x7e, 0x20 };
|
0x7b, 0x7c, 0x7d, 0x7e, 0x20 };
|
||||||
char cz_table_3[] = { 0x20, 0x21, 0x5c, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
char cz_table_caps_hacek[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
|
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
|
||||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
|
||||||
0x40, 0x41, 0x42, 0x80, 0x85, 0x89, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
|
|
||||||
0x9c, 0x4d, 0xa5, 0xa7, 0x50, 0x51, 0x9e, 0x9b, 0x86, 0xa6, 0x56, 0x57,
|
0x61, 0x62, 0x87, 0x83, 0x88, 0x66, 0x67, 0x68, 0x69, 0x6a,
|
||||||
0x58, 0x59, 0x92, 0x5b, 0x5c, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62,
|
0x6b, 0x8c, 0x6d, 0xa4, 0x93, 0x70, 0x71, 0xa9, 0xa8, 0x9f,
|
||||||
0x87, 0x83, 0x88, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x8c, 0x6d, 0xa4,
|
0x96, 0x76, 0x77, 0x78, 0x79, 0x91,
|
||||||
0x93, 0x70, 0x71, 0xa9, 0xa8, 0x9f, 0x96, 0x76, 0x77, 0x78, 0x79, 0x91,
|
|
||||||
|
0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
|
||||||
|
|
||||||
|
0x41, 0x42, 0x80, 0x85, 0x89, 0x46, 0x47, 0x48, 0x49, 0x4a,
|
||||||
|
0x4b, 0x9c, 0x4d, 0xa5, 0xa7, 0x50, 0x51, 0x9e, 0x9b, 0x86,
|
||||||
|
0xa6, 0x56, 0x57, 0x58, 0x59, 0x92,
|
||||||
|
|
||||||
|
|
||||||
0x7b, 0x7c, 0x7d, 0x7e, 0x20 };
|
0x7b, 0x7c, 0x7d, 0x7e, 0x20 };
|
||||||
char *cz_key_tabs[]={cz_table_1,cz_table_2,cz_table_3};
|
char *cz_key_tabs[]={cz_table_small_normal,cz_table_small_carka,cz_table_small_hacek,
|
||||||
|
cz_table_caps_normal, cz_table_caps_carka, cz_table_caps_hacek};
|
||||||
|
|
||||||
void keyboard(EVENT_MSG *msg,void *user_data)
|
void keyboard(EVENT_MSG *msg,void *user_data)
|
||||||
{
|
{
|
||||||
|
@ -71,6 +119,7 @@ void keyboard(EVENT_MSG *msg,void *user_data)
|
||||||
else if (c=='=' && d<55 && !cz_mode) cz_mode=1;
|
else if (c=='=' && d<55 && !cz_mode) cz_mode=1;
|
||||||
else if (c>32 && c<127 && d<=53)
|
else if (c>32 && c<127 && d<=53)
|
||||||
{
|
{
|
||||||
|
if (get_capslock_state()) cz_mode +=3;
|
||||||
c=cz_key_tabs[cz_mode][c-32];
|
c=cz_key_tabs[cz_mode][c-32];
|
||||||
i=d;
|
i=d;
|
||||||
i=(i<<8)+c;
|
i=(i<<8)+c;
|
||||||
|
|
|
@ -36,6 +36,7 @@ void SetWheelMapping(char up, char down);
|
||||||
|
|
||||||
char get_control_key_state(void);
|
char get_control_key_state(void);
|
||||||
char get_shift_key_state(void);
|
char get_shift_key_state(void);
|
||||||
|
char get_capslock_state(void);
|
||||||
void display_error(const char *text);
|
void display_error(const char *text);
|
||||||
|
|
||||||
int stricmp(const char *a, const char *b);
|
int stricmp(const char *a, const char *b);
|
||||||
|
|
|
@ -1,14 +1,25 @@
|
||||||
#include "global_context.h"
|
#include "global_context.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "../platform.h"
|
||||||
|
|
||||||
char get_control_key_state() {
|
char get_control_key_state() {
|
||||||
return 0; //todo
|
return get_sdl_global_context().get_control_key_state()?1:0;
|
||||||
}
|
}
|
||||||
char get_shift_key_state() {
|
char get_shift_key_state() {
|
||||||
return 0; //todo
|
return get_sdl_global_context().get_shift_key_state()?1:0;
|
||||||
|
}
|
||||||
|
char get_capslock_state() {
|
||||||
|
return get_sdl_global_context().get_capslock_state()?1:0;
|
||||||
}
|
}
|
||||||
uint32_t _bios_keybrd(int mode) {
|
uint32_t _bios_keybrd(int mode) {
|
||||||
return 0;
|
if (mode == _KEYBRD_READY) {
|
||||||
|
return get_sdl_global_context().is_keyboard_ready()?1:0;
|
||||||
|
} else if (mode == _KEYBRD_READ) {
|
||||||
|
return get_sdl_global_context().pop_keyboard_code();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetWheelMapping(char up, char down) { //todo
|
void SetWheelMapping(char up, char down) { //todo
|
||||||
|
|
|
@ -16,8 +16,11 @@ extern "C" {
|
||||||
#include <devices.h>
|
#include <devices.h>
|
||||||
|
|
||||||
|
|
||||||
char get_control_key_state();
|
char get_control_key_state(void);
|
||||||
char get_shift_key_state();
|
char get_shift_key_state(void);
|
||||||
|
char get_capslock_state(void);
|
||||||
|
|
||||||
|
|
||||||
uint32_t _bios_keybrd(int mode);
|
uint32_t _bios_keybrd(int mode);
|
||||||
void SetWheelMapping(char up, char down);
|
void SetWheelMapping(char up, char down);
|
||||||
void get_ms_event(MS_EVENT *event);
|
void get_ms_event(MS_EVENT *event);
|
||||||
|
|
131
platform/sdl/keyboard_map.h
Normal file
131
platform/sdl/keyboard_map.h
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
struct SDLKey2Bios {
|
||||||
|
SDL_Scancode scan_code;
|
||||||
|
uint16_t normal;
|
||||||
|
uint16_t shift;
|
||||||
|
uint16_t ctrl;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class KeyCodeMap {
|
||||||
|
public:
|
||||||
|
|
||||||
|
template<int n>
|
||||||
|
constexpr KeyCodeMap(const SDLKey2Bios (&codes)[n]) {
|
||||||
|
for (const SDLKey2Bios &x: codes) {
|
||||||
|
int idx = static_cast<int>(x.scan_code);
|
||||||
|
normal[idx] = x.normal;
|
||||||
|
w_ctrl[idx] = x.ctrl;
|
||||||
|
w_shift[idx] = x.shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
constexpr uint16_t get_bios_code(SDL_Scancode scan, bool shift, bool control) const {
|
||||||
|
if (control) return w_ctrl[static_cast<int>(scan)];
|
||||||
|
if (shift) return w_shift[static_cast<int>(scan)];
|
||||||
|
return normal[static_cast<int>(scan)];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint16_t normal[SDL_NUM_SCANCODES] = {};
|
||||||
|
uint16_t w_shift[SDL_NUM_SCANCODES] = {};
|
||||||
|
uint16_t w_ctrl[SDL_NUM_SCANCODES] = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr auto sdl_keycode_map = KeyCodeMap({
|
||||||
|
{SDL_SCANCODE_A, 0x1E61, 0x1E41, 0x1E01},
|
||||||
|
{SDL_SCANCODE_B,0x3062,0x3042,0x3002},
|
||||||
|
{SDL_SCANCODE_C,0x2E63,0x2E42,0x2E03},
|
||||||
|
{SDL_SCANCODE_D,0x2064,0x2044,0x2004},
|
||||||
|
{SDL_SCANCODE_E,0x1265,0x1245,0x1205},
|
||||||
|
{SDL_SCANCODE_F,0x2166,0x2146,0x2106},
|
||||||
|
{SDL_SCANCODE_G,0x2267,0x2247,0x2207},
|
||||||
|
{SDL_SCANCODE_H,0x2368,0x2348,0x2308},
|
||||||
|
{SDL_SCANCODE_I,0x1769,0x1749,0x1709},
|
||||||
|
{SDL_SCANCODE_J,0x246A,0x244A,0x240A},
|
||||||
|
{SDL_SCANCODE_K,0x256B,0x254B,0x250B},
|
||||||
|
{SDL_SCANCODE_L,0x266C,0x264C,0x260C},
|
||||||
|
{SDL_SCANCODE_M,0x326D,0x324D,0x320D},
|
||||||
|
{SDL_SCANCODE_N,0x316E,0x314E,0x310E},
|
||||||
|
{SDL_SCANCODE_O,0x186F,0x184F,0x180F},
|
||||||
|
{SDL_SCANCODE_P,0x1970,0x1950,0x1910},
|
||||||
|
{SDL_SCANCODE_Q,0x1071,0x1051,0x1011},
|
||||||
|
{SDL_SCANCODE_R,0x1372,0x1352,0x1312},
|
||||||
|
{SDL_SCANCODE_S,0x1F73,0x1F53,0x1F13},
|
||||||
|
{SDL_SCANCODE_T,0x1474,0x1454,0x1414},
|
||||||
|
{SDL_SCANCODE_U,0x1675,0x1655,0x1615},
|
||||||
|
{SDL_SCANCODE_V,0x2F76,0x2F56,0x2F16},
|
||||||
|
{SDL_SCANCODE_W,0x1177,0x1157,0x1117},
|
||||||
|
{SDL_SCANCODE_X,0x2D78,0x2D58,0x2D18},
|
||||||
|
{SDL_SCANCODE_Y,0x1579,0x1559,0x1519},
|
||||||
|
{SDL_SCANCODE_Z,0x2C7A,0x2C5A,0x2C1A},
|
||||||
|
{SDL_SCANCODE_1,0x0231,0x0221,0x7800},
|
||||||
|
{SDL_SCANCODE_2,0x0332,0x0340,0x0300},
|
||||||
|
{SDL_SCANCODE_3,0x0433,0x0423,0x7A00},
|
||||||
|
{SDL_SCANCODE_4,0x0534,0x0524,0x7B00},
|
||||||
|
{SDL_SCANCODE_5,0x0635,0x0625,0x7C00},
|
||||||
|
{SDL_SCANCODE_6,0x0736,0x075E,0x071E},
|
||||||
|
{SDL_SCANCODE_7,0x0837,0x0826,0x7E00},
|
||||||
|
{SDL_SCANCODE_8,0x0938,0x092A,0x7F00},
|
||||||
|
{SDL_SCANCODE_9,0x0A39,0x0A28,0x8000},
|
||||||
|
{SDL_SCANCODE_0,0x0B30,0x0B29,0x8100},
|
||||||
|
{SDL_SCANCODE_MINUS,0x0C2D,0x0C5F,0x0C1F},
|
||||||
|
{SDL_SCANCODE_EQUALS,0x0D3D,0x0D2B,0x8300},
|
||||||
|
{SDL_SCANCODE_LEFTBRACKET,0x1A5B,0x1A7B,0x1A1B},
|
||||||
|
{SDL_SCANCODE_RIGHTBRACKET,0x1B5D,0x1B7D,0x1B1D},
|
||||||
|
{SDL_SCANCODE_SEMICOLON,0x273B,0x273A,0x2700},
|
||||||
|
{SDL_SCANCODE_APOSTROPHE,0x2827,0x2822,0},
|
||||||
|
{SDL_SCANCODE_GRAVE,0x2960,0x297E,0},
|
||||||
|
{SDL_SCANCODE_BACKSLASH,0x2B5C,0x2B7C,0x2B1C},
|
||||||
|
{SDL_SCANCODE_COMMA,0x332C,0x333C,0},
|
||||||
|
{SDL_SCANCODE_PERIOD,0x342E,0x343E,0},
|
||||||
|
{SDL_SCANCODE_SLASH,0x352F,0x353F,0},
|
||||||
|
{SDL_SCANCODE_F1 ,0x3B00,0x5400,0x5E00},
|
||||||
|
{SDL_SCANCODE_F2 ,0x3C00,0x5500,0x5F00},
|
||||||
|
{SDL_SCANCODE_F3 ,0x3D00,0x5600,0x6000},
|
||||||
|
{SDL_SCANCODE_F4 ,0x3E00,0x5700,0x6100},
|
||||||
|
{SDL_SCANCODE_F5 ,0x3F00,0x5800,0x6200},
|
||||||
|
{SDL_SCANCODE_F6 ,0x4000,0x5900,0x6300},
|
||||||
|
{SDL_SCANCODE_F7 ,0x4100,0x5A00,0x6400},
|
||||||
|
{SDL_SCANCODE_F8 ,0x4200,0x5B00,0x6500},
|
||||||
|
{SDL_SCANCODE_F9 ,0x4300,0x5C00,0x6600},
|
||||||
|
{SDL_SCANCODE_F10,0x4400,0x5D00,0x6700},
|
||||||
|
{SDL_SCANCODE_F11,0x8500,0x8700,0x8900},
|
||||||
|
{SDL_SCANCODE_F12,0x8600,0x8800,0x8A00},
|
||||||
|
{SDL_SCANCODE_BACKSPACE,0x0E08,0x0E08,0x0E7F},
|
||||||
|
{SDL_SCANCODE_DELETE,0x5300,0x5300,0x9300},
|
||||||
|
{SDL_SCANCODE_DOWN,0x5000,0x5000,0x9100},
|
||||||
|
{SDL_SCANCODE_END,0x4F00,0x4F00,0x7500},
|
||||||
|
{SDL_SCANCODE_RETURN,0x1C0D,0x1C0D,0x1C0A},
|
||||||
|
{SDL_SCANCODE_ESCAPE,0x011B,0x011B,0x011B},
|
||||||
|
{SDL_SCANCODE_HOME,0x4700,0x4700,0x7700},
|
||||||
|
{SDL_SCANCODE_INSERT,0x5200,0x5200,0x9200},
|
||||||
|
{SDL_SCANCODE_KP_MULTIPLY,0x372A,0x9600,0x3700},
|
||||||
|
{SDL_SCANCODE_KP_MINUS,0x4A2D,0x4A2D,0x8E00},
|
||||||
|
{SDL_SCANCODE_KP_PLUS,0x4E2B,0x4E2B,0x4E00},
|
||||||
|
{SDL_SCANCODE_KP_DIVIDE,0x352F,0x352F,0x9500},
|
||||||
|
{SDL_SCANCODE_LEFT,0x4B00,0x4B00,0x7300},
|
||||||
|
{SDL_SCANCODE_PAGEDOWN,0x5100,0x5100,0x7600},
|
||||||
|
{SDL_SCANCODE_PAGEUP,0x4900,0x4900,0x8400},
|
||||||
|
{SDL_SCANCODE_PRINTSCREEN,0x7200,0,0},
|
||||||
|
{SDL_SCANCODE_RIGHT,0x4D00,0x4D00,0x7400},
|
||||||
|
{SDL_SCANCODE_SPACE,0x3920,0x3920,0x3920},
|
||||||
|
{SDL_SCANCODE_TAB,0x0F09,0x0F09,0x9400},
|
||||||
|
{SDL_SCANCODE_UP,0x4800,0x4800,0x8D00},
|
||||||
|
{SDL_SCANCODE_KP_1,0x4F31,0x4F00,0x7500},
|
||||||
|
{SDL_SCANCODE_KP_2,0x5032,0x5000,0x9100},
|
||||||
|
{SDL_SCANCODE_KP_3,0x5133,0x5100,0x7600},
|
||||||
|
{SDL_SCANCODE_KP_4,0x4B34,0x4B00,0x7300},
|
||||||
|
{SDL_SCANCODE_KP_5,0x4C35,0x4C00,0x8F00},
|
||||||
|
{SDL_SCANCODE_KP_6,0x4D36,0x4D00,0x7400},
|
||||||
|
{SDL_SCANCODE_KP_7,0x4737,0x4700,0x7700},
|
||||||
|
{SDL_SCANCODE_KP_8,0x4838,0x4800,0x8D00},
|
||||||
|
{SDL_SCANCODE_KP_9,0x4939,0x4900,0x8400},
|
||||||
|
{SDL_SCANCODE_KP_0,0x5230,0x5200,0x9200},
|
||||||
|
{SDL_SCANCODE_KP_PERIOD,0x532E,0x5300,0x9300}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#include "sdl_context.h"
|
#include "sdl_context.h"
|
||||||
|
#include "keyboard_map.h"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "../platform.h"
|
#include "../platform.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
void SDLContext::SDL_Deleter::operator ()(SDL_Window* window) {
|
void SDLContext::SDL_Deleter::operator ()(SDL_Window* window) {
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
|
@ -83,13 +85,20 @@ void SDLContext::init_screen(DisplayMode mode, const char *title) {
|
||||||
throw std::runtime_error(buff);
|
throw std::runtime_error(buff);
|
||||||
}
|
}
|
||||||
_renderer.reset(renderer);
|
_renderer.reset(renderer);
|
||||||
// Vytvoření textury pro zobrazení backbufferu
|
|
||||||
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
snprintf(buff, sizeof(buff), "Chyba při vytváření textury: %s\n", SDL_GetError());
|
snprintf(buff, sizeof(buff), "Chyba při vytváření textury: %s\n", SDL_GetError());
|
||||||
throw std::runtime_error(buff);
|
throw std::runtime_error(buff);
|
||||||
}
|
}
|
||||||
_texture.reset(texture);
|
_texture.reset(texture);
|
||||||
|
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
||||||
|
if (!texture) {
|
||||||
|
snprintf(buff, sizeof(buff), "Chyba při vytváření textury: %s\n", SDL_GetError());
|
||||||
|
throw std::runtime_error(buff);
|
||||||
|
}
|
||||||
|
_texture2.reset(texture);
|
||||||
|
_visible_texture = _texture.get();
|
||||||
|
_hidden_texture = _texture.get();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
e = std::current_exception();
|
e = std::current_exception();
|
||||||
err = true;
|
err = true;
|
||||||
|
@ -99,6 +108,7 @@ void SDLContext::init_screen(DisplayMode mode, const char *title) {
|
||||||
SDL_ShowCursor(SDL_DISABLE);
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
if (!err) event_loop(stp);
|
if (!err) event_loop(stp);
|
||||||
_texture.reset();
|
_texture.reset();
|
||||||
|
_texture2.reset();
|
||||||
_renderer.reset();
|
_renderer.reset();
|
||||||
_window.reset();
|
_window.reset();
|
||||||
});
|
});
|
||||||
|
@ -139,9 +149,19 @@ void SDLContext::event_loop(std::stop_token stp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.type == SDL_KEYDOWN) {
|
if (e.type == SDL_KEYDOWN) {
|
||||||
|
_key_capslock = e.key.keysym.mod & KMOD_CAPS;
|
||||||
|
_key_shift =e.key.keysym.mod & KMOD_SHIFT;
|
||||||
|
_key_control =e.key.keysym.mod & KMOD_CTRL;
|
||||||
if (e.key.keysym.sym == SDLK_RETURN && (e.key.keysym.mod & KMOD_ALT)) {
|
if (e.key.keysym.sym == SDLK_RETURN && (e.key.keysym.mod & KMOD_ALT)) {
|
||||||
_fullscreen_mode = !_fullscreen_mode;
|
_fullscreen_mode = !_fullscreen_mode;
|
||||||
SDL_SetWindowFullscreen(_window.get(), _fullscreen_mode ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
SDL_SetWindowFullscreen(_window.get(), _fullscreen_mode ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||||
|
} else {
|
||||||
|
auto code =sdl_keycode_map.get_bios_code(e.key.keysym.scancode,
|
||||||
|
e.key.keysym.mod & KMOD_SHIFT, e.key.keysym.mod & KMOD_CTRL);
|
||||||
|
if (code) {
|
||||||
|
std::lock_guard _(_mx);
|
||||||
|
_keyboard_queue.push(code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (e.type == SDL_MOUSEMOTION) {
|
} else if (e.type == SDL_MOUSEMOTION) {
|
||||||
int mouseX = e.motion.x;
|
int mouseX = e.motion.x;
|
||||||
|
@ -233,34 +253,112 @@ void SDLContext::present_rect(uint16_t *pixels, unsigned int pitch,
|
||||||
static_cast<int>(y),
|
static_cast<int>(y),
|
||||||
static_cast<int>(xs),
|
static_cast<int>(xs),
|
||||||
static_cast<int>(ys)};
|
static_cast<int>(ys)};
|
||||||
std::vector<short> data;
|
|
||||||
data.resize(xs*ys);
|
|
||||||
auto iter = data.begin();
|
|
||||||
for (unsigned int yp = 0; yp <ys; ++yp) {
|
|
||||||
iter = std::copy(beg, beg+xs,iter );
|
|
||||||
beg+=pitch;
|
|
||||||
}
|
|
||||||
std::lock_guard _(_mx);
|
std::lock_guard _(_mx);
|
||||||
|
signal_push();
|
||||||
|
push_update_msg(r, beg, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint16_t SDLContext::pop_keyboard_code() {
|
||||||
|
std::lock_guard _(_mx);
|
||||||
|
std::uint16_t out = _keyboard_queue.front();
|
||||||
|
_keyboard_queue.pop();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDLContext::is_keyboard_ready() const {
|
||||||
|
std::lock_guard _(_mx);
|
||||||
|
return !_keyboard_queue.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDLContext::signal_push() {
|
||||||
if (_display_update_queue.empty()) {
|
if (_display_update_queue.empty()) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
event.type = _update_request_event;
|
event.type = _update_request_event;
|
||||||
SDL_PushEvent(&event);
|
SDL_PushEvent(&event);
|
||||||
}
|
}
|
||||||
_display_update_queue.push_back({std::move(r), std::move(data)});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLContext::update_screen() {
|
void SDLContext::update_screen() {
|
||||||
{
|
{
|
||||||
std::lock_guard _(_mx);
|
std::lock_guard _(_mx);
|
||||||
for (const UpdateMsg &msg:_display_update_queue) {
|
QueueIter iter = _display_update_queue.data();
|
||||||
SDL_UpdateTexture(_texture.get(), &msg.rc, msg.data.data(), msg.rc.w*2);
|
QueueIter end = iter + _display_update_queue.size();
|
||||||
|
while (iter != end) {
|
||||||
|
DisplayRequest req;
|
||||||
|
pop_item(iter, req);
|
||||||
|
switch (req) {
|
||||||
|
case DisplayRequest::update: {
|
||||||
|
SDL_Rect r;
|
||||||
|
pop_item(iter, r);
|
||||||
|
std::string_view data = pop_data(iter, r.w*r.h*2);
|
||||||
|
SDL_UpdateTexture(_texture.get(), &r, data.data(), r.w*2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DisplayRequest::swap_render_buffers: {
|
||||||
|
std::swap(_texture,_texture2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DisplayRequest::swap_visible_buffers: {
|
||||||
|
std::swap(_visible_texture,_hidden_texture);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_display_update_queue.clear();
|
_display_update_queue.clear();
|
||||||
}
|
}
|
||||||
SDL_RenderClear(_renderer.get());
|
SDL_RenderClear(_renderer.get());
|
||||||
SDL_RenderCopy(_renderer.get(), _texture.get(), NULL, NULL);
|
SDL_RenderCopy(_renderer.get(), _visible_texture, NULL, NULL);
|
||||||
SDL_RenderPresent(_renderer.get());
|
SDL_RenderPresent(_renderer.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
requires(std::is_trivially_copy_constructible_v<T>)
|
||||||
|
void SDLContext::push_item(const T &item) {
|
||||||
|
auto b = reinterpret_cast<const char *>(&item);
|
||||||
|
auto e = b + sizeof(T);
|
||||||
|
auto sz = _display_update_queue.size();
|
||||||
|
_display_update_queue.resize(sz + sizeof(T));
|
||||||
|
std::copy(b, e, _display_update_queue.begin()+sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDLContext::push_item(const std::string_view &item) {
|
||||||
|
auto sz = _display_update_queue.size();
|
||||||
|
_display_update_queue.resize(sz + item.size());
|
||||||
|
std::copy(item.begin(), item.end(), _display_update_queue.begin()+sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDLContext::push_update_msg(const SDL_Rect &rc, const uint16_t *data, int pitch) {
|
||||||
|
push_item(DisplayRequest::update);
|
||||||
|
push_item(rc);
|
||||||
|
for (int yp = 0; yp < rc.h; ++yp) {
|
||||||
|
push_item(std::string_view(reinterpret_cast<const char *>(data), rc.w*2));
|
||||||
|
data += pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
requires(std::is_trivially_copy_constructible_v<T>)
|
||||||
|
void SDLContext::pop_item(QueueIter &iter, T &item) {
|
||||||
|
std::copy(iter, iter+sizeof(T), reinterpret_cast<char *>(&item));
|
||||||
|
iter += sizeof(T);
|
||||||
|
}
|
||||||
|
std::string_view SDLContext::pop_data(QueueIter &iter, std::size_t size) {
|
||||||
|
const char *c = iter;
|
||||||
|
iter += size;
|
||||||
|
return std::string_view(c, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDLContext::swap_render_buffers() {
|
||||||
|
std::lock_guard _(_mx);
|
||||||
|
signal_push();
|
||||||
|
push_item(DisplayRequest::swap_render_buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDLContext::swap_display_buffers() {
|
||||||
|
std::lock_guard _(_mx);
|
||||||
|
signal_push();
|
||||||
|
push_item(DisplayRequest::swap_render_buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <mouse.h>
|
#include <mouse.h>
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
class SDLContext {
|
class SDLContext {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -25,6 +27,8 @@ public:
|
||||||
|
|
||||||
|
|
||||||
void present_rect(uint16_t *pixels, unsigned int pitch, unsigned int x, unsigned int y, unsigned int xs,unsigned ys);
|
void present_rect(uint16_t *pixels, unsigned int pitch, unsigned int x, unsigned int y, unsigned int xs,unsigned ys);
|
||||||
|
void swap_render_buffers();
|
||||||
|
void swap_display_buffers();
|
||||||
|
|
||||||
MS_EVENT getMsEvent() {
|
MS_EVENT getMsEvent() {
|
||||||
std::lock_guard _(_mx);
|
std::lock_guard _(_mx);
|
||||||
|
@ -33,6 +37,20 @@ public:
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get_shift_key_state() const {
|
||||||
|
return _key_shift;
|
||||||
|
}
|
||||||
|
bool get_control_key_state() const {
|
||||||
|
return _key_control;
|
||||||
|
}
|
||||||
|
bool get_capslock_state() const {
|
||||||
|
return _key_capslock;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_keyboard_ready() const;
|
||||||
|
std::uint16_t pop_keyboard_code() ;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
struct SDL_Deleter {
|
struct SDL_Deleter {
|
||||||
|
@ -42,30 +60,62 @@ protected:
|
||||||
void operator()(SDL_Texture *);
|
void operator()(SDL_Texture *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UpdateMsg {
|
||||||
|
SDL_Rect rc;
|
||||||
|
std::vector<short> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class DisplayRequest {
|
||||||
|
update,
|
||||||
|
swap_render_buffers,
|
||||||
|
swap_visible_buffers,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
MS_EVENT ms_event;
|
MS_EVENT ms_event;
|
||||||
|
mutable std::mutex _mx;
|
||||||
|
|
||||||
std::unique_ptr<SDL_Window, SDL_Deleter> _window;
|
std::unique_ptr<SDL_Window, SDL_Deleter> _window;
|
||||||
std::unique_ptr<SDL_Renderer, SDL_Deleter> _renderer;
|
std::unique_ptr<SDL_Renderer, SDL_Deleter> _renderer;
|
||||||
std::unique_ptr<SDL_Texture, SDL_Deleter> _texture;
|
std::unique_ptr<SDL_Texture, SDL_Deleter> _texture;
|
||||||
|
std::unique_ptr<SDL_Texture, SDL_Deleter> _texture2;
|
||||||
|
SDL_Texture *_visible_texture;
|
||||||
|
SDL_Texture *_hidden_texture;
|
||||||
|
|
||||||
std::jthread _render_thread;
|
std::jthread _render_thread;
|
||||||
|
|
||||||
bool _quit_requested = false;
|
bool _quit_requested = false;
|
||||||
bool _fullscreen_mode = false;
|
bool _fullscreen_mode = false;
|
||||||
bool _present = false;
|
bool _present = false;
|
||||||
void charge_timer();
|
std::atomic<bool> _key_control = false;
|
||||||
|
std::atomic<bool> _key_shift = false;
|
||||||
|
std::atomic<bool> _key_capslock = false;
|
||||||
|
|
||||||
void event_loop(std::stop_token stp);
|
|
||||||
std::mutex _mx;
|
|
||||||
|
|
||||||
struct UpdateMsg {
|
std::vector<char> _display_update_queue;
|
||||||
SDL_Rect rc;
|
using QueueIter = const char *;
|
||||||
std::vector<short> data;
|
std::queue<uint16_t> _keyboard_queue;
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<UpdateMsg> _display_update_queue;
|
|
||||||
Uint32 _update_request_event;
|
Uint32 _update_request_event;
|
||||||
|
|
||||||
|
|
||||||
|
void event_loop(std::stop_token stp);
|
||||||
void update_screen();
|
void update_screen();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
requires(std::is_trivially_copy_constructible_v<T>)
|
||||||
|
void push_item(const T &item);
|
||||||
|
void push_item(const std::string_view &item);
|
||||||
|
void push_update_msg(const SDL_Rect &rc, const uint16_t *data, int pitch);
|
||||||
|
void push_swap_buffers();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
requires(std::is_trivially_copy_constructible_v<T>)
|
||||||
|
void pop_item(QueueIter &iter, T &item);
|
||||||
|
std::string_view pop_data(QueueIter &iter, std::size_t size);
|
||||||
|
|
||||||
|
void signal_push();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue