diff --git a/libs/devices.c b/libs/devices.c index 72e6fb4..307a9c3 100644 --- a/libs/devices.c +++ b/libs/devices.c @@ -24,34 +24,82 @@ void get_ms_event(MS_EVENT *event) win_mouseEvent.event=0; } */ -char cz_table_1[] = { 0x20, 0x31, 0x21, 0x33, 0x34, 0x35, 0x37, 0xad, 0x39, - 0x30, 0x38, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x82, 0x2b, 0x88, 0xa8, 0x87, - 0xa9, 0x91, 0x98, 0xa0, 0xa1, 0x5c, 0x22, 0x96, 0x3f, 0x3d, 0x3a, 0x5f, +char cz_table_small_normal[] = + { 0x20, 0x31, 0x21, 0x33, 0x34, 0x35, 0x37, 0xad, + 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, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0xa3, 0x5c, 0x5c, 0x29, 0x36, 0x3d, 0x3b, 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, - 0x2f, 0x7c, 0x28, 0x3b, 0x20 }; -char cz_table_2[] = { 0x20, 0x21, 0x5c, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x58, 0x59, 0x5a, 0xa3, 0x5c, 0x29, 0x36, 0x3d, 0x3b, 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, 0x2f, + 0x7c, 0x28, 0x3b, 0x20 }; +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, 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, 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, + 0x40, + + 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, + + 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 }; -char cz_table_3[] = { 0x20, 0x21, 0x5c, 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, 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, +char cz_table_caps_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, + + 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, + + 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 }; -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) { @@ -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>32 && c<127 && d<=53) { + if (get_capslock_state()) cz_mode +=3; c=cz_key_tabs[cz_mode][c-32]; i=d; i=(i<<8)+c; diff --git a/platform/platform.h b/platform/platform.h index 378d08e..fc25ae4 100644 --- a/platform/platform.h +++ b/platform/platform.h @@ -36,6 +36,7 @@ void SetWheelMapping(char up, char down); char get_control_key_state(void); char get_shift_key_state(void); +char get_capslock_state(void); void display_error(const char *text); int stricmp(const char *a, const char *b); diff --git a/platform/sdl/input.cpp b/platform/sdl/input.cpp index c853e9e..519209e 100644 --- a/platform/sdl/input.cpp +++ b/platform/sdl/input.cpp @@ -1,14 +1,25 @@ #include "global_context.h" #include "input.h" +#include "../platform.h" char get_control_key_state() { - return 0; //todo + return get_sdl_global_context().get_control_key_state()?1:0; } 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) { - 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 diff --git a/platform/sdl/input.h b/platform/sdl/input.h index dcf2bfb..f2d1cd8 100644 --- a/platform/sdl/input.h +++ b/platform/sdl/input.h @@ -16,8 +16,11 @@ extern "C" { #include -char get_control_key_state(); -char get_shift_key_state(); +char get_control_key_state(void); +char get_shift_key_state(void); +char get_capslock_state(void); + + uint32_t _bios_keybrd(int mode); void SetWheelMapping(char up, char down); void get_ms_event(MS_EVENT *event); diff --git a/platform/sdl/keyboard_map.h b/platform/sdl/keyboard_map.h new file mode 100644 index 0000000..8323c95 --- /dev/null +++ b/platform/sdl/keyboard_map.h @@ -0,0 +1,131 @@ +#include + +struct SDLKey2Bios { + SDL_Scancode scan_code; + uint16_t normal; + uint16_t shift; + uint16_t ctrl; + +}; + +class KeyCodeMap { +public: + + template + constexpr KeyCodeMap(const SDLKey2Bios (&codes)[n]) { + for (const SDLKey2Bios &x: codes) { + int idx = static_cast(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(scan)]; + if (shift) return w_shift[static_cast(scan)]; + return normal[static_cast(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} +}); + + diff --git a/platform/sdl/sdl_context.cpp b/platform/sdl/sdl_context.cpp index 148cbc1..d7c4021 100644 --- a/platform/sdl/sdl_context.cpp +++ b/platform/sdl/sdl_context.cpp @@ -1,9 +1,11 @@ #include "sdl_context.h" +#include "keyboard_map.h" #include #include #include "../platform.h" +#include #include void SDLContext::SDL_Deleter::operator ()(SDL_Window* window) { SDL_DestroyWindow(window); @@ -83,13 +85,20 @@ void SDLContext::init_screen(DisplayMode mode, const char *title) { throw std::runtime_error(buff); } _renderer.reset(renderer); - // Vytvoření textury pro zobrazení backbufferu SDL_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); } _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 (...) { e = std::current_exception(); err = true; @@ -99,6 +108,7 @@ void SDLContext::init_screen(DisplayMode mode, const char *title) { SDL_ShowCursor(SDL_DISABLE); if (!err) event_loop(stp); _texture.reset(); + _texture2.reset(); _renderer.reset(); _window.reset(); }); @@ -139,9 +149,19 @@ void SDLContext::event_loop(std::stop_token stp) { } 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)) { _fullscreen_mode = !_fullscreen_mode; 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) { int mouseX = e.motion.x; @@ -233,34 +253,112 @@ void SDLContext::present_rect(uint16_t *pixels, unsigned int pitch, static_cast(y), static_cast(xs), static_cast(ys)}; - std::vector data; - data.resize(xs*ys); - auto iter = data.begin(); - for (unsigned int yp = 0; yp +requires(std::is_trivially_copy_constructible_v) +void SDLContext::push_item(const T &item) { + auto b = reinterpret_cast(&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(data), rc.w*2)); + data += pitch; + } +} + +template +requires(std::is_trivially_copy_constructible_v) +void SDLContext::pop_item(QueueIter &iter, T &item) { + std::copy(iter, iter+sizeof(T), reinterpret_cast(&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); +} + diff --git a/platform/sdl/sdl_context.h b/platform/sdl/sdl_context.h index 779222c..5262470 100644 --- a/platform/sdl/sdl_context.h +++ b/platform/sdl/sdl_context.h @@ -7,6 +7,8 @@ #include #include +#include + class SDLContext { 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 swap_render_buffers(); + void swap_display_buffers(); MS_EVENT getMsEvent() { std::lock_guard _(_mx); @@ -33,6 +37,20 @@ public: 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: struct SDL_Deleter { @@ -42,30 +60,62 @@ protected: void operator()(SDL_Texture *); }; + struct UpdateMsg { + SDL_Rect rc; + std::vector data; + }; + + enum class DisplayRequest { + update, + swap_render_buffers, + swap_visible_buffers, + }; + + MS_EVENT ms_event; + mutable std::mutex _mx; std::unique_ptr _window; std::unique_ptr _renderer; std::unique_ptr _texture; + std::unique_ptr _texture2; + SDL_Texture *_visible_texture; + SDL_Texture *_hidden_texture; std::jthread _render_thread; bool _quit_requested = false; bool _fullscreen_mode = false; bool _present = false; - void charge_timer(); + std::atomic _key_control = false; + std::atomic _key_shift = false; + std::atomic _key_capslock = false; - void event_loop(std::stop_token stp); - std::mutex _mx; - struct UpdateMsg { - SDL_Rect rc; - std::vector data; - }; + std::vector _display_update_queue; + using QueueIter = const char *; + std::queue _keyboard_queue; - std::vector _display_update_queue; Uint32 _update_request_event; + + void event_loop(std::stop_token stp); void update_screen(); + template + requires(std::is_trivially_copy_constructible_v) + 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 + requires(std::is_trivially_copy_constructible_v) + void pop_item(QueueIter &iter, T &item); + std::string_view pop_data(QueueIter &iter, std::size_t size); + + void signal_push(); + + + };