[PATCH] Remove keymap.c::KeyStates[] array replicating ikbd.c::ScanCodeState[] one

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Both keymap.c::KeyStates[] and ikbd.c::ScanCodeState[] arrays were
used to keep track of each ST key (scancode) press status, but they
had different sizes.

Removing KeyStates[] required moving part of de-bounce handling to
a new ikbd.c::IKBD_ReleaseKeysExceptListed() function, and making
ikbd.c::IKBD_PressSTKey() code marginally smarter.

At the same time this optimizes de-bounce handling by providing full
lookup table instead of using a zero-terminated one that needs to be
scanned through for each scancode.
---
 src/ikbd.c          | 44 +++++++++++++++-----
 src/includes/ikbd.h |  7 ++--
 src/keymap.c        | 98 +++++++++++----------------------------------
 3 files changed, 63 insertions(+), 86 deletions(-)

diff --git a/src/ikbd.c b/src/ikbd.c
index 48644417..5827f03f 100644
--- a/src/ikbd.c
+++ b/src/ikbd.c
@@ -379,7 +379,7 @@ static void	(*pIKBD_CustomCodeHandler_Read) ( void );
 static void	(*pIKBD_CustomCodeHandler_Write) ( Uint8 );
 static bool	IKBD_ExeMode = false;
 
-static Uint8	ScanCodeState[ 128 ];			/* state of each key : 0=released 1=pressed */
+static bool	ScanCodeState[ KBD_NUM_SCANCODES ];	/* state of each key : false=released true=pressed */
 
 /* This array contains all known custom 6301 programs, with their CRC */
 static const struct
@@ -570,9 +570,8 @@ static void	IKBD_Boot_ROM ( bool ClearAllRAM )
 
 	KeyboardProcessor.Joy.PrevJoyData[0] = KeyboardProcessor.Joy.PrevJoyData[1] = 0;
 
-	for ( i=0 ; i<128 ; i++ )
-		ScanCodeState[ i ] = 0;				/* key is released */
-
+	/* release (=0) all keys */
+	memset(ScanCodeState, 0, sizeof(ScanCodeState));
 
 	/* Reset our keyboard states and clear key state table */
 	Keyboard.BufferHead = Keyboard.BufferTail = 0;
@@ -580,7 +579,6 @@ static void	IKBD_Boot_ROM ( bool ClearAllRAM )
 	Keyboard.nBytesInInputBuffer = 0;
 	Keyboard.PauseOutput = false;
 
-	memset(Keyboard.KeyStates, 0, sizeof(Keyboard.KeyStates));
 	Keyboard.bLButtonDown = BUTTON_NULL;
 	Keyboard.bRButtonDown = BUTTON_NULL;
 	Keyboard.bOldLButtonDown = Keyboard.bOldRButtonDown = BUTTON_NULL;
@@ -1737,9 +1735,14 @@ void IKBD_PressSTKey(Uint8 ScanCode, bool bPress)
 	if ( KeyboardProcessor.JoystickMode == AUTOMODE_JOYSTICK_MONITORING )
 		return;
 
-	/* Store the state of each ST scancode : 1=pressed 0=released */
-	if ( bPress )		ScanCodeState[ ScanCode & 0x7f ] = 1;
-	else			ScanCodeState[ ScanCode & 0x7f ] = 0;
+	/* should not need masking... */
+	assert(!(ScanCode & ~KBD_SCANCODE_MASK));
+	ScanCode &= KBD_SCANCODE_MASK;
+
+	/* ignore if already in requested state */
+	if (ScanCodeState[ScanCode] == bPress)
+		return;
+	ScanCodeState[ScanCode] = bPress;
 
 	if (!bPress)
 		ScanCode |= 0x80;				/* Set top bit if released key */
@@ -1754,6 +1757,29 @@ void IKBD_PressSTKey(Uint8 ScanCode, bool bPress)
 		(*pIKBD_CustomCodeHandler_Read) ();
 }
 
+/*-----------------------------------------------------------------------*/
+/**
+ * Release all pressed keys except the (modifier) ones with true
+ * values in the given array (having same size as scancode table)
+ */
+void IKBD_ReleaseKeysExceptListed(const bool *SkipList, Uint8 items)
+{
+	Uint8 ScanCode;
+
+	assert(items == ARRAY_SIZE(ScanCodeState));
+
+	for (ScanCode = 0; ScanCode < items; ScanCode++)
+	{
+		/* not pressed? */
+		if (!ScanCodeState[ScanCode])
+			continue;
+		/* not to be released? */
+		if (SkipList[ScanCode])
+			continue;
+		/* release */
+		IKBD_PressSTKey(ScanCode, false);
+	}
+}
 
 /*-----------------------------------------------------------------------*/
 /**
@@ -1765,7 +1791,7 @@ static int IKBD_CheckPressedKey(void)
 {
 	unsigned int	i;
 
-	for (i=0 ; i<sizeof(ScanCodeState) ; i++ )
+	for (i=0 ; i < ARRAY_SIZE(ScanCodeState) ; i++ )
 		if ( ScanCodeState[ i ] )
 			return i;
 
diff --git a/src/includes/ikbd.h b/src/includes/ikbd.h
index e4bf6898..cd1ded76 100644
--- a/src/includes/ikbd.h
+++ b/src/includes/ikbd.h
@@ -40,13 +40,13 @@ typedef struct {
 } KEYBOARD_PROCESSOR;
 
 /* Keyboard state */
-#define KBD_MAX_SCANCODE          0x72
+#define KBD_MAX_SCANCODE          0x7f
+#define KBD_NUM_SCANCODES         0x80
+#define KBD_SCANCODE_MASK         0x7f    /* bit 0x80 used for extra info */
 #define SIZE_KEYBOARD_BUFFER      1024    /* Allow this many bytes to be stored in buffer (waiting to send to ACIA) */
 #define KEYBOARD_BUFFER_MASK      (SIZE_KEYBOARD_BUFFER-1)
 #define SIZE_KEYBOARDINPUT_BUFFER 8
 typedef struct {
-  Uint8 KeyStates[KBD_MAX_SCANCODE + 1];	/* State of ST keys, TRUE is down */
-
   Uint8 Buffer[SIZE_KEYBOARD_BUFFER];		/* Keyboard output buffer */
   int BufferHead,BufferTail;			/* Pointers into above buffer */
   int NbBytesInOutputBuffer;			/* Number of bytes in output buffer */
@@ -95,6 +95,7 @@ extern void IKBD_InterruptHandler_AutoSend(void);
 extern void IKBD_UpdateClockOnVBL ( void );
 
 extern void IKBD_PressSTKey(Uint8 ScanCode, bool bPress);
+extern void IKBD_ReleaseKeysExceptListed(const bool *SkipList, Uint8 items);
 
 extern void IKBD_Info(FILE *fp, Uint32 dummy);
 
diff --git a/src/keymap.c b/src/keymap.c
index 83d03934..5a03b4a0 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -11,6 +11,7 @@
 const char Keymap_fileid[] = "Hatari keymap.c";
 
 #include <ctype.h>
+#include <assert.h>
 #include "main.h"
 #include "keymap.h"
 #include "configuration.h"
@@ -29,17 +30,8 @@ const char Keymap_fileid[] = "Hatari keymap.c";
 /* Table for loaded keys: */
 static int LoadedKeymap[KBD_MAX_SCANCODE][2];
 
-/* List of ST scan codes to NOT de-bounce when running in maximum speed */
-static const uint8_t DebounceExtendedKeys[] =
-{
-	0x1d,  /* CTRL */
-	0x2a,  /* Left SHIFT */
-	0x01,  /* ESC */
-	0x38,  /* ALT */
-	0x36,  /* Right SHIFT */
-	0      /* term */
-};
-
+/* ST scancodes NOT to release when running in max speed are set true */
+static bool SkipList[ KBD_NUM_SCANCODES ];
 
 
 /*-----------------------------------------------------------------------*/
@@ -48,6 +40,24 @@ static const uint8_t DebounceExtendedKeys[] =
  */
 void Keymap_Init(void)
 {
+	/* List of ST scancodes NOT to release when running in max speed */
+	static const uint8_t skip[] =
+	{
+		0x1d,  /* CTRL */
+		0x2a,  /* Left SHIFT */
+		0x01,  /* ESC */
+		0x38,  /* ALT */
+		0x36,  /* Right SHIFT */
+		0      /* term */
+	};
+	uint8_t i, scancode;
+
+	memset(SkipList, 0, sizeof(SkipList));
+	for (i = 0; (scancode = skip[i]); i++)
+	{
+		assert(scancode < ARRAY_SIZE(SkipList));
+		SkipList[scancode] = true;
+	}
 	Keymap_LoadRemapFile(ConfigureParams.Keyboard.szMappingFileName);
 }
 
@@ -511,37 +521,6 @@ void Keymap_LoadRemapFile(const char *pszFileName)
 }
 
 
-/*-----------------------------------------------------------------------*/
-/**
- * Scan list of keys to NOT de-bounce when running in maximum speed, eg ALT,SHIFT,CTRL etc...
- * @return true if key requires de-bouncing
- */
-static bool Keymap_DebounceSTKey(uint8_t STScanCode)
-{
-	int i=0;
-
-	/* Are we in fast forward, and have disabled key repeat? */
-	if ((ConfigureParams.System.bFastForward == true)
-	    && (ConfigureParams.Keyboard.bDisableKeyRepeat))
-	{
-		/* We should de-bounce all non extended keys,
-		 * e.g. leave ALT, SHIFT, CTRL etc... held */
-		while (DebounceExtendedKeys[i])
-		{
-			if (STScanCode == DebounceExtendedKeys[i])
-				return false;
-			i++;
-		}
-
-		/* De-bounce key */
-		return true;
-	}
-
-	/* Do not de-bounce key */
-	return false;
-}
-
-
 /*-----------------------------------------------------------------------*/
 /**
  * Debounce any PC key held down if running with key repeat disabled.
@@ -550,8 +529,6 @@ static bool Keymap_DebounceSTKey(uint8_t STScanCode)
  */
 void Keymap_DebounceAllKeys(void)
 {
-	uint8_t nScanCode;
-
 	/* Return if we aren't in fast forward or have not disabled key repeat */
 	if ((ConfigureParams.System.bFastForward == false)
 	        || (!ConfigureParams.Keyboard.bDisableKeyRepeat))
@@ -559,21 +536,7 @@ void Keymap_DebounceAllKeys(void)
 		return;
 	}
 
-	/* Now run through each key looking for ones held down */
-	for (nScanCode = 1; nScanCode < ARRAY_SIZE(Keyboard.KeyStates); nScanCode++)
-	{
-		/* Is key held? */
-		if (Keyboard.KeyStates[nScanCode])
-		{
-			/* Does this require de-bouncing? */
-			if (Keymap_DebounceSTKey(nScanCode))
-			{
-				IKBD_PressSTKey(nScanCode, false);
-				Keyboard.KeyStates[nScanCode] = false;
-			}
-		}
-	}
-
+	IKBD_ReleaseKeysExceptListed(SkipList, ARRAY_SIZE(SkipList));
 }
 
 
@@ -624,14 +587,7 @@ void Keymap_KeyDown(const SDL_Keysym *sdlkey)
 	STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey);
 	LOG_TRACE(TRACE_KEYMAP, "key map: sym=0x%x to ST-scan=0x%02x\n", symkey, STScanCode);
 	if (STScanCode != ST_NO_SCANCODE)
-	{
-		if (!Keyboard.KeyStates[STScanCode])
-		{
-			/* Set down */
-			Keyboard.KeyStates[STScanCode] = true;
-			IKBD_PressSTKey(STScanCode, true);
-		}
-	}
+		IKBD_PressSTKey(STScanCode, true);
 }
 
 
@@ -664,13 +620,7 @@ void Keymap_KeyUp(const SDL_Keysym *sdlkey)
 	STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey);
 	/* Release key (only if was pressed) */
 	if (STScanCode != ST_NO_SCANCODE)
-	{
-		if (Keyboard.KeyStates[STScanCode])
-		{
-			IKBD_PressSTKey(STScanCode, false);
-			Keyboard.KeyStates[STScanCode] = false;
-		}
-	}
+		IKBD_PressSTKey(STScanCode, false);
 }
 
 /*-----------------------------------------------------------------------*/
-- 
2.30.2


--------------1D6AEA978A2F8B7A83A60D1C--



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/