Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
keyboard_mapping.c
Go to the documentation of this file.
1 /* Xep128: Minimalistic Enterprise-128 emulator with focus on "exotic" hardware
2  Copyright (C)2015,2016 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
3  http://xep128.lgb.hu/
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18 
19 #include "xep128.h"
20 #include "keyboard_mapping.h"
21 
22 
23 /* _default_ scancode mapping. This is used to initialize configuration,
24  but config file, command line options can override this. So, this table is
25  _not_ used directly by the emulator! */
26 
27 
29  const SDL_Scancode code;
30  const int pos;
31  const char *description;
32 };
33 
34 static const char *unknown_key_name = "SomeUnknownKey";
35 static struct keyMappingTable_st *keyMappingTable = NULL;
36 static int keyMappingTableSize = 0;
37 
38 static const struct keyMappingDefault_st keyMappingDefaults[] = {
39  { SDL_SCANCODE_1, 0x31, "1" },
40  { SDL_SCANCODE_2, 0x36, "2" },
41  { SDL_SCANCODE_3, 0x35, "3" },
42  { SDL_SCANCODE_4, 0x33, "4" },
43  { SDL_SCANCODE_5, 0x34, "5" },
44  { SDL_SCANCODE_6, 0x32, "6" },
45  { SDL_SCANCODE_7, 0x30, "7" },
46  { SDL_SCANCODE_8, 0x50, "8" },
47  { SDL_SCANCODE_9, 0x52, "9" },
48  { SDL_SCANCODE_0, 0x54, "0" },
49  { SDL_SCANCODE_Q, 0x21, "Q" },
50  { SDL_SCANCODE_W, 0x26, "W" },
51  { SDL_SCANCODE_E, 0x25, "E" },
52  { SDL_SCANCODE_R, 0x23, "R" },
53  { SDL_SCANCODE_T, 0x24, "T" },
54  { SDL_SCANCODE_Y, 0x22, "Y" },
55  { SDL_SCANCODE_U, 0x20, "U" },
56  { SDL_SCANCODE_I, 0x90, "I" },
57  { SDL_SCANCODE_O, 0x92, "O" },
58  { SDL_SCANCODE_P, 0x94, "P" },
59  { SDL_SCANCODE_A, 0x16, "A" },
60  { SDL_SCANCODE_S, 0x15, "S" },
61  { SDL_SCANCODE_D, 0x13, "D" },
62  { SDL_SCANCODE_F, 0x14, "F" },
63  { SDL_SCANCODE_G, 0x12, "G" },
64  { SDL_SCANCODE_H, 0x10, "H" },
65  { SDL_SCANCODE_J, 0x60, "J" },
66  { SDL_SCANCODE_K, 0x62, "K" },
67  { SDL_SCANCODE_L, 0x64, "L" },
68  { SDL_SCANCODE_RETURN, 0x76, "ENTER" },
69  { SDL_SCANCODE_LSHIFT, 0x07, "L-SHIFT" },
70  { SDL_SCANCODE_RSHIFT, 0x85, "R-SHIFT" },
71  { SDL_SCANCODE_CAPSLOCK, 0x11, "CAPS" },
72  { SDL_SCANCODE_Z, 0x06, "Z" },
73  { SDL_SCANCODE_X, 0x05, "X" },
74  { SDL_SCANCODE_C, 0x03, "C" },
75  { SDL_SCANCODE_V, 0x04, "V" },
76  { SDL_SCANCODE_B, 0x02, "B" },
77  { SDL_SCANCODE_N, 0x00, "N" },
78  { SDL_SCANCODE_M, 0x80, "M" },
79  { SDL_SCANCODE_LCTRL, 0x17, "CTRL" },
80  { SDL_SCANCODE_SPACE, 0x86, "SPACE" },
81  { SDL_SCANCODE_SEMICOLON, 0x63, ";" },
82  { SDL_SCANCODE_LEFTBRACKET, 0x95, "[" },
83  { SDL_SCANCODE_RIGHTBRACKET, 0x66, "]" },
84  { SDL_SCANCODE_APOSTROPHE, 0x65, ":" }, // for EP : we map PC '
85  { SDL_SCANCODE_MINUS, 0x53, "-" },
86  { SDL_SCANCODE_BACKSLASH, 0x01, "\\" },
87  { SDL_SCANCODE_TAB, 0x27, "TAB" },
88  { SDL_SCANCODE_ESCAPE, 0x37, "ESC" },
89  { SDL_SCANCODE_INSERT, 0x87, "INS" },
90  { SDL_SCANCODE_BACKSPACE, 0x56, "ERASE" },
91  { SDL_SCANCODE_DELETE, 0x81, "DEL" },
92  { SDL_SCANCODE_LEFT, 0x75, "LEFT" },
93  { SDL_SCANCODE_RIGHT, 0x72, "RIGHT" },
94  { SDL_SCANCODE_UP, 0x73, "UP" },
95  { SDL_SCANCODE_DOWN, 0x71, "DOWN" },
96  { SDL_SCANCODE_SLASH, 0x83, "/" },
97  { SDL_SCANCODE_PERIOD, 0x84, "." },
98  { SDL_SCANCODE_COMMA, 0x82, "," },
99  { SDL_SCANCODE_EQUALS, 0x93, "@" }, // for EP @ we map PC =
100  { SDL_SCANCODE_F1, 0x47, "F1" },
101  { SDL_SCANCODE_F2, 0x46, "F2" },
102  { SDL_SCANCODE_F3, 0x42, "F3" },
103  { SDL_SCANCODE_F4, 0x40, "F4" },
104  { SDL_SCANCODE_F5, 0x44, "F5" },
105  { SDL_SCANCODE_F6, 0x43, "F6" },
106  { SDL_SCANCODE_F7, 0x45, "F7" },
107  { SDL_SCANCODE_F8, 0x41, "F8" },
108 // { SDL_SCANCODE_F9, 0x77, "F9" },
109  { SDL_SCANCODE_HOME, 0x74, "HOLD" }, // for EP HOLD we map PC HOME
110  { SDL_SCANCODE_END, 0x70, "STOP" }, // for EP STOP we map PC END
111  /* ---- Not real EP kbd matrix, used for extjoy emulation with numeric keypad ---- */
112  { SDL_SCANCODE_KP_5, 0xA0, "ExtJoy FIRE" }, // for EP external joy FIRE we map PC num keypad 5
113  { SDL_SCANCODE_KP_8, 0xA1, "ExtJoy UP" }, // for EP external joy UP we map PC num keypad 8
114  { SDL_SCANCODE_KP_2, 0xA2, "ExtJoy DOWN" }, // for EP external joy DOWN we map PC num keypad 2
115  { SDL_SCANCODE_KP_4, 0xA3, "ExtJoy LEFT" }, // for EP external joy LEFT we map PC num keypad 4
116  { SDL_SCANCODE_KP_6, 0xA4, "ExtJoy RIGHT" }, // for EP external joy RIGHT we map PC num keypad 6
117  /* ---- emu related "SYS" keys (like screenshot, exit, fullscreen ...) position codes are the identifier for the caller! Must be values, not used otherwise by the emulated computer! */
118  { SDL_SCANCODE_F11, 0xFF, "EMU fullscreen" }, // ... on EP the lower nibble is the mask shift, so values X8-XF are not used!
119  { SDL_SCANCODE_F9, 0xFE, "EMU exit" },
120  { SDL_SCANCODE_F10, 0xFD, "EMU screenshot" },
121  { SDL_SCANCODE_PAUSE, 0xFC, "EMU reset" },
122  { SDL_SCANCODE_PAGEDOWN, 0xFB, "EMU slower-cpu" },
123  { SDL_SCANCODE_PAGEUP, 0xFA, "EMU faster-cpu" },
124  { SDL_SCANCODE_GRAVE, 0xF9, "EMU osd-replay" },
125  { SDL_SCANCODE_KP_MINUS, 0xF8, "EMU console" },
126  /* ---- end of table marker, must be the last entry ---- */
127  { 0, -1, NULL }
128 };
129 
130 
131 
132 
133 static void keymap_set_key ( SDL_Scancode code, int posep )
134 {
135  int n = keyMappingTableSize;
136  struct keyMappingTable_st *p = keyMappingTable;
137  const struct keyMappingDefault_st *q = keyMappingDefaults;
138  while (n && p->code != code) {
139  n--;
140  p++;
141  }
142  if (!n) {
143  keyMappingTable = realloc(keyMappingTable, (keyMappingTableSize + 1) * sizeof(struct keyMappingTable_st));
144  CHECK_MALLOC(keyMappingTable);
145  p = keyMappingTable + (keyMappingTableSize++);
146  p->code = code;
147  }
148  p->posep = posep;
149  /* search for description */
150  while (q->description) {
151  if (q->pos == posep) {
152  p->description = q->description;
153  return;
154  }
155  q++;
156  }
157  p->description = unknown_key_name;
158 }
159 
160 
161 
162 int keymap_set_key_by_name ( const char *name, int posep )
163 {
164  SDL_Scancode code = SDL_GetScancodeFromName(name);
165  if (code == SDL_SCANCODE_UNKNOWN)
166  return 1;
167  keymap_set_key(code, posep);
168  return 0;
169 }
170 
171 
172 
174 {
175  const struct keyMappingDefault_st *p = keyMappingDefaults;
176  while (p->pos != -1) {
177  keymap_set_key(p->code, p->pos);
178  p++;
179  }
180 }
181 
182 
183 
184 void keymap_dump_config ( FILE *fp )
185 {
186  int n = keyMappingTableSize;
187  struct keyMappingTable_st *p = keyMappingTable;
188  fprintf(fp,
189  "# Note: key names are SDL scan codes! Sometimes it's nothing to do with the letters" NL
190  "# on your keyboard (eg some national layout, like Hungarian etc) but the \"physical\"" NL
191  "# scan code assignment, eg the right neighbour of key \"L\" is \";\" even if your layout" NL
192  "# means something different there!" NL NL
193  );
194  while (n--) {
195  const char *name = SDL_GetScancodeName(p->code);
196  if (!name) {
197  fprintf(fp, "# WARNING: cannot get SDL key name for epkey@%02x with SDL scan code of %d!" NL, p->posep, p->code);
198  } else {
199  fprintf(fp, "epkey@%02x = %s\t# %s" NL, p->posep, name, p->description);
200  }
201  p++;
202  }
203 }
204 
205 
206 
207 const struct keyMappingTable_st *keymap_resolve_event ( SDL_Keysym sym )
208 {
209  int n = keyMappingTableSize;
210  struct keyMappingTable_st *p = keyMappingTable;
211  DEBUG("KBD: SEARCH: scan=%d sym=%d (map size=%d)" NL, sym.scancode, sym.sym, n);
212  while (n--) {
213  if (p->code == sym.scancode) {
214  DEBUG("KBD: FOUND: key position %02Xh (%s)" NL, p->posep, p->description);
215  return p;
216  }
217  p++;
218  }
219  DEBUG("KBD: FOUND: none." NL);
220  return NULL;
221 }
222 
keyMappingDefault_st::pos
const int pos
Definition: keyboard_mapping.c:30
keyMappingDefault_st::description
const char * description
Definition: keyboard_mapping.c:31
keyboard_mapping.h
keyMappingTable_st
Definition: keyboard_mapping.h:24
keyMappingTable_st::code
SDL_Scancode code
Definition: keyboard_mapping.h:25
keymap_preinit_config_internal
void keymap_preinit_config_internal(void)
Definition: keyboard_mapping.c:173
keyMappingTable_st::posep
Uint8 posep
Definition: keyboard_mapping.h:26
CHECK_MALLOC
#define CHECK_MALLOC(p)
Definition: xep128.h:119
NL
#define NL
Definition: fat32.c:37
keymap_set_key_by_name
int keymap_set_key_by_name(const char *name, int posep)
Definition: keyboard_mapping.c:162
xep128.h
keyMappingDefault_st::code
const SDL_Scancode code
Definition: keyboard_mapping.c:29
keymap_dump_config
void keymap_dump_config(FILE *fp)
Definition: keyboard_mapping.c:184
keyMappingDefault_st
Definition: keyboard_mapping.c:28
keymap_resolve_event
const struct keyMappingTable_st * keymap_resolve_event(SDL_Keysym sym)
Definition: keyboard_mapping.c:207
name
const char * name
Definition: joystick.c:46
DEBUG
#define DEBUG(...)
Definition: emutools_basicdefs.h:167
keyMappingTable_st::description
const char * description
Definition: keyboard_mapping.h:27