Rename variables sectorbuf and verbose to avoid clashes in rbutil. Cleanup exports...
[Rockbox.git] / apps / plugins / zxbox / spkey.c
bloba21aed6af25a9724c5a07b05b0963f9bed832ca5
1 /*
2 * Copyright (C) 1996-1998 Szeredi Miklos
3 * Email: mszeredi@inf.bme.hu
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. See the file COPYING.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 /* #define DEBUG_KEYS */
22 #include "zxmisc.h"
24 #include "spkey.h"
25 #include "spkey_p.h"
27 #include "spperif.h"
28 #include "z80.h"
30 #include "sptape.h"
31 #include "snapshot.h"
32 #include "spsound.h"
33 #include "spscr.h"
35 #include "interf.h"
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <ctype.h>
41 int keyboard_type = 0;
43 /* for kempston support via SK_KP_Up and so on.... */
44 int cursor_type = 2;
47 int spkb_allow_ascii = 1;
48 int spkb_trueshift = -1;
49 int spkb_funcshift = -1;
51 static unsigned trueshift;
52 static unsigned funcshift;
54 struct spkeydef {
55 int type;
56 spkeyboard kb;
59 struct spbasekey {
60 int index;
61 spkeyboard kb;
62 spkeyboard misc;
65 struct spnamedkey {
66 const char *name;
67 spkeyboard kb;
68 spkeyboard misc;
71 extern int endofsingle;
72 extern int sp_nosync;
73 extern int showframe;
74 extern int privatemap;
76 spkeyboard spkey_state;
77 spkeyboard spmisc_state;
79 static spkeyboard oldstate = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
81 struct keystate spkb_kbstate[NR_SPKEYS];
82 struct onekey spkb_last;
84 int spkb_state_changed;
86 #define SKE {0, 0, 0, 0, 0, 0, 0, 0}
88 #define SKP(x) (1 << x)
90 #define SKN0(x) {SKP(x), 0, 0, 0, 0, 0, 0, 0}
91 #define SKN1(x) {0, SKP(x), 0, 0, 0, 0, 0, 0}
92 #define SKN2(x) {0, 0, SKP(x), 0, 0, 0, 0, 0}
93 #define SKN3(x) {0, 0, 0, SKP(x), 0, 0, 0, 0}
94 #define SKN4(x) {0, 0, 0, 0, SKP(x), 0, 0, 0}
95 #define SKN5(x) {0, 0, 0, 0, 0, SKP(x), 0, 0}
96 #define SKN6(x) {0, 0, 0, 0, 0, 0, SKP(x), 0}
97 #define SKN7(x) {0, 0, 0, 0, 0, 0, 0, SKP(x)}
99 #define SKCS0(x) {SKP(0) | SKP(x), 0, 0, 0, 0, 0, 0, 0}
100 #define SKCS1(x) {SKP(0), SKP(x), 0, 0, 0, 0, 0, 0}
101 #define SKCS2(x) {SKP(0), 0, SKP(x), 0, 0, 0, 0, 0}
102 #define SKCS3(x) {SKP(0), 0, 0, SKP(x), 0, 0, 0, 0}
103 #define SKCS4(x) {SKP(0), 0, 0, 0, SKP(x), 0, 0, 0}
104 #define SKCS5(x) {SKP(0), 0, 0, 0, 0, SKP(x), 0, 0}
105 #define SKCS6(x) {SKP(0), 0, 0, 0, 0, 0, SKP(x), 0}
106 #define SKCS7(x) {SKP(0), 0, 0, 0, 0, 0, 0, SKP(x)}
109 #define SKSS0(x) {SKP(x), 0, 0, 0, 0, 0, 0, SKP(1)}
110 #define SKSS1(x) {0, SKP(x), 0, 0, 0, 0, 0, SKP(1)}
111 #define SKSS2(x) {0, 0, SKP(x), 0, 0, 0, 0, SKP(1)}
112 #define SKSS3(x) {0, 0, 0, SKP(x), 0, 0, 0, SKP(1)}
113 #define SKSS4(x) {0, 0, 0, 0, SKP(x), 0, 0, SKP(1)}
114 #define SKSS5(x) {0, 0, 0, 0, 0, SKP(x), 0, SKP(1)}
115 #define SKSS6(x) {0, 0, 0, 0, 0, 0, SKP(x), SKP(1)}
116 #define SKSS7(x) {0, 0, 0, 0, 0, 0, 0, SKP(x) | SKP(1)}
119 #define KEMP(x) {x, 0, 0, 0, 0, 0, 0, 0}
121 #define KEMPR 0x01
122 #define KEMPL 0x02
123 #define KEMPD 0x04
124 #define KEMPU 0x08
125 #define KEMPF 0x10
127 #define KEMP_PORT 0x1F
130 #define T_MAIN 0
131 #define T_CMPX 1
132 #define T_EXTR 2
134 #define SPK_SPACE SKN7(0)
136 #define SPK_0 SKN4(0)
137 #define SPK_1 SKN3(0)
138 #define SPK_2 SKN3(1)
139 #define SPK_3 SKN3(2)
140 #define SPK_4 SKN3(3)
141 #define SPK_5 SKN3(4)
142 #define SPK_6 SKN4(4)
143 #define SPK_7 SKN4(3)
144 #define SPK_8 SKN4(2)
145 #define SPK_9 SKN4(1)
147 #define SPK_A SKN1(0)
148 #define SPK_B SKN7(4)
149 #define SPK_C SKN0(3)
150 #define SPK_D SKN1(2)
151 #define SPK_E SKN2(2)
152 #define SPK_F SKN1(3)
153 #define SPK_G SKN1(4)
154 #define SPK_H SKN6(4)
155 #define SPK_I SKN5(2)
156 #define SPK_J SKN6(3)
157 #define SPK_K SKN6(2)
158 #define SPK_L SKN6(1)
159 #define SPK_M SKN7(2)
160 #define SPK_N SKN7(3)
161 #define SPK_O SKN5(1)
162 #define SPK_P SKN5(0)
163 #define SPK_Q SKN2(0)
164 #define SPK_R SKN2(3)
165 #define SPK_S SKN1(1)
166 #define SPK_T SKN2(4)
167 #define SPK_U SKN5(3)
168 #define SPK_V SKN0(4)
169 #define SPK_W SKN2(1)
170 #define SPK_X SKN0(2)
171 #define SPK_Y SKN5(4)
172 #define SPK_Z SKN0(1)
174 #define SPK_ENTER SKN6(0)
175 #define SPK_CAPSSHIFT SKN0(0)
176 #define SPK_SYMBOLSHIFT SKN7(1)
178 #define SPK_BS SKCS4(0)
179 #define SPK_UP SKCS4(3)
180 #define SPK_DOWN SKCS4(4)
181 #define SPK_LEFT SKCS3(4)
182 #define SPK_RIGHT SKCS4(2)
183 #define SPK_CAPSLOCK SKCS3(1)
184 #define SPK_EXTRA SKCS7(1)
185 #define SPK_EDIT SKCS3(0)
187 static spkeyboard spk_extra = SPK_EXTRA;
189 static struct spkeydef spkey_ascii[] = {
190 {T_MAIN, SPK_SPACE}, /* space */
191 {T_CMPX, SKSS3(0)}, /* ! */
192 {T_CMPX, SKSS5(0)}, /* " */
193 {T_CMPX, SKSS3(2)}, /* # */
194 {T_CMPX, SKSS3(3)}, /* $ */
195 {T_CMPX, SKSS3(4)}, /* % */
196 {T_CMPX, SKSS4(4)}, /* & */
197 {T_CMPX, SKSS4(3)}, /* ' */
198 {T_CMPX, SKSS4(2)}, /* ( */
199 {T_CMPX, SKSS4(1)}, /* ) */
200 {T_CMPX, SKSS7(4)}, /* * */
201 {T_CMPX, SKSS6(2)}, /* + */
202 {T_CMPX, SKSS7(3)}, /* , */
203 {T_CMPX, SKSS6(3)}, /* - */
204 {T_CMPX, SKSS7(2)}, /* . */
205 {T_CMPX, SKSS0(4)}, /* / */
207 {T_MAIN, SPK_0}, /* 0 */
208 {T_MAIN, SPK_1}, /* 1 */
209 {T_MAIN, SPK_2}, /* 2 */
210 {T_MAIN, SPK_3}, /* 3 */
211 {T_MAIN, SPK_4}, /* 4 */
212 {T_MAIN, SPK_5}, /* 5 */
213 {T_MAIN, SPK_6}, /* 6 */
214 {T_MAIN, SPK_7}, /* 7 */
215 {T_MAIN, SPK_8}, /* 8 */
216 {T_MAIN, SPK_9}, /* 9 */
218 {T_CMPX, SKSS0(1)}, /* : */
219 {T_CMPX, SKSS5(1)}, /* ; */
220 {T_CMPX, SKSS2(3)}, /* < */
221 {T_CMPX, SKSS6(1)}, /* = */
222 {T_CMPX, SKSS2(4)}, /* > */
223 {T_CMPX, SKSS0(3)}, /* ? */
224 {T_CMPX, SKSS3(1)}, /* @ */
226 {T_CMPX, SKCS1(0)}, /* A */
227 {T_CMPX, SKCS7(4)}, /* B */
228 {T_CMPX, SKCS0(3)}, /* C */
229 {T_CMPX, SKCS1(2)}, /* D */
230 {T_CMPX, SKCS2(2)}, /* E */
231 {T_CMPX, SKCS1(3)}, /* F */
232 {T_CMPX, SKCS1(4)}, /* G */
233 {T_CMPX, SKCS6(4)}, /* H */
234 {T_CMPX, SKCS5(2)}, /* I */
235 {T_CMPX, SKCS6(3)}, /* J */
236 {T_CMPX, SKCS6(2)}, /* K */
237 {T_CMPX, SKCS6(1)}, /* L */
238 {T_CMPX, SKCS7(2)}, /* M */
239 {T_CMPX, SKCS7(3)}, /* N */
240 {T_CMPX, SKCS5(1)}, /* O */
241 {T_CMPX, SKCS5(0)}, /* P */
242 {T_CMPX, SKCS2(0)}, /* Q */
243 {T_CMPX, SKCS2(3)}, /* R */
244 {T_CMPX, SKCS1(1)}, /* S */
245 {T_CMPX, SKCS2(4)}, /* T */
246 {T_CMPX, SKCS5(3)}, /* U */
247 {T_CMPX, SKCS0(4)}, /* V */
248 {T_CMPX, SKCS2(1)}, /* W */
249 {T_CMPX, SKCS0(2)}, /* X */
250 {T_CMPX, SKCS5(4)}, /* Y */
251 {T_CMPX, SKCS0(1)}, /* Z */
253 {T_EXTR, SKCS5(4)}, /* [ */
254 {T_EXTR, SKCS1(2)}, /* backslash */
255 {T_EXTR, SKCS5(3)}, /* ] */
256 {T_CMPX, SKSS6(4)}, /* ^ */
257 {T_CMPX, SKSS4(0)}, /* _ */
258 {T_CMPX, SKSS0(2)}, /* ` */
260 {T_MAIN, SPK_A}, /* a */
261 {T_MAIN, SPK_B}, /* b */
262 {T_MAIN, SPK_C}, /* c */
263 {T_MAIN, SPK_D}, /* d */
264 {T_MAIN, SPK_E}, /* e */
265 {T_MAIN, SPK_F}, /* f */
266 {T_MAIN, SPK_G}, /* g */
267 {T_MAIN, SPK_H}, /* h */
268 {T_MAIN, SPK_I}, /* i */
269 {T_MAIN, SPK_J}, /* j */
270 {T_MAIN, SPK_K}, /* k */
271 {T_MAIN, SPK_L}, /* l */
272 {T_MAIN, SPK_M}, /* m */
273 {T_MAIN, SPK_N}, /* n */
274 {T_MAIN, SPK_O}, /* o */
275 {T_MAIN, SPK_P}, /* p */
276 {T_MAIN, SPK_Q}, /* q */
277 {T_MAIN, SPK_R}, /* r */
278 {T_MAIN, SPK_S}, /* s */
279 {T_MAIN, SPK_T}, /* t */
280 {T_MAIN, SPK_U}, /* u */
281 {T_MAIN, SPK_V}, /* v */
282 {T_MAIN, SPK_W}, /* w */
283 {T_MAIN, SPK_X}, /* x */
284 {T_MAIN, SPK_Y}, /* y */
285 {T_MAIN, SPK_Z}, /* z */
287 {T_EXTR, SKCS1(3)}, /* { */
288 {T_EXTR, SKCS1(1)}, /* | */
289 {T_EXTR, SKCS1(4)}, /* } */
290 {T_EXTR, SKCS1(0)}, /* ~ */
293 static struct spnamedkey spkey_misc[] = {
294 {"none", SKE, SKE},
296 {"space", SPK_SPACE, SKE},
297 {"enter", SPK_ENTER, SKE},
298 {"capsshift", SPK_CAPSSHIFT, SKE},
299 {"symbolshift", SPK_SYMBOLSHIFT, SKE},
301 {"kempston_up", SKE, KEMP(KEMPU)},
302 {"kempston_down", SKE, KEMP(KEMPD)},
303 {"kempston_left", SKE, KEMP(KEMPL)},
304 {"kempston_right", SKE, KEMP(KEMPR)},
305 {"kempston_fire", SKE, KEMP(KEMPF)},
307 {NULL, SKE, SKE}
310 #define MAXBASEKEYS 128
312 static struct spbasekey basekeys[MAXBASEKEYS];
313 static int numbasekeys;
315 static struct spbasekey customkeys[MAXBASEKEYS];
316 static int numcustomkeys = 0;
318 static struct spbasekey normalkeys[] = {
319 {'0', SPK_0, SKE}, /* 0 */
320 {'1', SPK_1, SKE}, /* 1 */
321 {'2', SPK_2, SKE}, /* 2 */
322 {'3', SPK_3, SKE}, /* 3 */
323 {'4', SPK_4, SKE}, /* 4 */
324 {'5', SPK_5, SKE}, /* 5 */
325 {'6', SPK_6, SKE}, /* 6 */
326 {'7', SPK_7, SKE}, /* 7 */
327 {'8', SPK_8, SKE}, /* 8 */
328 {'9', SPK_9, SKE}, /* 9 */
330 {'a', SPK_A, SKE}, /* a */
331 {'b', SPK_B, SKE}, /* b */
332 {'c', SPK_C, SKE}, /* c */
333 {'d', SPK_D, SKE}, /* d */
334 {'e', SPK_E, SKE}, /* e */
335 {'f', SPK_F, SKE}, /* f */
336 {'g', SPK_G, SKE}, /* g */
337 {'h', SPK_H, SKE}, /* h */
338 {'i', SPK_I, SKE}, /* i */
339 {'j', SPK_J, SKE}, /* j */
340 {'k', SPK_K, SKE}, /* k */
341 {'l', SPK_L, SKE}, /* l */
342 {'m', SPK_M, SKE}, /* m */
343 {'n', SPK_N, SKE}, /* n */
344 {'o', SPK_O, SKE}, /* o */
345 {'p', SPK_P, SKE}, /* p */
346 {'q', SPK_Q, SKE}, /* q */
347 {'r', SPK_R, SKE}, /* r */
348 {'s', SPK_S, SKE}, /* s */
349 {'t', SPK_T, SKE}, /* t */
350 {'u', SPK_U, SKE}, /* u */
351 {'v', SPK_V, SKE}, /* v */
352 {'w', SPK_W, SKE}, /* w */
353 {'x', SPK_X, SKE}, /* x */
354 {'y', SPK_Y, SKE}, /* y */
355 {'z', SPK_Z, SKE}, /* z */
357 {-1, SKE, SKE}
360 static struct spbasekey extendedkeys[] = {
361 {' ', SPK_SPACE, SKE}, /* space */
362 {TRKS(SK_Return), SPK_ENTER, SKE}, /* enter */
363 {TRKS(SK_KP_Enter), SPK_ENTER, SKE},
364 {TRKS(SK_Shift_L), SPK_CAPSSHIFT, SKE}, /* caps shift */
365 {TRKS(SK_Shift_R), SPK_SYMBOLSHIFT, SKE}, /* symbol shift */
366 {TRKS(SK_BackSpace), SPK_BS, SKE}, /* backspace */
367 {TRKS(SK_Delete), SPK_BS, SKE},
368 {TRKS(SK_KP_Delete), SPK_BS, SKE},
369 {TRKS(SK_Escape), SPK_EDIT, SKE}, /* caps shift + '1' */
371 {-1, SKE, SKE}
374 static struct spbasekey spectrumkeys[] = {
375 {',', SPK_SYMBOLSHIFT, SKE},
376 {'.', SPK_SPACE, SKE},
377 {';', SPK_ENTER, SKE},
379 {-1, SKE, SKE}
383 static struct spbasekey compatkeys[] = {
384 {TRKS(SK_Shift_L), SPK_CAPSSHIFT, SKE}, /* caps shift */
385 {TRKS(SK_Shift_R), SPK_CAPSSHIFT, SKE},
386 {TRKS(SK_Alt_L), SPK_SYMBOLSHIFT, SKE}, /* symbol shift */
387 {TRKS(SK_Alt_R), SPK_SYMBOLSHIFT, SKE},
388 {TRKS(SK_Meta_L), SPK_SYMBOLSHIFT, SKE},
389 {TRKS(SK_Meta_R), SPK_SYMBOLSHIFT, SKE},
390 #ifdef TRUEKOMPAT
391 {TRKS(SK_Control_L), SPK_EXTRA, SKE}, /* caps shift + symbol shift */
392 {TRKS(SK_Control_R), SPK_EXTRA, SKE},
393 #endif
395 {-1, SKE, SKE}
398 static struct spbasekey shiftedcurs[] = {
399 {TRKS(SK_Up), SPK_UP, SKE}, /* up */
400 {TRKS(SK_KP_Up), SPK_UP, SKE},
401 {TRKS(SK_Down), SPK_DOWN, SKE}, /* down */
402 {TRKS(SK_KP_Down), SPK_DOWN, SKE},
403 {TRKS(SK_Left), SPK_LEFT, SKE}, /* left */
404 {TRKS(SK_KP_Left), SPK_LEFT, SKE},
405 {TRKS(SK_Right), SPK_RIGHT, SKE}, /* right */
406 {TRKS(SK_KP_Right), SPK_RIGHT, SKE},
408 {-1, SKE, SKE}
411 static struct spbasekey rawcurs[] = {
412 {TRKS(SK_Up), SPK_7, SKE}, /* up */
413 {TRKS(SK_KP_Up), SPK_7, SKE},
414 {TRKS(SK_Down), SPK_6, SKE}, /* down */
415 {TRKS(SK_KP_Down), SPK_6, SKE},
416 {TRKS(SK_Left), SPK_5, SKE}, /* left */
417 {TRKS(SK_KP_Left), SPK_5, SKE},
418 {TRKS(SK_Right), SPK_8, SKE}, /* right */
419 {TRKS(SK_KP_Right), SPK_8, SKE},
421 {-1, SKE, SKE}
424 static struct spbasekey joycurs[] = {
425 {TRKS(SK_Up), SKE, KEMP(KEMPU)}, /* up */
426 {TRKS(SK_KP_Up), SKE, KEMP(KEMPU)},
427 {TRKS(SK_Down), SKE, KEMP(KEMPD)}, /* down */
428 {TRKS(SK_KP_Down), SKE, KEMP(KEMPD)},
429 {TRKS(SK_Left), SKE, KEMP(KEMPL)}, /* left */
430 {TRKS(SK_KP_Left), SKE, KEMP(KEMPL)},
431 {TRKS(SK_Right), SKE, KEMP(KEMPR)}, /* right */
432 {TRKS(SK_KP_Right), SKE, KEMP(KEMPR)},
433 {TRKS(SK_KP_Insert), SKE, KEMP(KEMPF)}, /* fire */
434 {TRKS(SK_Insert), SKE, KEMP(KEMPF)},
435 {TRKS(SK_KP_Delete), SKE, KEMP(KEMPF)},
436 {TRKS(SK_KP_Home), SKE, KEMP(KEMPU | KEMPL)}, /* up + left*/
437 {TRKS(SK_Home), SKE, KEMP(KEMPU | KEMPL)},
438 {TRKS(SK_KP_Page_Up), SKE, KEMP(KEMPU | KEMPR)}, /* up + right*/
439 {TRKS(SK_Page_Up), SKE, KEMP(KEMPU | KEMPR)},
440 {TRKS(SK_KP_End), SKE, KEMP(KEMPD | KEMPL)}, /* down + left*/
441 {TRKS(SK_End), SKE, KEMP(KEMPD | KEMPL)},
442 {TRKS(SK_KP_Page_Down), SKE, KEMP(KEMPD | KEMPR)}, /* down + right*/
443 {TRKS(SK_Page_Down), SKE, KEMP(KEMPD | KEMPR)},
445 {-1, SKE, SKE}
448 int spkey_new_custom(int key)
450 if(numcustomkeys >= MAXBASEKEYS) return 0;
452 customkeys[numcustomkeys].index = key;
453 SP_SETEMPTY(customkeys[numcustomkeys].kb);
454 SP_SETEMPTY(customkeys[numcustomkeys].misc);
455 numcustomkeys++;
457 return 1;
460 int spkey_add_custom(const char *name)
462 int curr;
464 curr = numcustomkeys - 1;
466 if(!name[1] && isalnum(name[0])) {
467 int ai;
468 ai = tolower(name[0])-32;
469 SP_COMBINE(customkeys[curr].kb, spkey_ascii[ai].kb);
470 return 1;
472 else {
473 int i;
475 for(i = 0; spkey_misc[i].name != NULL; i++) {
476 if(mis_strcasecmp(spkey_misc[i].name, name) == 0) {
477 SP_COMBINE(customkeys[curr].kb, spkey_misc[i].kb);
478 SP_COMBINE(customkeys[curr].misc, spkey_misc[i].misc);
479 return 1;
483 return 0;
486 static int key_reset(struct keystate *ck)
488 if(ck->state == 2 && sp_int_ctr >= ck->frame) {
489 ck->state = 0;
490 return 1;
492 else return 0;
496 void process_keys(void)
498 int i;
499 struct keystate *ck;
500 int tsh;
501 int kalone;
502 static int extrai = 0;
503 static qbyte extraendframe;
505 if(extrai && !spkb_kbstate[extrai].state) extrai = 0;
507 if(!spkb_state_changed && (!extrai || !extraendframe)) return;
509 SP_SETEMPTY(spkey_state);
510 SP_SETEMPTY(spmisc_state);
512 kalone = 0;
513 ck = spkb_kbstate + spkb_last.index;
514 tsh = spkb_last.modif & trueshift;
515 key_reset(ck);
518 if(spkb_allow_ascii && ck->state && (!ck->base || tsh)) {
519 unsigned ks;
520 ks = tsh ? spkb_last.shifted : spkb_last.keysym;
521 if(ks >= 32 && ks < 127) {
522 if(spkey_ascii[ks-32].type <= T_CMPX) {
523 SP_COMBINE(spkey_state, spkey_ascii[ks-32].kb);
524 kalone = 1;
526 else if(spkey_ascii[ks-32].type == T_EXTR) {
527 if(!extrai || sp_int_ctr < extraendframe) {
528 if(!extrai) {
529 extrai = spkb_last.index;
530 extraendframe = sp_int_ctr + 1;
532 SP_COMBINE(spkey_state, spk_extra);
534 else {
535 SP_COMBINE(spkey_state, spkey_ascii[ks-32].kb);
536 extraendframe = 0;
538 kalone = 1;
543 if(!kalone) {
544 for(i = 0; i < numbasekeys; i++) {
545 ck = spkb_kbstate + basekeys[i].index;
546 key_reset(ck);
547 if(ck->state) {
548 SP_COMBINE(spkey_state, basekeys[i].kb);
549 SP_COMBINE(spmisc_state, basekeys[i].misc);
553 SP_COMBINE(spkey_state, kb_mkey);
555 spkb_refresh();
556 spkb_state_changed = 0;
559 void clear_keystates(void)
561 int i;
562 for(i = 0; i < NR_SPKEYS; i++) spkb_kbstate[i].state = 0;
563 spkb_last.index = 0;
564 SP_SETEMPTY(spkey_state);
565 SP_SETEMPTY(kb_mkey);
566 SP_SETEMPTY(spmisc_state);
567 spkb_refresh();
570 static void keycpy(struct spbasekey *to, struct spbasekey *from)
572 to->index = from->index;
573 SP_COPY(to->kb, from->kb);
574 SP_COPY(to->misc, from->misc);
577 static void copy_key(struct spbasekey *addk)
579 int i;
580 int nindex;
582 nindex = addk->index;
584 if(SP_NONEMPTY(addk->kb) || SP_NONEMPTY(addk->misc)) {
585 for(i = 0; i < numbasekeys; i++) {
586 if(basekeys[i].index == nindex) { /* Replace */
587 keycpy(&basekeys[i], addk);
588 return;
591 if(numbasekeys < MAXBASEKEYS - 1) { /* Add */
592 keycpy(&basekeys[numbasekeys], addk);
593 spkb_kbstate[nindex].base = 1;
594 numbasekeys++;
597 else { /* Delete */
598 for(i = 0; i < numbasekeys; i++) {
599 if(basekeys[i].index == nindex) {
600 i++;
601 for(; i < numbasekeys; i++) keycpy(&basekeys[i-1], &basekeys[i]);
602 spkb_kbstate[nindex].base = 0;
603 numbasekeys--;
604 break;
610 static void copy_basekeys(struct spbasekey *addk)
612 int i;
614 for(i = 0; addk[i].index >= 0; i++) copy_key(&addk[i]);
617 static unsigned transform_shift(int modif)
619 if(!modif) return 0;
620 else return (1 << (modif - 1));
624 void init_basekeys(void)
626 int i;
627 numbasekeys = 0;
629 for(i = 0; i < NR_SPKEYS; i++) spkb_kbstate[i].base = 0;
631 customkeys[numcustomkeys].index = -1;
633 copy_basekeys(normalkeys);
634 copy_basekeys(extendedkeys);
635 copy_basekeys(shiftedcurs);
637 switch(keyboard_type) {
638 case 0:
639 break;
641 case 1:
642 copy_basekeys(spectrumkeys);
643 break;
645 case 2:
646 if(spkb_trueshift == -1) spkb_trueshift = 0;
647 #ifdef TRUEKOMPAT
648 if(spkb_funcshift == -1) spkb_funcshift = 0;
649 #endif
651 copy_basekeys(compatkeys);
652 break;
654 case 3:
655 copy_basekeys(customkeys);
656 break;
659 switch(cursor_type) {
660 case 0:
661 break;
663 case 1:
664 copy_basekeys(rawcurs);
665 break;
667 case 2:
668 copy_basekeys(joycurs);
669 break;
672 if(spkb_trueshift == -1) spkb_trueshift = 4; /* mod1 */
673 if(spkb_funcshift == -1) spkb_funcshift = 3; /* control */
675 trueshift = transform_shift(spkb_trueshift);
676 funcshift = transform_shift(spkb_funcshift);
680 void spkb_refresh(void)
682 int port, pb;
683 int i, j, changed;
684 byte *km, *kmo;
685 byte mm;
686 byte pv;
687 spkeyboard statemx;
689 km = spkey_state;
690 kmo = oldstate;
691 changed = 0;
692 for(i = 8; i; i--) {
693 if(*km != *kmo) *kmo = *km, changed = 1;
694 km++, kmo++;
697 if(changed) {
699 /* Matrix behavior: ONLY 1 level, does anybody need more ? */
701 for(i = 0; i < 8; i++) {
702 pv = spkey_state[i];
703 mm = pv;
704 if(pv) {
705 km = spkey_state;
706 for(j = 8; j; j--) {
707 if((*km & pv) & 0x1F) mm |= *km;
708 km++;
711 statemx[i] = mm;
714 for(port = 0; port < 256; port++) {
715 km = statemx;
716 pv = 0;
717 pb = port;
718 for(i = 8; i; i--) {
719 if(!(pb & 1)) pv |= *km;
720 pb >>= 1;
721 km++;
723 sp_fe_inport_high[port] =
724 (sp_fe_inport_high[port] | 0x1F) & ~(pv & 0x1F);
728 pv = spmisc_state[0];
730 if((pv & KEMPR) && (pv & KEMPL)) pv &= ~(KEMPR | KEMPL);
731 if((pv & KEMPU) && (pv & KEMPD)) pv &= ~(KEMPD | KEMPU);
732 z80_inports[KEMP_PORT] = pv;