// This is the basic program loop. // When the program launches, or when a game ends, you end up here. // If the player has already said what he wants to do next // (by storing it in rogue.nextGame -- possibilities listed in enum NGCommands), // we'll do it. The path (rogue.nextGamePath) is essentially a parameter for this command, and // tells NG_VIEW_RECORDING and NG_OPEN_GAME which file to open. If there is a command but no // accompanying path, and it's a command that should take a path, then pop up a dialog to have // the player specify a path. If there is no command (i.e. if rogue.nextGame contains NG_NOTHING), // then we'll display the title screen so the player can choose. void mainBrogueJunction() { rogueEvent theEvent; char path[BROGUE_FILENAME_MAX], buf[100], seedDefault[100]; char maxSeed[20]; short i, j, k; boolean seedTooBig; // clear screen and display buffer for (i=0; i<COLS; i++) { for (j=0; j<ROWS; j++) { displayBuffer[i][j].character = 0; displayBuffer[i][j].needsUpdate = false; displayBuffer[i][j].opacity = 100; for (k=0; k<3; k++) { displayBuffer[i][j].foreColorComponents[k] = 0; displayBuffer[i][j].backColorComponents[k] = 0; } plotCharWithColor(' ', i, j, &black, &black); } } initializeLaunchArguments(&rogue.nextGame, rogue.nextGamePath, &rogue.nextGameSeed); do { rogue.gameHasEnded = false; rogue.playbackFastForward = false; rogue.playbackMode = false; switch (rogue.nextGame) { case NG_NOTHING: // Run the main menu to get a decision out of the player. // Seth: Added setBrogueGameEvent(BrogueGameEventShowTitle); titleMenu(); break; case NG_NEW_GAME: case NG_NEW_GAME_WITH_SEED: rogue.nextGamePath[0] = '\0'; randomNumbersGenerated = 0; rogue.playbackMode = false; rogue.playbackFastForward = false; rogue.playbackBetweenTurns = false; getAvailableFilePath(path, LAST_GAME_NAME, GAME_SUFFIX); strcat(path, GAME_SUFFIX); strcpy(currentFilePath, path); if (rogue.nextGame == NG_NEW_GAME_WITH_SEED) { if (rogue.nextGameSeed == 0) { // Prompt for seed; default is the previous game's seed. sprintf(maxSeed, "%lu", ULONG_MAX); if (previousGameSeed == 0) { seedDefault[0] = '\0'; } else { sprintf(seedDefault, "%lu", previousGameSeed); } if (getInputTextString(buf, "Generate dungeon with seed number:", log10(ULONG_MAX) + 1, seedDefault, "", TEXT_INPUT_NUMBERS, true) && buf[0] != '\0') { seedTooBig = false; if (strlen(buf) > strlen(maxSeed)) { seedTooBig = true; } else if (strlen(buf) == strlen(maxSeed)) { for (i=0; maxSeed[i]; i++) { if (maxSeed[i] > buf[i]) { break; // we're good } else if (maxSeed[i] < buf[i]) { seedTooBig = true; break; } } } if (seedTooBig) { rogue.nextGameSeed = ULONG_MAX; } else { sscanf(buf, "%lu", &rogue.nextGameSeed); } } else { rogue.nextGame = NG_NOTHING; break; // Don't start a new game after all. } } } else { rogue.nextGameSeed = 0; // Seed based on clock. } // Seth: Added setBrogueGameEvent(BrogueGameEventStartNewGame); rogue.nextGame = NG_NOTHING; initializeRogue(rogue.nextGameSeed); startLevel(rogue.depthLevel, 1); // descending into level 1 mainInputLoop(); freeEverything(); break; case NG_OPEN_GAME: rogue.nextGame = NG_NOTHING; // Seth: Added setBrogueGameEvent(BrogueGameEventBeginOpenGame); path[0] = '\0'; if (rogue.nextGamePath[0]) { strcpy(path, rogue.nextGamePath); rogue.nextGamePath[0] = '\0'; } else { dialogChooseFile(path, GAME_SUFFIX, "Open saved game:"); //chooseFile(path, "Open saved game: ", "Saved game", GAME_SUFFIX); } if (openFile(path)) { loadSavedGame(); // Seth: Added setBrogueGameEvent(BrogueGameEventOpenGame); mainInputLoop(); freeEverything(); } else { //dialogAlert("File not found."); } rogue.playbackMode = false; rogue.playbackOOS = false; // Seth: Added setBrogueGameEvent(BrogueGameEventOpenGameFinished); break; case NG_VIEW_RECORDING: rogue.nextGame = NG_NOTHING; // Seth: Added setBrogueGameEvent(BrogueGameEventBeginOpenGame); path[0] = '\0'; if (rogue.nextGamePath[0]) { strcpy(path, rogue.nextGamePath); rogue.nextGamePath[0] = '\0'; } else { dialogChooseFile(path, RECORDING_SUFFIX, "View recording:"); //chooseFile(path, "View recording: ", "Recording", RECORDING_SUFFIX); } if (openFile(path)) { // Seth: Added setBrogueGameEvent(BrogueGameEventPlayRecording); randomNumbersGenerated = 0; rogue.playbackMode = true; initializeRogue(0); // Seed argument is ignored because we're in playback. if (!rogue.gameHasEnded) { startLevel(rogue.depthLevel, 1); pausePlayback(); displayAnnotation(); // in case there's an annotation for turn 0 } while(!rogue.gameHasEnded && rogue.playbackMode) { rogue.RNG = RNG_COSMETIC; // dancing terrain colors can't influence recordings rogue.playbackBetweenTurns = true; nextBrogueEvent(&theEvent, false, true, false); rogue.RNG = RNG_SUBSTANTIVE; executeEvent(&theEvent); } freeEverything(); } else { // announce file not found } rogue.playbackMode = false; rogue.playbackOOS = false; break; case NG_HIGH_SCORES: rogue.nextGame = NG_NOTHING; // Seth: Added setBrogueGameEvent(BrogueGameEventShowHighScores); printHighScores(false); break; case NG_SCUM: rogue.nextGame = NG_NOTHING; scum(1, 1000, 5); break; case NG_QUIT: // No need to do anything. break; default: break; } } while (rogue.nextGame != NG_QUIT); }
// This is the basic program loop. // When the program launches, or when a game ends, you end up here. // If the player has already said what he wants to do next // (by storing it in rogue.nextGame -- possibilities listed in enum NGCommands), // we'll do it. The path (rogue.nextGamePath) is essentially a parameter for this command, and // tells NG_VIEW_RECORDING and NG_OPEN_GAME which file to open. If there is a command but no // accompanying path, and it's a command that should take a path, then pop up a dialog to have // the player specify a path. If there is no command (i.e. if rogue.nextGame contains NG_NOTHING), // then we'll display the title screen so the player can choose. void mainBrogueJunction() { rogueEvent theEvent; char path[BROGUE_FILENAME_MAX], buf[100], seedDefault[100]; char maxSeed[64]; short i; boolean seedTooBig; if (ioInitialize() != 0) { printf("Failure to initialize display\n"); exit(1); } initializeLaunchArguments(&rogue.nextGame, rogue.nextGamePath, &rogue.nextGameSeed); do { rogue.gameHasEnded = false; rogue.playbackFastForward = false; rogue.playbackMode = false; switch (rogue.nextGame) { case NG_NOTHING: // Run the main menu to get a decision out of the player. titleMenu(); break; case NG_NEW_GAME: case NG_NEW_GAME_WITH_SEED: rogue.nextGamePath[0] = '\0'; randomNumbersGenerated = 0; rogue.playbackMode = false; rogue.playbackFastForward = false; rogue.playbackBetweenTurns = false; getAvailableFilePath(path, LAST_GAME_NAME, GAME_SUFFIX); strcat(path, GAME_SUFFIX); strcpy(currentFilePath, path); if (rogue.nextGame == NG_NEW_GAME_WITH_SEED) { if (rogue.nextGameSeed == 0) { // Prompt for seed; default is the previous game's seed. sprintf(maxSeed, "%lu", ULONG_MAX); if (previousGameSeed == 0) { seedDefault[0] = '\0'; } else { sprintf(seedDefault, "%lu", previousGameSeed); } if (getInputTextString(buf, "输入随机数种子生成地下城:", log10(ULONG_MAX) + 1 + 6, // pad for header text seedDefault, "", TEXT_INPUT_NUMBERS, true) && buf[0] != '\0') { seedTooBig = false; if (strlen(buf) > strlen(maxSeed)) { seedTooBig = true; } else if (strlen(buf) == strlen(maxSeed)) { for (i=0; maxSeed[i]; i++) { if (maxSeed[i] > buf[i]) { break; // we're good } else if (maxSeed[i] < buf[i]) { seedTooBig = true; break; } } } if (seedTooBig) { rogue.nextGameSeed = ULONG_MAX; } else { sscanf(buf, "%lu", &rogue.nextGameSeed); } } else { rogue.nextGame = NG_NOTHING; break; // Don't start a new game after all. } } } else { rogue.nextGameSeed = 0; // Seed based on clock. } rogue.nextGame = NG_NOTHING; initializeRogue(rogue.nextGameSeed); startLevel(rogue.depthLevel, 1); // descending into level 1 mainInputLoop(); freeEverything(); break; case NG_OPEN_GAME: rogue.nextGame = NG_NOTHING; path[0] = '\0'; if (rogue.nextGamePath[0]) { strcpy(path, rogue.nextGamePath); rogue.nextGamePath[0] = '\0'; } else { dialogChooseFile(path, GAME_SUFFIX, "选择中断存档进行读取:"); //chooseFile(path, "Open saved game: ", "Saved game", GAME_SUFFIX); } if (openFile(path)) { loadSavedGame(); mainInputLoop(); freeEverything(); } else { //dialogAlert("File not found."); } rogue.playbackMode = false; rogue.playbackOOS = false; break; case NG_VIEW_RECORDING: rogue.nextGame = NG_NOTHING; path[0] = '\0'; if (rogue.nextGamePath[0]) { strcpy(path, rogue.nextGamePath); rogue.nextGamePath[0] = '\0'; } else { dialogChooseFile(path, RECORDING_SUFFIX, "选择录像文件进行回放:"); //chooseFile(path, "View recording: ", "Recording", RECORDING_SUFFIX); } if (openFile(path)) { randomNumbersGenerated = 0; rogue.playbackMode = true; initializeRogue(0); // Seed argument is ignored because we're in playback. if (!rogue.gameHasEnded) { startLevel(rogue.depthLevel, 1); pausePlayback(); displayAnnotation(); // in case there's an annotation for turn 0 } while(!rogue.gameHasEnded && rogue.playbackMode) { rogue.RNG = RNG_COSMETIC; // dancing terrain colors can't influence recordings rogue.playbackBetweenTurns = true; nextBrogueEvent(&theEvent, false, true, false); rogue.RNG = RNG_SUBSTANTIVE; executeEvent(&theEvent); } freeEverything(); } else { // announce file not found } rogue.playbackMode = false; rogue.playbackOOS = false; break; case NG_HIGH_SCORES: rogue.nextGame = NG_NOTHING; printHighScores(false); break; case NG_SCUM: rogue.nextGame = NG_NOTHING; scum(1, 1000, 5); break; case NG_QUIT: // No need to do anything. break; default: break; } } while (rogue.nextGame != NG_QUIT); }