int main(int argc, char *argv[]) { Zipper *zipper = new GuiZipper(); FileManager *fileManager = new FileManager(zipper); CliPackageReporter *packageReporter = new CliPackageReporter(); fileManager->setListener(packageReporter); char *shipsBaseDir = fileManager->getAbsFilePath(SHIPS_SUBDIR); char *stagesBaseDir = fileManager->getAbsFilePath(STAGES_SUBDIR); if (flagExists(argc, argv, "packstage")) { char **stageInfo = parseFlag(argc, argv, "packstage", 2); if (stageInfo == 0) { printUsage(); } else { // TODO: add a new flag for obfuscating source code bool obfuscate = false; try { char *stageAbsName = fileManager->getAbsFilePath(stageInfo[0]); char *stageName = fileManager->parseRelativeFilePath(stagesBaseDir, stageAbsName); if (stageName == 0) { std::cout << "Stage must be located under " << STAGES_SUBDIR << "/ subdirectory: " << stageInfo[0] << std::endl; } else { fileManager->packageStage(stagesBaseDir, stageName, stageInfo[1], CACHE_SUBDIR, TMP_SUBDIR, obfuscate, true); delete stageName; } delete stageAbsName; } catch (std::exception *e) { std::cout << "BerryBots encountered an error:" << std::endl; std::cout << " " << e->what() << std::endl; delete e; } delete stageInfo; } return 0; } if (flagExists(argc, argv, "packbot")) { char **shipInfo = parseFlag(argc, argv, "packbot", 2); if (shipInfo == 0) { printUsage(); } else { // TODO: add a new flag for obfuscating source code bool obfuscate = false; try { char *shipAbsName = fileManager->getAbsFilePath(shipInfo[0]); char *shipName = fileManager->parseRelativeFilePath(shipsBaseDir, shipAbsName); if (shipName == 0) { std::cout << "Ship must be located under " << SHIPS_SUBDIR << "/ subdirectory: " << shipInfo[0] << std::endl; } else { fileManager->packageShip(shipsBaseDir, shipName, shipInfo[1], CACHE_SUBDIR, TMP_SUBDIR, obfuscate, true); delete shipName; } delete shipAbsName; } catch (std::exception *e) { std::cout << "BerryBots encountered an error:" << std::endl; std::cout << " " << e->what() << std::endl; delete e; } delete shipInfo; } return 0; } bool nodisplay = flagExists(argc, argv, "nodisplay"); bool saveReplay = flagExists(argc, argv, "savereplay"); int optArgsOffset = (nodisplay ? 1 : 0) + (saveReplay ? 1 : 0); if (argc < 3 + optArgsOffset) { printUsage(); } srand(time(NULL)); CliPrintHandler *printHandler = new CliPrintHandler(); BerryBotsEngine *engine = new BerryBotsEngine(printHandler, fileManager, resourcePath().c_str()); Stage *stage = engine->getStage(); char *stageAbsName = fileManager->getAbsFilePath(argv[1 + optArgsOffset]); char *stageName = fileManager->parseRelativeFilePath(stagesBaseDir, stageAbsName); if (stageName == 0) { std::cout << "Stage must be located under " << STAGES_SUBDIR << "/ subdirectory: " << argv[1 + optArgsOffset] << std::endl; return 0; } try { engine->initStage(stagesBaseDir, stageName, CACHE_SUBDIR); } catch (EngineException *e) { delete stageAbsName; delete stageName; std::cout << "BerryBots initialization failed:" << std::endl; std::cout << " " << e->what() << std::endl; delete e; return 0; } delete stageAbsName; delete stageName; int firstTeam = (2 + optArgsOffset); int numTeams = argc - firstTeam; char **teams = new char*[numTeams]; for (int x = 0; x < numTeams; x++) { char *teamAbsName = fileManager->getAbsFilePath(argv[x + firstTeam]); char *teamName = fileManager->parseRelativeFilePath(shipsBaseDir, teamAbsName); if (teamName == 0) { std::cout << "Ship must be located under " << SHIPS_SUBDIR << "/ subdirectory: " << argv[x + firstTeam] << std::endl; return 0; } teams[x] = teamName; delete teamAbsName; } printHandler->setNumTeams(numTeams); try { engine->initShips(shipsBaseDir, teams, numTeams, CACHE_SUBDIR); } catch (EngineException *e) { std::cout << "BerryBots initialization failed:" << std::endl; std::cout << " " << e->what() << std::endl; delete e; return 0; } printHandler->updateTeams(engine->getTeams()); GfxManager *gfxManager; sf::RenderWindow *window = 0; GfxEventHandler *gfxHandler = 0; unsigned int viewWidth = stage->getWidth() + (STAGE_MARGIN * 2); unsigned int viewHeight = stage->getHeight() + (STAGE_MARGIN * 2); if (!nodisplay) { gfxHandler = new GfxEventHandler(); stage->addEventHandler((EventHandler*) gfxHandler); unsigned int screenWidth = sf::VideoMode::getDesktopMode().width; unsigned int screenHeight = sf::VideoMode::getDesktopMode().height; double windowScale = std::min(1.0, std::min(((double) screenWidth) / viewWidth, ((double) screenHeight) / viewHeight)); unsigned int targetWidth = round(windowScale * viewWidth); unsigned int targetHeight = round(windowScale * viewHeight); gfxManager = new GfxManager(false); window = new sf::RenderWindow(sf::VideoMode(targetWidth, targetHeight), "BerryBots", sf::Style::Default, sf::ContextSettings(0, 0, 16, 2, 0)); gfxManager->initViews(window, viewWidth, viewHeight); gfxManager->initBbGfx(window, viewHeight, stage, engine->getTeams(), engine->getNumTeams(), engine->getShips(), engine->getNumShips(), resourcePath()); window->clear(); gfxManager->drawGame(window, stage, engine->getShips(), engine->getNumShips(), engine->getGameTime(), gfxHandler, false, false, 0); window->display(); } time_t realTime1; time_t realTime2; time(&realTime1); int realSeconds = 0; try { while ((nodisplay || window->isOpen()) && !engine->isGameOver()) { engine->processTick(); if (!nodisplay) { sf::Event event; bool resized = false; while (window->pollEvent(event)) { if (event.type == sf::Event::Closed) { window->close(); } if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) { window->close(); } if (event.type == sf::Event::Resized && !resized) { resized = true; gfxManager->onResize(window, viewWidth, viewHeight); } } window->clear(); gfxManager->drawGame(window, stage, engine->getShips(), engine->getNumShips(), engine->getGameTime(), gfxHandler, false, false, 0); window->display(); } time(&realTime2); if (realTime2 - realTime1 > 0) { realSeconds++; if (realSeconds % 10 == 0) { std::cout << "TPS: " << (((double) engine->getGameTime()) / realSeconds) << std::endl; } } realTime1 = realTime2; } } catch (EngineException *e) { std::cout << "BerryBots encountered an error:" << std::endl; std::cout << " " << e->what() << std::endl; delete e; return 0; } if (!nodisplay) { gfxManager->destroyBbGfx(); delete window; } const char* winnerName = engine->getWinnerName(); if (winnerName != 0) { std::cout << std::endl<< winnerName << " wins! Congratulations!" << std::endl; } std::cout << std::endl << "Results:" << std::endl; Team **rankedTeams = engine->getRankedTeams(); bool hasScores = false; for (int x = 0; x < numTeams; x++) { if (rankedTeams[x]->result.score != 0) { hasScores = true; break; } } TeamResult *firstResult = &(rankedTeams[0]->result); int numStats = firstResult->numStats; char **statKeys = 0; if (numStats > 0) { statKeys = new char*[firstResult->numStats]; for (int x = 0; x < numStats; x++) { statKeys[x] = new char[strlen(firstResult->stats[x]->key) + 1]; strcpy(statKeys[x], firstResult->stats[x]->key); } } for (int x = 0; x < engine->getNumTeams(); x++) { TeamResult *result = &(rankedTeams[x]->result); if (result->showResult) { std::cout << " " << rankedTeams[x]->name << ":" << std::endl; std::cout << " Rank: "; if (result->rank == 0) { std::cout << "-"; } else { std::cout << result->rank; } std::cout << std::endl; if (hasScores) { std::cout << " Score: " << round(result->score, 2) << std::endl; } for (int y = 0; y < numStats; y++) { char *key = statKeys[y]; bool found = false; for (int z = 0; z < result->numStats; z++) { char *resultKey = result->stats[z]->key; if (strcmp(key, resultKey) == 0) { std::cout << " " << key << ": " << round(result->stats[z]->value, 2) << std::endl; found = true; break; } } if (!found) { std::cout << " " << key << ": -" << std::endl; } } } } std::cout << std::endl << "CPU time used per tick (microseconds):" << std::endl; for (int x = 0; x < engine->getNumTeams(); x++) { Team *team = engine->getTeam(x); if (!team->stageShip && !team->disabled) { std::cout << " " << team->name << ": " << (team->totalCpuTime / team->totalCpuTicks) << std::endl; } } if (realSeconds > 0) { std::cout << std::endl << "TPS: " << (((double) engine->getGameTime()) / realSeconds) << std::endl; } if (saveReplay) { ReplayBuilder *replayBuilder = engine->getReplayBuilder(); // TODO: move this into a function in the engine Team **rankedTeams = engine->getRankedTeams(); replayBuilder->setResults(rankedTeams, engine->getNumTeams()); char *filename = 0; char *absFilename = 0; do { if (filename != 0) { delete filename; } if (absFilename != 0) { delete absFilename; } filename = replayFilename(stage->getName()); char *filePath = fileManager->getFilePath(REPLAYS_SUBDIR, filename); absFilename = fileManager->getAbsFilePath(filePath); delete filePath; } while (fileManager->fileExists(absFilename)); replayBuilder->saveReplay(filename); std::cout << std::endl << "Saved replay to: " << REPLAYS_SUBDIR << "/" << filename << std::endl; delete filename; delete absFilename; } std::cout << std::endl; delete engine; for (int x = 0; x < numTeams; x++) { delete teams[x]; } delete teams; delete rankedTeams; for (int x = 0; x < numStats; x++) { delete statKeys[x]; } delete statKeys; delete printHandler; if (!nodisplay) { delete gfxManager; } delete packageReporter; delete fileManager; delete zipper; delete shipsBaseDir; delete stagesBaseDir; return 0; }
void StagePreview::showPreview(sf::RenderWindow *window, const char *stageName, int x, int y) { if (stageName_ != 0) { delete stageName_; } stageName_ = new char[strlen(stageName) + 1]; strcpy(stageName_, stageName); SetPosition(wxPoint(x, y)); infoSizer_->Clear(true); descSizer_->Clear(true); BerryBotsEngine *engine = new BerryBotsEngine(0, fileManager_, 0); Stage *stage = engine->getStage(); try { engine->initStage(getStagesDir().c_str(), stageName, getCacheDir().c_str()); } catch (EngineException *e) { wxMessageDialog errorMessage(NULL, e->what(), "Preview failure", wxOK | wxICON_EXCLAMATION); errorMessage.ShowModal(); delete engine; delete e; return; } SetTitle(wxString::Format(wxT("%s"), stage->getName())); unsigned int targetWidth; unsigned int targetHeight; char *previewFilename = savePreviewImage(window, engine, targetWidth, targetHeight); wxImage previewImage(previewFilename); delete previewFilename; double backingScale = getBackingScaleFactor(); if (backingScale > 1) { targetWidth /= backingScale; targetHeight /= backingScale; } visualPreview_->SetMinSize(wxSize(targetWidth, targetHeight)); visualPreview_->SetMaxSize(wxSize(targetWidth, targetHeight)); #ifdef __WXOSX__ int padding = 4; #else int padding = 8; #endif wxSizer *infoGrid = new wxFlexGridSizer(2, 0, padding); addInfo(infoGrid, "Name:", stage->getName()); addInfo(infoGrid, "Size:", wxString::Format(wxT("%i x %i"), stage->getWidth(), stage->getHeight())); if (engine->getTeamSize() > 1) { addInfo(infoGrid, "Team size:", engine->getTeamSize()); } addInfo(infoGrid, "Walls:", (stage->getWallCount() - 4)); addInfo(infoGrid, "Zones:", stage->getZoneCount()); addInfo(infoGrid, "Starts:", stage->getStartCount()); int numStageShips = stage->getStageShipCount(); if (numStageShips > 0) { char **stageShips = stage->getStageShips(); for (int x = 0; x < numStageShips; x++) { const char *shipName = stageShips[x]; if (shipName != 0) { int count = 1; for (int y = x + 1; y < numStageShips; y++) { const char *shipName2 = stageShips[y]; if (shipName2 != 0 && strcmp(shipName, shipName2) == 0) { count++; stageShips[y] = 0; } } wxString wxShipName = (count == 1) ? wxString(stageShips[x]) : wxString::Format(wxT("%s x%i"), shipName, count); addInfo(infoGrid, (x == 0 ? "Ships:" : ""), wxShipName); } } } infoSizer_->Add(infoGrid); char *description = fileManager_->getStageDescription( getStagesDir().c_str(), stageName, getCacheDir().c_str()); if (description == 0) { std::string descstr("<No description>"); description = new char[descstr.length() + 1]; strcpy(description, descstr.c_str()); } wxStaticText *descCtrl = new wxStaticText(mainPanel_, wxID_ANY, description); descSizer_->Add(descCtrl); delete description; mainPanel_->GetSizer()->SetSizeHints(mainPanel_); mainPanel_->Layout(); Fit(); mainPanel_->SetFocus(); wxBitmap bitmap; #ifdef __WINDOWS__ bitmap = wxBitmap(previewImage); #else bitmap.CreateScaled(targetWidth, targetHeight, wxBITMAP_SCREEN_DEPTH, backingScale); wxMemoryDC dc(bitmap); double logicalScale = (backingScale > 1) ? (1.0 / backingScale) : 1; dc.SetLogicalScale(logicalScale, logicalScale); dc.DrawBitmap(wxBitmap(previewImage), 0, 0); #endif // On Windows, if we set the bitmap before the Layout/Fit stuff, we get visual // artifacts when paging through the stages with up/down keys. visualPreview_->SetBitmap(bitmap); delete engine; }