void drawMenuFlames(signed short flames[COLS][(ROWS + MENU_FLAME_ROW_PADDING)][3], unsigned char mask[COLS][ROWS]) { short i, j, versionStringLength; color tempColor = {0}; const color *maskColor = &black; char dchar; versionStringLength = strLenWithoutEscapes(BROGUE_VERSION_STRING); for (j=0; j<ROWS; j++) { for (i=0; i<COLS; i++) { if (j == ROWS - 1 && i >= COLS - versionStringLength) { dchar = BROGUE_VERSION_STRING[i - (COLS - versionStringLength)]; } else { dchar = ' '; } if (mask[i][j] == 100) { plotCharWithColor(dchar, i, j, &darkGray, maskColor); } else { tempColor = black; tempColor.red = flames[i][j][0] / MENU_FLAME_PRECISION_FACTOR; tempColor.green = flames[i][j][1] / MENU_FLAME_PRECISION_FACTOR; tempColor.blue = flames[i][j][2] / MENU_FLAME_PRECISION_FACTOR; if (mask[i][j] > 0) { applyColorAverage(&tempColor, maskColor, mask[i][j]); } plotCharWithColor(dchar, i, j, &darkGray, &tempColor); } } } }
// Draws the button to the screen, or to a display buffer if one is given. // Button back color fades from -50% intensity at the edges to the back color in the middle. // Text is white, but can use color escapes. // Hovering highlight augments fore and back colors with buttonHoverColor by 20%. // Pressed darkens the middle color (or turns it the hover color if the button is black). void drawButton(brogueButton *button, enum buttonDrawStates highlight, cellDisplayBuffer dbuf[COLS][ROWS]) { short i, textLoc, width, midPercent, symbolNumber, opacity, oldRNG; color fColor, bColor, fColorBase, bColorBase, bColorEdge, bColorMid; uchar displayCharacter; if (!(button->flags & B_DRAW)) { return; } //assureCosmeticRNG; oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; symbolNumber = 0; width = strLenWithoutEscapes(button->text); bColorBase = button->buttonColor; fColorBase = ((button->flags & B_ENABLED) ? white : gray); if (highlight == BUTTON_HOVER && (button->flags & B_HOVER_ENABLED)) { //applyColorAugment(&fColorBase, &buttonHoverColor, 20); //applyColorAugment(&bColorBase, &buttonHoverColor, 20); applyColorAverage(&fColorBase, &buttonHoverColor, 25); applyColorAverage(&bColorBase, &buttonHoverColor, 25); } bColorEdge = bColorBase; bColorMid = bColorBase; applyColorAverage(&bColorEdge, &black, 50); if (highlight == BUTTON_PRESSED) { applyColorAverage(&bColorMid, &black, 75); if (COLOR_DIFF(bColorMid, bColorBase) < 50) { bColorMid = bColorBase; applyColorAverage(&bColorMid, &buttonHoverColor, 50); } } bColor = bColorMid; opacity = button->opacity; if (highlight == BUTTON_HOVER || highlight == BUTTON_PRESSED) { opacity = 100 - ((100 - opacity) * opacity / 100); // Apply the opacity twice. } for (i = textLoc = 0; i < width && i + button->x < COLS; i++, textLoc++) { while (button->text[textLoc] == COLOR_ESCAPE) { textLoc = decodeMessageColor(button->text, textLoc, &fColorBase); } fColor = fColorBase; if (button->flags & B_GRADIENT) { midPercent = smoothHiliteGradient(i, width - 1); bColor = bColorEdge; applyColorAverage(&bColor, &bColorMid, midPercent); } if (highlight == BUTTON_PRESSED) { applyColorAverage(&fColor, &bColor, 30); } if (button->opacity < 100) { applyColorAverage(&fColor, &bColor, 100 - opacity); } bakeColor(&fColor); bakeColor(&bColor); separateColors(&fColor, &bColor); displayCharacter = button->text[textLoc]; if (button->text[textLoc] == '*') { if (button->symbol[symbolNumber]) { displayCharacter = button->symbol[symbolNumber]; } symbolNumber++; } if (coordinatesAreInWindow(button->x + i, button->y)) { if (dbuf) { plotCharToBuffer(displayCharacter, button->x + i, button->y, &fColor, &bColor, dbuf); dbuf[button->x + i][button->y].opacity = opacity; } else { plotCharWithColor(displayCharacter, button->x + i, button->y, &fColor, &bColor); } } } restoreRNG; }
void initializeMenuFlames(boolean includeTitle, const color *colors[COLS][(ROWS + MENU_FLAME_ROW_PADDING)], color colorStorage[COLS], signed short colorSources[MENU_FLAME_COLOR_SOURCE_COUNT][4], signed short flames[COLS][(ROWS + MENU_FLAME_ROW_PADDING)][3], unsigned char mask[COLS][ROWS]) { short i, j, k, colorSourceCount; const char title[MENU_TITLE_HEIGHT][MENU_TITLE_WIDTH+1] = { "######## ######## ###### ####### #### ### #########", " ## ### ## ### ## ### ## ## ## # ## #", " ## ## ## ## ## ### ## # ## # ## #", " ## ## ## ## # # ## # # ## # ## ", " ## ## ## ## ## ## ## ## ## # ## # ", " ## ## ## ## ## ### ## ## ## # ## # ", " ###### ## ### ## #### ## ## ## # ####### ", " ## ## ## ## ## #### ## ## ## # ## # ", " ## ## ## ## ## ### ## ## ##### ## # ## # ", " ## ## ## ## ### ## ## ### ## ## # ## ", " ## ## ## ## ## # # ## ## ## # ## ", " ## ## ## ## ### ## ### ## ### # ## #", " ## ## ## ## ### ## ### ### ### # ## #", "######## #### ### ###### ##### ###### #########", " ## ", " ########## ", " ## ", " ## ", " #### ", }; for (i=0; i<COLS; i++) { for (j=0; j<ROWS; j++) { mask[i][j] = 0; } } for (i=0; i<COLS; i++) { for (j=0; j<(ROWS + MENU_FLAME_ROW_PADDING); j++) { colors[i][j] = NULL; for (k=0; k<3; k++) { flames[i][j][k] = 0; } } } // Seed source color random components. for (i=0; i<MENU_FLAME_COLOR_SOURCE_COUNT; i++) { for (k=0; k<4; k++) { colorSources[i][k] = rand_range(0, 1000); } } // Put some flame source along the bottom row. colorSourceCount = 0; for (i=0; i<COLS; i++) { colorStorage[colorSourceCount] = flameSourceColor; applyColorAverage(&(colorStorage[colorSourceCount]), &flameSourceColorSecondary, 100 - (smoothHiliteGradient(i, COLS - 1) + 25)); colors[i][(ROWS + MENU_FLAME_ROW_PADDING)-1] = &(colorStorage[colorSourceCount]); colorSourceCount++; } if (includeTitle) { // Wreathe the title in flames, and mask it in black. for (i=0; i<MENU_TITLE_WIDTH; i++) { for (j=0; j<MENU_TITLE_HEIGHT; j++) { if (title[j][i] != ' ') { colors[(COLS - MENU_TITLE_WIDTH)/2 + i + MENU_TITLE_OFFSET_X][(ROWS - MENU_TITLE_HEIGHT)/2 + j + MENU_TITLE_OFFSET_Y] = &flameTitleColor; colorSourceCount++; mask[(COLS - MENU_TITLE_WIDTH)/2 + i + MENU_TITLE_OFFSET_X][(ROWS - MENU_TITLE_HEIGHT)/2 + j + MENU_TITLE_OFFSET_Y] = 100; } } } // Anti-alias the mask. antiAlias(mask); } brogueAssert(colorSourceCount <= MENU_FLAME_COLOR_SOURCE_COUNT); // Simulate the background flames for a while for (i=0; i<100; i++) { updateMenuFlames(colors, colorSources, flames); } }