diff --git a/Core/Config.cpp b/Core/Config.cpp index 483ffe11fb..c8155bce66 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -401,6 +401,10 @@ static int DefaultAndroidHwScale() { } static ConfigSetting graphicsSettings[] = { + ConfigSetting("EnableCardboard", &g_Config.bEnableCardboard, false, true, true), + ConfigSetting("CardboardScreenSize", &g_Config.iCardboardScreenSize, 50, true, true), + ConfigSetting("CardboardXShift", &g_Config.iCardboardXShift, 0, true, true), + ConfigSetting("CardboardYShift", &g_Config.iCardboardXShift, 0, true, true), ConfigSetting("ShowFPSCounter", &g_Config.iShowFPSCounter, 0, true, true), ReportedConfigSetting("GPUBackend", &g_Config.iGPUBackend, 0), ReportedConfigSetting("RenderingMode", &g_Config.iRenderingMode, &DefaultRenderingMode, true, true), diff --git a/Core/Config.h b/Core/Config.h index f829757202..ddab87cced 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -152,6 +152,11 @@ public: bool bAutoFrameSkip; bool bFrameSkipUnthrottle; + bool bEnableCardboard; // Cardboard Master Switch + int iCardboardScreenSize; // Screen Size (in %) + int iCardboardXShift; // X-Shift of Screen (in %) + int iCardboardYShift; // Y-Shift of Screen (in %) + int iWindowX; int iWindowY; int iWindowWidth; // Windows and other windowed environments diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index f61586a5f3..ce9fc0d6c0 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -497,15 +497,38 @@ void FramebufferManager::DrawFramebuffer(const u8 *srcPixels, GEBufferFormat src DisableState(); + struct CardboardSettings cardboardSettings; + GetCardboardSettings(&cardboardSettings); + // This might draw directly at the backbuffer (if so, applyPostShader is set) so if there's a post shader, we need to apply it here. // Should try to unify this path with the regular path somehow, but this simple solution works for most of the post shaders // (it always runs at output resolution so FXAA may look odd). float x, y, w, h; CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight); - if (applyPostShader && usePostShader_ && useBufferedRendering_) { - DrawActiveTexture(0, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, false, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, postShaderProgram_); + if (cardboardSettings.enabled) { + // Left Eye Image + glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + if (applyPostShader && usePostShader_ && useBufferedRendering_) { + DrawActiveTexture(0, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, false, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, postShaderProgram_); + } else { + DrawActiveTexture(0, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, false, 0.0f, 0.0f, 480.0f / 512.0f); + } + + // Right Eye Image + glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + if (applyPostShader && usePostShader_ && useBufferedRendering_) { + DrawActiveTexture(0, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, false, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, postShaderProgram_); + } else { + DrawActiveTexture(0, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, false, 0.0f, 0.0f, 480.0f / 512.0f); + } } else { - DrawActiveTexture(0, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, false, 0.0f, 0.0f, 480.0f / 512.0f); + // Fullscreen Image + glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + if (applyPostShader && usePostShader_ && useBufferedRendering_) { + DrawActiveTexture(0, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, false, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, postShaderProgram_); + } else { + DrawActiveTexture(0, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, false, 0.0f, 0.0f, 480.0f / 512.0f); + } } } @@ -961,6 +984,32 @@ void FramebufferManager::BindFramebufferColor(int stage, VirtualFramebuffer *fra } } +struct CardboardSettings * FramebufferManager::GetCardboardSettings(struct CardboardSettings * cardboardSettings) { + if (cardboardSettings) { + // Calculate Cardboard Settings + float cardboardScreenScale = g_Config.iCardboardScreenSize / 100.0f; + float cardboardScreenWidth = PSP_CoreParameter().pixelWidth / 2.0f * cardboardScreenScale; + float cardboardScreenHeight = PSP_CoreParameter().pixelHeight / 2.0f * cardboardScreenScale; + float cardboardMaxXShift = (PSP_CoreParameter().pixelWidth / 2.0f - cardboardScreenWidth) / 2.0f; + float cardboardUserXShift = g_Config.iCardboardXShift / 100.0f * cardboardMaxXShift; + float cardboardLeftEyeX = cardboardMaxXShift + cardboardUserXShift; + float cardboardRightEyeX = PSP_CoreParameter().pixelWidth / 2.0f + cardboardMaxXShift - cardboardUserXShift; + float cardboardMaxYShift = PSP_CoreParameter().pixelHeight / 2.0f - cardboardScreenHeight / 2.0f; + float cardboardUserYShift = g_Config.iCardboardYShift / 100.0f * cardboardMaxYShift; + float cardboardScreenY = cardboardMaxYShift + cardboardUserYShift; + + // Copy current Settings into Structure + cardboardSettings->enabled = g_Config.bEnableCardboard; + cardboardSettings->leftEyeXPosition = cardboardLeftEyeX; + cardboardSettings->rightEyeXPosition = cardboardRightEyeX; + cardboardSettings->screenYPosition = cardboardScreenY; + cardboardSettings->screenWidth = cardboardScreenWidth; + cardboardSettings->screenHeight = cardboardScreenHeight; + } + + return cardboardSettings; +} + void FramebufferManager::CopyDisplayToOutput() { fbo_unbind(); glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); @@ -969,6 +1018,9 @@ void FramebufferManager::CopyDisplayToOutput() { u32 offsetX = 0; u32 offsetY = 0; + struct CardboardSettings cardboardSettings; + GetCardboardSettings(&cardboardSettings); + VirtualFramebuffer *vfb = GetVFBAt(displayFramebufPtr_); if (!vfb) { // Let's search for a framebuf within this range. @@ -1070,9 +1122,19 @@ void FramebufferManager::CopyDisplayToOutput() { const float v1 = (272.0f + offsetY) / (float)vfb->bufferHeight; if (!usePostShader_) { - glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); - // These are in the output display coordinates - DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, u0, v0, u1, v1); + if (cardboardSettings.enabled) { + // Left Eye Image + glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, u0, v0, u1, v1); + + // Right Eye Image + glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, u0, v0, u1, v1); + } else { + // Fullscreen Image + glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, u0, v0, u1, v1); + } } else if (usePostShader_ && extraFBOs_.size() == 1 && !postShaderAtOutputResolution_) { // An additional pass, post-processing shader to the extra FBO. fbo_bind_as_render_target(extraFBOs_[0]); @@ -1090,14 +1152,34 @@ void FramebufferManager::CopyDisplayToOutput() { return; } colorTexture = fbo_get_color_texture(extraFBOs_[0]); - glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); - // These are in the output display coordinates - DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, u0, v0, u1, v1); + + if (g_Config.bEnableCardboard) { + // Left Eye Image + glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, u0, v0, u1, v1); + + // Right Eye Image + glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, u0, v0, u1, v1); + } else { + // Fullscreen Image + glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, u0, v0, u1, v1); + } } else { - // Use post-shader, but run shader at output resolution. - glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); - // These are in the output display coordinates - DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, u0, v0, u1, v1, postShaderProgram_); + if (g_Config.bEnableCardboard) { + // Left Eye Image + glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, u0, v0, u1, v1); + + // Right Eye Image + glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); + DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, u0, v0, u1, v1); + } else { + // Fullscreen Image + glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, u0, v0, u1, v1, postShaderProgram_); + } } glBindTexture(GL_TEXTURE_2D, 0); diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index 427d918c1d..a51e2dbc46 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -56,6 +56,15 @@ struct AsyncPBO { #endif +struct CardboardSettings { + bool enabled; + float leftEyeXPosition; + float rightEyeXPosition; + float screenYPosition; + float screenWidth; + float screenHeight; +}; + class FramebufferManager : public FramebufferManagerCommon { public: FramebufferManager(); @@ -115,6 +124,9 @@ public: FBO *GetTempFBO(u16 w, u16 h, FBOColorDepth depth = FBO_8888); + // Cardboard Settings Calculator + struct CardboardSettings * GetCardboardSettings(struct CardboardSettings * cardboardSettings); + protected: virtual void DisableState() override; virtual void ClearBuffer() override; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 1568e37415..aa21897d19 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -136,7 +136,6 @@ void GameSettingsScreen::CreateViews() { PopupMultiChoice *renderingModeChoice = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iRenderingMode, gs->T("Mode"), renderingMode, 0, ARRAY_SIZE(renderingMode), gs, screenManager())); renderingModeChoice->OnChoice.Handle(this, &GameSettingsScreen::OnRenderingMode); renderingModeChoice->SetDisabledPtr(&g_Config.bSoftwareRendering); - CheckBox *blockTransfer = graphicsSettings->Add(new CheckBox(&g_Config.bBlockTransferGPU, gs->T("Simulate Block Transfer", "Simulate Block Transfer (unfinished)"))); blockTransfer->SetDisabledPtr(&g_Config.bSoftwareRendering); @@ -269,6 +268,18 @@ void GameSettingsScreen::CreateViews() { PopupMultiChoice *bufFilter = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iBufFilter, gs->T("Screen Scaling Filter"), bufFilters, 1, ARRAY_SIZE(bufFilters), gs, screenManager())); bufFilter->SetDisabledPtr(&g_Config.bSoftwareRendering); +#ifdef ANDROID + graphicsSettings->Add(new ItemHeader(gs->T("Cardboard Settings", "Cardboard Settings"))); + CheckBox *cardboardMode = graphicsSettings->Add(new CheckBox(&g_Config.bEnableCardboard, gs->T("Enable Cardboard", "Enable Cardboard"))); + cardboardMode->SetDisabledPtr(&g_Config.bSoftwareRendering); + PopupSliderChoice * cardboardScreenSize = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardScreenSize, 30, 100, gs->T("Cardboard Screen Size", "Screen Size (in % of the viewport)"), 1, screenManager())); + cardboardScreenSize->SetDisabledPtr(&g_Config.bSoftwareRendering); + PopupSliderChoice *cardboardXShift = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardXShift, -100, 100, gs->T("Cardboard Screen X Shift", "X Shift (in % of the void)"), 1, screenManager())); + cardboardXShift->SetDisabledPtr(&g_Config.bSoftwareRendering); + PopupSliderChoice *cardboardYShift = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardYShift, -100, 100, gs->T("Cardboard Screen Y Shift", "Y Shift (in % of the void)"), 1, screenManager())); + cardboardYShift->SetDisabledPtr(&g_Config.bSoftwareRendering); +#endif + graphicsSettings->Add(new ItemHeader(gs->T("Hack Settings", "Hack Settings (these WILL cause glitches)"))); graphicsSettings->Add(new CheckBox(&g_Config.bTimerHack, gs->T("Timer Hack"))); CheckBox *alphaHack = graphicsSettings->Add(new CheckBox(&g_Config.bDisableAlphaTest, gs->T("Disable Alpha Test (PowerVR speedup)"))); @@ -312,6 +323,7 @@ void GameSettingsScreen::CreateViews() { // We normally use software rendering to debug so put it in debugging. CheckBox *softwareGPU = graphicsSettings->Add(new CheckBox(&g_Config.bSoftwareRendering, gs->T("Software Rendering", "Software Rendering (experimental)"))); softwareGPU->OnClick.Handle(this, &GameSettingsScreen::OnSoftwareRendering); + if (PSP_IsInited() || g_Config.iGPUBackend != GPU_BACKEND_OPENGL) softwareGPU->SetEnabled(false);