1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Implement "widescreen hack".

This commit is contained in:
Sergey Lipskiy 2015-03-25 20:18:34 +06:00
parent c9d486222b
commit 2525b86f49
3 changed files with 93 additions and 23 deletions

View File

@ -193,6 +193,7 @@ void OGLVideo::updateScale()
void OGLVideo::_setBufferSize()
{
m_bAdjustScreen = false;
if (config.frameBufferEmulation.enable) {
switch (config.frameBufferEmulation.aspect) {
case Config::aStretch: // stretch
@ -223,7 +224,16 @@ void OGLVideo::_setBufferSize()
m_height = m_screenHeight;
}
break;
default:
case Config::aAdjust: // adjust
m_width = m_screenWidth;
m_height = m_screenHeight;
if (m_screenWidth * 3 / 4 > m_screenHeight) {
f32 width43 = m_screenHeight * 4.0f / 3.0f;
m_adjustScale = width43 / m_screenWidth;
m_bAdjustScreen = true;
}
break;
default:
assert(false && "Unknown aspect ratio");
m_width = m_screenWidth;
m_height = m_screenHeight;
@ -438,6 +448,14 @@ void OGLRender::_updateCullFace() const
glDisable( GL_CULL_FACE );
}
inline
float _adjustViewportX(f32 _X0)
{
const float halfX = gDP.colorImage.width / 2.0f;
const float halfVP = gSP.viewport.width / 2.0f;
return (_X0 + halfVP - halfX) * video().getAdjustScale() + halfX - halfVP;
}
void OGLRender::_updateViewport() const
{
OGLVideo & ogl = video();
@ -445,14 +463,20 @@ void OGLRender::_updateViewport() const
if (pCurrentBuffer == NULL) {
const f32 scaleX = ogl.getScaleX();
const f32 scaleY = ogl.getScaleY();
const GLint X = gSP.viewport.vscale[0] < 0 ? (GLint)((gSP.viewport.x + gSP.viewport.vscale[0] * 2.0f) * scaleX) : (GLint)(gSP.viewport.x * scaleX);
float Xf = gSP.viewport.vscale[0] < 0 ? (gSP.viewport.x + gSP.viewport.vscale[0] * 2.0f) : gSP.viewport.x;
if (ogl.isAdjustScreen() && gSP.viewport.width < gDP.colorImage.width && gDP.colorImage.width > VI.width * 98 / 100)
Xf = _adjustViewportX(Xf);
const GLint X = (GLint)(Xf * scaleX);
const GLint Y = gSP.viewport.vscale[1] < 0 ? (GLint)((gSP.viewport.y + gSP.viewport.vscale[1] * 2.0f) * scaleY) : (GLint)((VI.height - (gSP.viewport.y + gSP.viewport.height)) * scaleY);
glViewport( X, Y + ogl.getHeightOffset(),
glViewport(X, Y + ogl.getHeightOffset(),
max((GLint)(gSP.viewport.width * scaleX), 0), max((GLint)(gSP.viewport.height * scaleY), 0));
} else {
const f32 scaleX = pCurrentBuffer->m_scaleX;
const f32 scaleY = pCurrentBuffer->m_scaleY;
const GLint X = gSP.viewport.vscale[0] < 0 ? (GLint)((gSP.viewport.x + gSP.viewport.vscale[0] * 2.0f) * scaleX) : (GLint)(gSP.viewport.x * scaleX);
float Xf = gSP.viewport.vscale[0] < 0 ? (gSP.viewport.x + gSP.viewport.vscale[0] * 2.0f) : gSP.viewport.x;
if (ogl.isAdjustScreen() && gSP.viewport.width < gDP.colorImage.width && gDP.colorImage.width > VI.width * 98 / 100)
Xf = _adjustViewportX(Xf);
const GLint X = (GLint)(Xf * scaleX);
const GLint Y = gSP.viewport.vscale[1] < 0 ? (GLint)((gSP.viewport.y + gSP.viewport.vscale[1] * 2.0f) * scaleY) : (GLint)((pCurrentBuffer->m_height - (gSP.viewport.y + gSP.viewport.height)) * scaleY);
glViewport(X, Y,
max((GLint)(gSP.viewport.width * scaleX), 0), max((GLint)(gSP.viewport.height * scaleY), 0));
@ -460,6 +484,43 @@ void OGLRender::_updateViewport() const
gSP.changed &= ~CHANGED_VIEWPORT;
}
inline
void _adjustScissorX(f32 & _X0, f32 & _X1, float _scale)
{
const float halfX = gDP.colorImage.width / 2.0f;
_X0 = (_X0 - halfX) * _scale + halfX;
_X1 = (_X1 - halfX) * _scale + halfX;
}
void OGLRender::_updateScissor() const
{
OGLVideo & ogl = video();
f32 scaleX, scaleY;
u32 heightOffset, screenHeight;
FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent();
if (pCurrentBuffer == NULL) {
scaleX = ogl.getScaleX();
scaleY = ogl.getScaleY();
heightOffset = ogl.getHeightOffset();
screenHeight = VI.height;
}
else {
scaleX = pCurrentBuffer->m_scaleX;
scaleY = pCurrentBuffer->m_scaleY;
heightOffset = 0;
screenHeight = (pCurrentBuffer->m_height == 0) ? VI.height : pCurrentBuffer->m_height;
}
float SX0 = gDP.scissor.ulx;
float SX1 = gDP.scissor.lrx;
if (ogl.isAdjustScreen() && gSP.viewport.width < gDP.colorImage.width && gDP.colorImage.width > VI.width * 98 / 100)
_adjustScissorX(SX0, SX1, ogl.getAdjustScale());
glScissor((GLint)(SX0 * scaleX), (GLint)((screenHeight - gDP.scissor.lry) * scaleY + heightOffset),
max((GLint)((SX1 - SX0) * scaleX), 0), max((GLint)((gDP.scissor.lry - gDP.scissor.uly) * scaleY), 0));
gDP.changed &= ~CHANGED_SCISSOR;
}
void OGLRender::_updateDepthUpdate() const
{
if (gDP.otherMode.depthUpdate != 0)
@ -527,21 +588,8 @@ void OGLRender::_updateStates(RENDER_STATE _renderState) const
}
}
if (gDP.changed & CHANGED_SCISSOR) {
FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent();
if (pCurrentBuffer == NULL) {
const f32 scaleX = ogl.getScaleX();
const f32 scaleY = ogl.getScaleY();
glScissor((GLint)(gDP.scissor.ulx * scaleX), (GLint)((VI.height - gDP.scissor.lry) * scaleY) + ogl.getHeightOffset(),
max((GLint)((gDP.scissor.lrx - gDP.scissor.ulx) * scaleX), 0), max((GLint)((gDP.scissor.lry - gDP.scissor.uly) * scaleY), 0));
} else {
const f32 scaleX = pCurrentBuffer->m_scaleX;
const f32 scaleY = pCurrentBuffer->m_scaleY;
glScissor((GLint)(gDP.scissor.ulx * scaleX), (GLint)((pCurrentBuffer->m_height - gDP.scissor.lry) * scaleY),
max((GLint)((gDP.scissor.lrx - gDP.scissor.ulx) * scaleX), 0), max((GLint)((gDP.scissor.lry - gDP.scissor.uly) * scaleY), 0));
}
gDP.changed &= ~CHANGED_SCISSOR;
}
if (gDP.changed & CHANGED_SCISSOR)
_updateScissor();
if (gSP.changed & CHANGED_VIEWPORT)
_updateViewport();
@ -783,10 +831,17 @@ void OGLRender::drawRect(int _ulx, int _uly, int _lrx, int _lry, float *_pColor)
m_rect[3].z = Z;
m_rect[3].w = W;
if (ogl.isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100) && (_lrx - _ulx < VI.width * 9 / 10)) {
const float scale = ogl.getAdjustScale();
for (u32 i = 0; i < 4; ++i)
m_rect[i].x *= scale;
}
if (gDP.otherMode.cycleType == G_CYC_FILL)
glVertexAttrib4fv(SC_COLOR, _pColor);
else
glVertexAttrib4f(SC_COLOR, 0.0f, 0.0f, 0.0f, 0.0f);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
gSP.changed |= CHANGED_GEOMETRYMODE | CHANGED_VIEWPORT;
}
@ -1067,6 +1122,12 @@ void OGLRender::drawTexturedRect(const TexturedRectParams & _params)
m_rect[2].t1 = texST[1].t1;
}
if (ogl.isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100) && (_params.lrx - _params.ulx < VI.width * 9 / 10)) {
const float scale = ogl.getAdjustScale();
for (u32 i = 0; i < 4; ++i)
m_rect[i].x *= scale;
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
gSP.changed |= CHANGED_GEOMETRYMODE | CHANGED_VIEWPORT;
}

View File

@ -100,6 +100,7 @@ private:
void _setBlendMode() const;
void _updateCullFace() const;
void _updateViewport() const;
void _updateScissor() const;
void _updateDepthUpdate() const;
void _updateStates(RENDER_STATE _renderState) const;
void _prepareDrawTriangle(bool _dma);
@ -146,12 +147,14 @@ public:
void updateScale();
f32 getScaleX() const {return m_scaleX;}
f32 getScaleY() const {return m_scaleY;}
u32 getWidth() const {return m_width;}
f32 getAdjustScale() const {return m_adjustScale;}
u32 getWidth() const { return m_width; }
u32 getHeight() const {return m_height;}
u32 getScreenWidth() const {return m_screenWidth;}
u32 getScreenHeight() const {return m_screenHeight;}
u32 getHeightOffset() const {return m_heightOffset;}
bool isFullscreen() const {return m_bFullscreen;}
bool isAdjustScreen() const {return m_bAdjustScreen;}
OGLRender & getRender() {return m_render;}
@ -159,10 +162,10 @@ public:
protected:
OGLVideo() :
m_bCaptureScreen(false), m_bToggleFullscreen(false), m_bResizeWindow(false), m_bFullscreen(false),
m_bCaptureScreen(false), m_bToggleFullscreen(false), m_bResizeWindow(false), m_bFullscreen(false), m_bAdjustScreen(false),
m_width(0), m_height(0), m_heightOffset(0),
m_screenWidth(0), m_screenHeight(0), m_resizeWidth(0), m_resizeHeight(0),
m_scaleX(0), m_scaleY(0), m_strScreenDirectory(NULL)
m_scaleX(0), m_scaleY(0), m_adjustScale(0), m_strScreenDirectory(NULL)
{}
void _setBufferSize();
@ -171,11 +174,13 @@ protected:
bool m_bToggleFullscreen;
bool m_bResizeWindow;
bool m_bFullscreen;
bool m_bAdjustScreen;
u32 m_width, m_height, m_heightOffset;
u32 m_screenWidth, m_screenHeight;
u32 m_resizeWidth, m_resizeHeight;
f32 m_scaleX, m_scaleY;
f32 m_adjustScale;
const char * m_strScreenDirectory;

View File

@ -554,11 +554,15 @@ void gSPProcessVertex(u32 v)
if (gSP.changed & CHANGED_MATRIX)
gSPCombineMatrices();
OGLRender & render = video().getRender();
OGLVideo & ogl = video();
OGLRender & render = ogl.getRender();
SPVertex & vtx = render.getVertex(v);
float vPos[3] = {(float)vtx.x, (float)vtx.y, (float)vtx.z};
gSPTransformVertex( &vtx.x, gSP.matrix.combined );
if (ogl.isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100))
vtx.x *= ogl.getAdjustScale();
if (gSP.viewport.vscale[0] < 0)
vtx.x = -vtx.x;