예제 #1
0
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];
    }
}
예제 #2
0
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;
}
예제 #3
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];
}