1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-04 10:03:36 +00:00

Implement screen aspect ratio support.

This commit is contained in:
Sergey Lipskiy 2014-10-02 10:42:18 +07:00
parent 2ca283cf0f
commit 768430a234
10 changed files with 93 additions and 31 deletions

View File

@ -13,6 +13,7 @@ struct Config
u32 fullscreenWidth, fullscreenHeight, windowedWidth, windowedHeight;
u32 fullscreenBits, fullscreenRefresh;
u32 multisampling, verticalSync;
u32 aspect; // 0: stretch ; 1: 4/3 ; 2: 16/9
} video;
struct

View File

@ -363,7 +363,7 @@ void FrameBufferList::renderBuffer(u32 _address)
}
// glDisable(GL_SCISSOR_TEST) does not affect glBlitFramebuffer, at least on AMD
glScissor(0, 0, ogl.getWidth(), ogl.getHeight());
glScissor(0, 0, ogl.getScreenWidth(), ogl.getScreenHeight());
glDisable(GL_SCISSOR_TEST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
@ -371,9 +371,11 @@ void FrameBufferList::renderBuffer(u32 _address)
float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
ogl.getRender().clearColorBuffer(clearColor);
const float scaleY = ogl.getScaleY();
const float hOffset = (ogl.getScreenWidth() - ogl.getWidth()) / 2.0f;
const float vOffset = (ogl.getScreenHeight() - ogl.getHeight()) / 2.0f;
glBlitFramebuffer(
0, (GLint)(srcY0*scaleY), ogl.getWidth(), (GLint)(srcY1*scaleY),
0, ogl.getHeightOffset() + (GLint)(dstY0*scaleY), ogl.getWidth(), ogl.getHeightOffset() + (GLint)(dstY1*scaleY),
hOffset, vOffset + ogl.getHeightOffset() + (GLint)(dstY0*scaleY), hOffset + ogl.getWidth(), vOffset + ogl.getHeightOffset() + (GLint)(dstY1*scaleY),
GL_COLOR_BUFFER_BIT, GL_LINEAR
);
@ -388,7 +390,7 @@ void FrameBufferList::renderBuffer(u32 _address)
glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO);
glBlitFramebuffer(
0, (GLint)(srcY0*scaleY), ogl.getWidth(), (GLint)(srcY1*scaleY),
0, ogl.getHeightOffset() + (GLint)(dstY0*scaleY), ogl.getWidth(), ogl.getHeightOffset() + (GLint)(dstY1*scaleY),
hOffset, vOffset + ogl.getHeightOffset() + (GLint)(dstY0*scaleY), hOffset + ogl.getWidth(), vOffset + ogl.getHeightOffset() + (GLint)(dstY1*scaleY),
GL_COLOR_BUFFER_BIT, GL_LINEAR
);
}

View File

@ -173,6 +173,49 @@ void OGLVideo::updateScale()
m_scaleY = m_height / (float)VI.height;
}
void OGLVideo::_setBufferSize()
{
if (m_bFullscreen && config.frameBufferEmulation.enable) {
switch (config.video.aspect) {
case 0: // stretch
m_width = m_screenWidth;
m_height = m_screenHeight;
break;
case 1: // force 4/3
if (m_screenWidth * 3 / 4 > m_screenHeight) {
m_height = m_screenHeight;
m_width = m_screenHeight * 4 / 3;
} else if (m_screenHeight * 4 / 3 > m_screenWidth) {
m_width = m_screenWidth;
m_height = m_screenWidth * 3 / 4;
} else {
m_width = m_screenWidth;
m_height = m_screenHeight;
}
break;
case 2: // force 16/9
if (m_screenWidth * 9 / 16 > m_screenHeight) {
m_height = m_screenHeight;
m_width = m_screenHeight * 16 / 9;
} else if (m_screenHeight * 16 / 9 > m_screenWidth) {
m_width = m_screenWidth;
m_height = m_screenWidth * 9 / 16;
} else {
m_width = m_screenWidth;
m_height = m_screenHeight;
}
break;
default:
assert(false && "Unknown aspect ratio");
m_width = m_screenWidth;
m_height = m_screenHeight;
}
} else {
m_width = m_screenWidth;
m_height = m_screenHeight;
}
}
void OGLVideo::readScreen(void **_pDest, long *_pWidth, long *_pHeight )
{
*_pWidth = m_width;
@ -635,7 +678,7 @@ void OGLRender::drawRect(int _ulx, int _uly, int _lrx, int _lry, float *_pColor)
FrameBuffer* pBuffer = fbList.getCurrent();
OGLVideo & ogl = video();
if (!fbList.isFboMode())
glViewport( 0, ogl.getHeightOffset(), ogl.getWidth(), ogl.getHeight());
glViewport( 0, ogl.getHeightOffset(), ogl.getScreenWidth(), ogl.getScreenHeight());
else {
glViewport( 0, 0, pBuffer->m_width*pBuffer->m_scaleX, pBuffer->m_height*pBuffer->m_scaleY );
}
@ -693,7 +736,7 @@ void OGLRender::drawTexturedRect(float _ulx, float _uly, float _lrx, float _lry,
FrameBuffer* pBuffer = fbList.getCurrent();
OGLVideo & ogl = video();
if (!fbList.isFboMode())
glViewport( 0, ogl.getHeightOffset(), ogl.getWidth(), ogl.getHeight());
glViewport( 0, ogl.getHeightOffset(), ogl.getScreenWidth(), ogl.getScreenHeight());
else
glViewport( 0, 0, pBuffer->m_width*pBuffer->m_scaleX, pBuffer->m_height*pBuffer->m_scaleY );
glDisable( GL_CULL_FACE );
@ -871,7 +914,7 @@ void OGLRender::_initStates()
glPolygonOffset( -3.0f, -3.0f );
OGLVideo & ogl = video();
glViewport( 0, ogl.getHeightOffset(), ogl.getWidth(), ogl.getHeight());
glViewport( 0, ogl.getHeightOffset(), ogl.getScreenWidth(), ogl.getScreenHeight());
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT );

View File

@ -131,6 +131,8 @@ public:
f32 getScaleY() const {return m_scaleY;}
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;}
@ -141,16 +143,21 @@ public:
protected:
OGLVideo() :
m_bCaptureScreen(false), m_bToggleFullscreen(false), m_bResizeWindow(false), m_bFullscreen(false),
m_width(0), m_height(0), m_heightOffset(0), m_resizeWidth(0), m_resizeHeight(0),
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)
{}
void _setBufferSize();
bool m_bCaptureScreen;
bool m_bToggleFullscreen;
bool m_bResizeWindow;
bool m_bFullscreen;
u32 m_width, m_height, m_heightOffset, m_resizeWidth, m_resizeHeight;
u32 m_width, m_height, m_heightOffset;
u32 m_screenWidth, m_screenHeight;
u32 m_resizeWidth, m_resizeHeight;
f32 m_scaleX, m_scaleY;
const char * m_strScreenDirectory;

View File

@ -41,6 +41,8 @@ bool Config_SetDefault()
res = ConfigSetDefaultInt(g_configVideoGliden64, "MultiSampling", 0, "Enable/Disable MultiSampling (0=off, 2,4,8,16=quality)");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "AspectRatio", 0, "Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9)");
assert(res == M64ERR_SUCCESS);
//#Texture Settings
res = ConfigSetDefaultBool(g_configVideoGliden64, "ForceBilinear", 0, "Force bilinear texture filter");
@ -85,6 +87,7 @@ void Config_LoadConfig()
config.video.verticalSync = ConfigGetParamBool(g_configVideoGeneral, "VerticalSync");
config.video.multisampling = ConfigGetParamInt(g_configVideoGliden64, "MultiSampling");
config.video.aspect = ConfigGetParamInt(g_configVideoGliden64, "AspectRatio");
//#Texture Settings
config.texture.forceBilinear = ConfigGetParamBool(g_configVideoGliden64, "ForceBilinear");

View File

@ -61,13 +61,14 @@ bool OGLVideoMupenPlus::_start()
_setAttributes();
m_bFullscreen = config.video.fullscreen > 0;
m_width = config.video.windowedWidth;
m_height = config.video.windowedHeight;
m_screenWidth = config.video.windowedWidth;
m_screenHeight = config.video.windowedHeight;
_setBufferSize();
printf("(II) Setting video mode %dx%d...\n", m_width, m_height);
printf("(II) Setting video mode %dx%d...\n", m_screenWidth, m_screenHeight);
const m64p_video_flags flags = M64VIDEOFLAG_SUPPORT_RESIZING;
if (CoreVideo_SetVideoMode(m_width, m_height, 0, m_bFullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED, flags) != M64ERR_SUCCESS) {
printf("(EE) Error setting videomode %dx%d\n", m_width, m_height);
if (CoreVideo_SetVideoMode(m_screenWidth, m_screenHeight, 0, m_bFullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED, flags) != M64ERR_SUCCESS) {
printf("(EE) Error setting videomode %dx%d\n", m_screenWidth, m_screenHeight);
CoreVideo_Quit();
return false;
}
@ -105,12 +106,12 @@ bool OGLVideoMupenPlus::_resizeWindow()
_setAttributes();
m_bFullscreen = false;
m_width = m_resizeWidth;
m_height = m_resizeHeight;
if (CoreVideo_ResizeWindow(m_width, m_height) != M64ERR_SUCCESS) {
printf("(EE) Error setting videomode %dx%d\n", m_width, m_height);
m_width = config.video.windowedWidth;
m_height = config.video.windowedHeight;
m_width = m_screenWidth = m_resizeWidth;
m_height = m_screenHeight = m_resizeHeight;
if (CoreVideo_ResizeWindow(m_screenWidth, m_screenHeight) != M64ERR_SUCCESS) {
printf("(EE) Error setting videomode %dx%d\n", m_screenWidth, m_screenHeight);
m_width = m_screenWidth = config.video.windowedWidth;
m_height = m_screenHeight = config.video.windowedHeight;
CoreVideo_Quit();
return false;
}

View File

@ -468,6 +468,7 @@ void Config_LoadConfig()
fclose( f );
config.video.aspect = 1;
// manually set frame bufer emulation options
config.frameBufferEmulation.copyToRDRAM = FALSE;
config.frameBufferEmulation.copyFromRDRAM = FALSE;

View File

@ -38,12 +38,13 @@ bool OGLVideoPosix::_start()
Uint32 videoFlags = 0;
if (m_bFullscreen) {
m_width = config.video.fullscreenWidth;
m_height = config.video.fullscreenHeight;
m_screenWidth = config.video.fullscreenWidth;
m_screenHeight = config.video.fullscreenHeight;
} else {
m_width = config.video.windowedWidth;
m_height = config.video.windowedHeight;
m_screenWidth = config.video.windowedWidth;
m_screenHeight = config.video.windowedHeight;
}
_setBufferSize();
/* Initialize SDL */
printf( "[glN64]: (II) Initializing SDL video subsystem...\n" );
@ -80,10 +81,10 @@ bool OGLVideoPosix::_start()
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );*/
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); // 32 bit z-buffer
printf( "[glN64]: (II) Setting video mode %dx%d...\n", m_width, m_height );
if (!(hScreen = SDL_SetVideoMode(m_width, m_height, 0, videoFlags)))
printf("[glN64]: (II) Setting video mode %dx%d...\n", m_screenWidth, m_screenHeight);
if (!(hScreen = SDL_SetVideoMode(m_screenWidth, m_screenHeight, 0, videoFlags)))
{
printf( "[glN64]: (EE) Error setting videomode %dx%d: %s\n", m_width, m_height, SDL_GetError() );
printf("[glN64]: (EE) Error setting videomode %dx%d: %s\n", m_screenWidth, m_screenHeight, SDL_GetError());
SDL_QuitSubSystem( SDL_INIT_VIDEO );
return false;
}

View File

@ -113,6 +113,7 @@ void Config_LoadConfig()
config.enableHWLighting = FALSE;
}
config.video.aspect = 1;
// manually set frame bufer emulation options
config.frameBufferEmulation.copyToRDRAM = FALSE;
config.frameBufferEmulation.copyFromRDRAM = FALSE;

View File

@ -233,14 +233,16 @@ bool OGLVideoWindows::_resizeWindow()
RECT windowRect, statusRect, toolRect;
if (m_bFullscreen) {
m_width = config.video.fullscreenWidth;
m_height = config.video.fullscreenHeight;
m_screenWidth = config.video.fullscreenWidth;
m_screenHeight = config.video.fullscreenHeight;
m_heightOffset = 0;
_setBufferSize();
return (SetWindowPos( hWnd, NULL, 0, 0, m_width, m_height, SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW ) == TRUE);
return (SetWindowPos(hWnd, NULL, 0, 0, m_screenWidth, m_screenHeight, SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW) == TRUE);
} else {
m_width = config.video.windowedWidth;
m_height = config.video.windowedHeight;
m_screenWidth = m_width = config.video.windowedWidth;
m_screenHeight = config.video.windowedHeight;
_setBufferSize();
GetClientRect( hWnd, &windowRect );
GetWindowRect( hStatusBar, &statusRect );