#include "ViewController.h" #include "../Log.h" #include "../SystemData.h" #include "BasicGameListView.h" #include "DetailedGameListView.h" ViewController::ViewController(Window* window) : GuiComponent(window), mCurrentView(nullptr), mCameraPos(Eigen::Affine3f::Identity()) { mState.viewing = START_SCREEN; } void ViewController::goToSystemSelect() { mState.viewing = SYSTEM_SELECT; goToSystem(SystemData::sSystemVector.at(0)); } SystemData* getSystemCyclic(SystemData* from, bool reverse) { std::vector<SystemData*>& sysVec = SystemData::sSystemVector; if(reverse) { auto it = std::find(sysVec.rbegin(), sysVec.rend(), from); assert(it != sysVec.rend()); it++; if(it == sysVec.rend()) it = sysVec.rbegin(); return *it; }else{ auto it = std::find(sysVec.begin(), sysVec.end(), from); assert(it != sysVec.end()); it++; if(it == sysVec.end()) it = sysVec.begin(); return *it; } } void ViewController::goToNextSystem() { assert(mState.viewing == SYSTEM); SystemData* system = mState.data.system; if(system == NULL) return; goToSystem(getSystemCyclic(system, false)); } void ViewController::goToPrevSystem() { assert(mState.viewing == SYSTEM); SystemData* system = mState.data.system; if(system == NULL) return; goToSystem(getSystemCyclic(system, true)); } void ViewController::goToSystem(SystemData* system) { mState.viewing = SYSTEM; mState.data.system = system; mCurrentView = getSystemView(system); } void ViewController::onFileChanged(FileData* file, FileChangeType change) { for(auto it = mSystemViews.begin(); it != mSystemViews.end(); it++) { it->second->onFileChanged(file, change); } } void ViewController::launch(FileData* game) { if(game->getType() != GAME) { LOG(LogError) << "tried to launch something that isn't a game"; return; } // Effect TODO game->getSystem()->launchGame(mWindow, game); } std::shared_ptr<GameListView> ViewController::getSystemView(SystemData* system) { //if we already made one, return that one auto exists = mSystemViews.find(system); if(exists != mSystemViews.end()) return exists->second; //if we didn't, make it, remember it, and return it std::shared_ptr<GameListView> view; if(system != NULL) { //decide type bool detailed = false; std::vector<FileData*> files = system->getRootFolder()->getFilesRecursive(GAME | FOLDER); for(auto it = files.begin(); it != files.end(); it++) { if(!(*it)->getThumbnailPath().empty()) { detailed = true; break; } } if(detailed) view = std::shared_ptr<GameListView>(new DetailedGameListView(mWindow, system->getRootFolder())); else view = std::shared_ptr<GameListView>(new BasicGameListView(mWindow, system->getRootFolder())); view->setTheme(system->getTheme()); }else{ LOG(LogError) << "null system"; // should eventually return an "all games" gamelist view } std::vector<SystemData*>& sysVec = SystemData::sSystemVector; int id = std::find(sysVec.begin(), sysVec.end(), system) - sysVec.begin(); view->setPosition(id * (float)Renderer::getScreenWidth(), 0); mSystemViews[system] = view; return view; } bool ViewController::input(InputConfig* config, Input input) { if(mCurrentView) return mCurrentView->input(config, input); return false; } float clamp(float min, float max, float val) { if(val < min) val = min; else if(val > max) val = max; return val; } //http://en.wikipedia.org/wiki/Smoothstep float smoothStep(float edge0, float edge1, float x) { // Scale, and clamp x to 0..1 range x = clamp(0, 1, (x - edge0)/(edge1 - edge0)); // Evaluate polynomial return x*x*x*(x*(x*6 - 15) + 10); } void ViewController::update(int deltaTime) { if(mCurrentView) { mCurrentView->update(deltaTime); // move camera towards current view (should use smoothstep) Eigen::Vector3f diff = (mCurrentView->getPosition() + mCameraPos.translation()) * 0.0075f * (float)deltaTime; mCameraPos.translate(-diff); } } void ViewController::render(const Eigen::Affine3f& parentTrans) { Eigen::Affine3f trans = parentTrans * mCameraPos; //should really do some clipping here for(auto it = mSystemViews.begin(); it != mSystemViews.end(); it++) { Eigen::Vector3f pos = it->second->getPosition(); Eigen::Vector2f size = it->second->getSize(); Eigen::Vector3f camPos = -trans.translation(); Eigen::Vector2f camSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight()); if(pos.x() + size.x() >= camPos.x() && pos.y() + size.y() >= camPos.y() && pos.x() <= camPos.x() + camSize.x() && pos.y() <= camPos.y() + camSize.y()) it->second->render(trans); } }