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 */
code_init(void)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 */
internal_oscode_find_keyboard(unsigned oscode)73 static 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 
internal_oscode_find_joystick(unsigned oscode)86 static 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 */
internal_oscode_find(unsigned oscode,unsigned type)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 */
internal_oscode_add(unsigned oscode,unsigned type)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 */
internal_code_find_keyboard(InputCode code)148 static 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 
internal_code_find_joystick(InputCode code)174 static 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 */
internal_code_pressed(InputCode code)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 */
internal_code_name(InputCode 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 */
internal_code_update(void)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 */
code_close(void)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 */
keyoscode_to_code(unsigned oscode)311 InputCode keyoscode_to_code(unsigned oscode)
312 {
313 	InputCode code;
314 
315 	if (oscode == OSD_KEY_NONE)
316 		return CODE_NONE;
317 
318 	code = internal_oscode_find(oscode,CODE_TYPE_KEYBOARD);
319 
320 	/* insert if missing */
321 	if (code == CODE_NONE)
322 		code = internal_oscode_add(oscode,CODE_TYPE_KEYBOARD);
323 
324 	return code;
325 }
326 
327 /* Convert one joystick oscode to one code */
joyoscode_to_code(unsigned oscode)328 InputCode joyoscode_to_code(unsigned oscode)
329 {
330 	InputCode code = internal_oscode_find(oscode,CODE_TYPE_JOYSTICK);
331 
332 	/* insert if missing */
333 	if (code == CODE_NONE)
334 		code = internal_oscode_add(oscode,CODE_TYPE_JOYSTICK);
335 
336 	return code;
337 }
338 
339 /* Convert one saved code to one code */
savecode_to_code(unsigned savecode)340 InputCode savecode_to_code(unsigned savecode)
341 {
342 	unsigned type = savecode & SAVECODE_FLAGS_TYPE_MASK;
343 	InputCode code = savecode & ~SAVECODE_FLAGS_TYPE_MASK;
344 
345 	switch (type)
346 	{
347 		case SAVECODE_FLAGS_TYPE_STANDARD :
348 			return code;
349 		case SAVECODE_FLAGS_TYPE_KEYBOARD :
350 			return keyoscode_to_code(code);
351 		case SAVECODE_FLAGS_TYPE_JOYSTICK :
352 			return joyoscode_to_code(code);
353 	}
354 
355 	/* never happen */
356 	assert(0);
357 	return CODE_NONE;
358 }
359 
360 /* Convert one code to one saved code */
code_to_savecode(InputCode code)361 unsigned code_to_savecode(InputCode code)
362 {
363 	if (code < __code_max || code >= code_mac)
364                	/* if greather than code_mac is a special CODE like CODE_OR */
365 		return code | SAVECODE_FLAGS_TYPE_STANDARD;
366 
367 	switch (code_map[code].type)
368 	{
369 		case CODE_TYPE_KEYBOARD : return code_map[code].oscode | SAVECODE_FLAGS_TYPE_KEYBOARD;
370 		case CODE_TYPE_JOYSTICK : return code_map[code].oscode | SAVECODE_FLAGS_TYPE_JOYSTICK;
371 	}
372 
373 	/* never happen */
374 	assert(0);
375 	return 0;
376 }
377 
378 /***************************************************************************/
379 /* Interface */
380 
code_name(InputCode code)381 const char *code_name(InputCode code)
382 {
383 	if (code < code_mac)
384 		return internal_code_name(code);
385 
386 	switch (code)
387 	{
388 		case CODE_NONE : return "None";
389 		case CODE_NOT : return "not";
390 		case CODE_OR : return "or";
391 	}
392 
393 	return "n/a";
394 }
395 
code_pressed(InputCode code)396 int code_pressed(InputCode code)
397 {
398 	int pressed;
399 
400 	profiler_mark(PROFILER_INPUT);
401 
402 	pressed = internal_code_pressed(code);
403 
404 	profiler_mark(PROFILER_END);
405 
406 	return pressed;
407 }
408 
code_pressed_memory(InputCode code)409 int code_pressed_memory(InputCode code)
410 {
411 	int pressed;
412 
413 	profiler_mark(PROFILER_INPUT);
414 
415 	pressed = internal_code_pressed(code);
416 
417 	if (pressed)
418 	{
419 		if (code_map[code].memory == 0)
420 			code_map[code].memory = 1;
421 		else
422 			pressed = 0;
423 	} else
424 		code_map[code].memory = 0;
425 
426 	profiler_mark(PROFILER_END);
427 
428 	return pressed;
429 }
430 
431 /* Report the pressure only if isn't already signaled with one of the */
432 /* functions code_memory and code_memory_repeat */
code_pressed_not_memorized(InputCode code)433 static int code_pressed_not_memorized(InputCode code)
434 {
435 	int pressed;
436 
437 	profiler_mark(PROFILER_INPUT);
438 
439 	pressed = internal_code_pressed(code);
440 
441 	if (pressed)
442 	{
443 		if (code_map[code].memory != 0)
444 			pressed = 0;
445 	} else
446 		code_map[code].memory = 0;
447 
448 	profiler_mark(PROFILER_END);
449 
450 	return pressed;
451 }
452 
code_pressed_memory_repeat(InputCode code,int speed)453 int code_pressed_memory_repeat(InputCode code, int speed)
454 {
455 	static int counter;
456 	static int keydelay;
457 	int pressed;
458 
459 	profiler_mark(PROFILER_INPUT);
460 
461 	pressed = internal_code_pressed(code);
462 
463 	if (pressed)
464 	{
465 		if (code_map[code].memory == 0)
466 		{
467 			code_map[code].memory = 1;
468 			keydelay = 3;
469 			counter = 0;
470 		}
471 		else if (++counter > keydelay * speed * Machine->drv->frames_per_second / 60)
472 		{
473 			keydelay = 1;
474 			counter = 0;
475 		} else
476 			pressed = 0;
477 	} else
478 		code_map[code].memory = 0;
479 
480 	profiler_mark(PROFILER_END);
481 
482 	return pressed;
483 }
484 
code_read_async(void)485 InputCode code_read_async(void)
486 {
487 	unsigned i;
488 
489 	profiler_mark(PROFILER_INPUT);
490 
491 	/* update the table */
492 	internal_code_update();
493 
494 	for(i=0;i<code_mac;++i)
495 		if (code_pressed_memory(i))
496 			return i;
497 
498 	profiler_mark(PROFILER_END);
499 
500 	return CODE_NONE;
501 }
502 
code_read_sync(void)503 InputCode code_read_sync(void)
504 {
505 	InputCode code;
506 	unsigned oscode;
507 
508 	/* now let the OS process it */
509 	oscode = osd_wait_keypress();
510 
511 	/* convert the code */
512 	code = keyoscode_to_code(oscode);
513 
514 	/* update the memory of the code, like if code_pressed_memory was called */
515 	if (code != CODE_NONE)
516 		code_map[code].memory = 1;
517 
518 	while (code == CODE_NONE)
519 		code = code_read_async();
520 
521 	return code;
522 }
523 
524 /* returns the numerical value of a typed hex digit, or -1 if none */
code_read_hex_async(void)525 INT8 code_read_hex_async(void)
526 {
527 	unsigned i;
528 
529 	profiler_mark(PROFILER_INPUT);
530 
531 	/* update the table */
532 	internal_code_update();
533 
534 	for(i=0;i<code_mac;++i)
535 		if (code_pressed_memory(i))
536 		{
537 			if ((i >= KEYCODE_A) && (i <= KEYCODE_F))
538 				return i - KEYCODE_A + 10;
539 			else if ((i >= KEYCODE_0) && (i <= KEYCODE_9))
540 				return i - KEYCODE_0;
541 			else
542 				return -1;
543 		}
544 
545 	profiler_mark(PROFILER_END);
546 
547 	return -1;
548 }
549 
550 /***************************************************************************/
551 /* Sequences */
552 
seq_set_0(InputSeq * a)553 void seq_set_0(InputSeq* a)
554 {
555 	int j;
556 	for(j=0;j<SEQ_MAX;++j)
557 		(*a)[j] = CODE_NONE;
558 }
559 
seq_set_1(InputSeq * a,InputCode code)560 void seq_set_1(InputSeq* a, InputCode code)
561 {
562 	int j;
563 	(*a)[0] = code;
564 	for(j=1;j<SEQ_MAX;++j)
565 		(*a)[j] = CODE_NONE;
566 }
567 
seq_set_2(InputSeq * a,InputCode code1,InputCode code2)568 void seq_set_2(InputSeq* a, InputCode code1, InputCode code2)
569 {
570 	int j;
571 	(*a)[0] = code1;
572 	(*a)[1] = code2;
573 	for(j=2;j<SEQ_MAX;++j)
574 		(*a)[j] = CODE_NONE;
575 }
576 
seq_set_3(InputSeq * a,InputCode code1,InputCode code2,InputCode code3)577 void seq_set_3(InputSeq* a, InputCode code1, InputCode code2, InputCode code3)
578 {
579 	int j;
580 	(*a)[0] = code1;
581 	(*a)[1] = code2;
582 	(*a)[2] = code3;
583 	for(j=3;j<SEQ_MAX;++j)
584 		(*a)[j] = CODE_NONE;
585 }
586 
seq_copy(InputSeq * a,InputSeq * b)587 void seq_copy(InputSeq* a, InputSeq* b)
588 {
589 	int j;
590 	for(j=0;j<SEQ_MAX;++j)
591 		(*a)[j] = (*b)[j];
592 }
593 
seq_cmp(InputSeq * a,InputSeq * b)594 int seq_cmp(InputSeq* a, InputSeq* b)
595 {
596 	int j;
597 	for(j=0;j<SEQ_MAX;++j)
598 		if ((*a)[j] != (*b)[j])
599 			return -1;
600 	return 0;
601 }
602 
seq_name(InputSeq * code,char * buffer,unsigned max)603 void seq_name(InputSeq* code, char* buffer, unsigned max)
604 {
605 	int j;
606 	char* dest = buffer;
607 	for(j=0;j<SEQ_MAX;++j)
608 	{
609 		const char* name;
610 
611 		if ((*code)[j]==CODE_NONE)
612 			break;
613 
614 		if (j && 1 + 1 <= max)
615 		{
616 			*dest = ' ';
617 			dest += 1;
618 			max -= 1;
619 		}
620 
621 		name = code_name((*code)[j]);
622 		if (!name)
623 			break;
624 
625 		if (strlen(name) + 1 <= max)
626 		{
627 			strcpy(dest,name);
628 			dest += strlen(name);
629 			max -= strlen(name);
630 		}
631 	}
632 
633 	if (dest == buffer && 4 + 1 <= max)
634 		strcpy(dest,"None");
635 	else
636 		*dest = 0;
637 }
638 
seq_pressed(InputSeq * code)639 int seq_pressed(InputSeq* code)
640 {
641 	int j;
642 	int res = 1;
643 	int invert = 0;
644 	int count = 0;
645 
646 	for(j=0;j<SEQ_MAX;++j)
647 	{
648 		switch ((*code)[j])
649 		{
650 			case CODE_NONE :
651 				return res && count;
652 			case CODE_OR :
653 				if (res && count)
654 					return 1;
655 				res = 1;
656 				count = 0;
657 				break;
658 			case CODE_NOT :
659 				invert = !invert;
660 				break;
661 			default:
662 				if (res)
663 				{
664 					int pressed = code_pressed_not_memorized((*code)[j]);
665 					if ((pressed != 0) == invert)
666 						res = 0;
667 				}
668 				invert = 0;
669 				++count;
670 		}
671 	}
672 	return res && count;
673 }
674 
675 /* Static informations used in key/joy recording */
676 static InputCode record_seq[SEQ_MAX]; /* buffer for key recording */
677 static int record_count; /* number of key/joy press recorded */
678 static clock_t record_last; /* time of last key/joy press */
679 
680 #ifdef SDL
681 #define RECORD_TIME (1000*2/3) /* max time between key press */
682 #else
683 #define RECORD_TIME (CLOCKS_PER_SEC*2/3) /* max time between key press */
684 #endif
685 
686 /* Start a sequence recording */
seq_read_async_start(void)687 void seq_read_async_start(void)
688 {
689 	unsigned i;
690 
691 	record_count = 0;
692 	record_last = clock();
693 
694 	/* reset code memory, otherwise this memory may interferes with the input memory */
695 	for(i=0;i<code_mac;++i)
696 		code_map[i].memory = 1;
697 }
698 
699 /* Check that almost one key/joy must be pressed */
seq_valid(InputSeq * seq)700 static int seq_valid(InputSeq* seq)
701 {
702 	int j;
703 	int positive = 0;
704 	int pred_not = 0;
705 	int operand = 0;
706 	for(j=0;j<SEQ_MAX;++j)
707 	{
708 		switch ((*seq)[j])
709 		{
710 			case CODE_NONE :
711 				break;
712 			case CODE_OR :
713 				if (!operand || !positive)
714 					return 0;
715 				pred_not = 0;
716 				positive = 0;
717 				operand = 0;
718 				break;
719 			case CODE_NOT :
720 				if (pred_not)
721 					return 0;
722 				pred_not = !pred_not;
723 				operand = 0;
724 				break;
725 			default:
726 				if (!pred_not)
727 					positive = 1;
728 				pred_not = 0;
729 				operand = 1;
730 				break;
731 		}
732 	}
733 	return positive && operand;
734 }
735 
736 /* Record a key/joy sequence
737 	return <0 if more input is needed
738 	return ==0 if sequence succesfully recorded
739 	return >0 if aborted
740 */
seq_read_async(InputSeq * seq,int first)741 int seq_read_async(InputSeq* seq, int first)
742 {
743 	InputCode newkey;
744 
745 	if (input_ui_pressed(IPT_UI_CANCEL))
746 		return 1;
747 
748 	if (record_count == SEQ_MAX
749 		|| (record_count > 0 && clock() > record_last + RECORD_TIME))	{
750 		int k = 0;
751 		if (!first)
752 		{
753 			/* search the first space free */
754 			while (k < SEQ_MAX && (*seq)[k] != CODE_NONE)
755 				++k;
756 		}
757 
758 		/* if no space restart */
759 		if (k + record_count + (k!=0) > SEQ_MAX)
760 			k = 0;
761 
762 		/* insert */
763 		if (k + record_count + (k!=0) <= SEQ_MAX)
764 		{
765 			int j;
766 			if (k!=0)
767 				(*seq)[k++] = CODE_OR;
768 			for(j=0;j<record_count;++j,++k)
769 				(*seq)[k] = record_seq[j];
770 		}
771 		/* fill to end */
772 		while (k < SEQ_MAX)
773 		{
774 			(*seq)[k] = CODE_NONE;
775 			++k;
776 		}
777 
778 		if (!seq_valid(seq))
779 			seq_set_1(seq,CODE_NONE);
780 
781 		return 0;
782 	}
783 
784 	newkey = code_read_async();
785 
786 	if (newkey != CODE_NONE)
787 	{
788 		/* if code is duplicate negate the code */
789 		if (record_count && newkey == record_seq[record_count-1])
790 			record_seq[record_count-1] = CODE_NOT;
791 
792 		record_seq[record_count++] = newkey;
793 		record_last = clock();
794 	}
795 
796 	return -1;
797 }
798 
799 /***************************************************************************/
800 /* input ui */
801 
802 /* Static buffer for memory input */
803 struct ui_info {
804 	int memory;
805 };
806 
807 static struct ui_info ui_map[__ipt_max];
808 
input_ui_pressed(int code)809 int input_ui_pressed(int code)
810 {
811 	int pressed;
812 
813 	profiler_mark(PROFILER_INPUT);
814 
815 	pressed = seq_pressed(input_port_type_seq(code));
816 
817 	if (pressed)
818 	{
819 		if (ui_map[code].memory == 0)
820 		{
821                         ui_map[code].memory = 1;
822 		} else
823 			pressed = 0;
824 	} else
825 		ui_map[code].memory = 0;
826 
827 	profiler_mark(PROFILER_END);
828 
829 	return pressed;
830 }
831 
input_ui_pressed_repeat(int code,int speed)832 int input_ui_pressed_repeat(int code,int speed)
833 {
834 	static int counter,inputdelay;
835 	int pressed;
836 
837 	profiler_mark(PROFILER_INPUT);
838 
839 	pressed = seq_pressed(input_port_type_seq(code));
840 
841 	if (pressed)
842 	{
843 		if (ui_map[code].memory == 0)
844 		{
845 			ui_map[code].memory = 1;
846 			inputdelay = 3;
847 			counter = 0;
848 		}
849 		else if (++counter > inputdelay * speed * Machine->drv->frames_per_second / 60)
850 		{
851 			inputdelay = 1;
852 			counter = 0;
853 		} else
854 			pressed = 0;
855 	} else
856 		ui_map[code].memory = 0;
857 
858 	profiler_mark(PROFILER_END);
859 
860 	return pressed;
861 }
862 
863