79
79
typedef struct cmatrix {
80
80
int val ;
81
81
bool is_head ;
82
+ int color ; // For multi-color mode, each character can have a different color
82
83
} cmatrix ;
83
84
84
85
/* Global variables */
@@ -92,6 +93,11 @@ int *updates = NULL; /* What does this do again? */
92
93
#ifndef _WIN32
93
94
volatile sig_atomic_t signal_status = 0 ; /* Indicates a caught signal */
94
95
#endif
96
+ int * color_array = NULL ; /* Array of color values for multi-color mode */
97
+ int num_colors = 0 ; /* Number of colors in current use (0 when not in multi-color mode) */
98
+ int original_num_colors = 0 ; /* Remember the original number of colors */
99
+ int mcolor = COLOR_GREEN ; /* Current matrix color */
100
+ int rainbow = 0 ; /* Flag for rainbow mode */
95
101
96
102
int va_system (char * str , ...) {
97
103
@@ -164,7 +170,9 @@ void usage(void) {
164
170
printf (" -M [message]: Prints your message in the center of the screen. Overrides -L's default message.\n" );
165
171
printf (" -u delay (0 - 10, default 4): Screen update delay\n" );
166
172
printf (" -C [color]: Use this color for matrix (default green)\n" );
173
+ printf (" Multiple colors can be specified as comma-separated list (e.g. -C red,blue,green)\n" );
167
174
printf (" -r: rainbow mode\n" );
175
+ printf (" Will use colors from -C if multiple specified, otherwise full rainbow\n" );
168
176
printf (" -m: lambda mode\n" );
169
177
printf (" -k: Characters change while scrolling. (Works without -o opt.)\n" );
170
178
printf (" -t [tty]: Set tty to use\n" );
@@ -189,6 +197,29 @@ void *nmalloc(size_t howmuch) {
189
197
return r ;
190
198
}
191
199
200
+ /* Parse a color name and return the corresponding COLOR_* constant */
201
+ int parse_color (const char * color_name ) {
202
+ if (!strcasecmp (color_name , "green" )) {
203
+ return COLOR_GREEN ;
204
+ } else if (!strcasecmp (color_name , "red" )) {
205
+ return COLOR_RED ;
206
+ } else if (!strcasecmp (color_name , "blue" )) {
207
+ return COLOR_BLUE ;
208
+ } else if (!strcasecmp (color_name , "white" )) {
209
+ return COLOR_WHITE ;
210
+ } else if (!strcasecmp (color_name , "yellow" )) {
211
+ return COLOR_YELLOW ;
212
+ } else if (!strcasecmp (color_name , "cyan" )) {
213
+ return COLOR_CYAN ;
214
+ } else if (!strcasecmp (color_name , "magenta" )) {
215
+ return COLOR_MAGENTA ;
216
+ } else if (!strcasecmp (color_name , "black" )) {
217
+ return COLOR_BLACK ;
218
+ } else {
219
+ return -1 ; /* Invalid color */
220
+ }
221
+ }
222
+
192
223
/* Initialize the global variables */
193
224
void var_init () {
194
225
int i , j ;
@@ -223,6 +254,7 @@ void var_init() {
223
254
for (i = 0 ; i <= LINES ; i ++ ) {
224
255
for (j = 0 ; j <= COLS - 1 ; j += 2 ) {
225
256
matrix [i ][j ].val = -1 ;
257
+ matrix [i ][j ].color = mcolor ; // Initialize with default color
226
258
}
227
259
}
228
260
@@ -310,6 +342,27 @@ void resize_screen(void) {
310
342
refresh ();
311
343
}
312
344
345
+ /**
346
+ * Selects a color for a matrix character based on current global program state.
347
+ *
348
+ * This function uses GLOBAL STATE variables:
349
+ * - num_colors: Number of colors in the custom palette
350
+ * - color_array: Array of custom color values
351
+ * - rainbow: Flag indicating if rainbow mode is active
352
+ * - mcolor: Current default color
353
+ *
354
+ * @return The selected color value (COLOR_* constant)
355
+ */
356
+ int select_matrix_color (void ) {
357
+ if (num_colors > 0 && color_array != NULL && !rainbow ) {
358
+ /* Multi-color mode - select from custom palette */
359
+ return color_array [rand () % num_colors ];
360
+ } else {
361
+ /* Single color mode or no custom palette - use global color */
362
+ return mcolor ;
363
+ }
364
+ }
365
+
313
366
int main (int argc , char * argv []) {
314
367
int i , y , z , optchr , keypress ;
315
368
int j = 0 ;
@@ -323,8 +376,6 @@ int main(int argc, char *argv[]) {
323
376
int random = 0 ;
324
377
int update = 4 ;
325
378
int highnum = 0 ;
326
- int mcolor = COLOR_GREEN ;
327
- int rainbow = 0 ;
328
379
int lambda = 0 ;
329
380
int randnum = 0 ;
330
381
int randmin = 0 ;
@@ -356,26 +407,48 @@ int main(int argc, char *argv[]) {
356
407
bold = 2 ;
357
408
break ;
358
409
case 'C' :
359
- if (!strcasecmp (optarg , "green" )) {
360
- mcolor = COLOR_GREEN ;
361
- } else if (!strcasecmp (optarg , "red" )) {
362
- mcolor = COLOR_RED ;
363
- } else if (!strcasecmp (optarg , "blue" )) {
364
- mcolor = COLOR_BLUE ;
365
- } else if (!strcasecmp (optarg , "white" )) {
366
- mcolor = COLOR_WHITE ;
367
- } else if (!strcasecmp (optarg , "yellow" )) {
368
- mcolor = COLOR_YELLOW ;
369
- } else if (!strcasecmp (optarg , "cyan" )) {
370
- mcolor = COLOR_CYAN ;
371
- } else if (!strcasecmp (optarg , "magenta" )) {
372
- mcolor = COLOR_MAGENTA ;
373
- } else if (!strcasecmp (optarg , "black" )) {
374
- mcolor = COLOR_BLACK ;
410
+ if (strchr (optarg , ',' )) {
411
+ /* Multiple colors specified, parse them */
412
+ char * colors_copy = strdup (optarg );
413
+ if (!colors_copy ) {
414
+ c_die ("CMatrix: Out of memory!\n" );
415
+ }
416
+
417
+ /* Count number of colors */
418
+ int color_count = 1 ;
419
+ for (char * p = colors_copy ; * p ; p ++ ) {
420
+ if (* p == ',' ) color_count ++ ;
421
+ }
422
+
423
+ /* Allocate the color array */
424
+ color_array = nmalloc (color_count * sizeof (int ));
425
+ num_colors = 0 ;
426
+
427
+ /* Parse each color */
428
+ char * token = strtok (colors_copy , "," );
429
+ while (token != NULL ) {
430
+ int color = parse_color (token );
431
+ if (color == -1 ) {
432
+ free (colors_copy );
433
+ c_die (" Invalid color selection '%s'\n Valid "
434
+ "colors are green, red, blue, "
435
+ "white, yellow, cyan, magenta and black.\n" , token );
436
+ }
437
+ color_array [num_colors ++ ] = color ;
438
+ token = strtok (NULL , "," );
439
+ }
440
+ original_num_colors = num_colors ; // Remember the original count
441
+ free (colors_copy );
375
442
} else {
376
- c_die (" Invalid color selection\n Valid "
377
- "colors are green, red, blue, "
378
- "white, yellow, cyan, magenta " "and black.\n" );
443
+ /* Single color specified */
444
+ num_colors = 0 ;
445
+ color_array = NULL ; /* Ensure color_array is NULL */
446
+ mcolor = parse_color (optarg );
447
+ if (mcolor == -1 ) {
448
+ c_die (" Invalid color selection\n Valid "
449
+ "colors are green, red, blue, "
450
+ "white, yellow, cyan, magenta and black.\n" );
451
+ }
379
452
}
380
453
break ;
381
454
case 'c' :
@@ -618,42 +691,57 @@ if (console) {
618
691
case '!' :
619
692
mcolor = COLOR_RED ;
620
693
rainbow = 0 ;
694
+ num_colors = 0 ;
621
695
break ;
622
696
case '@' :
623
697
mcolor = COLOR_GREEN ;
624
698
rainbow = 0 ;
699
+ num_colors = 0 ;
625
700
break ;
626
701
case '#' :
627
702
mcolor = COLOR_YELLOW ;
628
703
rainbow = 0 ;
704
+ num_colors = 0 ;
629
705
break ;
630
706
case '$' :
631
707
mcolor = COLOR_BLUE ;
632
708
rainbow = 0 ;
709
+ num_colors = 0 ;
633
710
break ;
634
711
case '%' :
635
712
mcolor = COLOR_MAGENTA ;
636
713
rainbow = 0 ;
714
+ num_colors = 0 ;
637
715
break ;
638
716
case 'r' :
639
717
rainbow = 1 ;
718
+ if (original_num_colors > 0 ) {
719
+ num_colors = original_num_colors ; // Restore original count for rainbow
720
+ }
640
721
break ;
641
722
case 'm' :
642
723
lambda = !lambda ;
643
724
break ;
644
725
case '^' :
645
726
mcolor = COLOR_CYAN ;
646
727
rainbow = 0 ;
728
+ num_colors = 0 ;
647
729
break ;
648
730
case '&' :
649
731
mcolor = COLOR_WHITE ;
650
732
rainbow = 0 ;
733
+ num_colors = 0 ;
651
734
break ;
652
735
case 'p' :
653
736
case 'P' :
654
737
pause = (pause == 0 )?1 :0 ;
655
738
break ;
656
-
739
+ case '+' :
740
+ rainbow = 0 ;
741
+ if (original_num_colors > 0 ) {
742
+ num_colors = original_num_colors ; // Restore multi-color mode
743
+ }
744
+ break ;
657
745
}
658
746
}
659
747
}
@@ -664,6 +752,7 @@ if (console) {
664
752
if (oldstyle ) {
665
753
for (i = LINES - 1 ; i >= 1 ; i -- ) {
666
754
matrix [i ][j ].val = matrix [i - 1 ][j ].val ;
755
+ matrix [i ][j ].color = matrix [i - 1 ][j ].color ;
667
756
}
668
757
random = (int ) rand () % (randnum + 8 ) + randmin ;
669
758
@@ -683,13 +772,15 @@ if (console) {
683
772
matrix [0 ][j ].val = 0 ;
684
773
} else {
685
774
matrix [0 ][j ].val = (int ) rand () % randnum + randmin ;
775
+ matrix [0 ][j ].color = select_matrix_color ();
686
776
}
687
777
spaces [j ] = (int ) rand () % LINES + 1 ;
688
778
}
689
779
} else if (random > highnum && matrix [1 ][j ].val != 1 ) {
690
780
matrix [0 ][j ].val = ' ' ;
691
781
} else {
692
782
matrix [0 ][j ].val = (int ) rand () % randnum + randmin ;
783
+ matrix [0 ][j ].color = select_matrix_color ();
693
784
}
694
785
695
786
} else { /* New style scrolling (default) */
@@ -700,6 +791,10 @@ if (console) {
700
791
&& matrix [1 ][j ].val == ' ' ) {
701
792
length [j ] = (int ) rand () % (LINES - 3 ) + 3 ;
702
793
matrix [0 ][j ].val = (int ) rand () % randnum + randmin ;
794
+ matrix [0 ][j ].is_head = true;
795
+
796
+ // Assign a random color to the character head
797
+ matrix [0 ][j ].color = select_matrix_color ();
703
798
704
799
spaces [j ] = (int ) rand () % LINES + 1 ;
705
800
}
@@ -740,6 +835,9 @@ if (console) {
740
835
matrix [i ][j ].val = (int ) rand () % randnum + randmin ;
741
836
matrix [i ][j ].is_head = true;
742
837
838
+ // Assign a random color to the new character head
839
+ matrix [i ][j ].color = select_matrix_color ();
840
+
743
841
/* If we're at the top of the column and it's reached its
744
842
full length (about to start moving down), we do this
745
843
to get it moving. This is also how we keep segments not
@@ -794,28 +892,37 @@ if (console) {
794
892
}
795
893
} else {
796
894
if (rainbow ) {
797
- int randomColor = rand () % 6 ;
798
-
799
- switch (randomColor ) {
800
- case 0 :
801
- mcolor = COLOR_GREEN ;
802
- break ;
803
- case 1 :
804
- mcolor = COLOR_BLUE ;
805
- break ;
806
- case 2 :
807
- mcolor = COLOR_BLACK ;
808
- break ;
809
- case 3 :
810
- mcolor = COLOR_YELLOW ;
811
- break ;
812
- case 4 :
813
- mcolor = COLOR_CYAN ;
814
- break ;
815
- case 5 :
816
- mcolor = COLOR_MAGENTA ;
817
- break ;
818
- }
895
+ if (num_colors > 0 && color_array != NULL ) {
896
+ // Rainbow mode with custom color palette
897
+ mcolor = color_array [rand () % num_colors ];
898
+ } else {
899
+ // Standard rainbow mode with predefined colors
900
+ int randomColor = rand () % 6 ;
901
+
902
+ switch (randomColor ) {
903
+ case 0 :
904
+ mcolor = COLOR_GREEN ;
905
+ break ;
906
+ case 1 :
907
+ mcolor = COLOR_BLUE ;
908
+ break ;
909
+ case 2 :
910
+ mcolor = COLOR_BLACK ;
911
+ break ;
912
+ case 3 :
913
+ mcolor = COLOR_YELLOW ;
914
+ break ;
915
+ case 4 :
916
+ mcolor = COLOR_CYAN ;
917
+ break ;
918
+ case 5 :
919
+ mcolor = COLOR_MAGENTA ;
920
+ break ;
921
+ }
922
+ }
923
+ } else if (num_colors > 0 ) {
924
+ // Multi-color mode - use stored character colors
925
+ mcolor = matrix [i ][j ].color ;
819
926
}
820
927
attron (COLOR_PAIR (mcolor ));
821
928
if (matrix [i ][j ].val == 1 ) {
0 commit comments