ckb-next  v0.2.8 at branch master
ckb-next driver for corsair devices
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ckb-anim.h
Go to the documentation of this file.
1 #ifndef CKB_ANIM_H
2 #define CKB_ANIM_H
3 
4 // Standardized header for C/C++ CKB animations.
5 // If your animation contains multiple source files, #define CKB_NO_MAIN in all but one of them so you don't get duplicate symbols.
6 // The main function will be defined for you. You must write several specialized functions in order to handle animations:
7 
8 // void ckb_info()
9 // Prints information about the program and any parameters it wishes to receive. See info helpers section.
10 // This function will be caled in a separate invocation of the program. No other functions will be called at this time.
11 
12 // void ckb_init(ckb_runctx* context)
13 // Called during normal invocation of the program, once, before any other functions. See runtime information section.
14 // void ckb_parameter(ckb_runctx* context, const char* name, const char* value)
15 // Receives the user-chosen value of a parameter (specified from ckb_info).
16 // Do not make assumptions about the order or presence of parameters. Assign sane defaults as fallbacks and use the CKB parameter parsing macros.
17 // This function will be called at start up, after ckb_init but before any other functions, once for each parameter.
18 // If live params are enabled, it will also be called while the animation is running.
19 
20 // void ckb_start(ckb_runctx* context, int state)
21 // Starts/restarts (state = 1) or stops (state = 0) an animation in the center of the keyboard (i.e. without a keypress).
22 // Do not assume that this will be called at start up, or at all. It may not be the case depending on configuration.
23 // void ckb_keypress(ckb_runctx* context, ckb_key* key, int x, int y, int state)
24 // Receives a key down / key up event. Called only if KP mode is not NONE.
25 // x and y are always filled and valid. key may be null if KP mode is POSITION.
26 // Once again, do not assume when (or if) this will be called.
27 // void ckb_time(ckb_runctx* context, double delta)
28 // Advances the animation frame. Do not assume that this will occur at a regular interval; use delta to see how much time has passed.
29 // If timing mode is DURATION, delta is in durations (0 <= delta <= 1). If timing mode is ABSOLUTE, delta is in seconds (0 <= delta).
30 // Try to return as quickly as possible, because ckb may stop sending frames if it does not receive a response in time.
31 // int ckb_frame(ckb_runctx* context)
32 // Requests frame data from the animation. Update the context with appropriate colors.
33 // Return 0 to continue running or any other number to exit. On exit, the last-set frame will remain on the keyboard.
34 
35 #include <ctype.h>
36 #include <math.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 
41 #ifndef M_PI
42 #define M_PI 3.14159265358979323846
43 #endif
44 
45 #ifndef TRUE
46 #define TRUE 1
47 #endif
48 #ifndef FALSE
49 #define FALSE 0
50 #endif
51 
52 #define CKB_DOWN 1
53 #define CKB_UP 0
54 
55 // * Info output helpers
56 
57 #define CKB_CONTAINER(macro) do { macro } while(0)
58 
59 // Plugin GUID
60 #define CKB_GUID(guid) CKB_CONTAINER( printf("guid "); printurl(guid); printf("\n"); )
61 // Plugin name
62 #define CKB_NAME(name) CKB_CONTAINER( printf("name "); printurl(name); printf("\n"); )
63 // Plugin version
64 #define CKB_VERSION(version) CKB_CONTAINER( printf("version "); printurl(version); printf("\n"); )
65 // Plugin copyright
66 #define CKB_COPYRIGHT(year, author) CKB_CONTAINER( printf("author "); printurl(author); printf("\nyear %s\n", year); )
67 // Plugin license
68 #define CKB_LICENSE(license) CKB_CONTAINER( printf("license "); printurl(license); printf("\n"); )
69 // Plugin description
70 #define CKB_DESCRIPTION(description) CKB_CONTAINER( printf("description "); printurl(description); printf("\n"); )
71 
72 // Parameter helpers
73 #define CKB_PARAM(type, name, prefix, postfix, extra) CKB_CONTAINER( printf("param %s %s ", type, name); printurl(prefix); printf(" "); printurl(postfix); printf(" "); extra; printf("\n"); )
74 #define CKB_PARAM_LONG(name, prefix, postfix, default, min, max) CKB_PARAM("long", name, prefix, postfix, printf("%ld %ld %ld", (long)(default), (long)(min), (long)(max)))
75 #define CKB_PARAM_DOUBLE(name, prefix, postfix, default, min, max) CKB_PARAM("double", name, prefix, postfix, printf("%lf %lf %lf", (double)(default), (double)(min), (double)(max)))
76 #define CKB_PARAM_BOOL(name, text, default) CKB_PARAM("bool", name, text, "", printf((default) ? "1" : "0"))
77 #define CKB_PARAM_RGB(name, prefix, postfix, r, g, b) CKB_PARAM("rgb", name, prefix, postfix, printf("%02x%02x%02x", (unsigned char)(r), (unsigned char)(g), (unsigned char)(b)))
78 #define CKB_PARAM_ARGB(name, prefix, postfix, a, r, g, b) CKB_PARAM("argb", name, prefix, postfix, printf("%02x%02x%02x%02x", (unsigned char)(a), (unsigned char)(r), (unsigned char)(g), (unsigned char)(b)))
79 #define CKB_PARAM_GRADIENT(name, prefix, postfix, default) CKB_PARAM("gradient", name, prefix, postfix, printurl(default))
80 #define CKB_PARAM_AGRADIENT(name, prefix, postfix, default) CKB_PARAM("agradient", name, prefix, postfix, printurl(default))
81 #define CKB_PARAM_ANGLE(name, prefix, postfix, default) CKB_PARAM("angle", name, prefix, postfix, printf("%ld", (long)(default)))
82 #define CKB_PARAM_STRING(name, prefix, postfix, default) CKB_PARAM("string", name, prefix, postfix, printurl(default))
83 #define CKB_PARAM_LABEL(name, text) CKB_PARAM("label", name, text, "", )
84 
85 #define CKB_PRESET_START(name) CKB_CONTAINER( printf("preset "); printurl(name); )
86 #define CKB_PRESET_PARAM(name, value) CKB_CONTAINER( printf(" %s=", name); printurl(value); )
87 #define CKB_PRESET_END CKB_CONTAINER( printf("\n"); )
88 
89 // Keypress interaction (none, by name, or by position). Default: NONE
90 #define CKB_KP_NONE "none"
91 #define CKB_KP_NAME "name"
92 #define CKB_KP_POSITION "position"
93 #define CKB_KPMODE(mode) CKB_CONTAINER( printf("kpmode %s\n", mode); )
94 // Timing mode (relative to a duration, or absolute). Default: DURATION
95 #define CKB_TIME_DURATION "duration"
96 #define CKB_TIME_ABSOLUTE "absolute"
97 #define CKB_TIMEMODE(mode) CKB_CONTAINER( printf("time %s\n", mode); )
98 // Repeatability. If enabled, the animation will be restarted after a user-chosen amount of time. Default: TRUE
99 #define CKB_REPEAT(enable) CKB_CONTAINER( printf("repeat %s\n", (enable) ? "on" : "off"); )
100 // Startup preemption. Requires duration and repeat enabled. Default: FALSE
101 // If enabled, ckb will play an extra start command on mode switch, placed 1 duration before the actual starting animation.
102 #define CKB_PREEMPT(enable) CKB_CONTAINER( printf("preempt %s\n", (enable) ? "on" : "off"); )
103 // Live parameter updates. Default: FALSE
104 #define CKB_LIVEPARAMS(enable) CKB_CONTAINER( printf("parammode %s\n", (enable) ? "live" : "static"); )
105 
106 // * Runtime information
107 
108 // Parameter input parsers. Usage (within ckb_parameter only):
109 // CKB_PARSE_BOOL("mybool", &mybool){
110 // <actions to take when bool is parsed>
111 // }
112 // or:
113 // CKB_PARSE_BOOL("mybool", &mybool){}
114 
115 #define CKB_PARSE_LONG(param_name, value_ptr) if(!strcmp(name, param_name) && sscanf(value, "%ld", value_ptr) == 1)
116 #define CKB_PARSE_DOUBLE(param_name, value_ptr) if(!strcmp(name, param_name) && sscanf(value, "%lf", value_ptr) == 1)
117 #define CKB_PARSE_BOOL(param_name, value_ptr) if(!strcmp(name, param_name) && sscanf(value, "%u", value_ptr) == 1)
118 #define CKB_PARSE_RGB(param_name, r_ptr, g_ptr, b_ptr) if(!strcmp(name, param_name) && sscanf(value, "%2hhx%2hhx%2hhx", r_ptr, g_ptr, b_ptr) == 3)
119 #define CKB_PARSE_ARGB(param_name, a_ptr, r_ptr, g_ptr, b_ptr) if(!strcmp(name, param_name) && sscanf(value, "%2hhx%2hhx%2hhx%2hhx", a_ptr, r_ptr, g_ptr, b_ptr) == 4)
120 #define CKB_PARSE_GRADIENT(param_name, gradient_ptr) if(!strcmp(name, param_name) && ckb_scan_grad(value, gradient_ptr, 0))
121 #define CKB_PARSE_AGRADIENT(param_name, gradient_ptr) if(!strcmp(name, param_name) && ckb_scan_grad(value, gradient_ptr, 1))
122 #define CKB_PARSE_ANGLE(param_name, value_ptr) if(!strcmp(name, param_name) && sscanf(value, "%ld", value_ptr) == 1)
123 #define CKB_PARSE_STRING(param_name) if(!strcmp(name, param_name))
124 
125 // Converts an angle from ckb output to the correct angle for math functions.
126 // Input: [0, 359], positive direction CW. Output: [0, 2π), positive direction CCW.
127 #define CKB_REAL_ANGLE(angle) fmod((-(angle) + 90.) * M_PI / 180. + M_PI * 2., M_PI * 2.)
128 
129 // Key definition
130 #define CKB_KEYNAME_MAX 12
131 typedef struct {
132  char name[CKB_KEYNAME_MAX];
133  int x, y;
134  unsigned char a, r, g, b;
135 } ckb_key;
136 
137 // Run context. This contains all invocation info except for the user-specified parameters.
138 typedef struct {
139  // Keys
141  unsigned keycount;
142  // Keyboard dimensions
143  unsigned width, height;
144 } ckb_runctx;
145 
146 // Clear all keys in a context (ARGB 00000000).
147 // Call this at the beginning of ckb_frame to start from a blank slate. If you don't, the colors from the previous frame are left intact.
148 #define CKB_KEYCLEAR(context) CKB_CONTAINER( ckb_key* key = context->keys; unsigned count = context->keycount; unsigned i = 0; for(; i < count; i++) key[i].a = key[i].r = key[i].g = key[i].b = 0; )
149 
150 // Gradient structure
151 #define CKB_GRAD_MAX 100
152 typedef struct {
153  // Number of points (at least two)
154  // Gradients MUST have points at 0 and at 100
155  int ptcount;
156  // Point positions, in order (range: [0, 100])
157  char pts[CKB_GRAD_MAX];
158  // Point colors
159  unsigned char a[CKB_GRAD_MAX];
160  unsigned char r[CKB_GRAD_MAX];
161  unsigned char g[CKB_GRAD_MAX];
162  unsigned char b[CKB_GRAD_MAX];
163 } ckb_gradient;
164 int ckb_scan_grad(const char* string, ckb_gradient* gradient, int alpha);
165 
166 // Color of a point on a gradient, with position given between 0 and 100 inclusive
167 void ckb_grad_color(float* a, float* r, float* g, float* b, const ckb_gradient* grad, float pos);
168 
169 // Alpha blend a color into a key
170 void ckb_alpha_blend(ckb_key* key, float a, float r, float g, float b);
171 
172 
173 // * Internal functions
174 
175 #ifndef CKB_NO_MAIN
176 
177 // URL-encoded string printer
178 void printurl(const char* src){
179  char out[strlen(src) * 3 + 1];
180  char* dst = out;
181  char s;
182  while((s = *src++)){
183  if(s <= ',' || s == '/' ||
184  (s >= ':' && s <= '@') ||
185  s == '[' || s == ']' ||
186  s >= 0x7F){
187  char a = s >> 4, b = s & 0xF;
188  if(a >= 10)
189  a += 'A' - 10;
190  else
191  a += '0';
192  if(b >= 10)
193  b += 'A' - 10;
194  else
195  b += '0';
196  dst[0] = '%';
197  dst[1] = a;
198  dst[2] = b;
199  dst += 3;
200  } else
201  *dst++ = s;
202  }
203  *dst = '\0';
204  printf("%s", out);
205 }
206 
207 // URL decode
208 void urldecode(char *dst, const char *src){
209  char a, b;
210  char s;
211  while((s = *src)){
212  if((s == '%') &&
213  ((a = src[1]) && (b = src[2])) &&
214  (isxdigit(a) && isxdigit(b))){
215  if(a >= 'a')
216  a -= 'a'-'A';
217  if(a >= 'A')
218  a -= 'A' - 10;
219  else
220  a -= '0';
221  if(b >= 'a')
222  b -= 'a'-'A';
223  if(b >= 'A')
224  b -= 'A' - 10;
225  else
226  b -= '0';
227  *dst++ = 16*a + b;
228  src += 3;
229  } else {
230  *dst++ = s;
231  src++;
232  }
233  }
234  *dst = '\0';
235 }
236 
237 // Read input line
238 #define CKB_MAX_WORD (4 * 1024)
239 void ckb_getline(char word1[CKB_MAX_WORD], char word2[CKB_MAX_WORD], char word3[CKB_MAX_WORD]){
240  char line[CKB_MAX_WORD * 3 + 3];
241  fgets(line, sizeof(line), stdin);
242  word1[0] = word1[1] = word1[2] = 0;
243  int res = sscanf(line, "%s %s %s", word1, word2, word3);
244  if(res >= 1)
245  urldecode(word1, word1);
246  if(res >= 2)
247  urldecode(word2, word2);
248  if(res >= 3)
249  urldecode(word3, word3);
250  line[strlen(line) - 1] = 0;
251 }
252 
253 // Gradient interpolation
254 void ckb_grad_color(float* a, float* r, float* g, float* b, const ckb_gradient* grad, float pos){
255  // Find the points surrounding this position
256  int count = grad->ptcount;
257  if(count == 0){
258  *a = *r = *g = *b = 0.f;
259  return;
260  }
261  int i = 1;
262  for(; i < count; i++){
263  if(grad->pts[i] >= pos)
264  break;
265  }
266  // Get color by linear interpolation. Premultiply the alpha value so that it returns the expected color
267  // (i.e. stops with zero opacity won't contribute to color)
268  float distance = grad->pts[i] - grad->pts[i - 1];
269  float dx = (pos - grad->pts[i - 1]) / distance;
270  float a1 = grad->a[i] / 255., a2 = grad->a[i - 1] / 255.;
271  float a3 = *a = a1 * dx + a2 * (1.f - dx);
272  if(a3 == 0.){
273  *a = *r = *g = *b = 0.f;
274  return;
275  }
276  *a *= 255.f;
277  *r = (grad->r[i] * a1 * dx + grad->r[i - 1] * a2 * (1.f - dx)) / a3;
278  *g = (grad->g[i] * a1 * dx + grad->g[i - 1] * a2 * (1.f - dx)) / a3;
279  *b = (grad->b[i] * a1 * dx + grad->b[i - 1] * a2 * (1.f - dx)) / a3;
280 }
281 
282 // Alpha blend
283 void ckb_alpha_blend(ckb_key* key, float a, float r, float g, float b){
284  a /= 255.f;
285  float ka = key->a / 255.f;
286  float a2 = a + (1.f - a) * ka;
287  if(a2 == 0.f){
288  key->a = key->r = key->g = key->b = 0;
289  return;
290  }
291  key->a = round(a2 * 255.f);
292  key->r = round((r * a + key->r * ka * (1.f - a)) / a2);
293  key->g = round((g * a + key->g * ka * (1.f - a)) / a2);
294  key->b = round((b * a + key->b * ka * (1.f - a)) / a2);
295 }
296 
297 // Gradient parser
298 int ckb_scan_grad(const char* string, ckb_gradient* gradient, int alpha){
299  char pos = -1;
300  unsigned char a = 255, r, g, b;
301  int count = 0;
302  while(1){
303  int scanned = 0;
304  char newpos;
305  if(sscanf(string, "%hhd:%2hhx%2hhx%2hhx%2hhx%n", &newpos, &a, &r, &g, &b, &scanned) != 5)
306  break;
307  string += scanned;
308  // Don't allow stops out-of-order or past 100
309  if(newpos <= pos || newpos > 100)
310  return 0;
311  pos = newpos;
312  if(!alpha)
313  a = 255;
314  gradient->pts[count] = pos;
315  gradient->a[count] = a;
316  gradient->r[count] = r;
317  gradient->g[count] = g;
318  gradient->b[count] = b;
319  count++;
320  }
321  if(count == 0){
322  // If nothing was read, try a single ARGB constant.
323  if(sscanf(string, "%2hhx%2hhx%2hhx%2hhx", &a, &r, &g, &b) != 4)
324  return 0;
325  count = 2;
326  gradient->pts[0] = 0;
327  gradient->pts[1] = 100;
328  gradient->a[0] = a;
329  gradient->a[1] = 0;
330  gradient->r[0] = gradient->r[1] = r;
331  gradient->g[0] = gradient->g[1] = g;
332  gradient->b[0] = gradient->b[1] = b;
333  }
334  if(count < 2)
335  return 0;
336  gradient->ptcount = count;
337  return 1;
338 }
339 
340 extern void ckb_info();
341 extern void ckb_init(ckb_runctx* context);
342 extern void ckb_parameter(ckb_runctx*, const char*, const char*);
343 extern void ckb_keypress(ckb_runctx*, ckb_key*, int, int, int);
344 extern void ckb_start(ckb_runctx*, int);
345 extern void ckb_time(ckb_runctx*, double);
346 extern int ckb_frame(ckb_runctx*);
347 
348 // Update parameter values
350  char cmd[CKB_MAX_WORD], param[CKB_MAX_WORD], value[CKB_MAX_WORD];
351  do {
352  ckb_getline(cmd, param, value);
353  if(!*cmd){
354  printf("Error [ckb-main]: Reached EOF reading parameters");
355  return;
356  }
357  if(!strcmp(cmd, "end") && !strcmp(param, "params"))
358  break;
359  if(strcmp(cmd, "param"))
360  continue;
361  ckb_parameter(ctx, param, value);
362  } while(1);
363 }
364 
365 int main(int argc, char *argv[]){
366  if(argc == 2){
367  if(!strcmp(argv[1], "--ckb-info")){
368  ckb_info();
369  fflush(stdout);
370  return 0;
371  } else if(!strcmp(argv[1], "--ckb-run")){
372  ckb_runctx ctx;
373  // Read the keymap lines
374  char cmd[CKB_MAX_WORD], param[CKB_MAX_WORD], value[CKB_MAX_WORD];
375  // Skip anything up until "begin keymap"
376  do {
377  ckb_getline(cmd, param, value);
378  if(!*cmd){
379  // If end-of-file is reached, abort
380  printf("Error [ckb-main]: Reached EOF looking for \"begin keymap\"");
381  return -2;
382  }
383  } while(strcmp(cmd, "begin") || strcmp(param, "keymap"));
384  ckb_getline(cmd, param, value);
385  unsigned keycount;
386  if(strcmp(cmd, "keycount") || sscanf(param, "%u", &keycount) != 1 || keycount == 0){
387  // If keycount isn't the next line, something is wrong
388  printf("Error [ckb-main]: \"begin keymap\" not followed with \"keycount\"");
389  return -3;
390  }
391  ctx.keys = (ckb_key*)calloc(keycount, sizeof(ckb_key));
392  ctx.keycount = keycount;
393  unsigned max_x = 0, max_y = 0;
394  unsigned i = 0;
395  for(; i < ctx.keycount; i++){
396  ckb_getline(cmd, param, value);
397  unsigned x, y;
398  if(strcmp(cmd, "key") || !*param || !sscanf(value, "%u,%u", &x, &y)){
399  i--;
400  continue;
401  }
402  ckb_key* key = ctx.keys + i;
403  strncpy(key->name, param, CKB_KEYNAME_MAX);
404  key->x = x;
405  key->y = y;
406  if(x > max_x)
407  max_x = x;
408  if(y > max_y)
409  max_y = y;
410  }
411  ctx.width = max_x + 1;
412  ctx.height = max_y + 1;
413  // Skip anything else until "end keymap"
414  do {
415  ckb_getline(cmd, param, value);
416  if(!*cmd){
417  printf("Error [ckb-main]: Reached EOF looking for \"end keymap\"");
418  return -2;
419  }
420  } while(strcmp(cmd, "end") || strcmp(param, "keymap"));
421  // Run init function
422  ckb_init(&ctx);
423  // Skip anything else until "begin params"
424  do {
425  ckb_getline(cmd, param, value);
426  if(!*cmd){
427  printf("Error [ckb-main]: Reached EOF looking for \"begin params\"");
428  return -2;
429  }
430  } while(strcmp(cmd, "begin") || strcmp(param, "params"));
431  // Parse parameters
432  ckb_read_params(&ctx);
433  // Skip anything else until "begin run"
434  do {
435  ckb_getline(cmd, param, value);
436  if(!*cmd){
437  printf("Error [ckb-main]: Reached EOF looking for \"begin run\"");
438  return -2;
439  }
440  } while(strcmp(cmd, "begin") || strcmp(param, "run"));
441  // Run the main loop
442  printf("begin run\n");
443  fflush(stdout);
444  while(1){
445  ckb_getline(cmd, param, value);
446  if(!*cmd || (!strcmp(cmd, "end") && !strcmp(param, "run")))
447  break;
448  // Parse input
449  if(!strcmp(cmd, "start"))
450  ckb_start(&ctx, 1);
451  else if(!strcmp(cmd, "stop"))
452  ckb_start(&ctx, 0);
453  else if(!strcmp(cmd, "begin") && !strcmp(param, "params"))
454  ckb_read_params(&ctx);
455  else if(!strcmp(cmd, "key")){
456  int x, y;
457  if(sscanf(param, "%d,%d", &x, &y) == 2){
458  // Find a key with this position
459  ckb_key* key = 0;
460  for(i = 0; i < keycount; i++){
461  if(ctx.keys[i].x == x && ctx.keys[i].y == y){
462  key = ctx.keys + i;
463  break;
464  }
465  }
466  if(key)
467  ckb_keypress(&ctx, key, key->x, key->y, !strcmp(value, "down"));
468  else
469  ckb_keypress(&ctx, 0, x, y, !strcmp(value, "down"));
470  } else {
471  // Find a key with this name
472  ckb_key* key = 0;
473  for(i = 0; i < keycount; i++){
474  if(!strcmp(ctx.keys[i].name, param)){
475  key = ctx.keys + i;
476  break;
477  }
478  }
479  if(key)
480  ckb_keypress(&ctx, key, key->x, key->y, !strcmp(value, "down"));
481  }
482  } else if(!strcmp(cmd, "frame")){
483  int end = ckb_frame(&ctx);
484  // Output the frame
485  printf("begin frame\n");
486  for(i = 0; i < ctx.keycount; i++){
487  ckb_key* key = ctx.keys + i;
488  printf("argb %s %02hhx%02hhx%02hhx%02hhx\n", key->name, key->a, key->r, key->g, key->b);
489  }
490  printf("end frame\n");
491  if(end)
492  break;
493  fflush(stdout);
494  } else {
495  double delta = 0.;
496  if(!strcmp(cmd, "time") && sscanf(param, "%lf", &delta) == 1)
497  ckb_time(&ctx, delta);
498  }
499  }
500  printf("end run\n");
501  fflush(stdout);
502  free(ctx.keys);
503  return 0;
504  }
505  }
506  printf("This program must be run from within ckb\n");
507  return -1;
508 }
509 
510 #endif // CKB_NO_MAIN
511 
512 #endif // CKB_ANIM_H
void printurl(const char *src)
Definition: ckb-anim.h:178
int ckb_scan_grad(const char *string, ckb_gradient *gradient, int alpha)
Definition: ckb-anim.h:298
unsigned char b[100]
Definition: ckb-anim.h:162
int x
Definition: ckb-anim.h:133
char pts[100]
Definition: ckb-anim.h:157
float y
Definition: main.c:66
#define CKB_MAX_WORD
Definition: ckb-anim.h:238
unsigned char g
Definition: ckb-anim.h:134
void ckb_parameter(ckb_runctx *, const char *, const char *)
Definition: main.c:68
void ckb_keypress(ckb_runctx *, ckb_key *, int, int, int)
Definition: main.c:75
cmd
Definition: command.h:7
unsigned char g[100]
Definition: ckb-anim.h:161
float x
Definition: main.c:66
unsigned char b
Definition: ckb-anim.h:134
char name[12]
Definition: ckb-anim.h:132
#define CKB_GRAD_MAX
Definition: ckb-anim.h:151
unsigned char r
Definition: ckb-anim.h:134
unsigned char a
Definition: ckb-anim.h:134
Definition: keymap.h:49
unsigned height
Definition: ckb-anim.h:143
void ckb_init(ckb_runctx *context)
Definition: main.c:57
void ckb_time(ckb_runctx *, double)
Definition: main.c:126
unsigned keycount
Definition: ckb-anim.h:141
int main(int argc, char *argv[])
Definition: ckb-anim.h:365
unsigned char r[100]
Definition: ckb-anim.h:160
unsigned char a[100]
Definition: ckb-anim.h:159
void ckb_start(ckb_runctx *, int)
Definition: main.c:114
int y
Definition: ckb-anim.h:133
void urldecode(char *dst, const char *src)
Definition: ckb-anim.h:208
void ckb_getline(char word1[(4 *1024)], char word2[(4 *1024)], char word3[(4 *1024)])
Definition: ckb-anim.h:239
void ckb_read_params(ckb_runctx *ctx)
Definition: ckb-anim.h:349
void ckb_info()
Definition: main.c:5
#define CKB_KEYNAME_MAX
Definition: ckb-anim.h:130
ckb_key * keys
Definition: ckb-anim.h:140
int ckb_frame(ckb_runctx *)
Definition: main.c:137
void ckb_alpha_blend(ckb_key *key, float a, float r, float g, float b)
Definition: ckb-anim.h:283
unsigned width
Definition: ckb-anim.h:143
void ckb_grad_color(float *a, float *r, float *g, float *b, const ckb_gradient *grad, float pos)
Definition: ckb-anim.h:254