mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-28 19:00:23 +00:00
Merge pull request #8082 from LunaMoo/DisplayEditing
Add "Display layout editor"
This commit is contained in:
commit
fbb30260e3
@ -861,6 +861,8 @@ set(NativeAppSource
|
||||
UI/NativeApp.cpp
|
||||
UI/BackgroundAudio.cpp
|
||||
UI/DevScreens.cpp
|
||||
UI/DisplayLayoutEditor.cpp
|
||||
UI/DisplayLayoutScreen.cpp
|
||||
UI/EmuScreen.cpp
|
||||
UI/GameInfoCache.cpp
|
||||
UI/MainScreen.cpp
|
||||
|
@ -436,14 +436,17 @@ static ConfigSetting graphicsSettings[] = {
|
||||
ReportedConfigSetting("TextureSecondaryCache", &g_Config.bTextureSecondaryCache, false, true, true),
|
||||
ReportedConfigSetting("VertexDecJit", &g_Config.bVertexDecoderJit, &DefaultJit, false),
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef MOBILE_DEVICE
|
||||
ConfigSetting("FullScreen", &g_Config.bFullScreen, false),
|
||||
#endif
|
||||
|
||||
// TODO: Replace these settings with a list of options
|
||||
ConfigSetting("PartialStretch", &g_Config.bPartialStretch, &DefaultPartialStretch, true, true),
|
||||
ConfigSetting("StretchToDisplay", &g_Config.bStretchToDisplay, false, true, true),
|
||||
ConfigSetting("SmallDisplay", &g_Config.bSmallDisplay, false, true, true),
|
||||
ConfigSetting("SmallDisplayZoom", &g_Config.iSmallDisplayZoom, 0, true, true),
|
||||
ConfigSetting("SmallDisplayOffsetX", &g_Config.fSmallDisplayOffsetX, 0.5f, true, true),
|
||||
ConfigSetting("SmallDisplayOffsetY", &g_Config.fSmallDisplayOffsetY, 0.5f, true, true),
|
||||
ConfigSetting("SmallDisplayCustomZoom", &g_Config.fSmallDisplayCustomZoom, 8.0f, true, true),
|
||||
ConfigSetting("ImmersiveMode", &g_Config.bImmersiveMode, false, true, true),
|
||||
|
||||
ReportedConfigSetting("TrueColor", &g_Config.bTrueColor, true, true, true),
|
||||
|
@ -144,7 +144,10 @@ public:
|
||||
int iBufFilter; // 1 = linear, 2 = nearest
|
||||
bool bPartialStretch;
|
||||
bool bStretchToDisplay;
|
||||
bool bSmallDisplay; // Useful on large tablets with touch controls to not overlap the image. Temporary setting - will be replaced by more comprehensive display size settings.
|
||||
int iSmallDisplayZoom; // Used to fit display into screen 0 = auto, anything higher is used to set's integer zoom of psp resolution and allows manual editing
|
||||
float fSmallDisplayOffsetX; // Along with Y it goes from 0.0 to 1.0, XY (0.5, 0.5) = center of the screen
|
||||
float fSmallDisplayOffsetY;
|
||||
float fSmallDisplayCustomZoom; //This is actually used for zoom, both in and out.
|
||||
bool bImmersiveMode; // Mode on Android Kitkat 4.4 that hides the back button etc.
|
||||
bool bVSync;
|
||||
int iFrameSkip;
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "GPU/GPUState.h"
|
||||
#include "UI/OnScreenDisplay.h" // Gross dependency!
|
||||
|
||||
void CenterRect(float *x, float *y, float *w, float *h, float origW, float origH, float frameW, float frameH, int rotation) {
|
||||
void CenterDisplayOutputRect(float *x, float *y, float *w, float *h, float origW, float origH, float frameW, float frameH, int rotation, bool invertY) {
|
||||
float outW;
|
||||
float outH;
|
||||
|
||||
@ -40,16 +40,50 @@ void CenterRect(float *x, float *y, float *w, float *h, float origW, float origH
|
||||
outW = frameW;
|
||||
outH = frameH;
|
||||
} else {
|
||||
// Add special case for 1080p displays, cutting off the bottom and top 1-pixel rows from the original 480x272.
|
||||
// This will be what 99.9% of users want.
|
||||
if (origW == 480 && origH == 272 && frameW == 1920 && frameH == 1080 && !rotated) {
|
||||
*x = 0;
|
||||
*y = -4;
|
||||
*w = 1920;
|
||||
*h = 1088;
|
||||
return;
|
||||
bool fullScreenZoom = true;
|
||||
#ifndef MOBILE_DEVICE
|
||||
fullScreenZoom = g_Config.bFullScreen;
|
||||
#endif
|
||||
if (fullScreenZoom) {
|
||||
if (g_Config.iSmallDisplayZoom != 0) {
|
||||
float offsetX = (g_Config.fSmallDisplayOffsetX - 0.5f) * 2.0f * frameW;
|
||||
float offsetY = (g_Config.fSmallDisplayOffsetY - 0.5f) * 2.0f * frameH;
|
||||
// Have to invert Y coordinates for software rendering as well as non buffered mode for GL
|
||||
#if defined(USING_WIN_UI)
|
||||
if (g_Config.bSoftwareRendering || (g_Config.iRenderingMode == FB_NON_BUFFERED_MODE && g_Config.iGPUBackend == GPU_BACKEND_OPENGL && !invertY)) { offsetY = offsetY * -1.0f; }
|
||||
#else
|
||||
if (g_Config.bSoftwareRendering || (g_Config.iRenderingMode == FB_NON_BUFFERED_MODE && !invertY)) { offsetY = offsetY * -1.0f; }
|
||||
#endif
|
||||
float customZoom = g_Config.fSmallDisplayCustomZoom / 8.0f;
|
||||
float smallDisplayW = origW * customZoom;
|
||||
float smallDisplayH = origH * customZoom;
|
||||
if (!rotated) {
|
||||
*x = ((frameW - smallDisplayW) / 2.0f) + offsetX;
|
||||
*y = ((frameH - smallDisplayH) / 2.0f) + offsetY;
|
||||
*w = smallDisplayW;
|
||||
*h = smallDisplayH;
|
||||
return;
|
||||
} else {
|
||||
*x = ((frameW - smallDisplayH) / 2.0f) + offsetX;
|
||||
*y = ((frameH - smallDisplayW) / 2.0f) + offsetY;
|
||||
*w = smallDisplayH;
|
||||
*h = smallDisplayW;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
float pixelCrop = frameH / 270.0f;
|
||||
float resCommonWidescreen = pixelCrop - floor(pixelCrop);
|
||||
if (!rotated && resCommonWidescreen == 0.0f) {
|
||||
*x = 0;
|
||||
*y = -pixelCrop;
|
||||
*w = frameW;
|
||||
*h = pixelCrop * 272.0f;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float origRatio = !rotated ? origW / origH : origH / origW;
|
||||
float frameRatio = frameW / frameH;
|
||||
|
||||
@ -67,11 +101,6 @@ void CenterRect(float *x, float *y, float *w, float *h, float origW, float origH
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Config.bSmallDisplay) {
|
||||
outW /= 2.0f;
|
||||
outH /= 2.0f;
|
||||
}
|
||||
|
||||
*x = (frameW - outW) / 2.0f;
|
||||
*y = (frameH - outH) / 2.0f;
|
||||
*w = outW;
|
||||
|
@ -284,4 +284,4 @@ protected:
|
||||
};
|
||||
};
|
||||
|
||||
void CenterRect(float *x, float *y, float *w, float *h, float origW, float origH, float frameW, float frameH, int rotation);
|
||||
void CenterDisplayOutputRect(float *x, float *y, float *w, float *h, float origW, float origH, float frameW, float frameH, int rotation, bool invertY);
|
||||
|
@ -185,8 +185,12 @@ namespace DX9 {
|
||||
void FramebufferManagerDX9::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) {
|
||||
if (useBufferedRendering_ && vfb->fbo) {
|
||||
fbo_bind_as_render_target(vfb->fbo);
|
||||
dxstate.viewport.set(0, 0, vfb->renderWidth, vfb->renderHeight);
|
||||
} else {
|
||||
float x, y, w, h;
|
||||
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, false, false);
|
||||
dxstate.viewport.set(x, y, w, h);
|
||||
}
|
||||
dxstate.viewport.set(0, 0, vfb->renderWidth, vfb->renderHeight);
|
||||
MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height);
|
||||
DisableState();
|
||||
DrawActiveTexture(drawPixelsTex_, dstX, dstY, width, height, vfb->bufferWidth, vfb->bufferHeight, false, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
@ -203,7 +207,7 @@ namespace DX9 {
|
||||
// (it always runs at output resolution so FXAA may look odd).
|
||||
float x, y, w, h;
|
||||
int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL;
|
||||
CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, uvRotation);
|
||||
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, uvRotation, false);
|
||||
DrawActiveTexture(drawPixelsTex_, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, false, 0.0f, 0.0f, 480.0f / 512.0f, uvRotation);
|
||||
}
|
||||
|
||||
@ -764,7 +768,7 @@ namespace DX9 {
|
||||
// Output coordinates
|
||||
float x, y, w, h;
|
||||
int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL;
|
||||
CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, uvRotation);
|
||||
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, uvRotation, false);
|
||||
|
||||
const float u0 = offsetX / (float)vfb->bufferWidth;
|
||||
const float v0 = offsetY / (float)vfb->bufferHeight;
|
||||
|
@ -649,7 +649,7 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) {
|
||||
} else {
|
||||
float pixelW = PSP_CoreParameter().pixelWidth;
|
||||
float pixelH = PSP_CoreParameter().pixelHeight;
|
||||
CenterRect(&renderX, &renderY, &renderWidth, &renderHeight, 480, 272, pixelW, pixelH, ROTATION_LOCKED_HORIZONTAL);
|
||||
CenterDisplayOutputRect(&renderX, &renderY, &renderWidth, &renderHeight, 480, 272, pixelW, pixelH, ROTATION_LOCKED_HORIZONTAL, false);
|
||||
renderWidthFactor = renderWidth / 480.0f;
|
||||
renderHeightFactor = renderHeight / 272.0f;
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ void FramebufferManager::UpdatePostShaderUniforms(int renderWidth, int renderHei
|
||||
float v_pixel_delta = v_delta;
|
||||
if (postShaderAtOutputResolution_) {
|
||||
float x, y, w, h;
|
||||
CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL);
|
||||
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL, false);
|
||||
u_pixel_delta = 1.0f / w;
|
||||
v_pixel_delta = 1.0f / h;
|
||||
}
|
||||
@ -395,7 +395,7 @@ void FramebufferManager::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY,
|
||||
glViewport(0, 0, vfb->renderWidth, vfb->renderHeight);
|
||||
} else {
|
||||
float x, y, w, h;
|
||||
CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, false);
|
||||
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, false, false);
|
||||
glViewport(x, y, w, h);
|
||||
}
|
||||
MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height);
|
||||
@ -418,7 +418,7 @@ void FramebufferManager::DrawFramebuffer(const u8 *srcPixels, GEBufferFormat src
|
||||
// (it always runs at output resolution so FXAA may look odd).
|
||||
float x, y, w, h;
|
||||
int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL;
|
||||
CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation);
|
||||
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation, true);
|
||||
if (applyPostShader) {
|
||||
glsl_bind(postShaderProgram_);
|
||||
UpdatePostShaderUniforms(renderWidth_, renderHeight_);
|
||||
@ -1049,7 +1049,7 @@ void FramebufferManager::CopyDisplayToOutput() {
|
||||
|
||||
// Output coordinates
|
||||
float x, y, w, h;
|
||||
CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation);
|
||||
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation, false);
|
||||
|
||||
// TODO ES3: Use glInvalidateFramebuffer to discard depth/stencil data at the end of frame.
|
||||
|
||||
|
@ -740,7 +740,7 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
|
||||
} else {
|
||||
float pixelW = PSP_CoreParameter().pixelWidth;
|
||||
float pixelH = PSP_CoreParameter().pixelHeight;
|
||||
CenterRect(&displayOffsetX, &displayOffsetY, &renderWidth, &renderHeight, 480, 272, pixelW, pixelH, ROTATION_LOCKED_HORIZONTAL);
|
||||
CenterDisplayOutputRect(&displayOffsetX, &displayOffsetY, &renderWidth, &renderHeight, 480, 272, pixelW, pixelH, ROTATION_LOCKED_HORIZONTAL, false);
|
||||
renderWidthFactor = renderWidth / 480.0f;
|
||||
renderHeightFactor = renderHeight / 272.0f;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "GPU/Software/SoftGpu.h"
|
||||
#include "GPU/Software/TransformUnit.h"
|
||||
#include "GPU/Software/Rasterizer.h"
|
||||
#include "GPU/Common/FramebufferCommon.h"
|
||||
|
||||
static GLuint temp_texture = 0;
|
||||
|
||||
@ -48,9 +49,6 @@ FormatBuffer fb;
|
||||
FormatBuffer depthbuf;
|
||||
u32 clut[4096];
|
||||
|
||||
// TODO: This one lives in GPU/GLES/Framebuffer.cpp, move it to somewhere common.
|
||||
void CenterRect(float *x, float *y, float *w, float *h,
|
||||
float origW, float origH, float frameW, float frameH, int rotation);
|
||||
|
||||
GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShader)
|
||||
{
|
||||
@ -247,7 +245,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight)
|
||||
glUseProgram(program);
|
||||
|
||||
float x, y, w, h;
|
||||
CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, dstwidth, dstheight, ROTATION_LOCKED_HORIZONTAL);
|
||||
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, dstwidth, dstheight, ROTATION_LOCKED_HORIZONTAL, false);
|
||||
|
||||
x /= 0.5f * dstwidth;
|
||||
y /= 0.5f * dstheight;
|
||||
|
54
UI/DisplayLayoutEditor.cpp
Normal file
54
UI/DisplayLayoutEditor.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "DisplayLayoutEditor.h"
|
||||
#include "ui/ui_context.h"
|
||||
#include "ui_atlas.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
void MultiTouchDisplay::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
|
||||
const AtlasImage &image = dc.Draw()->GetAtlas()->images[img_];
|
||||
w = image.w * scale_;
|
||||
h = image.h * scale_;
|
||||
}
|
||||
|
||||
void MultiTouchDisplay::Touch(const TouchInput &input) {
|
||||
if ((input.flags & TOUCH_DOWN) && bounds_.Contains(input.x, input.y)) {
|
||||
pointerDownMask_ |= 1 << input.id;
|
||||
}
|
||||
if (input.flags & TOUCH_MOVE) {
|
||||
if (bounds_.Contains(input.x, input.y))
|
||||
pointerDownMask_ |= 1 << input.id;
|
||||
else
|
||||
pointerDownMask_ &= ~(1 << input.id);
|
||||
}
|
||||
if (input.flags & TOUCH_UP) {
|
||||
pointerDownMask_ &= ~(1 << input.id);
|
||||
}
|
||||
if (input.flags & TOUCH_RELEASE_ALL) {
|
||||
pointerDownMask_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MultiTouchDisplay::Draw(UIContext &dc) {
|
||||
float opacity = 0.5f;
|
||||
float scale = scale_;
|
||||
uint32_t color = colorAlpha(0xFFFFFF, opacity);
|
||||
dc.Draw()->DrawImageRotated(img_, bounds_.centerX(), bounds_.centerY(), scale, angle_ * (M_PI * 2 / 360.0f), color, flipImageH_);
|
||||
}
|
51
UI/DisplayLayoutEditor.h
Normal file
51
UI/DisplayLayoutEditor.h
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
#include "gfx_es2/draw_buffer.h"
|
||||
#include "ui/view.h"
|
||||
#include "ui/viewgroup.h"
|
||||
|
||||
class MultiTouchDisplay : public UI::View {
|
||||
public:
|
||||
MultiTouchDisplay(int img, float scale, UI::LayoutParams *layoutParams)
|
||||
: UI::View(layoutParams), pointerDownMask_(0), scale_(scale), img_(img), angle_(0.0f), flipImageH_(false) {
|
||||
}
|
||||
virtual void Touch(const TouchInput &input) override;
|
||||
virtual void Draw(UIContext &dc) override;
|
||||
virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
|
||||
// chainable
|
||||
MultiTouchDisplay *FlipImageH(bool flip) { flipImageH_ = flip; return this; }
|
||||
MultiTouchDisplay *SetAngle(float angle) { angle_ = angle; return this; }
|
||||
|
||||
protected:
|
||||
uint32_t pointerDownMask_;
|
||||
float scale_;
|
||||
|
||||
private:
|
||||
int img_;
|
||||
float angle_;
|
||||
bool flipImageH_;
|
||||
};
|
||||
|
||||
class PSPDisplay : public MultiTouchDisplay {
|
||||
public:
|
||||
PSPDisplay(int img, float scale, UI::LayoutParams *layoutParams)
|
||||
: MultiTouchDisplay(img, scale, layoutParams) {
|
||||
}
|
||||
};
|
||||
|
227
UI/DisplayLayoutScreen.cpp
Normal file
227
UI/DisplayLayoutScreen.cpp
Normal file
@ -0,0 +1,227 @@
|
||||
// Copyright (c) 2013- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/colorutil.h"
|
||||
#include "gfx_es2/draw_buffer.h"
|
||||
#include "i18n/i18n.h"
|
||||
#include "ui/ui_context.h"
|
||||
#include "ui_atlas.h"
|
||||
|
||||
#include "DisplayLayoutScreen.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/System.h"
|
||||
#include "DisplayLayoutEditor.h"
|
||||
|
||||
static const int leftColumnWidth = 200;
|
||||
|
||||
// Ugly hackery, need to rework some stuff to get around this
|
||||
static float local_dp_xres;
|
||||
static float local_dp_yres;
|
||||
|
||||
class DragDropDisplay : public MultiTouchDisplay {
|
||||
public:
|
||||
DragDropDisplay(float &x, float &y, int img, float &scale)
|
||||
: MultiTouchDisplay(img, scale, new UI::AnchorLayoutParams(x*local_dp_xres, y*local_dp_yres, UI::NONE, UI::NONE, true)),
|
||||
x_(x), y_(y), theScale_(scale) {
|
||||
scale_ = theScale_;
|
||||
}
|
||||
|
||||
virtual void SaveDisplayPosition() {
|
||||
x_ = bounds_.centerX() / local_dp_xres;
|
||||
y_ = bounds_.centerY() / local_dp_yres;
|
||||
scale_ = theScale_;
|
||||
}
|
||||
|
||||
virtual float GetScale() const { return theScale_; }
|
||||
virtual void SetScale(float s) { theScale_ = s; scale_ = s; }
|
||||
|
||||
private:
|
||||
|
||||
float &x_, &y_;
|
||||
float &theScale_;
|
||||
};
|
||||
|
||||
DisplayLayoutScreen::DisplayLayoutScreen() {
|
||||
picked_ = 0;
|
||||
};
|
||||
|
||||
|
||||
bool DisplayLayoutScreen::touch(const TouchInput &touch) {
|
||||
UIScreen::touch(touch);
|
||||
|
||||
using namespace UI;
|
||||
|
||||
int mode = mode_->GetSelection();
|
||||
if (g_Config.iSmallDisplayZoom == 0) { mode = -1; }
|
||||
|
||||
const Bounds &screen_bounds = screenManager()->getUIContext()->GetBounds();
|
||||
|
||||
if ((touch.flags & TOUCH_MOVE) && picked_ != 0) {
|
||||
if (mode == 0) {
|
||||
const Bounds &bounds = picked_->GetBounds();
|
||||
|
||||
int mintouchX = screen_bounds.w / 4;
|
||||
int maxTouchX = screen_bounds.w - screen_bounds.w / 4;
|
||||
|
||||
int minTouchY = screen_bounds.h / 4;
|
||||
int maxTouchY = screen_bounds.h - screen_bounds.h / 4;
|
||||
|
||||
int newX = bounds.centerX(), newY = bounds.centerY();
|
||||
// we have to handle x and y separately since even if x is blocked, y may not be.
|
||||
if (touch.x > mintouchX && touch.x < maxTouchX) {
|
||||
// if the leftmost point of the control is ahead of the margin,
|
||||
// move it. Otherwise, don't.
|
||||
newX = touch.x;
|
||||
}
|
||||
if (touch.y > minTouchY && touch.y < maxTouchY) {
|
||||
newY = touch.y;
|
||||
}
|
||||
picked_->ReplaceLayoutParams(new UI::AnchorLayoutParams(newX, newY, NONE, NONE, true));
|
||||
}
|
||||
else if (mode == 1) {
|
||||
// Resize. Vertical = scaling, horizontal = spacing;
|
||||
// Up should be bigger so let's negate in that direction
|
||||
float diffX = (touch.x - startX_);
|
||||
float diffY = -(touch.y - startY_);
|
||||
|
||||
float movementScale = 0.5f;
|
||||
float newScale = startScale_ + diffY * movementScale;
|
||||
if (newScale > 100.0f) newScale = 100.0f;
|
||||
if (newScale < 1.0f) newScale = 1.0f;
|
||||
picked_->SetScale(newScale);
|
||||
}
|
||||
}
|
||||
if ((touch.flags & TOUCH_DOWN) && picked_ == 0) {
|
||||
picked_ = displayRepresentation_;
|
||||
if (picked_) {
|
||||
startX_ = touch.x;
|
||||
startY_ = touch.y;
|
||||
startScale_ = picked_->GetScale();
|
||||
}
|
||||
}
|
||||
if ((touch.flags & TOUCH_UP) && picked_ != 0) {
|
||||
const Bounds &bounds = picked_->GetBounds();
|
||||
float saveX_ = touch.x;
|
||||
float saveY_ = touch.y;
|
||||
startScale_ = picked_->GetScale();
|
||||
picked_->SaveDisplayPosition();
|
||||
picked_ = 0;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
void DisplayLayoutScreen::onFinish(DialogResult reason) {
|
||||
g_Config.Save();
|
||||
}
|
||||
|
||||
UI::EventReturn DisplayLayoutScreen::OnCenter(UI::EventParams &e) {
|
||||
g_Config.fSmallDisplayOffsetX = 0.5f;
|
||||
g_Config.fSmallDisplayOffsetY = 0.5f;
|
||||
RecreateViews();
|
||||
return UI::EVENT_DONE;
|
||||
};
|
||||
|
||||
UI::EventReturn DisplayLayoutScreen::OnZoomChange(UI::EventParams &e) {
|
||||
if (g_Config.iSmallDisplayZoom > 0) {
|
||||
g_Config.fSmallDisplayCustomZoom = (float)(g_Config.iSmallDisplayZoom * 8);
|
||||
} else {
|
||||
const Bounds &bounds = screenManager()->getUIContext()->GetBounds();
|
||||
float autoBound = bounds.w / 480.0f * 8.0f;
|
||||
g_Config.fSmallDisplayCustomZoom = autoBound;
|
||||
g_Config.fSmallDisplayOffsetX = 0.5f;
|
||||
g_Config.fSmallDisplayOffsetY = 0.5f;
|
||||
}
|
||||
RecreateViews();
|
||||
return UI::EVENT_DONE;
|
||||
};
|
||||
|
||||
|
||||
void DisplayLayoutScreen::dialogFinished(const Screen *dialog, DialogResult result) {
|
||||
RecreateViews();
|
||||
}
|
||||
|
||||
void DisplayLayoutScreen::CreateViews() {
|
||||
if (g_Config.bStretchToDisplay) {
|
||||
// Shouldn't even be able to get here as the way into this dialog should be closed.
|
||||
return;
|
||||
}
|
||||
const Bounds &bounds = screenManager()->getUIContext()->GetBounds();
|
||||
|
||||
local_dp_xres = bounds.w;
|
||||
local_dp_yres = bounds.h;
|
||||
|
||||
using namespace UI;
|
||||
|
||||
I18NCategory *gr = GetI18NCategory("Graphics");
|
||||
|
||||
root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));
|
||||
|
||||
// Just visual boundaries of the screen, should be easier to use than imagination
|
||||
float verticalBoundaryPositionL = local_dp_xres / 4.0f;
|
||||
float verticalBoundaryPositionR = local_dp_xres - verticalBoundaryPositionL;
|
||||
float horizontalBoundaryPositionL = local_dp_yres / 4.0f;
|
||||
float horizontalBoundaryPositionR = local_dp_yres - horizontalBoundaryPositionL;
|
||||
TabHolder *verticalBoundaryL = new TabHolder(ORIENT_VERTICAL, verticalBoundaryPositionL, new AnchorLayoutParams(0, 0, 0, 0, false));
|
||||
TabHolder *verticalBoundaryR = new TabHolder(ORIENT_VERTICAL, verticalBoundaryPositionR, new AnchorLayoutParams(0, 0, 0, 0, false));
|
||||
TabHolder *horizontalBoundaryL = new TabHolder(ORIENT_VERTICAL, verticalBoundaryPositionL * 2.0f, new AnchorLayoutParams(verticalBoundaryPositionL * 2.0f, horizontalBoundaryPositionL - 31.0f, 0, 0, true));
|
||||
TabHolder *horizontalBoundaryR = new TabHolder(ORIENT_VERTICAL, verticalBoundaryPositionL * 2.0f, new AnchorLayoutParams(verticalBoundaryPositionL * 2.0f, horizontalBoundaryPositionR + 31.0f, 0, 0, true));
|
||||
AnchorLayout *topBoundary = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));
|
||||
AnchorLayout *bottomBoundary = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));
|
||||
root_->Add(verticalBoundaryL);
|
||||
root_->Add(verticalBoundaryR);
|
||||
root_->Add(horizontalBoundaryL);
|
||||
root_->Add(horizontalBoundaryR);
|
||||
horizontalBoundaryL->AddTab("", topBoundary);
|
||||
horizontalBoundaryR->AddTab("", bottomBoundary);
|
||||
|
||||
Choice *back = new Choice(gr->T("Back"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 10));
|
||||
static const char *zoomLevels[] = { "Auto", "1x", "2x", "3x", "4x", "5x", "6x", "7x", "8x", "9x", "10x" };
|
||||
zoom_ = new PopupMultiChoice(&g_Config.iSmallDisplayZoom, gr->T("Zoom settings"), zoomLevels, 0, ARRAY_SIZE(zoomLevels), gr->GetName(), screenManager(), new AnchorLayoutParams(300, WRAP_CONTENT, verticalBoundaryPositionL * 2 - 150, NONE, NONE, 10));
|
||||
zoom_->OnChoice.Handle(this, &DisplayLayoutScreen::OnZoomChange);
|
||||
|
||||
|
||||
|
||||
mode_ = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 158 + 64 + 10));
|
||||
if (g_Config.iSmallDisplayZoom == 0) {
|
||||
mode_->AddChoice(gr->T("Active (Auto)"));
|
||||
float autoBound = bounds.w / 480.0f * 8.0f;
|
||||
g_Config.fSmallDisplayCustomZoom = autoBound;
|
||||
g_Config.fSmallDisplayOffsetX = 0.5f;
|
||||
g_Config.fSmallDisplayOffsetY = 0.5f;
|
||||
} else {
|
||||
Choice *center = new Choice(gr->T("Center"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 84));
|
||||
center->OnClick.Handle(this, &DisplayLayoutScreen::OnCenter);
|
||||
root_->Add(center);
|
||||
mode_->AddChoice(gr->T("Move"));
|
||||
mode_->AddChoice(gr->T("Resize"));
|
||||
mode_->SetSelection(0);
|
||||
}
|
||||
|
||||
|
||||
back->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
root_->Add(mode_);
|
||||
root_->Add(zoom_);
|
||||
root_->Add(back);
|
||||
|
||||
displayRepresentation_ = new DragDropDisplay(g_Config.fSmallDisplayOffsetX, g_Config.fSmallDisplayOffsetY, I_PSP_DISPLAY, g_Config.fSmallDisplayCustomZoom);
|
||||
if (g_Config.iInternalScreenRotation == 2 || g_Config.iInternalScreenRotation == 4) {
|
||||
displayRepresentation_->SetAngle(90.0f);
|
||||
}
|
||||
root_->Add(displayRepresentation_);
|
||||
}
|
50
UI/DisplayLayoutScreen.h
Normal file
50
UI/DisplayLayoutScreen.h
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2013- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ui/view.h"
|
||||
#include "ui/viewgroup.h"
|
||||
#include "MiscScreens.h"
|
||||
#include <vector>
|
||||
|
||||
class DragDropDisplay;
|
||||
|
||||
class DisplayLayoutScreen : public UIDialogScreenWithBackground {
|
||||
public:
|
||||
DisplayLayoutScreen();
|
||||
|
||||
virtual void CreateViews() override;
|
||||
virtual bool touch(const TouchInput &touch) override;
|
||||
virtual void dialogFinished(const Screen *dialog, DialogResult result) override;
|
||||
virtual void onFinish(DialogResult reason) override;
|
||||
|
||||
protected:
|
||||
virtual UI::EventReturn OnCenter(UI::EventParams &e);
|
||||
virtual UI::EventReturn OnZoomChange(UI::EventParams &e);
|
||||
|
||||
private:
|
||||
DragDropDisplay *picked_;
|
||||
DragDropDisplay *displayRepresentation_;
|
||||
UI::ChoiceStrip *mode_;
|
||||
UI::PopupMultiChoice *zoom_;
|
||||
// Touch down state for drag to resize etc
|
||||
float startX_;
|
||||
float startY_;
|
||||
float startScale_;
|
||||
|
||||
};
|
@ -33,6 +33,7 @@
|
||||
#include "UI/MiscScreens.h"
|
||||
#include "UI/ControlMappingScreen.h"
|
||||
#include "UI/DevScreens.h"
|
||||
#include "UI/DisplayLayoutScreen.h"
|
||||
#include "UI/SavedataScreen.h"
|
||||
#include "UI/TouchControlLayoutScreen.h"
|
||||
#include "UI/TouchControlVisibilityScreen.h"
|
||||
@ -163,8 +164,12 @@ void GameSettingsScreen::CreateViews() {
|
||||
graphicsSettings->Add(new CheckBox(&g_Config.bFullScreen, gr->T("FullScreen")))->OnClick.Handle(this, &GameSettingsScreen::OnFullscreenChange);
|
||||
#endif
|
||||
graphicsSettings->Add(new CheckBox(&g_Config.bStretchToDisplay, gr->T("Stretch to Display")));
|
||||
// Small Display: To avoid overlapping touch controls on large tablets. Better control over this will be coming later.
|
||||
graphicsSettings->Add(new CheckBox(&g_Config.bSmallDisplay, gr->T("Small Display")));
|
||||
|
||||
// Display Layout Editor: To avoid overlapping touch controls on large tablets, meet geeky demands for integer zoom/unstretched image etc.
|
||||
displayEditor_ = graphicsSettings->Add(new Choice(gr->T("Display layout editor")));
|
||||
displayEditor_->OnClick.Handle(this, &GameSettingsScreen::OnDisplayLayoutEditor);
|
||||
displayEditor_->SetDisabledPtr(&g_Config.bStretchToDisplay);
|
||||
|
||||
if (pixel_xres < pixel_yres * 1.3) // Smaller than 4:3
|
||||
graphicsSettings->Add(new CheckBox(&g_Config.bPartialStretch, gr->T("Partial Vertical Stretch")));
|
||||
|
||||
@ -774,6 +779,11 @@ UI::EventReturn GameSettingsScreen::OnFullscreenChange(UI::EventParams &e) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn GameSettingsScreen::OnDisplayLayoutEditor(UI::EventParams &e) {
|
||||
screenManager()->push(new DisplayLayoutScreen());
|
||||
return UI::EVENT_DONE;
|
||||
};
|
||||
|
||||
UI::EventReturn GameSettingsScreen::OnResolutionChange(UI::EventParams &e) {
|
||||
if (gpu) {
|
||||
gpu->Resized();
|
||||
|
@ -49,6 +49,7 @@ private:
|
||||
UI::CheckBox *enableReportsCheckbox_;
|
||||
UI::Choice *layoutEditorChoice_;
|
||||
UI::Choice *postProcChoice_;
|
||||
UI::Choice *displayEditor_;
|
||||
UI::PopupMultiChoice *resolutionChoice_;
|
||||
UI::CheckBox *frameSkipAuto_;
|
||||
#ifdef _WIN32
|
||||
@ -80,6 +81,7 @@ private:
|
||||
UI::EventReturn OnChangeMacAddress(UI::EventParams &e);
|
||||
UI::EventReturn OnClearRecents(UI::EventParams &e);
|
||||
UI::EventReturn OnFullscreenChange(UI::EventParams &e);
|
||||
UI::EventReturn OnDisplayLayoutEditor(UI::EventParams &e);
|
||||
UI::EventReturn OnResolutionChange(UI::EventParams &e);
|
||||
UI::EventReturn OnHwScaleChange(UI::EventParams &e);
|
||||
UI::EventReturn OnShaderChange(UI::EventParams &e);
|
||||
|
@ -24,6 +24,8 @@
|
||||
<ClCompile Include="ControlMappingScreen.cpp" />
|
||||
<ClCompile Include="CwCheatScreen.cpp" />
|
||||
<ClCompile Include="DevScreens.cpp" />
|
||||
<ClCompile Include="DisplayLayoutEditor.cpp" />
|
||||
<ClCompile Include="DisplayLayoutScreen.cpp" />
|
||||
<ClCompile Include="EmuScreen.cpp" />
|
||||
<ClCompile Include="GameInfoCache.cpp" />
|
||||
<ClCompile Include="GamepadEmu.cpp" />
|
||||
@ -50,6 +52,8 @@
|
||||
<ClInclude Include="ComboKeyMappingScreen.h" />
|
||||
<ClInclude Include="ControlMappingScreen.h" />
|
||||
<ClInclude Include="DevScreens.h" />
|
||||
<ClInclude Include="DisplayLayoutEditor.h" />
|
||||
<ClInclude Include="DisplayLayoutScreen.h" />
|
||||
<ClInclude Include="EmuScreen.h" />
|
||||
<ClInclude Include="GameInfoCache.h" />
|
||||
<ClInclude Include="GamepadEmu.h" />
|
||||
|
@ -62,6 +62,10 @@
|
||||
<ClCompile Include="ComboKeyMappingScreen.cpp">
|
||||
<Filter>Screens</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DisplayLayoutScreen.cpp">
|
||||
<Filter>Screens</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DisplayLayoutEditor.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GameInfoCache.h" />
|
||||
@ -124,10 +128,14 @@
|
||||
<ClInclude Include="ComboKeyMappingScreen.h">
|
||||
<Filter>Screens</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DisplayLayoutScreen.h">
|
||||
<Filter>Screens</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DisplayLayoutEditor.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Screens">
|
||||
<UniqueIdentifier>{faee5dce-633b-4ba6-b19d-ea70ee3c1c38}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
@ -334,6 +334,8 @@ LOCAL_SRC_FILES := \
|
||||
$(SRC)/android/jni/native-audio-so.cpp \
|
||||
$(SRC)/UI/BackgroundAudio.cpp \
|
||||
$(SRC)/UI/DevScreens.cpp \
|
||||
$(SRC)/UI/DisplayLayoutEditor.cpp \
|
||||
$(SRC)/UI/DisplayLayoutScreen.cpp \
|
||||
$(SRC)/UI/EmuScreen.cpp \
|
||||
$(SRC)/UI/MainScreen.cpp \
|
||||
$(SRC)/UI/MiscScreens.cpp \
|
||||
|
Loading…
Reference in New Issue
Block a user