diff --git a/src/Renderer_init_sdlgl.cpp b/src/Renderer_init_sdlgl.cpp index f3500538d..d4d28a061 100644 --- a/src/Renderer_init_sdlgl.cpp +++ b/src/Renderer_init_sdlgl.cpp @@ -71,7 +71,8 @@ namespace Renderer SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - sdlScreen = SDL_SetVideoMode(display_width, display_height, 16, SDL_OPENGL | (WINDOWED ? 0 : SDL_FULLSCREEN) | SDL_DOUBLEBUF); + //SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); //vsync + sdlScreen = SDL_SetVideoMode(display_width, display_height, 16, SDL_OPENGL | (WINDOWED ? 0 : SDL_FULLSCREEN)); if(sdlScreen == NULL) { diff --git a/src/components/GuiGameList.cpp b/src/components/GuiGameList.cpp index 9765a2cde..aad66bc10 100644 --- a/src/components/GuiGameList.cpp +++ b/src/components/GuiGameList.cpp @@ -11,7 +11,8 @@ Vector2i GuiGameList::getImagePos() return Vector2i((int)(Renderer::getScreenWidth() * mTheme->getFloat("gameImageOffsetX")), (int)(Renderer::getScreenHeight() * mTheme->getFloat("gameImageOffsetY"))); } -GuiGameList::GuiGameList(Window* window, bool useDetail) : GuiComponent(window), mDescription(window) +GuiGameList::GuiGameList(Window* window, bool useDetail) : GuiComponent(window), + mDescription(window), mTransitionImage(window, 0, 0, "", Renderer::getScreenWidth(), Renderer::getScreenHeight(), true) { mDetailed = useDetail; @@ -38,11 +39,23 @@ GuiGameList::GuiGameList(Window* window, bool useDetail) : GuiComponent(window), mDescription.setOffset(Vector2i((int)(Renderer::getScreenWidth() * 0.03), mScreenshot->getOffset().y + mScreenshot->getSize().y + 12)); mDescription.setExtent(Vector2u((int)(Renderer::getScreenWidth() * (mTheme->getFloat("listOffsetX") - 0.03)), 0)); + mTransitionImage.setOffset(Renderer::getScreenWidth(), 0); + mTransitionImage.setOrigin(0, 0); + mTransitionAnimation.addChild(&mTransitionImage); + + //a hack! the GuiGameList doesn't use the children system right now because I haven't redone it to do so yet. + //the list depends on knowing it's final window coordinates (getGlobalOffset), which requires knowing the where the GuiGameList is. + //the GuiGameList now moves during screen transitions, so we have to let it know somehow. + //this should be removed in favor of using real children soon. + mList->setParent(this); + setSystemId(0); } GuiGameList::~GuiGameList() { + //undo the parenting hack because otherwise it's not really a child and will try to remove itself on delete + mList->setParent(NULL); delete mList; if(mDetailed) @@ -83,6 +96,13 @@ void GuiGameList::setSystemId(int id) void GuiGameList::render() { + if(mTransitionImage.getOffset().x > 0) //transitioning in from the left + mOffset.x = mTransitionImage.getOffset().x - Renderer::getScreenWidth(); + else //transitioning in from the right + mOffset.x = mTransitionImage.getOffset().x + Renderer::getScreenWidth(); + + Renderer::translate(mOffset); + if(mTheme) mTheme->render(); @@ -106,6 +126,10 @@ void GuiGameList::render() } mList->render(); + + Renderer::translate(-mOffset); + + mTransitionImage.render(); } bool GuiGameList::input(InputConfig* config, Input input) @@ -156,11 +180,13 @@ bool GuiGameList::input(InputConfig* config, Input input) if(config->isMappedTo("right", input)) { setSystemId(mSystemId + 1); + doTransition(-1); return true; } if(config->isMappedTo("left", input)) { setSystemId(mSystemId - 1); + doTransition(1); return true; } } @@ -345,5 +371,15 @@ void GuiGameList::update(int deltaTime) if(mDetailed) mImageAnimation->update(deltaTime); + mTransitionAnimation.update(deltaTime); + mList->update(deltaTime); } + +void GuiGameList::doTransition(int dir) +{ + mTransitionImage.copyScreen(); + mTransitionImage.setOpacity(255); + mTransitionImage.setOffset(0, 0); + mTransitionAnimation.move(Renderer::getScreenWidth() * dir, 0, 50); +} diff --git a/src/components/GuiGameList.h b/src/components/GuiGameList.h index 29e16a713..7f51a0f15 100644 --- a/src/components/GuiGameList.h +++ b/src/components/GuiGameList.h @@ -39,6 +39,8 @@ private: void updateList(); void updateTheme(); void clearDetailData(); + void doTransition(int dir); + std::string getThemeFile(); SystemData* mSystem; @@ -53,6 +55,9 @@ private: AnimationComponent* mImageAnimation; ThemeComponent* mTheme; + ImageComponent mTransitionImage; + AnimationComponent mTransitionAnimation; + Vector2i getImagePos(); }; diff --git a/src/components/ImageComponent.cpp b/src/components/ImageComponent.cpp index 6edca1092..040348cff 100644 --- a/src/components/ImageComponent.cpp +++ b/src/components/ImageComponent.cpp @@ -354,3 +354,28 @@ bool ImageComponent::hasImage() unsigned char ImageComponent::getOpacity() { return mOpacity; } void ImageComponent::setOpacity(unsigned char opacity) { mOpacity = opacity; } + +void ImageComponent::copyScreen() +{ + unloadImage(); + + glReadBuffer(GL_FRONT); + + glGenTextures(1, &mTextureID); + glBindTexture(GL_TEXTURE_2D, mTextureID); + + int width = Renderer::getScreenWidth(); + int height = Renderer::getScreenHeight(); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, width, height, 0); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + mTextureSize.x = height; + mTextureSize.y = height; + + resize(); +} diff --git a/src/components/ImageComponent.h b/src/components/ImageComponent.h index cef220dae..3cf0204b1 100644 --- a/src/components/ImageComponent.h +++ b/src/components/ImageComponent.h @@ -18,6 +18,8 @@ public: ImageComponent(Window* window, int offsetX = 0, int offsetY = 0, std::string path = "", unsigned int maxWidth = 0, unsigned int maxHeight = 0, bool allowUpscale = false); virtual ~ImageComponent(); + //Copy the entire screen into a texture for us to use. + void copyScreen(); void setImage(std::string path); //Loads the image at the given filepath. void setOrigin(float originX, float originY); //Sets the origin as a percentage of this image (e.g. (0, 0) is top left, (0.5, 0.5) is the center) void setTiling(bool tile); //Enables or disables tiling. Must be called before loading an image or resizing will be weird. diff --git a/src/components/TextListComponent.h b/src/components/TextListComponent.h index b3bdbb057..3490d3577 100644 --- a/src/components/TextListComponent.h +++ b/src/components/TextListComponent.h @@ -141,14 +141,14 @@ void TextListComponent::onRender() if(listCutoff > (int)mRowVector.size()) listCutoff = mRowVector.size(); - Renderer::pushClipRect(getOffset(), getSize()); + Renderer::pushClipRect(getGlobalOffset(), getSize()); for(int i = startEntry; i < listCutoff; i++) { //draw selector bar if(mSelection == i) { - Renderer::drawRect(0, y, Renderer::getScreenWidth(), mFont->getHeight(), mSelectorColor); + Renderer::drawRect(0, y, getSize().x, mFont->getHeight(), mSelectorColor); } ListRow row = mRowVector.at((unsigned int)i);