void runGameLoop(const bpo::variables_map& variables) { FARender::Renderer& renderer = *FARender::Renderer::get(); Input::InputManager& input = *Input::InputManager::get(); Engine::ThreadManager& threadManager = *Engine::ThreadManager::get(); DiabloExe::DiabloExe exe; if (!exe.isLoaded()) { renderer.stop(); return; } FAWorld::World world; FALevelGen::FAsrand(time(NULL)); std::vector<Level::Level*> levels(9); int32_t currentLevel = variables["level"].as<int32_t>(); Level::Level* level = NULL; FARender::Tileset tileset; FAWorld::Player* player = world.getPlayer(); FAGui::initGui(); // -1 represents the main menu if(currentLevel != -1) { if(!(level = getLevel(currentLevel, exe))) { done = true; } else { tileset = renderer.getTileset(*level); levels[currentLevel] = level; setLevel(currentLevel, exe, world, level); } player->mPos = FAWorld::Position(level->upStairsPos().first, level->upStairsPos().second); FAGui::showIngameGui(); playLevelMusic(currentLevel, threadManager); } else { paused = true; FAGui::showMainMenu(); threadManager.playMusic("music/dintro.wav"); } boost::posix_time::ptime last = boost::posix_time::microsec_clock::local_time(); std::pair<size_t, size_t> destination = player->mPos.current(); //bpt::ptree hotkeypt; Misc::readIni("resources/hotkeys.ini", hotkeypt); quit_key = Input::Hotkey("Quit", hotkeypt); noclip_key = Input::Hotkey("Noclip", hotkeypt); changelvlup_key = Input::Hotkey("Changelvlup", hotkeypt); changelvldwn_key = Input::Hotkey("Changelvldwn", hotkeypt); // Main game logic loop while(!done) { input.processInput(paused); boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time(); while((size_t)(now.time_of_day().total_milliseconds() - last.time_of_day().total_milliseconds()) < 1000/FAWorld::World::ticksPerSecond) { boost::this_thread::yield(); now = boost::posix_time::microsec_clock::local_time(); } last = now; if(!paused) { if(mouseDown) { destination = renderer.getClickedTile(xClick, yClick, *level, player->mPos); if(click) level->activate(destination.first, destination.second); click = false; } if(changeLevel) { int32_t tmp = currentLevel + changeLevel; if(tmp >= 0 && tmp < (int32_t)levels.size()) { currentLevel = tmp; if(levels[currentLevel] == NULL) levels[currentLevel] = getLevel(currentLevel, exe); level = levels[currentLevel]; if(changeLevel == -1) player->mPos = FAWorld::Position(level->downStairsPos().first, level->downStairsPos().second); else player->mPos = FAWorld::Position(level->upStairsPos().first, level->upStairsPos().second); destination = player->mPos.current(); setLevel(currentLevel, exe, world, level); tileset = renderer.getTileset(*level); playLevelMusic(currentLevel, threadManager); } changeLevel = 0; } if(player->mPos.current() != destination) { if(player->mPos.mDist == 0) { std::pair<float, float> vector = Misc::getVec(player->mPos.current(), destination); if(!player->mPos.mMoving) { player->mPos.mMoving = true; player->setAnimation(FAWorld::AnimState::walk); } player->mPos.mDirection = Misc::getVecDir(vector); } } else if(player->mPos.mMoving && player->mPos.mDist == 0) { player->mPos.mMoving = false; player->setAnimation(FAWorld::AnimState::idle); } FAWorld::Actor* actorAtNext = world.getActorAt(player->mPos.next().first, player->mPos.next().second); if(!noclip && (!(*level)[player->mPos.next().first][player->mPos.next().second].passable() || (actorAtNext != NULL && actorAtNext != player))) { player->mPos.mMoving = false; destination = player->mPos.current(); player->setAnimation(FAWorld::AnimState::idle); } world.update(); } FAGui::updateGui(); FARender::RenderState* state = renderer.getFreeState(); if(state) { state->mPos = player->mPos; state->tileset = tileset; state->level = level; world.fillRenderState(state); Render::updateGuiBuffer(&state->guiDrawBuffer); } else { Render::updateGuiBuffer(NULL); } renderer.setCurrentState(state); } renderer.stop(); for(size_t i = 0; i < levels.size(); i++) { if(levels[i]) delete levels[i]; } }
int realmain(int argc, char** argv) { while(!FARender::Renderer::get()) {} FARender::Renderer& renderer = *FARender::Renderer::get(); Input::InputManager& input = *Input::InputManager::get(); size_t levelNum; boost::program_options::options_description desc("Options"); desc.add_options() ("help,h", "Print help") ("level,l", boost::program_options::value<size_t>(&levelNum)->default_value(0), "Level number to load (0-4)"); boost::program_options::variables_map vm; try { boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm); if(vm.count("help")) { std::cout << desc << std::endl; return 0; } boost::program_options::notify(vm); if(levelNum > 4) throw boost::program_options::validation_error( boost::program_options::validation_error::invalid_option_value, "level"); } catch(boost::program_options::error& e) { std::cerr << "ERROR: " << e.what() << std::endl << std::endl; std::cerr << desc << std::endl; return 1; } DiabloExe::DiabloExe exe; FAWorld::World world; FALevelGen::FAsrand(time(NULL)); std::vector<Level::Level*> levels(5); size_t currentLevel = levelNum; Level::Level* level; if(!(level = getLevel(levelNum, exe))) { done = true; } else { levels[currentLevel] = level; setLevel(levelNum, exe, world, renderer, *level); } FAWorld::Player* player = world.getPlayer(); if(levelNum == 0) player->mPos = FAWorld::Position(75, 68); else player->mPos = FAWorld::Position(level->upStairsPos().first, level->upStairsPos().second); boost::posix_time::ptime last = boost::posix_time::microsec_clock::local_time(); std::pair<size_t, size_t> destination = player->mPos.current(); // Main game logic loop while(!done) { if(mouseDown) { destination = renderer.getClickedTile(xClick, yClick); if(click) level->activate(destination.first, destination.second); click = false; } input.processInput(); if(changeLevel) { int32_t tmp = currentLevel + changeLevel; if(tmp >= 0 && tmp < (int32_t)levels.size()) { currentLevel = tmp; if(levels[currentLevel] == NULL) levels[currentLevel] = getLevel(currentLevel == 0 ? 0 : 1, exe); level = levels[currentLevel]; if(changeLevel == -1) player->mPos = FAWorld::Position(level->downStairsPos().first, level->downStairsPos().second); else player->mPos = FAWorld::Position(level->upStairsPos().first, level->upStairsPos().second); setLevel(currentLevel, exe, world, renderer, *level); } changeLevel = 0; } boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time(); while((size_t)(now.time_of_day().total_milliseconds() - last.time_of_day().total_milliseconds()) < 1000/FAWorld::World::ticksPerSecond) { boost::this_thread::sleep(boost::posix_time::milliseconds(1)); now = boost::posix_time::microsec_clock::local_time(); } last = now; if(player->mPos.current() != destination) { if(player->mPos.mDist == 0) { std::pair<float, float> vector = Misc::getVec(player->mPos.current(), destination); if(!player->mPos.mMoving) { player->mPos.mMoving = true; player->setAnimation(FAWorld::AnimState::walk); } player->mPos.mDirection = Misc::getVecDir(vector); } } else if(player->mPos.mMoving && player->mPos.mDist == 0) { player->mPos.mMoving = false; player->setAnimation(FAWorld::AnimState::idle); } if(!noclip && !(*level)[player->mPos.next().first][player->mPos.next().second].passable()) { player->mPos.mMoving = false; player->setAnimation(FAWorld::AnimState::idle); } world.update(); FARender::RenderState* state = renderer.getFreeState(); state->mPos = player->mPos; world.fillRenderState(state); renderer.setCurrentState(state); } renderer.stop(); while(!renderDone) {} // have to wait until the renderer stops before destroying all our locals for(size_t i = 0; i < levels.size(); i++) delete levels[i]; return 0; }
void runGameLoop(const bpo::variables_map& variables) { while(!FARender::Renderer::get()) {} FARender::Renderer& renderer = *FARender::Renderer::get(); Input::InputManager input(&keyPress, NULL, &mouseClick, &mouseRelease, &mouseMove, renderer.getRocketContext()); DiabloExe::DiabloExe exe; FAWorld::World world; FALevelGen::FAsrand(time(NULL)); std::vector<Level::Level*> levels(5); size_t currentLevel = variables["level"].as<size_t>(); Level::Level* level; if(!(level = getLevel(currentLevel, exe))) { done = true; } else { levels[currentLevel] = level; setLevel(currentLevel, exe, world, renderer, *level); } FAWorld::Player* player = world.getPlayer(); if(currentLevel == 0) player->mPos = FAWorld::Position(75, 68); else player->mPos = FAWorld::Position(level->upStairsPos().first, level->upStairsPos().second); boost::posix_time::ptime last = boost::posix_time::microsec_clock::local_time(); std::pair<size_t, size_t> destination = player->mPos.current(); FAGui::initGui(); // Main game logic loop while(!done) { if(mouseDown) { destination = renderer.getClickedTile(xClick, yClick); if(click) level->activate(destination.first, destination.second); click = false; } input.processInput(paused); if(changeLevel) { int32_t tmp = currentLevel + changeLevel; if(tmp >= 0 && tmp < (int32_t)levels.size()) { currentLevel = tmp; if(levels[currentLevel] == NULL) levels[currentLevel] = getLevel(currentLevel == 0 ? 0 : 1, exe); level = levels[currentLevel]; if(changeLevel == -1) player->mPos = FAWorld::Position(level->downStairsPos().first, level->downStairsPos().second); else player->mPos = FAWorld::Position(level->upStairsPos().first, level->upStairsPos().second); setLevel(currentLevel, exe, world, renderer, *level); } changeLevel = 0; } boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time(); while((size_t)(now.time_of_day().total_milliseconds() - last.time_of_day().total_milliseconds()) < 1000/FAWorld::World::ticksPerSecond) { boost::this_thread::sleep(boost::posix_time::milliseconds(1)); now = boost::posix_time::microsec_clock::local_time(); } last = now; if(player->mPos.current() != destination) { if(player->mPos.mDist == 0) { std::pair<float, float> vector = Misc::getVec(player->mPos.current(), destination); if(!player->mPos.mMoving) { player->mPos.mMoving = true; player->setAnimation(FAWorld::AnimState::walk); } player->mPos.mDirection = Misc::getVecDir(vector); } } else if(player->mPos.mMoving && player->mPos.mDist == 0) { player->mPos.mMoving = false; player->setAnimation(FAWorld::AnimState::idle); } if(!noclip && !(*level)[player->mPos.next().first][player->mPos.next().second].passable()) { player->mPos.mMoving = false; player->setAnimation(FAWorld::AnimState::idle); } if(!paused) world.update(); FAGui::updateGui(); FARender::RenderState* state = renderer.getFreeState(); state->mPos = player->mPos; world.fillRenderState(state); Render::updateGuiBuffer(state->guiDrawBuffer); renderer.setCurrentState(state); } FAGui::destroyGui(); renderer.stop(); while(!renderDone) {} // have to wait until the renderer stops before destroying all our locals for(size_t i = 0; i < levels.size(); i++) delete levels[i]; }