Develop and Download Open Source Software

Browse CVS Repository

Contents of /mame32jp/mame32jp/src/input.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.5 - (show annotations) (download) (as text)
Wed Apr 24 03:53:20 2002 UTC (21 years, 11 months ago) by zero
Branch: MAIN
CVS Tags: ver_0_60_1, ver0_59_13, ver0_59_14, ver0_60_2, ver0_60_3, ver0_60_4, ver0_60_5, HEAD
Changes since 1.4: +0 -0 lines
File MIME type: text/x-csrc
*** empty log message ***

1 /******************************************************************************
2
3 input.c
4
5 Handle input from the user - keyboard, joystick, etc.
6
7 ******************************************************************************/
8
9 #include "driver.h"
10
11 #include <time.h>
12 #include <assert.h>
13
14 /***************************************************************************/
15 /* Codes */
16
17 /* Subtype of codes */
18 #define CODE_TYPE_NONE 0U /* code not assigned */
19 #define CODE_TYPE_KEYBOARD 1U /* keyboard code */
20 #define CODE_TYPE_JOYSTICK 2U /* joystick code */
21
22 /* Informations for every input code */
23 struct code_info {
24 int memory; /* boolean memory */
25 unsigned oscode; /* os dependant code */
26 unsigned type; /* subtype: CODE_TYPE_KEYBOARD or CODE_TYPE_JOYSTICK */
27 };
28
29 /* Main code table, generic KEYCODE_*, JOYCODE_* are indexes in this table */
30 static struct code_info* code_map;
31
32 /* Size of the table */
33 static unsigned code_mac;
34
35 /* Create the code table */
36 int code_init(void)
37 {
38 unsigned i;
39
40 assert( __code_key_first == 0
41 && __code_key_last + 1 == __code_joy_first
42 && __code_joy_last + 1 == __code_max );
43
44 /* allocate */
45 code_map = (struct code_info*)malloc( __code_max * sizeof(struct code_info) );
46 if (!code_map)
47 return -1;
48
49 code_mac = 0;
50
51 /* insert all known codes */
52 for(i=0;i<__code_max;++i)
53 {
54 code_map[code_mac].memory = 0;
55 code_map[code_mac].oscode = 0; /* not used */
56
57 if (__code_key_first <= i && i <= __code_key_last)
58 code_map[code_mac].type = CODE_TYPE_KEYBOARD;
59 else if (__code_joy_first <= i && i <= __code_joy_last)
60 code_map[code_mac].type = CODE_TYPE_JOYSTICK;
61 else {
62 /* never happen */
63 assert(0);
64 code_map[code_mac].type = CODE_TYPE_NONE;
65 }
66 ++code_mac;
67 }
68
69 return 0;
70 }
71
72 /* Find the osd record of an oscode */
73 INLINE const struct KeyboardInfo* internal_oscode_find_keyboard(unsigned oscode)
74 {
75 const struct KeyboardInfo *keyinfo;
76 keyinfo = osd_get_key_list();
77 while (keyinfo->name)
78 {
79 if (keyinfo->code == oscode)
80 return keyinfo;
81 ++keyinfo;
82 }
83 return 0;
84 }
85
86 INLINE const struct JoystickInfo* internal_oscode_find_joystick(unsigned oscode)
87 {
88 const struct JoystickInfo *joyinfo;
89 joyinfo = osd_get_joy_list();
90 while (joyinfo->name)
91 {
92 if (joyinfo->code == oscode)
93 return joyinfo;
94 ++joyinfo;
95 }
96 return 0;
97 }
98
99 /* Find a oscode in the table */
100 static int internal_oscode_find(unsigned oscode, unsigned type)
101 {
102 unsigned i;
103 const struct KeyboardInfo *keyinfo;
104 const struct JoystickInfo *joyinfo;
105
106 /* Search in the main table for an oscode */
107 for(i=__code_max;i<code_mac;++i)
108 if (code_map[i].type == type && code_map[i].oscode == oscode)
109 return i;
110
111 /* Search in the osd table for a standard code */
112 switch (type)
113 {
114 case CODE_TYPE_KEYBOARD :
115 keyinfo = internal_oscode_find_keyboard(oscode);
116 if (keyinfo && keyinfo->standardcode != CODE_OTHER)
117 return keyinfo->standardcode;
118 break;
119 case CODE_TYPE_JOYSTICK :
120 joyinfo = internal_oscode_find_joystick(oscode);
121 if (joyinfo && joyinfo->standardcode != CODE_OTHER)
122 return joyinfo->standardcode;
123 break;
124 }
125
126 /* oscode not found */
127 return CODE_NONE;
128 }
129
130 /* Add a new oscode in the table */
131 static int internal_oscode_add(unsigned oscode, unsigned type)
132 {
133 struct code_info* new_code_map;
134 new_code_map = realloc( code_map, (code_mac+1) * sizeof(struct code_info) );
135 if (new_code_map)
136 {
137 code_map = new_code_map;
138 code_map[code_mac].memory = 0;
139 code_map[code_mac].oscode = oscode;
140 code_map[code_mac].type = type;
141 return code_mac++;
142 } else {
143 return CODE_NONE;
144 }
145 }
146
147 /* Find the osd record of a standard code */
148 INLINE const struct KeyboardInfo* internal_code_find_keyboard(InputCode code)
149 {
150 const struct KeyboardInfo *keyinfo;
151 keyinfo = osd_get_key_list();
152
153 assert( code < code_mac );
154
155 if (code < __code_max)
156 {
157 while (keyinfo->name)
158 {
159 if (keyinfo->standardcode == code)
160 return keyinfo;
161 ++keyinfo;
162 }
163 } else {
164 while (keyinfo->name)
165 {
166 if (keyinfo->standardcode == CODE_OTHER && keyinfo->code == code_map[code].oscode)
167 return keyinfo;
168 ++keyinfo;
169 }
170 }
171 return 0;
172 }
173
174 INLINE const struct JoystickInfo* internal_code_find_joystick(InputCode code)
175 {
176 const struct JoystickInfo *joyinfo;
177 joyinfo = osd_get_joy_list();
178
179 assert( code < code_mac );
180
181 if (code < __code_max)
182 {
183 while (joyinfo->name)
184 {
185 if (joyinfo->standardcode == code)
186 return joyinfo;
187 ++joyinfo;
188 }
189 } else {
190 while (joyinfo->name)
191 {
192 if (joyinfo->standardcode == CODE_OTHER && joyinfo->code == code_map[code].oscode)
193 return joyinfo;
194 ++joyinfo;
195 }
196 }
197 return 0;
198 }
199
200 /* Check if a code is pressed */
201 static int internal_code_pressed(InputCode code)
202 {
203 const struct KeyboardInfo *keyinfo;
204 const struct JoystickInfo *joyinfo;
205
206 assert( code < code_mac );
207
208 if (code < __code_max)
209 {
210 switch (code_map[code].type)
211 {
212 case CODE_TYPE_KEYBOARD :
213 keyinfo = internal_code_find_keyboard(code);
214 if (keyinfo)
215 return osd_is_key_pressed(keyinfo->code);
216 break;
217 case CODE_TYPE_JOYSTICK :
218 joyinfo = internal_code_find_joystick(code);
219 if (joyinfo)
220 return osd_is_joy_pressed(joyinfo->code);
221 break;
222 }
223 } else {
224 switch (code_map[code].type)
225 {
226 case CODE_TYPE_KEYBOARD :
227 return osd_is_key_pressed(code_map[code].oscode);
228 case CODE_TYPE_JOYSTICK :
229 return osd_is_joy_pressed(code_map[code].oscode);
230 }
231 }
232 return 0;
233 }
234
235 /* Return the name of the code */
236 static const char* internal_code_name(InputCode code)
237 {
238 const struct KeyboardInfo *keyinfo;
239 const struct JoystickInfo *joyinfo;
240
241 assert( code < code_mac );
242
243 switch (code_map[code].type)
244 {
245 case CODE_TYPE_KEYBOARD :
246 keyinfo = internal_code_find_keyboard(code);
247 if (keyinfo)
248 return keyinfo->name;
249 break;
250 case CODE_TYPE_JOYSTICK :
251 joyinfo = internal_code_find_joystick(code);
252 if (joyinfo)
253 return joyinfo->name;
254 break;
255 }
256 return "n/a";
257 }
258
259 /* Update the code table */
260 static void internal_code_update(void)
261 {
262 const struct KeyboardInfo *keyinfo;
263 const struct JoystickInfo *joyinfo;
264
265 /* add only oscode because all standard codes are already present */
266
267 keyinfo = osd_get_key_list();
268 while (keyinfo->name)
269 {
270 if (keyinfo->standardcode == CODE_OTHER)
271 if (internal_oscode_find(keyinfo->code,CODE_TYPE_KEYBOARD) == CODE_NONE)
272 internal_oscode_add(keyinfo->code,CODE_TYPE_KEYBOARD);
273 ++keyinfo;
274 }
275
276 joyinfo = osd_get_joy_list();
277 while (joyinfo->name)
278 {
279 if (joyinfo->standardcode == CODE_OTHER)
280 if (internal_oscode_find(joyinfo->code,CODE_TYPE_JOYSTICK)==CODE_NONE)
281 internal_oscode_add(joyinfo->code,CODE_TYPE_JOYSTICK);
282 ++joyinfo;
283 }
284 }
285
286 /* Delete the code table */
287 void code_close(void)
288 {
289 #if 0
290 int i;
291 logerror("List of OS dependant input codes:\n");
292 for(i=__code_max;i<code_mac;++i)
293 logerror("\tcode %d, oscode %d, %s, %s\n",i,code_map[i].oscode,code_map[i].type == CODE_TYPE_KEYBOARD ? "keyboard" : "joystick", internal_code_name(i));
294 #endif
295
296 code_mac = 0;
297 free(code_map);
298 code_map = 0;
299 }
300
301 /***************************************************************************/
302 /* Save support */
303
304 /* Flags used for saving codes to file */
305 #define SAVECODE_FLAGS_TYPE_STANDARD 0x10000000 /* code */
306 #define SAVECODE_FLAGS_TYPE_KEYBOARD 0x20000000 /* keyboard oscode */
307 #define SAVECODE_FLAGS_TYPE_JOYSTICK 0x30000000 /* joystick oscode */
308 #define SAVECODE_FLAGS_TYPE_MASK 0xF0000000
309
310 /* Convert one key oscode to one standard code */
311 InputCode keyoscode_to_code(unsigned oscode)
312 {
313 InputCode code;
314
315 code = internal_oscode_find(oscode,CODE_TYPE_KEYBOARD);
316
317 /* insert if missing */
318 if (code == CODE_NONE)
319 code = internal_oscode_add(oscode,CODE_TYPE_KEYBOARD);
320
321 return code;
322 }
323
324 /* Convert one joystick oscode to one code */
325 InputCode joyoscode_to_code(unsigned oscode)
326 {
327 InputCode code = internal_oscode_find(oscode,CODE_TYPE_JOYSTICK);
328
329 /* insert if missing */
330 if (code == CODE_NONE)
331 code = internal_oscode_add(oscode,CODE_TYPE_JOYSTICK);
332
333 return code;
334 }
335
336 /* Convert one saved code to one code */
337 InputCode savecode_to_code(unsigned savecode)
338 {
339 unsigned type = savecode & SAVECODE_FLAGS_TYPE_MASK;
340 InputCode code = savecode & ~SAVECODE_FLAGS_TYPE_MASK;
341
342 switch (type)
343 {
344 case SAVECODE_FLAGS_TYPE_STANDARD :
345 return code;
346 case SAVECODE_FLAGS_TYPE_KEYBOARD :
347 return keyoscode_to_code(code);
348 case SAVECODE_FLAGS_TYPE_JOYSTICK :
349 return joyoscode_to_code(code);
350 }
351
352 /* never happen */
353 assert(0);
354 return CODE_NONE;
355 }
356
357 /* Convert one code to one saved code */
358 unsigned code_to_savecode(InputCode code)
359 {
360 if (code < __code_max || code >= code_mac)
361 /* if greather than code_mac is a special CODE like CODE_OR */
362 return code | SAVECODE_FLAGS_TYPE_STANDARD;
363
364 switch (code_map[code].type)
365 {
366 case CODE_TYPE_KEYBOARD : return code_map[code].oscode | SAVECODE_FLAGS_TYPE_KEYBOARD;
367 case CODE_TYPE_JOYSTICK : return code_map[code].oscode | SAVECODE_FLAGS_TYPE_JOYSTICK;
368 }
369
370 /* never happen */
371 assert(0);
372 return 0;
373 }
374
375 /***************************************************************************/
376 /* Interface */
377
378 const char *code_name(InputCode code)
379 {
380 if (code < code_mac)
381 return internal_code_name(code);
382
383 switch (code)
384 {
385 #ifdef JAPANESE
386 case CODE_NONE : return "����";
387 #else
388 case CODE_NONE : return "None";
389 #endif
390 case CODE_NOT : return "not";
391 case CODE_OR : return "or";
392 }
393
394 #ifdef JAPANESE
395 return "�g�p�s��";
396 #else
397 return "n/a";
398 #endif
399 }
400
401 int code_pressed(InputCode code)
402 {
403 int pressed;
404
405 profiler_mark(PROFILER_INPUT);
406
407 pressed = internal_code_pressed(code);
408
409 profiler_mark(PROFILER_END);
410
411 return pressed;
412 }
413
414 int code_pressed_memory(InputCode code)
415 {
416 int pressed;
417
418 profiler_mark(PROFILER_INPUT);
419
420 pressed = internal_code_pressed(code);
421
422 if (pressed)
423 {
424 if (code_map[code].memory == 0)
425 code_map[code].memory = 1;
426 else
427 pressed = 0;
428 } else
429 code_map[code].memory = 0;
430
431 profiler_mark(PROFILER_END);
432
433 return pressed;
434 }
435
436 /* Report the pressure only if isn't already signaled with one of the */
437 /* functions code_memory and code_memory_repeat */
438 static int code_pressed_not_memorized(InputCode code)
439 {
440 int pressed;
441
442 profiler_mark(PROFILER_INPUT);
443
444 pressed = internal_code_pressed(code);
445
446 if (pressed)
447 {
448 if (code_map[code].memory != 0)
449 pressed = 0;
450 } else
451 code_map[code].memory = 0;
452
453 profiler_mark(PROFILER_END);
454
455 return pressed;
456 }
457
458 int code_pressed_memory_repeat(InputCode code, int speed)
459 {
460 static int counter;
461 static int keydelay;
462 int pressed;
463
464 profiler_mark(PROFILER_INPUT);
465
466 pressed = internal_code_pressed(code);
467
468 if (pressed)
469 {
470 if (code_map[code].memory == 0)
471 {
472 code_map[code].memory = 1;
473 keydelay = 3;
474 counter = 0;
475 }
476 else if (++counter > keydelay * speed * Machine->drv->frames_per_second / 60)
477 {
478 keydelay = 1;
479 counter = 0;
480 } else
481 pressed = 0;
482 } else
483 code_map[code].memory = 0;
484
485 profiler_mark(PROFILER_END);
486
487 return pressed;
488 }
489
490 InputCode code_read_async(void)
491 {
492 unsigned i;
493
494 profiler_mark(PROFILER_INPUT);
495
496 /* update the table */
497 internal_code_update();
498
499 for(i=0;i<code_mac;++i)
500 if (code_pressed_memory(i))
501 return i;
502
503 profiler_mark(PROFILER_END);
504
505 return CODE_NONE;
506 }
507
508 /* returns the numerical value of a typed hex digit, or -1 if none */
509 INT8 code_read_hex_async(void)
510 {
511 unsigned i;
512
513 profiler_mark(PROFILER_INPUT);
514
515 /* update the table */
516 internal_code_update();
517
518 for(i=0;i<code_mac;++i)
519 if (code_pressed_memory(i))
520 {
521 if ((i >= KEYCODE_A) && (i <= KEYCODE_F))
522 return i - KEYCODE_A + 10;
523 else if ((i >= KEYCODE_0) && (i <= KEYCODE_9))
524 return i - KEYCODE_0;
525 else
526 return -1;
527 }
528
529 profiler_mark(PROFILER_END);
530
531 return -1;
532 }
533
534 /***************************************************************************/
535 /* Sequences */
536
537 void seq_set_0(InputSeq* a)
538 {
539 int j;
540 for(j=0;j<SEQ_MAX;++j)
541 (*a)[j] = CODE_NONE;
542 }
543
544 void seq_set_1(InputSeq* a, InputCode code)
545 {
546 int j;
547 (*a)[0] = code;
548 for(j=1;j<SEQ_MAX;++j)
549 (*a)[j] = CODE_NONE;
550 }
551
552 void seq_set_2(InputSeq* a, InputCode code1, InputCode code2)
553 {
554 int j;
555 (*a)[0] = code1;
556 (*a)[1] = code2;
557 for(j=2;j<SEQ_MAX;++j)
558 (*a)[j] = CODE_NONE;
559 }
560
561 void seq_set_3(InputSeq* a, InputCode code1, InputCode code2, InputCode code3)
562 {
563 int j;
564 (*a)[0] = code1;
565 (*a)[1] = code2;
566 (*a)[2] = code3;
567 for(j=3;j<SEQ_MAX;++j)
568 (*a)[j] = CODE_NONE;
569 }
570
571 void seq_copy(InputSeq* a, InputSeq* b)
572 {
573 int j;
574 for(j=0;j<SEQ_MAX;++j)
575 (*a)[j] = (*b)[j];
576 }
577
578 int seq_cmp(InputSeq* a, InputSeq* b)
579 {
580 int j;
581 for(j=0;j<SEQ_MAX;++j)
582 if ((*a)[j] != (*b)[j])
583 return -1;
584 return 0;
585 }
586
587 void seq_name(InputSeq* code, char* buffer, unsigned max)
588 {
589 int j;
590 char* dest = buffer;
591 for(j=0;j<SEQ_MAX;++j)
592 {
593 const char* name;
594
595 if ((*code)[j]==CODE_NONE)
596 break;
597
598 if (j && 1 + 1 <= max)
599 {
600 *dest = ' ';
601 dest += 1;
602 max -= 1;
603 }
604
605 name = code_name((*code)[j]);
606 if (!name)
607 break;
608
609 if (strlen(name) + 1 <= max)
610 {
611 strcpy(dest,name);
612 dest += strlen(name);
613 max -= strlen(name);
614 }
615 }
616
617 if (dest == buffer && 4 + 1 <= max)
618 #ifdef JAPANESE
619 strcpy(dest,"����");
620 #else
621 strcpy(dest,"None");
622 #endif
623 else
624 *dest = 0;
625 }
626
627 int seq_pressed(InputSeq* code)
628 {
629 int j;
630 int res = 1;
631 int invert = 0;
632 int count = 0;
633
634 for(j=0;j<SEQ_MAX;++j)
635 {
636 switch ((*code)[j])
637 {
638 case CODE_NONE :
639 return res && count;
640 case CODE_OR :
641 if (res && count)
642 return 1;
643 res = 1;
644 count = 0;
645 break;
646 case CODE_NOT :
647 invert = !invert;
648 break;
649 default:
650 if (res)
651 {
652 int pressed = code_pressed_not_memorized((*code)[j]);
653 if ((pressed != 0) == invert)
654 res = 0;
655 }
656 invert = 0;
657 ++count;
658 }
659 }
660 return res && count;
661 }
662
663 /* Static informations used in key/joy recording */
664 static InputCode record_seq[SEQ_MAX]; /* buffer for key recording */
665 static int record_count; /* number of key/joy press recorded */
666 static clock_t record_last; /* time of last key/joy press */
667
668 #define RECORD_TIME (CLOCKS_PER_SEC*2/3) /* max time between key press */
669
670 /* Start a sequence recording */
671 void seq_read_async_start(void)
672 {
673 unsigned i;
674
675 record_count = 0;
676 record_last = clock();
677
678 /* reset code memory, otherwise this memory may interferes with the input memory */
679 for(i=0;i<code_mac;++i)
680 code_map[i].memory = 1;
681 }
682
683 /* Check that almost one key/joy must be pressed */
684 static int seq_valid(InputSeq* seq)
685 {
686 int j;
687 int positive = 0;
688 int pred_not = 0;
689 int operand = 0;
690 for(j=0;j<SEQ_MAX;++j)
691 {
692 switch ((*seq)[j])
693 {
694 case CODE_NONE :
695 break;
696 case CODE_OR :
697 if (!operand || !positive)
698 return 0;
699 pred_not = 0;
700 positive = 0;
701 operand = 0;
702 break;
703 case CODE_NOT :
704 if (pred_not)
705 return 0;
706 pred_not = !pred_not;
707 operand = 0;
708 break;
709 default:
710 if (!pred_not)
711 positive = 1;
712 pred_not = 0;
713 operand = 1;
714 break;
715 }
716 }
717 return positive && operand;
718 }
719
720 /* Record a key/joy sequence
721 return <0 if more input is needed
722 return ==0 if sequence succesfully recorded
723 return >0 if aborted
724 */
725 int seq_read_async(InputSeq* seq, int first)
726 {
727 InputCode newkey;
728
729 if (input_ui_pressed(IPT_UI_CANCEL))
730 return 1;
731
732 if (record_count == SEQ_MAX
733 || (record_count > 0 && clock() > record_last + RECORD_TIME)) {
734 int k = 0;
735 if (!first)
736 {
737 /* search the first space free */
738 while (k < SEQ_MAX && (*seq)[k] != CODE_NONE)
739 ++k;
740 }
741
742 /* if no space restart */
743 if (k + record_count + (k!=0) > SEQ_MAX)
744 k = 0;
745
746 /* insert */
747 if (k + record_count + (k!=0) <= SEQ_MAX)
748 {
749 int j;
750 if (k!=0)
751 (*seq)[k++] = CODE_OR;
752 for(j=0;j<record_count;++j,++k)
753 (*seq)[k] = record_seq[j];
754 }
755 /* fill to end */
756 while (k < SEQ_MAX)
757 {
758 (*seq)[k] = CODE_NONE;
759 ++k;
760 }
761
762 if (!seq_valid(seq))
763 seq_set_1(seq,CODE_NONE);
764
765 return 0;
766 }
767
768 newkey = code_read_async();
769
770 if (newkey != CODE_NONE)
771 {
772 /* if code is duplicate negate the code */
773 if (record_count && newkey == record_seq[record_count-1])
774 record_seq[record_count-1] = CODE_NOT;
775
776 record_seq[record_count++] = newkey;
777 record_last = clock();
778 }
779
780 return -1;
781 }
782
783 /***************************************************************************/
784 /* input ui */
785
786 /* Static buffer for memory input */
787 struct ui_info {
788 int memory;
789 };
790
791 static struct ui_info ui_map[__ipt_max];
792
793 int input_ui_pressed(int code)
794 {
795 int pressed;
796
797 profiler_mark(PROFILER_INPUT);
798
799 pressed = seq_pressed(input_port_type_seq(code));
800
801 if (pressed)
802 {
803 if (ui_map[code].memory == 0)
804 {
805 ui_map[code].memory = 1;
806 } else
807 pressed = 0;
808 } else
809 ui_map[code].memory = 0;
810
811 profiler_mark(PROFILER_END);
812
813 return pressed;
814 }
815
816 int input_ui_pressed_repeat(int code,int speed)
817 {
818 static int counter,inputdelay;
819 int pressed;
820
821 profiler_mark(PROFILER_INPUT);
822
823 pressed = seq_pressed(input_port_type_seq(code));
824
825 if (pressed)
826 {
827 if (ui_map[code].memory == 0)
828 {
829 ui_map[code].memory = 1;
830 inputdelay = 3;
831 counter = 0;
832 }
833 else if (++counter > inputdelay * speed * Machine->drv->frames_per_second / 60)
834 {
835 inputdelay = 1;
836 counter = 0;
837 } else
838 pressed = 0;
839 } else
840 ui_map[code].memory = 0;
841
842 profiler_mark(PROFILER_END);
843
844 return pressed;
845 }
846

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26