Skip to content

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Texarkanine
Copy link

@Texarkanine Texarkanine commented May 4, 2025

-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

  • When combined with -r (rainbow), the rainbow will be taken from the provided color palette instead of the full spectrum.
  • When used without -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

  • Behavior of single-color cmatrix -C red, etc, is unchanged.
  • Behavior of -r (rainbow) is unchanged if no palette is specified.

example

cmatrix.color.mix.demo.mp4

@Texarkanine Texarkanine changed the title Colormix feat: Allow -C to specify multi-color, custom palette May 4, 2025
Comment on lines +895 to +897
if (num_colors > 0 && color_array != NULL) {
// Rainbow mode with custom color palette
mcolor = color_array[rand() % num_colors];
Copy link
Author

@Texarkanine Texarkanine May 4, 2025

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.

Comment on lines +923 to +925
} else if (num_colors > 0) {
// Multi-color mode - use stored character colors
mcolor = matrix[i][j].color;
Copy link
Author

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.

Comment on lines +739 to +744
case '+':
rainbow = 0;
if (original_num_colors > 0) {
num_colors = original_num_colors; // Restore multi-color mode
}
break;
Copy link
Author

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.

Comment on lines +427 to +438
/* 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, ",");
Copy link
Author

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.

Comment on lines +345 to +364
/**
* 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;
}
}
Copy link
Author

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.

Comment on lines -326 to -327
int mcolor = COLOR_GREEN;
int rainbow = 0;
Copy link
Author

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 in var_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 to main().
  • rainbow to allow the select_matrix_color function to be global.

Comment on lines +99 to +100
int mcolor = COLOR_GREEN; /* Current matrix color */
int rainbow = 0; /* Flag for rainbow mode */
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +200 to +221
/* 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 */
}
}
Copy link
Author

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.

@Texarkanine Texarkanine marked this pull request as ready for review May 4, 2025 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant