void initializeButtonState(buttonState *state, brogueButton *buttons, short buttonCount, short winX, short winY, short winWidth, short winHeight) { short i, j; // Initialize variables for the state struct: state->buttonChosen = state->buttonFocused = state->buttonDepressed = -1; state->buttonCount = buttonCount; state->winX = winX; state->winY = winY; state->winWidth = winWidth; state->winHeight = winHeight; for (i=0; i < state->buttonCount; i++) { state->buttons[i] = buttons[i]; } copyDisplayBuffer(state->rbuf, displayBuffer); clearDisplayBuffer(state->dbuf); drawButtonsInState(state); // Clear the rbuf so that it resets only those parts of the screen in which buttons are drawn in the first place: for (i=0; i<COLS; i++) { for (j=0; j<ROWS; j++) { state->rbuf[i][j].opacity = (state->dbuf[i][j].opacity ? 100 : 0); } } }
boolean dialogChooseFile(char *path, const char *suffix, const char *prompt) { short i, j, count, x, y, width, height, suffixLength, pathLength, maxPathLength, currentPageStart; brogueButton buttons[FILES_ON_PAGE_MAX + 2]; fileEntry *files; boolean retval = false, again; cellDisplayBuffer dbuf[COLS][ROWS], rbuf[COLS][ROWS]; color *dialogColor = &interfaceBoxColor; char *membuf; suffixLength = strlen(suffix); files = listFiles(&count, &membuf); copyDisplayBuffer(rbuf, displayBuffer); maxPathLength = strLenWithoutEscapes(prompt); // First, we want to filter the list by stripping out any filenames that do not end with suffix. // i is the entry we're testing, and j is the entry that we move it to if it qualifies. for (i=0, j=0; i<count; i++) { pathLength = strlen(files[i].path); //printf("\nString 1: %s", &(files[i].path[(max(0, pathLength - suffixLength))])); if (stringsExactlyMatch(&(files[i].path[(max(0, pathLength - suffixLength))]), suffix)) { // This file counts! if (i > j) { files[j] = files[i]; //printf("\nMatching file: %s\twith date: %s", files[j].path, files[j].date); } j++; // Keep track of the longest length. if (min(pathLength, MAX_FILENAME_DISPLAY_LENGTH) + 10 > maxPathLength) { maxPathLength = min(pathLength, MAX_FILENAME_DISPLAY_LENGTH) + 10; } } } count = j; currentPageStart = 0; do { // Repeat to permit scrolling. again = false; for (i=0; i<min(count - currentPageStart, FILES_ON_PAGE_MAX); i++) { initializeButton(&(buttons[i])); buttons[i].flags &= ~(B_WIDE_CLICK_AREA | B_GRADIENT); buttons[i].buttonColor = *dialogColor; if (KEYBOARD_LABELS) { sprintf(buttons[i].text, "%c) ", 'a' + i); } else { buttons[i].text[0] = '\0'; } strncat(buttons[i].text, files[currentPageStart+i].path, MAX_FILENAME_DISPLAY_LENGTH); // Clip off the file suffix from the button text. buttons[i].text[strlen(buttons[i].text) - suffixLength] = '\0'; // Snip! buttons[i].hotkey[0] = 'a' + i; buttons[i].hotkey[1] = 'A' + i; // Clip the filename length if necessary. if (strlen(buttons[i].text) > MAX_FILENAME_DISPLAY_LENGTH) { strcpy(&(buttons[i].text[MAX_FILENAME_DISPLAY_LENGTH - 3]), "..."); } //printf("\nFound file: %s, with date: %s", files[currentPageStart+i].path, files[currentPageStart+i].date); } x = (COLS - maxPathLength) / 2; width = maxPathLength; height = min(count - currentPageStart, FILES_ON_PAGE_MAX) + 2; y = max(4, (ROWS - height) / 2); for (i=0; i<min(count - currentPageStart, FILES_ON_PAGE_MAX); i++) { pathLength = strlen(buttons[i].text); for (j=pathLength; j<(width - 8); j++) { buttons[i].text[j] = ' '; } buttons[i].text[j] = '\0'; strcpy(&(buttons[i].text[j]), files[currentPageStart+i].date); buttons[i].x = x; buttons[i].y = y + 1 + i; } if (count > FILES_ON_PAGE_MAX) { // Create up and down arrows. initializeButton(&(buttons[i])); strcpy(buttons[i].text, " * "); buttons[i].symbol[0] = UP_ARROW_CHAR; if (currentPageStart <= 0) { buttons[i].flags &= ~(B_ENABLED | B_DRAW); } else { buttons[i].hotkey[0] = UP_ARROW; buttons[i].hotkey[1] = NUMPAD_8; buttons[i].hotkey[2] = PAGE_UP_KEY; } buttons[i].x = x + (width - 11)/2; buttons[i].y = y; i++; initializeButton(&(buttons[i])); strcpy(buttons[i].text, " * "); buttons[i].symbol[0] = DOWN_ARROW_CHAR; if (currentPageStart + FILES_ON_PAGE_MAX >= count) { buttons[i].flags &= ~(B_ENABLED | B_DRAW); } else { buttons[i].hotkey[0] = DOWN_ARROW; buttons[i].hotkey[1] = NUMPAD_2; buttons[i].hotkey[2] = PAGE_DOWN_KEY; } buttons[i].x = x + (width - 11)/2; buttons[i].y = y + i; } if (count) { clearDisplayBuffer(dbuf); printString(prompt, x, y - 1, &itemMessageColor, dialogColor, dbuf); rectangularShading(x - 1, y - 1, width + 1, height + 1, dialogColor, INTERFACE_OPACITY, dbuf); overlayDisplayBuffer(dbuf, NULL); // for (j=0; j<min(count - currentPageStart, FILES_ON_PAGE_MAX); j++) { // printf("\nSanity check BEFORE: %s, with date: %s", files[currentPageStart+j].path, files[currentPageStart+j].date); // printf("\n (button name)Sanity check BEFORE: %s", buttons[j].text); // } i = buttonInputLoop(buttons, min(count - currentPageStart, FILES_ON_PAGE_MAX) + (count > FILES_ON_PAGE_MAX ? 2 : 0), x, y, width, height, NULL); // for (j=0; j<min(count - currentPageStart, FILES_ON_PAGE_MAX); j++) { // printf("\nSanity check AFTER: %s, with date: %s", files[currentPageStart+j].path, files[currentPageStart+j].date); // printf("\n (button name)Sanity check AFTER: %s", buttons[j].text); // } overlayDisplayBuffer(rbuf, NULL); if (i < min(count - currentPageStart, FILES_ON_PAGE_MAX)) { if (i >= 0) { retval = true; strcpy(path, files[currentPageStart+i].path); } else { // i is -1 retval = false; } } else if (i == min(count - currentPageStart, FILES_ON_PAGE_MAX)) { // Up arrow again = true; currentPageStart -= FILES_ON_PAGE_MAX; } else if (i == min(count - currentPageStart, FILES_ON_PAGE_MAX) + 1) { // Down arrow again = true; currentPageStart += FILES_ON_PAGE_MAX; } } } while (again); free(files); free(membuf); if (count == 0) { dialogAlert("No applicable files found."); return false; } else { return retval; } }
void titleMenu() { signed short flames[COLS][(ROWS + MENU_FLAME_ROW_PADDING)][3]; // red, green and blue signed short colorSources[MENU_FLAME_COLOR_SOURCE_COUNT][4]; // red, green, blue, and rand, one for each color source (no more than MENU_FLAME_COLOR_SOURCE_COUNT). color *colors[COLS][(ROWS + MENU_FLAME_ROW_PADDING)]; unsigned char mask[COLS][ROWS]; boolean controlKeyWasDown = false; short i, b, x, y, button; buttonState state; brogueButton buttons[6]; char whiteColorEscape[10] = ""; char goldColorEscape[10] = ""; char newGameText[100] = "", customNewGameText[100] = ""; rogueEvent theEvent; enum NGCommands buttonCommands[6] = {NG_NEW_GAME, NG_OPEN_GAME, NG_VIEW_RECORDING, NG_HIGH_SCORES, NG_QUIT}; cellDisplayBuffer shadowBuf[COLS][ROWS]; // Initialize the RNG so the flames aren't always the same. seedRandomGenerator(0); // Empty nextGamePath and nextGameSeed so that the buttons don't try to load an old game path or seed. rogue.nextGamePath[0] = '\0'; rogue.nextGameSeed = 0; // Initialize the title menu buttons. encodeMessageColor(whiteColorEscape, 0, &white); encodeMessageColor(goldColorEscape, 0, KEYBOARD_LABELS ? &itemMessageColor : &white); sprintf(newGameText, " %sN%sew Game ", goldColorEscape, whiteColorEscape); sprintf(customNewGameText, " %sN%sew Game (custom) ", goldColorEscape, whiteColorEscape); b = 0; button = -1; initializeButton(&(buttons[b])); strcpy(buttons[b].text, newGameText); buttons[b].hotkey[0] = 'n'; buttons[b].hotkey[1] = 'N'; b++; initializeButton(&(buttons[b])); sprintf(buttons[b].text, " %sO%spen Game ", goldColorEscape, whiteColorEscape); buttons[b].hotkey[0] = 'o'; buttons[b].hotkey[1] = 'O'; b++; initializeButton(&(buttons[b])); sprintf(buttons[b].text, " %sV%siew Recording ", goldColorEscape, whiteColorEscape); buttons[b].hotkey[0] = 'v'; buttons[b].hotkey[1] = 'V'; b++; initializeButton(&(buttons[b])); sprintf(buttons[b].text, " %sH%sigh Scores ", goldColorEscape, whiteColorEscape); buttons[b].hotkey[0] = 'h'; buttons[b].hotkey[1] = 'H'; b++; // Seth: /* initializeButton(&(buttons[b])); sprintf(buttons[b].text, " %sQ%suit ", goldColorEscape, whiteColorEscape); buttons[b].hotkey[0] = 'q'; buttons[b].hotkey[1] = 'Q'; b++;*/ x = COLS - 1 - 20 - 2; y = ROWS - 1; for (i = b-1; i >= 0; i--) { y -= 2; buttons[i].x = x; buttons[i].y = y; buttons[i].buttonColor = titleButtonColor; buttons[i].flags |= B_WIDE_CLICK_AREA; } blackOutScreen(); clearDisplayBuffer(shadowBuf); initializeButtonState(&state, buttons, b, x, y, 20, b*2-1); rectangularShading(x, y, 20, b*2-1, &black, INTERFACE_OPACITY, shadowBuf); drawButtonsInState(&state); initializeMenuFlames(true, colors, colorSources, flames, mask); rogue.creaturesWillFlashThisTurn = false; // total unconscionable hack do { if (!controlKeyWasDown && controlKeyIsDown()) { strcpy(state.buttons[0].text, customNewGameText); drawButtonsInState(&state); buttonCommands[0] = NG_NEW_GAME_WITH_SEED; controlKeyWasDown = true; } else if (controlKeyWasDown && !controlKeyIsDown()) { strcpy(state.buttons[0].text, newGameText); drawButtonsInState(&state); buttonCommands[0] = NG_NEW_GAME; controlKeyWasDown = false; } // Update the display. updateMenuFlames(colors, colorSources, flames); drawMenuFlames(flames, mask); overlayDisplayBuffer(shadowBuf, NULL); overlayDisplayBuffer(state.dbuf, NULL); // Pause briefly. if (pauseBrogue(MENU_FLAME_UPDATE_DELAY)) { // There was input during the pause! Get the input. nextBrogueEvent(&theEvent, true, false, true); // Process the input. button = processButtonInput(&state, NULL, &theEvent); } // Revert the display. overlayDisplayBuffer(state.rbuf, NULL); } while (button == -1 && rogue.nextGame == NG_NOTHING); drawMenuFlames(flames, mask); if (button != -1) { rogue.nextGame = buttonCommands[button]; } }