From 1b8740165c2d8f5793f8de4be13be17ddcc693bf Mon Sep 17 00:00:00 2001 From: Bart Trzynadlowski Date: Fri, 10 Feb 2012 19:53:51 +0000 Subject: [PATCH] Added a wide screen hack that can be enabled with the -'wide-screen' argument or WideScreen in the config file. --- Src/Graphics/Render2D.cpp | 87 +++++++++++++++++++++++++++------------ Src/Graphics/Render2D.h | 18 ++++---- Src/Graphics/Render3D.cpp | 49 +++++++++++++++++----- Src/Graphics/Render3D.h | 15 ++++--- Src/OSD/SDL/Main.cpp | 52 +++++++++++++++-------- Src/OSD/SDL/OSDConfig.h | 2 + 6 files changed, 155 insertions(+), 68 deletions(-) diff --git a/Src/Graphics/Render2D.cpp b/Src/Graphics/Render2D.cpp index a276614..f6d9647 100644 --- a/Src/Graphics/Render2D.cpp +++ b/Src/Graphics/Render2D.cpp @@ -22,15 +22,35 @@ /* * Render2D.cpp * + * To-Do List + * ---------- + * - Fix color offsets: they should probably be applied to layers A/A' and B/B' + * rather than to the top and bottom surfaces (an artifact left over from + * when layer priorities were fixed as B/B' -> bottom, A/A' -> top). This can + * no longer be performed by the shaders, unfortunately, because of arbitrary + * layer priorities. Rather, three palettes should be maintained: master (the + * actual palette data), A, and B. Color offset writes should recompute + * these and the tile renderer should use either A or B palette (depending on + * the layer being drawn). + * - Is there a better way to handle the overscan regions in wide screen mode + * than using palette entry 0 as the fill color? Is clearing two thin + * viewports better than one big clear? + * - Layer priorities in Spikeout attract mode might not be totally correct. + * - Are v-scroll values 9 or 10 bits? (Does it matter?) Lost World seems to + * have some scrolling issues. + * - A proper shut-down function is needed! OpenGL might not be available when + * the destructor for this class is called. + * * Implementation of the CRender2D class: OpenGL tile generator graphics. * * Tile Generator Hardware Overview * -------------------------------- * * Model 3's medium resolution tile generator hardware appears to be derived - * from the Model 2 and System 24 chipset. It consists of four 64x64 tile - * layers, comprised of 8x8 pixel tiles, with configurable priorities. There - * may be additional features but so far, no known Model 3 games use them. + * from the Model 2 and System 24 chipset, but is much simpler. It consists of + * four 64x64 tile layers, comprised of 8x8 pixel tiles, with configurable + * priorities. There may be additional features but so far, no known Model 3 + * games use them. * * VRAM is comprised of 1 MB for tile data and an additional 128 KB for the * palette. The four tilemap layers are referred to as: A (0), A' (1), B (2), @@ -65,8 +85,9 @@ * ???? ???? ???? ???? pqrs tuvw ???? ???? * * Bits 'pqrs' control the color depth of layers B', B, A', and A, - * respectively, and 'tuvw' form a 4-bit priority code. The other bits are - * unused or unknown. + * respectively. If set, the layer's pattern data is encoded as 4 bits, + * otherwise the pixels are 8 bits. Bits 'tuvw' form a 4-bit priority code. The + * other bits are unused or unknown. * * The remaining registers are described where appropriate further below. * @@ -257,17 +278,6 @@ * Where 'r', 'g', and 'b' appear to be signed 8-bit color offsets. Because * they exceed the color resolution of the palette, they must be scaled * appropriately. - * - * To-Do List - * ---------- - * - Fix color offsets: they should probably be applied to layers A/A' and B/B' - * rather than to the top and bottom surfaces (an artifact left over from - * when layer priorities were fixed as B/B' -> bottom, A/A' -> top). This can - * no longer be performed by the shaders, unfortunately, because of arbitrary - * layer priorities. - * - Are v-scroll values 9 or 10 bits? - * - A proper shut-down function is needed! OpenGL might not be available when - * the destructor for this class is called. */ #include @@ -358,8 +368,7 @@ void CRender2D::DrawTileLine8BitNoClip(UINT32 *buf, UINT16 tile, int tileLine) * scrolling is applied here. * * Parametes: - * dest Destination of 512-pixel wide output buffer to draw - * to. + * dest Destination of 512-pixel output buffer to draw to. * layerNum Layer number: * 0 = Layer A (@ 0xF8000) * 1 = Layer A' (@ 0xFA000) @@ -571,6 +580,13 @@ void CRender2D::DrawTilemaps(UINT32 *destBottom, UINT32 *destTop) MixLine(destTop, lineBuffer[0], 0, y, false); MixLine(destTop, lineBuffer[1], 1, y, false); break; + case 0x9: // ? all layers on top but relative order unknown (Spikeout Final Edition, after first boss) + memset(destBottom, 0, 496*sizeof(UINT32)); //TODO: use glClear(GL_COLOR_BUFFER_BIT) if there is no bottom layer + MixLine(destTop, lineBuffer[2], 2, y, true); + MixLine(destTop, lineBuffer[3], 3, y, false); + MixLine(destTop, lineBuffer[1], 1, y, false); + MixLine(destTop, lineBuffer[0], 0, y, false); + break; case 0xF: // all on top memset(destBottom, 0, 496*sizeof(UINT32)); //TODO: use glClear(GL_COLOR_BUFFER_BIT) if there is no bottom layer MixLine(destTop, lineBuffer[2], 2, y, true); @@ -606,6 +622,29 @@ void CRender2D::DrawTilemaps(UINT32 *destBottom, UINT32 *destTop) // Draws a surface to the screen (0 is top and 1 is bottom) void CRender2D::DisplaySurface(int surface, GLfloat z) { + // If bottom surface and wide screen, clear overscan areas + if (surface && g_Config.wideScreen) + { + UINT32 c = pal[0]; // just use palette color 0 for now (not the best solution, it's usually black) + GLfloat r = (GLfloat)(c&0xFF) / 255.0f; + GLfloat g = (GLfloat)((c>>8)&0xFF) / 255.0f; + GLfloat b = (GLfloat)((c>>16)&0xFF) / 255.0f; + glClearColor(r, g, b, 0.0); + glViewport(0, 0, xOffs, totalYPixels); + glClear(GL_COLOR_BUFFER_BIT); + glViewport(xOffs+xPixels, 0, totalXPixels, totalYPixels); + glClear(GL_COLOR_BUFFER_BIT); + } + + // Set up the viewport and orthogonal projection + glViewport(xOffs, yOffs, xPixels, yPixels); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0.0, 1.0, 1.0, 0.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // Draw the surface glBindTexture(GL_TEXTURE_2D, texID[surface]); glBegin(GL_QUADS); glTexCoord2f(0.0f/512.0f, 0.0f); glVertex3f(0.0f, 0.0f, z); @@ -618,14 +657,6 @@ void CRender2D::DisplaySurface(int surface, GLfloat z) // Set up viewport and OpenGL state for 2D rendering (sets up blending function but disables blending) void CRender2D::Setup2D(void) { - // Set up the viewport and orthogonal projection - glViewport(xOffs, yOffs, xPixels, yPixels); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, 1.0, 1.0, 0.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - // Enable texture mapping and blending glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); @@ -731,7 +762,7 @@ void CRender2D::AttachVRAM(const UINT8 *vramPtr) #define OFFSET_BOTTOM_SURFACE (512*384*4) // 512*384*4 #define OFFSET_LINE_BUFFERS (2*512*384*4) // 4*512*4 (4 lines) -bool CRender2D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes) +bool CRender2D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, unsigned totalXRes, unsigned totalYRes) { float memSizeMB = (float)MEMORY_POOL_SIZE/(float)0x100000; @@ -762,6 +793,8 @@ bool CRender2D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yPixels = yRes; xOffs = xOffset; yOffs = yOffset; + totalXPixels = totalXRes; + totalYPixels = totalYRes; // Create textures glPixelStorei(GL_UNPACK_ALIGNMENT, 1); diff --git a/Src/Graphics/Render2D.h b/Src/Graphics/Render2D.h index 287511a..496cf81 100644 --- a/Src/Graphics/Render2D.h +++ b/Src/Graphics/Render2D.h @@ -102,23 +102,26 @@ public: void AttachVRAM(const UINT8 *vramPtr); /* - * Init(xOffset, yOffset, xRes, yRes); + * Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes); * * One-time initialization of the context. Must be called before any other * members (meaning it should be called even before being attached to any * other objects that want to use it). * * Parameters: - * xOffset X offset within OpenGL display surface in pixels. + * xOffset X offset of the viewable area within OpenGL display + * surface, in pixels. * yOffset Y offset. - * xRes Horizontal resolution of display surface in pixels. + * xRes Horizontal resolution of the viewable area. * yRes Vertical resolution. + * totalXRes Horizontal resolution of the complete display area. + * totalYRes Vertical resolution. * * Returns: * OKAY is successful, otherwise FAILED if a non-recoverable error * occurred. Prints own error messages. */ - bool Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes); + bool Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, unsigned totalXRes, unsigned totalYRes); /* * CRender2D(void): @@ -150,9 +153,10 @@ private: const UINT32 *regs; // OpenGL data - GLuint texID[2]; // IDs for the 2 layer textures (top and bottom) - unsigned xPixels, yPixels; // display surface resolution - unsigned xOffs, yOffs; // offset + GLuint texID[2]; // IDs for the 2 layer textures (top and bottom) + unsigned xPixels, yPixels; // display surface resolution + unsigned xOffs, yOffs; // offset + unsigned totalXPixels, totalYPixels; // totay display surface resolution // Shader programs and input data locations GLuint shaderProgram; // shader program object diff --git a/Src/Graphics/Render3D.cpp b/Src/Graphics/Render3D.cpp index 31c2b6d..26f5fb5 100644 --- a/Src/Graphics/Render3D.cpp +++ b/Src/Graphics/Render3D.cpp @@ -210,7 +210,20 @@ void CRender3D::DecodeTexture(int format, int x, int y, int width, int height) i = 0; switch (format) { - default: + default: // Unknown + + for (yi = y; yi < (y+height); yi++) + { + for (xi = x; xi < (x+width); xi++) + { + textureBuffer[i++] = 0.0; // R + textureBuffer[i++] = 0.0; // G + textureBuffer[i++] = 1.0f; // B + textureBuffer[i++] = 1.0f; // A + } + } + break; + case 0: // T1RGB5 for (yi = y; yi < (y+height); yi++) { @@ -236,7 +249,7 @@ void CRender3D::DecodeTexture(int format, int x, int y, int width, int height) } } break; - + case 5: // 8-bit grayscale for (yi = y; yi < (y+height); yi++) { @@ -261,7 +274,6 @@ void CRender3D::DecodeTexture(int format, int x, int y, int width, int height) } break; - case 4: // 8-bit, L4A4 @@ -826,15 +838,28 @@ void CRender3D::RenderViewport(UINT32 addr, int pri) // TO-DO: investigate clipping planes // Set up viewport and projection (TO-DO: near and far clipping) - viewportX = xOffs + (GLint) ((float)vpX*xRatio); - viewportY = yOffs + (GLint) ((float)(384-(vpY+vpHeight))*yRatio); - viewportWidth = (GLint) ((float)vpWidth*xRatio); - viewportHeight = (GLint) ((float)vpHeight*yRatio); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective(fovYDegrees,(GLfloat)vpWidth/(GLfloat)vpHeight,0.1f,1e5); - - // Lighting (note that sun vector points toward sun -- away from vertex) + if (g_Config.wideScreen && (vpX==0) && (vpY==0) && (vpWidth>=495) && (vpHeight >= 383)) + { + // Wide screen hack only modifies X axis and not the Y FOV + viewportX = 0; + viewportY = yOffs + (GLint) ((float)(384-(vpY+vpHeight))*yRatio); + viewportWidth = totalXRes; + viewportHeight = (GLint) ((float)vpHeight*yRatio); + gluPerspective(fovYDegrees,(GLfloat)viewportWidth/(GLfloat)viewportHeight,0.1f,1e5); // use actual full screen ratio to get proper X FOV + //printf("viewportX=%d, viewportY=%d, viewportWidth=%d, viewportHeight=%d\tvpY=%d vpHeight=%d\n", viewportX, viewportY, viewportWidth, viewportHeight, vpY,vpHeight); + } + else + { + viewportX = xOffs + (GLint) ((float)vpX*xRatio); + viewportY = yOffs + (GLint) ((float)(384-(vpY+vpHeight))*yRatio); + viewportWidth = (GLint) ((float)vpWidth*xRatio); + viewportHeight = (GLint) ((float)vpHeight*yRatio); + gluPerspective(fovYDegrees,(GLfloat)vpWidth/(GLfloat)vpHeight,0.1f,1e5); // use Model 3 viewport ratio + } + + // Lighting (note that sun vector points toward sun -- away from vertex) lightingParams[0] = *(float *) &vpnode[0x05]; // sun X lightingParams[1] = *(float *) &vpnode[0x06]; // sun Y lightingParams[2] = *(float *) &vpnode[0x04]; // sun Z @@ -1034,7 +1059,7 @@ void CRender3D::SetStep(int stepID) DebugLog("Render3D set to Step %d.%d\n", (step>>4)&0xF, step&0xF); } -bool CRender3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes) +bool CRender3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, unsigned totalXResParam, unsigned totalYResParam) { // Allocate memory for texture buffer textureBuffer = new(std::nothrow) GLfloat[512*512*4]; @@ -1074,6 +1099,8 @@ bool CRender3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRatio = (GLfloat) yRes / 384.0f; xOffs = xOffset; yOffs = yOffset; + totalXRes = totalXResParam; + totalYRes = totalYResParam; // Load shaders const char *vsFile = g_Config.vertexShaderFile.size() ? g_Config.vertexShaderFile.c_str() : NULL; diff --git a/Src/Graphics/Render3D.h b/Src/Graphics/Render3D.h index 155acfe..6a691eb 100644 --- a/Src/Graphics/Render3D.h +++ b/Src/Graphics/Render3D.h @@ -263,7 +263,7 @@ public: void SetStep(int stepID); /* - * Init(xOffset, yOffset, xRes, yRes): + * Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes): * * One-time initialization of the context. Must be called before any other * members (meaning it should be called even before being attached to any @@ -272,18 +272,20 @@ public: * External shader files are loaded according to configuration settings. * * Parameters: - * xOffset X offset of display surface in pixels (in case resolution - * is smaller than the true display surface). + * xOffset X offset of the viewable area within OpenGL display + * surface, in pixels. * yOffset Y offset. - * xRes Horizontal resolution of display surface in pixels. + * xRes Horizontal resolution of the viewable area. * yRes Vertical resolution. + * totalXRes Horizontal resolution of the complete display area. + * totalYRes Vertical resolution. * * Returns: * OKAY is successful, otherwise FAILED if a non-recoverable error * occurred. Any allocated memory will not be freed until the * destructor is called. Prints own error messages. */ - bool Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes); + bool Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, unsigned totalXRes, unsigned totalYRes); /* * CRender3D(void): @@ -375,9 +377,10 @@ private: GLfloat texOffsetXY[2]; // decoded X, Y offsets UINT16 texOffset; // raw texture offset data as it appears in culling node - // Resolution scaling factors (to support resolutions higher than 496x384) and offsets + // Resolution and scaling factors (to support resolutions higher than 496x384) and offsets GLfloat xRatio, yRatio; unsigned xOffs, yOffs; + unsigned totalXRes, totalYRes; // Texture ID for complete 2048x2048 texture map GLuint texID; diff --git a/Src/OSD/SDL/Main.cpp b/Src/OSD/SDL/Main.cpp index de06f7c..e237201 100644 --- a/Src/OSD/SDL/Main.cpp +++ b/Src/OSD/SDL/Main.cpp @@ -119,8 +119,9 @@ bool ErrorLog(const char *fmt, ...) * (and computed offsets within the viewport) that will be rendered based on * what was obtained from SDL. */ -unsigned xOffset, yOffset; // offset of renderer output within OpenGL viewport -unsigned xRes, yRes; // renderer output resolution (can be smaller than GL viewport) +unsigned xOffset, yOffset; // offset of renderer output within OpenGL viewport +unsigned xRes, yRes; // renderer output resolution (can be smaller than GL viewport) +unsigned totalXRes, totalYRes; // total resolution (the whole GL viewport) /* * CreateGLScreen(): @@ -128,10 +129,13 @@ unsigned xRes, yRes; // renderer output resolution (can be smaller than GL vi * Creates an OpenGL display surface of the requested size. xOffset and yOffset * are used to return a display surface offset (for OpenGL viewport commands) * because the actual drawing area may need to be adjusted to preserve the - * Model 3 aspect ratio. The new resolution will be passed back as well. + * Model 3 aspect ratio. The new resolution will be passed back as well -- both + * the adjusted viewable area resolution and the total resolution. + * + * NOTE: keepAspectRatio should always be true. It has not yet been tested with + * the wide screen hack. */ -static bool CreateGLScreen(const char *caption, unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *xResPtr, unsigned *yResPtr, - bool keepAspectRatio, bool fullScreen) +static bool CreateGLScreen(const char *caption, unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *xResPtr, unsigned *yResPtr, unsigned *totalXResPtr, unsigned *totalYResPtr, bool keepAspectRatio, bool fullScreen) { const SDL_VideoInfo *VideoInfo; GLenum err; @@ -158,6 +162,8 @@ static bool CreateGLScreen(const char *caption, unsigned *xOffsetPtr, unsigned * // What resolution did we actually get? VideoInfo = SDL_GetVideoInfo(); + *totalXResPtr = VideoInfo->current_w; + *totalYResPtr = VideoInfo->current_h; // If required, fix the aspect ratio of the resolution that the user passed to match Model 3 ratio xRes = (float) *xResPtr; @@ -207,7 +213,7 @@ static bool CreateGLScreen(const char *caption, unsigned *xOffsetPtr, unsigned * gluPerspective(90.0,(GLfloat)xRes/(GLfloat)yRes,0.1,1e5); glMatrixMode(GL_MODELVIEW); - // Clear the screen to ensure black border + // Clear both buffers to ensure a black border for (int i = 0; i < 2; i++) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); @@ -219,10 +225,13 @@ static bool CreateGLScreen(const char *caption, unsigned *xOffsetPtr, unsigned * *yResPtr = (unsigned) yRes; // Scissor box (to clip visible area) - if (VideoInfo->current_w > *xResPtr || VideoInfo->current_h > *yResPtr) + if (!g_Config.wideScreen) { - glEnable(GL_SCISSOR_TEST); - glScissor(*xOffsetPtr, *yOffsetPtr, *xResPtr, *yResPtr); + if (VideoInfo->current_w > *xResPtr || VideoInfo->current_h > *yResPtr) + { + glEnable(GL_SCISSOR_TEST); + glScissor(*xOffsetPtr, *yOffsetPtr, *xResPtr, *yResPtr); + } } return 0; @@ -239,11 +248,11 @@ static void PrintGLInfo(bool createScreen, bool infoLog, bool printExtensions) const GLubyte *str; char *strLocal; GLint value; - unsigned xOffset, yOffset, xRes=496, yRes=384; + unsigned xOffset, yOffset, xRes=496, yRes=384, totalXRes, totalYRes; if (createScreen) { - if (OKAY != CreateGLScreen("Supermodel - Querying OpenGL Information...",&xOffset,&yOffset,&xRes,&yRes,false,false)) + if (OKAY != CreateGLScreen("Supermodel - Querying OpenGL Information...",&xOffset,&yOffset,&xRes,&yRes,&totalXRes,&totalYRes,false,false)) { ErrorLog("Unable to query OpenGL.\n"); return; @@ -339,7 +348,7 @@ static bool ConfigureInputs(CInputs *Inputs, bool configure) { // Open an SDL window unsigned xOffset, yOffset, xRes=496, yRes=384; - if (OKAY != CreateGLScreen("Supermodel - Configuring Inputs...",&xOffset,&yOffset,&xRes,&yRes,false,false)) + if (OKAY != CreateGLScreen("Supermodel - Configuring Inputs...",&xOffset,&yOffset,&xRes,&yRes,&totalXRes,&totalYRes,false,false)) return (bool) ErrorLog("Unable to start SDL to configure inputs.\n"); // Configure the inputs @@ -404,6 +413,8 @@ static void ApplySettings(CINIFile *INI, const char *section) INI->Get(section, "YResolution", g_Config.yRes); if (OKAY == INI->Get(section, "FullScreen", x)) g_Config.fullScreen = x ? true : false; + if (OKAY == INI->Get(section, "WideScreen", x)) + g_Config.wideScreen = x ? true : false; if (OKAY == INI->Get(section, "Throttle", x)) g_Config.throttle = x ? true : false; if (OKAY == INI->Get(section, "ShowFrameRate", x)) @@ -449,6 +460,7 @@ static void LogConfig(void) InfoLog("\tXResolution = %d", g_Config.xRes); InfoLog("\tYResolution = %d", g_Config.yRes); InfoLog("\tFullScreen = %d", g_Config.fullScreen); + InfoLog("\tWideScreen = %d", g_Config.wideScreen); InfoLog("\tThrottle = %d", g_Config.throttle); InfoLog("\tShowFrameRate = %d", g_Config.showFPS); #ifdef SUPERMODEL_DEBUGGER @@ -745,10 +757,10 @@ int Supermodel(const char *zipFile, CInputs *Inputs, CINIFile *CmdLine) LoadNVRAM(Model3); // Start up SDL and open a GL window - xRes = g_Config.xRes; - yRes = g_Config.yRes; + totalXRes = xRes = g_Config.xRes; + totalYRes = yRes = g_Config.yRes; sprintf(baseTitleStr, "Supermodel - %s", Model3->GetGameInfo()->title); - if (OKAY != CreateGLScreen(baseTitleStr,&xOffset,&yOffset,&xRes,&yRes,true,g_Config.fullScreen)) + if (OKAY != CreateGLScreen(baseTitleStr,&xOffset,&yOffset,&xRes,&yRes,&totalXRes,&totalYRes,true,g_Config.fullScreen)) return 1; // Info log GL information and user options @@ -769,9 +781,9 @@ int Supermodel(const char *zipFile, CInputs *Inputs, CINIFile *CmdLine) Model3->AttachInputs(Inputs); // Initialize the renderer - if (OKAY != Render2D->Init(xOffset, yOffset, xRes, yRes)) + if (OKAY != Render2D->Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes)) goto QuitError; - if (OKAY != Render3D->Init(xOffset, yOffset, xRes, yRes)) + if (OKAY != Render3D->Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes)) goto QuitError; Model3->AttachRenderers(Render2D,Render3D); @@ -1226,6 +1238,7 @@ static void Help(void) puts("Video Options:"); puts(" -res=, Resolution"); puts(" -fullscreen Full screen mode"); + puts(" -wide-screen Expand 3D field of view to screen width"); puts(" -no-throttle Disable 60 Hz frame rate lock"); puts(" -show-fps Display frame rate in window title bar"); puts(" -vert-shader= Load 3D vertex shader from external file"); @@ -1423,6 +1436,11 @@ int main(int argc, char **argv) n = 1; CmdLine.Set("Global", "FullScreen", n); } + else if (!strcmp(argv[i],"-wide-screen")) + { + n = 1; + CmdLine.Set("Global", "WideScreen", n); + } else if (!strcmp(argv[i],"-no-throttle")) { n = 0; diff --git a/Src/OSD/SDL/OSDConfig.h b/Src/OSD/SDL/OSDConfig.h index 7b959bd..1d5fe87 100644 --- a/Src/OSD/SDL/OSDConfig.h +++ b/Src/OSD/SDL/OSDConfig.h @@ -45,6 +45,7 @@ class COSDConfig public: unsigned xRes, yRes; // X and Y resolution, in pixels bool fullScreen; // Full screen mode (if true) + bool wideScreen; // Wide screen hack bool throttle; // 60 Hz frame limiting bool showFPS; // Show frame rate bool flipStereo; // Flip stereo channels @@ -107,6 +108,7 @@ public: xRes = 496; yRes = 384; fullScreen = false; + wideScreen = false; throttle = true; showFPS = false; flipStereo = false;