-
-
Notifications
You must be signed in to change notification settings - Fork 447
feat: Allow -C to specify multi-color, custom palette #200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
if (num_colors > 0 && color_array != NULL) { | ||
// Rainbow mode with custom color palette | ||
mcolor = color_array[rand() % num_colors]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rainbow Mode - Render
When in rainbow mode AND there's a custom color palette, colors are randomly picked from that palette instead of the default 6 colors.
} else if (num_colors > 0) { | ||
// Multi-color mode - use stored character colors | ||
mcolor = matrix[i][j].color; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multi-Color Mode - Render
A color was assigned to the character when it entered the matrix; just use it.
case '+': | ||
rainbow = 0; | ||
if (original_num_colors > 0) { | ||
num_colors = original_num_colors; // Restore multi-color mode | ||
} | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shift
+ +
will switch into non-rainbow multi-color mode.
/* Parse each color */ | ||
char *token = strtok(colors_copy, ","); | ||
while (token != NULL) { | ||
int color = parse_color(token); | ||
if (color == -1) { | ||
free(colors_copy); | ||
c_die(" Invalid color selection '%s'\n Valid " | ||
"colors are green, red, blue, " | ||
"white, yellow, cyan, magenta and black.\n", token); | ||
} | ||
color_array[num_colors++] = color; | ||
token = strtok(NULL, ","); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multi-Color - Init
We don't deduplicate the colors when parsing, so -C red,red,blue
will result in 2x as much red as blue. This is on purpose to allow more nuanced color mixes.
/** | ||
* Selects a color for a matrix character based on current global program state. | ||
* | ||
* This function uses GLOBAL STATE variables: | ||
* - num_colors: Number of colors in the custom palette | ||
* - color_array: Array of custom color values | ||
* - rainbow: Flag indicating if rainbow mode is active | ||
* - mcolor: Current default color | ||
* | ||
* @return The selected color value (COLOR_* constant) | ||
*/ | ||
int select_matrix_color(void) { | ||
if (num_colors > 0 && color_array != NULL && !rainbow) { | ||
/* Multi-color mode - select from custom palette */ | ||
return color_array[rand() % num_colors]; | ||
} else { | ||
/* Single color mode or no custom palette - use global color */ | ||
return mcolor; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DRY
This specific code was repeated a lot; made it its own function to reduce total lines of code & opportunity for error.
int mcolor = COLOR_GREEN; | ||
int rainbow = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These were hoisted to global:
mcolor
because we need to initialize a color invar_init()
, and it made sense to use "the current default color" to do so - but in order to do so,mcolor
couldn't be local tomain()
.rainbow
to allow theselect_matrix_color
function to be global.
int mcolor = COLOR_GREEN; /* Current matrix color */ | ||
int rainbow = 0; /* Flag for rainbow mode */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These were hoisted out of main()
; see https://github.com/abishekvashok/cmatrix/pull/200/files#r2072735532
/* Parse a color name and return the corresponding COLOR_* constant */ | ||
int parse_color(const char* color_name) { | ||
if (!strcasecmp(color_name, "green")) { | ||
return COLOR_GREEN; | ||
} else if (!strcasecmp(color_name, "red")) { | ||
return COLOR_RED; | ||
} else if (!strcasecmp(color_name, "blue")) { | ||
return COLOR_BLUE; | ||
} else if (!strcasecmp(color_name, "white")) { | ||
return COLOR_WHITE; | ||
} else if (!strcasecmp(color_name, "yellow")) { | ||
return COLOR_YELLOW; | ||
} else if (!strcasecmp(color_name, "cyan")) { | ||
return COLOR_CYAN; | ||
} else if (!strcasecmp(color_name, "magenta")) { | ||
return COLOR_MAGENTA; | ||
} else if (!strcasecmp(color_name, "black")) { | ||
return COLOR_BLACK; | ||
} else { | ||
return -1; /* Invalid color */ | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We needed to parse colors in two places, so this big if/else was pulled out into its own function.
-C color[,color[,color ...]]
Allow the
-C
flag for color selection to specify multi-color palettes.e.g.
cmatrix -C red,white,blue
cmatrix -C white,white,white,green
rainbow
-r
(rainbow), the rainbow will be taken from the provided color palette instead of the full spectrum.-r
, each character will be randomly assigned a color from the palette when it first appears on-screen.key shortcuts
At runtime, key combo
shift
++
will switch to multi-color mode, if another key combo shifted out of it.compatibility
cmatrix -C red
, etc, is unchanged.-r
(rainbow) is unchanged if no palette is specified.example
cmatrix.color.mix.demo.mp4