]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Macro/PartialMap/macro.c
Kishsaver is fully working with DPH!
[kiibohd-controller.git] / Macro / PartialMap / macro.c
1 /* Copyright (C) 2014 by Jacob Alexander
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to deal
5  * in the Software without restriction, including without limitation the rights
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19  * THE SOFTWARE.
20  */
21
22 // ----- Includes -----
23
24 // Compiler Includes
25 #include <Lib/MacroLib.h>
26
27 // Project Includes
28 #include <cli.h>
29 #include <led.h>
30 #include <print.h>
31 #include <scan_loop.h>
32 #include <output_com.h>
33
34 // Keymaps
35 #include "usb_hid.h"
36 #include <defaultMap.h>
37
38 // Local Includes
39 #include "macro.h"
40
41
42
43 // ----- Function Declarations -----
44
45 void cliFunc_capList    ( char* args );
46 void cliFunc_capSelect  ( char* args );
47 void cliFunc_lookComb   ( char* args );
48 void cliFunc_lookDefault( char* args );
49 void cliFunc_lookPartial( char* args );
50 void cliFunc_macroDebug ( char* args );
51
52
53
54 // ----- Variables -----
55
56 // Macro Module command dictionary
57 char*       macroCLIDictName = "Macro Module Commands (Not all commands fully work yet...)";
58 CLIDictItem macroCLIDict[] = {
59         { "capList",     "Prints an indexed list of all non USB keycode capabilities.", cliFunc_capList },
60         { "capSelect",   "Triggers the specified capability." NL "\t\t\033[35mU10\033[0m USB Code 0x0A, \033[35mK11\033[0m Keyboard Capability 0x0B, \033[35mS12\033[0m Scancode 0x0C", cliFunc_capSelect },
61         { "lookComb",    "Do a lookup on the Combined map." NL "\t\t\033[35mS10\033[0m Scancode 0x0A, \033[35mU11\033[0m USB Code 0x0B", cliFunc_lookComb },
62         { "lookDefault", "Do a lookup on the Default map." NL "\t\t\033[35mS10\033[0m Scancode 0x0A", cliFunc_lookDefault },
63         { "lookPartial", "Do a lookup on the layered Partial maps." NL "\t\t\033[35mS10\033[0m Scancode 0x0A, \033[35mU11\033[0m USB Code 0x0B", cliFunc_lookPartial },
64         { "macroDebug",  "Disables/Enables sending USB keycodes to the Output Module and prints U/K codes.", cliFunc_macroDebug },
65         { 0, 0, 0 } // Null entry for dictionary end
66 };
67
68
69 // Macro debug flag - If set, clears the USB Buffers after signalling processing completion
70 uint8_t macroDebugMode = 0;
71
72
73
74 // ----- Functions -----
75
76 inline void Macro_bufferAdd( uint8_t byte )
77 {
78         // Make sure we haven't overflowed the key buffer
79         // Default function for adding keys to the KeyIndex_Buffer, does a DefaultMap_Lookup
80         if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER )
81         {
82                 uint8_t key = DefaultMap_Lookup[byte];
83                 for ( uint8_t c = 0; c < KeyIndex_BufferUsed; c++ )
84                 {
85                         // Key already in the buffer
86                         if ( KeyIndex_Buffer[c] == key )
87                                 return;
88                 }
89
90                 // Add to the buffer
91                 KeyIndex_Buffer[KeyIndex_BufferUsed++] = key;
92         }
93 }
94
95 inline void Macro_bufferRemove( uint8_t byte )
96 {
97         uint8_t key = DefaultMap_Lookup[byte];
98
99         // Check for the released key, and shift the other keys lower on the buffer
100         for ( uint8_t c = 0; c < KeyIndex_BufferUsed; c++ )
101         {
102                 // Key to release found
103                 if ( KeyIndex_Buffer[c] == key )
104                 {
105                         // Shift keys from c position
106                         for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
107                                 KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
108
109                         // Decrement Buffer
110                         KeyIndex_BufferUsed--;
111
112                         return;
113                 }
114         }
115
116         // Error case (no key to release)
117         erro_msg("Could not find key to release: ");
118         printHex( key );
119 }
120
121 inline void Macro_finishWithUSBBuffer( uint8_t sentKeys )
122 {
123 }
124
125 inline void Macro_process()
126 {
127         // Only do one round of macro processing between Output Module timer sends
128         if ( USBKeys_Sent != 0 )
129                 return;
130
131         // Loop through input buffer
132         for ( uint8_t index = 0; index < KeyIndex_BufferUsed; index++ )
133         {
134                 //print(" KEYS: ");
135                 //printInt8( KeyIndex_BufferUsed );
136                 // Get the keycode from the buffer
137                 uint8_t key = KeyIndex_Buffer[index];
138
139                 // Set the modifier bit if this key is a modifier
140                 if ( (key & KEY_LCTRL) == KEY_LCTRL ) // AND with 0xE0
141                 {
142                         USBKeys_Modifiers |= 1 << (key ^ KEY_LCTRL); // Left shift 1 by key XOR 0xE0
143
144                         // Modifier processed, move on to the next key
145                         continue;
146                 }
147
148                 // Too many keys
149                 if ( USBKeys_Sent >= USBKeys_MaxSize )
150                 {
151                         warn_msg("USB Key limit reached");
152                         errorLED( 1 );
153                         break;
154                 }
155
156                 // Allow ignoring keys with 0's
157                 if ( key != 0 )
158                 {
159                         USBKeys_Array[USBKeys_Sent++] = key;
160                 }
161                 else
162                 {
163                         // Key was not mapped
164                         erro_msg( "Key not mapped... - " );
165                         printHex( key );
166                         errorLED( 1 );
167                 }
168         }
169
170         // Signal buffer that we've used it
171         Scan_finishedWithBuffer( KeyIndex_BufferUsed );
172
173         // If Macro debug mode is set, clear the USB Buffer
174         if ( macroDebugMode )
175         {
176                 USBKeys_Modifiers = 0;
177                 USBKeys_Sent = 0;
178         }
179 }
180
181 inline void Macro_setup()
182 {
183         // Register Macro CLI dictionary
184         CLI_registerDictionary( macroCLIDict, macroCLIDictName );
185
186         // Disable Macro debug mode
187         macroDebugMode = 0;
188 }
189
190
191 // ----- CLI Command Functions -----
192
193 void cliFunc_capList( char* args )
194 {
195         // TODO
196 }
197
198 void cliFunc_capSelect( char* args )
199 {
200         // Parse code from argument
201         //  NOTE: Only first argument is used
202         char* arg1Ptr;
203         char* arg2Ptr;
204         CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
205
206         // Depending on the first character, the lookup changes
207         switch ( arg1Ptr[0] )
208         {
209         // Keyboard Capability
210         case 'K':
211                 // TODO
212                 break;
213
214         // Scancode
215         case 'S':
216                 // Add to the USB Buffer using the DefaultMap lookup
217                 Macro_bufferAdd( decToInt( &arg1Ptr[1] ) );
218                 break;
219
220         // USB Code
221         case 'U':
222                 // Just add the key to the USB Buffer
223                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER )
224                 {
225                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = decToInt( &arg1Ptr[1] );
226                 }
227                 break;
228         }
229 }
230
231 void cliFunc_lookComb( char* args )
232 {
233         // Parse code from argument
234         //  NOTE: Only first argument is used
235         char* arg1Ptr;
236         char* arg2Ptr;
237         CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
238
239         // Depending on the first character, the lookup changes
240         switch ( arg1Ptr[0] )
241         {
242         // Scancode
243         case 'S':
244                 // TODO
245                 break;
246
247         // USB Code
248         case 'U':
249                 // TODO
250                 break;
251         }
252 }
253
254 void cliFunc_lookDefault( char* args )
255 {
256         // Parse code from argument
257         //  NOTE: Only first argument is used
258         char* arg1Ptr;
259         char* arg2Ptr;
260         CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
261
262         // Depending on the first character, the lookup changes
263         switch ( arg1Ptr[0] )
264         {
265         // Scancode
266         case 'S':
267                 print( NL );
268                 printInt8( DefaultMap_Lookup[decToInt( &arg1Ptr[1] )] );
269                 print(" ");
270                 printHex( DefaultMap_Lookup[decToInt( &arg1Ptr[1] )] );
271                 break;
272         }
273 }
274
275 void cliFunc_lookPartial( char* args )
276 {
277         // Parse code from argument
278         //  NOTE: Only first argument is used
279         char* arg1Ptr;
280         char* arg2Ptr;
281         CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
282
283         // Depending on the first character, the lookup changes
284         switch ( arg1Ptr[0] )
285         {
286         // Scancode
287         case 'S':
288                 // TODO
289                 break;
290
291         // USB Code
292         case 'U':
293                 // TODO
294                 break;
295         }
296 }
297
298 void cliFunc_macroDebug( char* args )
299 {
300         // Toggle macro debug mode
301         macroDebugMode = macroDebugMode ? 0 : 1;
302
303         print( NL );
304         info_msg("Macro Debug Mode: ");
305         printInt8( macroDebugMode );
306 }
307