changeset 214:5a5404338b9f

Adding support for layer packing - Only keep state for the scan code that are available for the layer - Also properly implemented scan code range checking (was not done before, only worked because the KLL compiler was well behaved)
author Jacob Alexander <haata@kiibohd.com>
date Tue, 16 Sep 2014 17:04:59 -0700
parents 2f6ec276a678
children 00a8c7f491d4
files Macro/PartialMap/kll.h Macro/PartialMap/macro.c
diffstat 2 files changed, 50 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/Macro/PartialMap/kll.h	Tue Sep 16 15:37:16 2014 -0700
+++ b/Macro/PartialMap/kll.h	Tue Sep 16 17:04:59 2014 -0700
@@ -118,7 +118,7 @@
 // TriggerMacro struct, one is created per TriggerMacro, no duplicates
 typedef struct TriggerMacro {
 	const uint8_t *guide;
-	var_uint_t result;
+	const var_uint_t result;
 	var_uint_t pos;
 	TriggerMacroState state;
 } TriggerMacro;
@@ -137,8 +137,8 @@
 
 // Capability
 typedef struct Capability {
-	void *func;
-	uint8_t argCount;
+	const void *func;
+	const uint8_t argCount;
 } Capability;
 
 // Total Number of Capabilities
@@ -205,28 +205,31 @@
 //   * Shift - 0x01
 //   * Latch - 0x02
 //   * Lock  - 0x04
+// Layer states are stored in the LayerState array
 //
 // Except for Off, all states an exist simultaneously for each layer
 // For example:
 // state -> 0x04 + 0x01 = 0x05 (Shift + Lock), which is effectively Off (0x00)
 //
-// Max defines the maximum number of keys in the map, maximum of 0xFF
+// First defines the first used scan code (most keyboards start at 0, some start higher e.g. 0x40)
 //  - Compiler calculates this
 //
+// Last defines the last scan code used (helps reduce RAM usage)
+//
 // The name is defined for cli debugging purposes (Null terminated string)
 
 typedef struct Layer {
 	const nat_ptr_t **triggerMap;
 	const char *name;
-	const uint8_t max;
-	uint8_t state;
+	const uint8_t first;
+	const uint8_t last;
 } Layer;
 
-
-// Layer_IN( map, name );
-//  * map  - Trigger map
-//  * name - Name of the trigger map
-#define Layer_IN( map, name ) { map, name, sizeof( map ) / sizeof( nat_ptr_t ) - 1, 0 }
+// Layer_IN( map, name, first );
+//  * map   - Trigger map
+//  * name  - Name of the trigger map
+//  * first - First scan code used (most keyboards start at 0, some start higher e.g. 0x40)
+#define Layer_IN( map, name, first ) { map, name, first, sizeof( map ) / sizeof( nat_ptr_t ) - 1 + first }
 
 // Total number of layers
 #define LayerNum sizeof( LayerIndex ) / sizeof( Layer )
--- a/Macro/PartialMap/macro.c	Tue Sep 16 15:37:16 2014 -0700
+++ b/Macro/PartialMap/macro.c	Tue Sep 16 17:04:59 2014 -0700
@@ -155,15 +155,15 @@
 	}
 
 	// Toggle Layer State Byte
-	if ( LayerIndex[ layer ].state & layerState )
+	if ( LayerState[ layer ] & layerState )
 	{
 		// Unset
-		LayerIndex[ layer ].state &= ~layerState;
+		LayerState[ layer ] &= ~layerState;
 	}
 	else
 	{
 		// Set
-		LayerIndex[ layer ].state |= layerState;
+		LayerState[ layer ] |= layerState;
 	}
 
 	// If the layer was not in the LayerIndexStack add it
@@ -173,7 +173,7 @@
 	}
 
 	// If the layer is in the LayerIndexStack and the state is 0x00, remove
-	if ( LayerIndex[ layer ].state == 0x00 && inLayerIndexStack )
+	if ( LayerState[ layer ] == 0x00 && inLayerIndexStack )
 	{
 		// Remove the layer from the LayerIndexStack
 		// Using the already positioned stackItem variable from the loop above
@@ -302,43 +302,55 @@
 	for ( uint16_t layerIndex = 0; layerIndex < macroLayerIndexStackSize; layerIndex++ )
 	{
 		// Lookup Layer
-		Layer *layer = &LayerIndex[ macroLayerIndexStack[ layerIndex ] ];
+		const Layer *layer = &LayerIndex[ macroLayerIndexStack[ layerIndex ] ];
 
 		// Check if latch has been pressed for this layer
 		// XXX Regardless of whether a key is found, the latch is removed on first lookup
-		uint8_t latch = layer->state & 0x02;
+		uint8_t latch = LayerState[ layerIndex ] & 0x02;
 		if ( latch )
 		{
-			layer->state &= ~0x02;
+			LayerState[ layerIndex ] &= ~0x02;
 		}
 
 		// Only use layer, if state is valid
 		// XOR each of the state bits
 		// If only two are enabled, do not use this state
-		if ( (layer->state & 0x01) ^ (latch>>1) ^ ((layer->state & 0x04)>>2) )
+		if ( (LayerState[ layerIndex ] & 0x01) ^ (latch>>1) ^ ((LayerState[ layerIndex ] & 0x04)>>2) )
 		{
 			// Lookup layer
 			nat_ptr_t **map = (nat_ptr_t**)layer->triggerMap;
 
 			// Determine if layer has key defined
-			if ( map != 0 && *map[ scanCode ] != 0 )
-				return map[ scanCode ];
+			// Make sure scanCode is between layer first and last scancodes
+			if ( map != 0
+			  && scanCode < layer->last
+			  && scanCode > layer->first
+			  && *map[ scanCode - layer->first ] != 0 )
+			{
+				return map[ scanCode - layer->first ];
+			}
 		}
 	}
 
 	// Do lookup on default layer
 	nat_ptr_t **map = (nat_ptr_t**)LayerIndex[0].triggerMap;
 
-	// Determine if layer has key defined
-	if ( map == 0 && *map[ scanCode ] == 0 )
+	// Lookup default layer
+	const Layer *layer = &LayerIndex[ macroLayerIndexStack[ 0 ] ];
+
+	// Make sure scanCode is between layer first and last scancodes
+	if ( map != 0
+	  && scanCode < layer->last
+	  && scanCode > layer->first
+	  && *map[ scanCode - layer->first ] != 0 )
 	{
-		erro_msg("Scan Code has no defined Trigger Macro: ");
-		printHex( scanCode );
-		return 0;
+		return map[ scanCode - layer->first ];
 	}
 
-	// Return lookup result
-	return map[ scanCode ];
+	// Otherwise no defined Trigger Macro
+	erro_msg("Scan Code has no defined Trigger Macro: ");
+	printHex( scanCode );
+	return 0;
 }
 
 
@@ -1157,11 +1169,13 @@
 
 		// Layer State
 		print( NL "\t\t Layer State: " );
-		printHex( LayerIndex[ layer ].state );
+		printHex( LayerState[ layer ] );
 
-		// Max Index
-		print(" Max Index: ");
-		printHex( LayerIndex[ layer ].max );
+		// First -> Last Indices
+		print(" First -> Last Indices: ");
+		printHex( LayerIndex[ layer ].first );
+		print(" -> ");
+		printHex( LayerIndex[ layer ].last );
 	}
 }
 
@@ -1206,7 +1220,7 @@
 			printHex( arg2 );
 
 			// Set the layer state
-			LayerIndex[ arg1 ].state = arg2;
+			LayerState[ arg1 ] = arg2;
 			break;
 		}
 	}