From 1df7127609fab71b113233cb02bc82dbb5386380 Mon Sep 17 00:00:00 2001 From: pogokeen Date: Sat, 14 Jul 2018 21:36:44 +0000 Subject: [PATCH] Support software renderer upscaling engine-side in sdlayer and sdlayer12 with various scaling factors (beyond just pixel doubling). When glsurface is available, use GL to upscale the render buffer. Additionally, fix build issues with sdlayer12 introduced by GLAD changes (r6656). git-svn-id: https://svn.eduke32.com/eduke32@6939 1a8010ca-5511-0410-912e-c29ae57300e0 --- Common.mak | 2 + GNUmakefile | 1 + platform/Windows/eduke32.vcxproj | 2 + platform/Windows/eduke32.vcxproj.filters | 6 + platform/Windows/msvc.mak | 1 + source/build/include/build.h | 4 +- source/build/include/glsurface.h | 4 +- source/build/include/softsurface.h | 47 +++++ source/build/src/2d.cpp | 68 ++++---- source/build/src/baselayer.cpp | 4 +- source/build/src/build.cpp | 12 +- source/build/src/engine.cpp | 78 ++++++--- source/build/src/glsurface.cpp | 4 +- source/build/src/palette.cpp | 6 - source/build/src/polymer.cpp | 4 +- source/build/src/polymost.cpp | 6 +- source/build/src/sdlayer.cpp | 175 ++++--------------- source/build/src/sdlayer12.cpp | 61 +++---- source/build/src/softsurface.cpp | 207 +++++++++++++++++++++++ source/build/src/winlayer.cpp | 9 +- source/duke3d/src/game.cpp | 50 +----- source/duke3d/src/gamestructures.cpp | 4 +- source/duke3d/src/menus.cpp | 32 ++-- source/duke3d/src/osdcmds.cpp | 17 +- source/duke3d/src/premap.cpp | 18 +- source/duke3d/src/premap.h | 8 - source/duke3d/src/screens.cpp | 2 +- 27 files changed, 475 insertions(+), 357 deletions(-) create mode 100644 source/build/include/softsurface.h create mode 100644 source/build/src/softsurface.cpp diff --git a/Common.mak b/Common.mak index f101b27cc..e10a6eca8 100644 --- a/Common.mak +++ b/Common.mak @@ -940,6 +940,8 @@ ifeq ($(PLATFORM),WINDOWS) LIBS += -lmingwex -lgdi32 -lpthread ifeq ($(RENDERTYPE),WIN) LIBS += -ldxguid + else ifeq ($(SDL_TARGET),1) + LIBS += -ldxguid -lmingw32 -limm32 -lole32 -loleaut32 -lversion else LIBS += -ldxguid_sdl -lmingw32 -limm32 -lole32 -loleaut32 -lversion endif diff --git a/GNUmakefile b/GNUmakefile index c39c6d314..79c65e475 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -192,6 +192,7 @@ engine_objs := \ osd.cpp \ pragmas.cpp \ scriptfile.cpp \ + softsurface.cpp \ mmulti_null.cpp \ mutex.cpp \ xxhash.c \ diff --git a/platform/Windows/eduke32.vcxproj b/platform/Windows/eduke32.vcxproj index 8f164a390..d11d1c420 100644 --- a/platform/Windows/eduke32.vcxproj +++ b/platform/Windows/eduke32.vcxproj @@ -141,6 +141,7 @@ + @@ -300,6 +301,7 @@ + diff --git a/platform/Windows/eduke32.vcxproj.filters b/platform/Windows/eduke32.vcxproj.filters index 6b4645bc8..627bba27c 100644 --- a/platform/Windows/eduke32.vcxproj.filters +++ b/platform/Windows/eduke32.vcxproj.filters @@ -579,6 +579,9 @@ build\headers + + build\headers + @@ -1031,6 +1034,9 @@ build\source + + build\source + diff --git a/platform/Windows/msvc.mak b/platform/Windows/msvc.mak index 2b78ccc86..7f844a3aa 100644 --- a/platform/Windows/msvc.mak +++ b/platform/Windows/msvc.mak @@ -184,6 +184,7 @@ ENGINE_OBJS= \ $(ENGINE_OBJ)\winbits.$o \ $(ENGINE_OBJ)\xxhash.$o \ $(ENGINE_OBJ)\screenshot.$o \ + $(ENGINE_OBJ)\softsurface.$o \ $(ENGINE_OBJ)\mhk.$o \ $(ENGINE_OBJ)\pngwrite.$o \ $(ENGINE_OBJ)\miniz.$o \ diff --git a/source/build/include/build.h b/source/build/include/build.h index 9e9117172..1a587781d 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -663,7 +663,7 @@ EXTERN int16_t thewall[MAXWALLSB]; EXTERN uspritetype *tspriteptr[MAXSPRITESONSCREEN + 1]; EXTERN int32_t wx1, wy1, wx2, wy2; -EXTERN int32_t xdim, ydim, numpages; +EXTERN int32_t xdim, ydim, numpages, upscalefactor; EXTERN int32_t yxaspect, viewingrange; EXTERN intptr_t *ylookup; @@ -1055,7 +1055,7 @@ intptr_t tileCreate(int16_t tilenume, int32_t xsiz, int32_t ysiz); void tileCopySection(int32_t tilenume1, int32_t sx1, int32_t sy1, int32_t xsiz, int32_t ysiz, int32_t tilenume2, int32_t sx2, int32_t sy2); void squarerotatetile(int16_t tilenume); -int32_t videoSetGameMode(char davidoption, int32_t daxdim, int32_t daydim, int32_t dabpp); +int32_t videoSetGameMode(char davidoption, int32_t daupscaledxdim, int32_t daupscaledydim, int32_t dabpp, int32_t daupscalefactor); void videoNextPage(void); void videoSetCorrectedAspect(); void videoSetViewableArea(int32_t x1, int32_t y1, int32_t x2, int32_t y2); diff --git a/source/build/include/glsurface.h b/source/build/include/glsurface.h index 880fe9214..dea8bf564 100644 --- a/source/build/include/glsurface.h +++ b/source/build/include/glsurface.h @@ -1,5 +1,5 @@ /* - * glsurface.cpp + * glsurface.h * A 32-bit rendering surface that can quickly blit 8-bit paletted buffers implemented in OpenGL. * * Copyright © 2018, Alex Dawson. All rights reserved. @@ -15,7 +15,7 @@ // glsurface will still render at the full size of the screen. // If a surface already exists, glsurface_destroy() will be automatically called before re-initializing. // Returns whether or not the glsurface could be successfully initialized. -bool glsurface_initialize(vec2_t inputBufferResolution); +bool glsurface_initialize(vec2_t bufferResolution); // Destroy an existing surface. void glsurface_destroy(); diff --git a/source/build/include/softsurface.h b/source/build/include/softsurface.h new file mode 100644 index 000000000..1317e0266 --- /dev/null +++ b/source/build/include/softsurface.h @@ -0,0 +1,47 @@ +/* + * softsurface.h + * An 8-bit rendering surface that can quickly upscale and blit 8-bit paletted buffers to an external 32-bit screen buffer. + * + * Copyright © 2018, Alex Dawson. All rights reserved. + */ + +#ifndef SOFTSURFACE_H_ +#define SOFTSURFACE_H_ + +#include "compat.h" + +// Initialize the softsurface with the Software renderer's buffer resolution. +// If the Software renderer's resolution and the actual resolution don't match, +// softsurface will still render at the full size of the screen. +// If a surface already exists, softsurface_destroy() will be automatically called before re-initializing. +// Returns whether or not the softsurface could be successfully initialized. +bool softsurface_initialize(vec2_t bufferResolution, + vec2_t destBufferResolution); + +// Destroy an existing surface. +void softsurface_destroy(); + +// Sets the palette to contain the RGBA byte buffer pointed to by pPalette. +// destRedMask/destGreenMask/destBlueMask mask the bits that represent each colour component in the destination buffer's pixel format. +// If the surface is not initialized, the function returns immediately. +void softsurface_setPalette(void* pPalette, + uint32_t destRedMask, + uint32_t destGreenMask, + uint32_t destBlueMask); + +// Returns a pointer to the start of the surface's 8-bit pixel buffer +// Returns NULL if the surface is not initialized. +uint8_t* softsurface_getBuffer(); + +// Returns the resolution of the surface's buffer +vec2_t softsurface_getBufferResolution(); + +// Returns the resolution of the destination buffer +vec2_t softsurface_getDestinationBufferResolution(); + +// Blit the surface's pixel buffer to the destination buffer using the palette set with softsurface_setPalette(). +// If the surface is not initialized, the function returns immediately. +void softsurface_blitBuffer(uint32_t* destBuffer, + uint32_t destBpp); + +#endif /* SOFTSURFACE_H_ */ diff --git a/source/build/src/2d.cpp b/source/build/src/2d.cpp index 482d21755..f581714cc 100644 --- a/source/build/src/2d.cpp +++ b/source/build/src/2d.cpp @@ -110,10 +110,10 @@ static void drawlinegl(int32_t x1, int32_t y1, int32_t x2, int32_t y2, palette_t { // setpolymost2dview(); // JBF 20040205: more efficient setup - glViewport(0, 0, xres, yres); + glViewport(0, 0, xdim, ydim); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glOrtho(0, xres, yres, 0, -1, 1); + glOrtho(0, xdim, ydim, 0, -1, 1); if (videoGetRenderMode() == REND_POLYMER) { glMatrixMode(GL_MODELVIEW); @@ -274,7 +274,7 @@ int32_t editorDraw2dLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int col swaplong(&y1, &y2); } - if (x1 >= xres || x2 < 0) + if (x1 >= xdim || x2 < 0) return 0; if (x1 < 0) @@ -283,10 +283,10 @@ int32_t editorDraw2dLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int col x1 = 0; } - if (x2 >= xres) + if (x2 >= xdim) { - if (d.y) y2 += scale(xres-1-x2, d.y, d.x); - x2 = xres-1; + if (d.y) y2 += scale(xdim-1-x2, d.y, d.x); + x2 = xdim-1; } if ((d.x < 0 && d.y >= 0) || (d.y < 0 && d.x >= 0)) @@ -301,14 +301,14 @@ int32_t editorDraw2dLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int col if (y1 < 0) { if (d.x) - x1 = clamp(x1 + scale(0 - y1, d.x, d.y), 0, xres - 1); + x1 = clamp(x1 + scale(0 - y1, d.x, d.y), 0, xdim - 1); y1 = 0; } if (y2 >= ydim16) { if (d.x) - x2 = clamp(x2 + scale(ydim16-1-y2, d.x, d.y), 0, xres-1); + x2 = clamp(x2 + scale(ydim16-1-y2, d.x, d.y), 0, xdim-1); y2 = ydim16-1; } @@ -319,7 +319,7 @@ int32_t editorDraw2dLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int col } //if (ox1||ox2||oy1||oy2) - // if (x1<0||x1>=xres || y2<0||y2>=yres) + // if (x1<0||x1>=xdim || y2<0||y2>=ydim) // attach_here(); d.x = klabs(x2-x1)+1; @@ -450,9 +450,9 @@ void editorDraw2dCircle(int32_t x1, int32_t y1, int32_t r, int32_t eccen, char c } if (r < 0) r = -r; - if (x1+r < 0 || y1+r < 0 || x1-r >= xres || y1-r >= ydim16) return; + if (x1+r < 0 || y1+r < 0 || x1-r >= xdim || y1-r >= ydim16) return; - uint32_t const uxres = xres, uydim16 = ydim16; + uint32_t const uxdim = xdim, uydim16 = ydim16; /* * d @@ -473,13 +473,13 @@ void editorDraw2dCircle(int32_t x1, int32_t y1, int32_t r, int32_t eccen, char c if (drawlinepat == 0xffffffff || drawlinepat & pow2long[(++patc)&31]) { - if ((uint32_t) y1 < uydim16 && (uint32_t) (x1+r) < uxres) + if ((uint32_t) y1 < uydim16 && (uint32_t) (x1+r) < uxdim) drawpixel((char *) (p+r), col); // a - if ((uint32_t) x1 < uxres && (uint32_t) (y1+r) < uydim16) + if ((uint32_t) x1 < uxdim && (uint32_t) (y1+r) < uydim16) drawpixel((char *) (p+(r*bytesperline)), col); // b - if ((uint32_t) y1 < uydim16 && (uint32_t) (x1-r) < uxres) + if ((uint32_t) y1 < uydim16 && (uint32_t) (x1-r) < uxdim) drawpixel((char *) (p-r), col); // c - if ((uint32_t) x1 < uxres && (uint32_t) (y1-r) < uydim16) + if ((uint32_t) x1 < uxdim && (uint32_t) (y1-r) < uydim16) drawpixel((char *) (p-(r*bytesperline)), col); // d } @@ -510,21 +510,21 @@ void editorDraw2dCircle(int32_t x1, int32_t y1, int32_t r, int32_t eccen, char c if (drawlinepat & pow2long[(++patc) & 31]) { - if ((uint32_t) (x1 + yp) < uxres && (uint32_t) (y1 + xp) < uydim16) + if ((uint32_t) (x1 + yp) < uxdim && (uint32_t) (y1 + xp) < uydim16) drawpixel_safe((char *) (p + yp + xpbpl), col); // 1 - if ((uint32_t) (x1 + xp) < uxres && (uint32_t) (y1 + yp) < uydim16) + if ((uint32_t) (x1 + xp) < uxdim && (uint32_t) (y1 + yp) < uydim16) drawpixel_safe((char *) (p + xp + ypbpl), col); // 2 - if ((uint32_t) (x1 - xp) < uxres && (uint32_t) (y1 + yp) < uydim16) + if ((uint32_t) (x1 - xp) < uxdim && (uint32_t) (y1 + yp) < uydim16) drawpixel_safe((char *) (p - xp + ypbpl), col); // 3 - if ((uint32_t) (x1 - yp) < uxres && (uint32_t) (y1 + xp) < uydim16) + if ((uint32_t) (x1 - yp) < uxdim && (uint32_t) (y1 + xp) < uydim16) drawpixel_safe((char *) (p - yp + xpbpl), col); // 4 - if ((uint32_t) (x1 - yp) < uxres && (uint32_t) (y1 - xp) < uydim16) + if ((uint32_t) (x1 - yp) < uxdim && (uint32_t) (y1 - xp) < uydim16) drawpixel_safe((char *) (p - yp - xpbpl), col); // 5 - if ((uint32_t) (x1 - xp) < uxres && (uint32_t) (y1 - yp) < uydim16) + if ((uint32_t) (x1 - xp) < uxdim && (uint32_t) (y1 - yp) < uydim16) drawpixel_safe((char *) (p - xp - ypbpl), col); // 6 - if ((uint32_t) (x1 + xp) < uxres && (uint32_t) (y1 - yp) < uydim16) + if ((uint32_t) (x1 + xp) < uxdim && (uint32_t) (y1 - yp) < uydim16) drawpixel_safe((char *) (p + xp - ypbpl), col); // 7 - if ((uint32_t) (x1 + yp) < uxres && (uint32_t) (y1 - xp) < uydim16) + if ((uint32_t) (x1 + yp) < uxdim && (uint32_t) (y1 - xp) < uydim16) drawpixel_safe((char *) (p + yp - xpbpl), col); // 8 } } while (yp > xp); @@ -553,21 +553,21 @@ void editorDraw2dCircle(int32_t x1, int32_t y1, int32_t r, int32_t eccen, char c int32_t const ypbpl = yp*bytesperline; int32_t const xpbpl = xp*bytesperline; - if ((uint32_t) (x1 + yp) < uxres && (uint32_t) (y1 + xp) < uydim16) + if ((uint32_t) (x1 + yp) < uxdim && (uint32_t) (y1 + xp) < uydim16) drawpixel_safe((char *) (p + yp + xpbpl), col); // 1 - if ((uint32_t) (x1 + xp) < uxres && (uint32_t) (y1 + yp) < uydim16) + if ((uint32_t) (x1 + xp) < uxdim && (uint32_t) (y1 + yp) < uydim16) drawpixel_safe((char *) (p + xp + ypbpl), col); // 2 - if ((uint32_t) (x1 - xp) < uxres && (uint32_t) (y1 + yp) < uydim16) + if ((uint32_t) (x1 - xp) < uxdim && (uint32_t) (y1 + yp) < uydim16) drawpixel_safe((char *) (p - xp + ypbpl), col); // 3 - if ((uint32_t) (x1 - yp) < uxres && (uint32_t) (y1 + xp) < uydim16) + if ((uint32_t) (x1 - yp) < uxdim && (uint32_t) (y1 + xp) < uydim16) drawpixel_safe((char *) (p - yp + xpbpl), col); // 4 - if ((uint32_t) (x1 - yp) < uxres && (uint32_t) (y1 - xp) < uydim16) + if ((uint32_t) (x1 - yp) < uxdim && (uint32_t) (y1 - xp) < uydim16) drawpixel_safe((char *) (p - yp - xpbpl), col); // 5 - if ((uint32_t) (x1 - xp) < uxres && (uint32_t) (y1 - yp) < uydim16) + if ((uint32_t) (x1 - xp) < uxdim && (uint32_t) (y1 - yp) < uydim16) drawpixel_safe((char *) (p - xp - ypbpl), col); // 6 - if ((uint32_t) (x1 + xp) < uxres && (uint32_t) (y1 - yp) < uydim16) + if ((uint32_t) (x1 + xp) < uxdim && (uint32_t) (y1 - yp) < uydim16) drawpixel_safe((char *) (p + xp - ypbpl), col); // 7 - if ((uint32_t) (x1 + yp) < uxres && (uint32_t) (y1 - xp) < uydim16) + if ((uint32_t) (x1 + yp) < uxdim && (uint32_t) (y1 - xp) < uydim16) drawpixel_safe((char *) (p + yp - xpbpl), col); // 8 } while (yp > xp); @@ -579,7 +579,7 @@ void editorDraw2dCircle(int32_t x1, int32_t y1, int32_t r, int32_t eccen, char c // void clear2dscreen(void) { - int32_t const clearsz = (ydim16 <= yres - STATUS2DSIZ2) ? yres - STATUS2DSIZ2 : yres; + int32_t const clearsz = (ydim16 <= ydim - STATUS2DSIZ2) ? ydim - STATUS2DSIZ2 : ydim; videoBeginDrawing(); //{{{ Bmemset((char *) frameplace, 0, bytesperline*clearsz); videoEndDrawing(); //}}} @@ -1380,11 +1380,11 @@ void polymostSet2dView(void) #ifdef USE_OPENGL if (videoGetRenderMode() < REND_POLYMOST) return; - glViewport(0, 0, xres, yres); + glViewport(0, 0, xdim, ydim); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glOrtho(0, xres, yres, 0, -1, 1); + glOrtho(0, xdim, ydim, 0, -1, 1); if (videoGetRenderMode() == REND_POLYMER) { diff --git a/source/build/src/baselayer.cpp b/source/build/src/baselayer.cpp index bd03c829f..710e8ff1f 100644 --- a/source/build/src/baselayer.cpp +++ b/source/build/src/baselayer.cpp @@ -128,8 +128,8 @@ int32_t mouseReadAbs(vec2_t * const pResult, vec2_t const * const pInput) int32_t const xwidth = max(scale(240<<16, xdim, ydim), 320<<16); - pResult->x = scale(pInput->x, xwidth, xdim) - ((xwidth>>1) - (320<<15)); - pResult->y = scale(pInput->y, 200<<16, ydim); + pResult->x = scale(pInput->x, xwidth, xres) - ((xwidth>>1) - (320<<15)); + pResult->y = scale(pInput->y, 200<<16, yres); return 1; } diff --git a/source/build/src/build.cpp b/source/build/src/build.cpp index e2e6ee44b..43abce968 100644 --- a/source/build/src/build.cpp +++ b/source/build/src/build.cpp @@ -279,7 +279,7 @@ int32_t osdcmd_restartvid(osdfuncparm_t const * const UNUSED(parm)) if (!in3dmode()) return OSDCMD_OK; videoResetMode(); - if (videoSetGameMode(fullscreen,xdim,ydim,bpp)) + if (videoSetGameMode(fullscreen,xres,yres,bpp,upscalefactor)) OSD_Printf("restartvid: Reset failed...\n"); return OSDCMD_OK; @@ -288,7 +288,7 @@ int32_t osdcmd_restartvid(osdfuncparm_t const * const UNUSED(parm)) static int32_t osdcmd_vidmode(osdfuncparm_t const * const parm) { - int32_t newx = xdim, newy = ydim, newbpp = bpp, newfullscreen = fullscreen; + int32_t newx = xres, newy = yres, newbpp = bpp, newfullscreen = fullscreen; #ifdef USE_OPENGL int32_t tmp; #endif @@ -335,7 +335,7 @@ static int32_t osdcmd_vidmode(osdfuncparm_t const * const parm) return OSDCMD_OK; } - if (videoSetGameMode(newfullscreen,newx,newy,newbpp)) + if (videoSetGameMode(newfullscreen,newx,newy,newbpp,upscalefactor)) OSD_Printf("vidmode: Mode change failed!\n"); xdimgame = newx; @@ -769,7 +769,7 @@ int app_main(int argc, char const * const * argv) g_videoBrightness = 0.0; videoSetPalette(0,0,0); - if (videoSetGameMode(fullscreen, xdim2d, ydim2d, 8) < 0) + if (videoSetGameMode(fullscreen, xdim2d, ydim2d, 8, upscalefactor) < 0) { CallExtUnInit(); engineUnInit(); @@ -792,7 +792,7 @@ int app_main(int argc, char const * const * argv) } else { - if (videoSetGameMode(fullscreen, xdimgame, ydimgame, bppgame) < 0) + if (videoSetGameMode(fullscreen, xdimgame, ydimgame, bppgame, upscalefactor) < 0) { CallExtUnInit(); engineUnInit(); @@ -8269,7 +8269,7 @@ CANCEL: fixspritesectors(); - if (videoSetGameMode(fullscreen,xdimgame,ydimgame,bppgame) < 0) + if (videoSetGameMode(fullscreen,xdimgame,ydimgame,bppgame,upscalefactor) < 0) { initprintf("%d * %d not supported in this graphics mode\n",xdim,ydim); CallExtUnInit(); diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index bd5a8c252..ce0352faf 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -21,6 +21,7 @@ #include "baselayer.h" #include "scriptfile.h" +#include "softsurface.h" #ifdef USE_OPENGL # include "glad/glad.h" # include "glsurface.h" @@ -2336,8 +2337,8 @@ static inline void wallmosts_finish(int16_t *mostbuf, int32_t z1, int32_t z2, #if 0 // enable for paranoia: - ix1 = clamp(ix1, 0, xres-1); - ix2 = clamp(ix2, 0, xres-1); + ix1 = clamp(ix1, 0, xdim-1); + ix2 = clamp(ix2, 0, xdim-1); if (ix2-ix1 < 0) swaplong(&ix1, &ix2); #endif @@ -6518,13 +6519,13 @@ static void dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t // bound clipping rectangle to screen if (cx1 < 0) cx1 = 0; - else if (cx1 > xres-1) cx1 = xres-1; + else if (cx1 > xdim-1) cx1 = xdim-1; if (cy1 < 0) cy1 = 0; - else if (cy1 > yres-1) cy1 = yres-1; + else if (cy1 > ydim-1) cy1 = ydim-1; if (cx2 < 0) cx2 = 0; - else if (cx2 > xres-1) cx2 = xres-1; + else if (cx2 > xdim-1) cx2 = xdim-1; if (cy2 < 0) cy2 = 0; - else if (cy2 > yres-1) cy2 = yres-1; + else if (cy2 > ydim-1) cy2 = ydim-1; xsiz = tilesiz[picnum].x; ysiz = tilesiz[picnum].y; @@ -9826,11 +9827,21 @@ static void videoAllocateBuffers(void) ysavecnt = YSAVES; nodesperline = tabledivide32_noinline(YSAVES, ydim); -#ifdef USE_OPENGL - extern char nogl; - if (videoGetRenderMode() == REND_CLASSIC && !nogl) +#ifdef RENDERTYPESDL + if (videoGetRenderMode() == REND_CLASSIC) { - glsurface_initialize({xdim, ydim}); +# ifdef USE_OPENGL + extern char nogl; + if (!nogl) + { + glsurface_initialize({ xdim, ydim }); + } + else +# endif + { + softsurface_initialize({ xdim, ydim }, + { xres, yres }); + } } #endif } @@ -9863,7 +9874,7 @@ static void PolymostProcessVoxels(void) // // JBF: davidoption now functions as a windowed-mode flag (0 == windowed, 1 == fullscreen) extern char videomodereset; -int32_t videoSetGameMode(char davidoption, int32_t daxdim, int32_t daydim, int32_t dabpp) +int32_t videoSetGameMode(char davidoption, int32_t daupscaledxdim, int32_t daupscaledydim, int32_t dabpp, int32_t daupscalefactor) { int32_t j; @@ -9872,11 +9883,11 @@ int32_t videoSetGameMode(char davidoption, int32_t daxdim, int32_t daydim, int32 if (nogl) dabpp = 8; #endif - daxdim = max(320, daxdim); - daydim = max(200, daydim); + daupscaledxdim = max(320, daupscaledxdim); + daupscaledydim = max(200, daupscaledydim); - if (in3dmode() && videomodereset == 0 && - (davidoption == fullscreen) && (xdim == daxdim) && (ydim == daydim) && (bpp == dabpp)) + if (in3dmode() && videomodereset == 0 && (davidoption == fullscreen) && + (xres == daupscaledxdim) && (yres == daupscaledydim) && (bpp == dabpp) && (upscalefactor == daupscalefactor)) return 0; Bstrcpy(kensmessage,"!!!! BUILD engine&tools programmed by Ken Silverman of E.G. RI." @@ -9891,7 +9902,7 @@ int32_t videoSetGameMode(char davidoption, int32_t daxdim, int32_t daydim, int32 j = bpp; g_lastpalettesum = 0; - if (videoSetMode(daxdim,daydim,dabpp,davidoption) < 0) return -1; + if (videoSetMode(daupscaledxdim,daupscaledydim,dabpp,davidoption) < 0) return -1; // Workaround possible bugs in the GL driver makeasmwriteable(); @@ -9901,14 +9912,25 @@ int32_t videoSetGameMode(char davidoption, int32_t daxdim, int32_t daydim, int32 else rendmode = REND_CLASSIC; #endif - xdim = daxdim; - ydim = daydim; + upscalefactor = max(1, min(tabledivide32(yres, 200), daupscalefactor)); + //POGOTODO: Polymost/Polymer could work with upscaling with a couple more changes + int32_t scalefactor = upscalefactor; +#ifdef RENDERTYPESDL + if (bpp != 8) +#endif + { + scalefactor = 1; + } + xdim = daupscaledxdim/scalefactor; + ydim = daupscaledydim/scalefactor; #ifdef USE_OPENGL - fxdim = (float) daxdim; - fydim = (float) daydim; + fxdim = (float) xdim; + fydim = (float) ydim; #endif + OSD_ResizeDisplay(xdim, ydim); + videoAllocateBuffers(); #ifdef HIGH_PRECISION_SPRITE @@ -12297,7 +12319,7 @@ void videoClearScreen(int32_t dacol) #endif videoBeginDrawing(); //{{{ - Bmemset((void *)frameplace,dacol,bytesperline*yres); + Bmemset((void *)frameplace,dacol,bytesperline*ydim); videoEndDrawing(); //}}} //nextpage(); @@ -12761,20 +12783,22 @@ void videoSet2dMode(int32_t daxdim, int32_t daydim) ydim = yres; #ifdef USE_OPENGL - fxdim = (float) xres; - fydim = (float) yres; + fxdim = (float) xdim; + fydim = (float) ydim; rendmode = REND_CLASSIC; #endif + OSD_ResizeDisplay(xdim, ydim); + videoAllocateBuffers(); - ydim16 = yres - STATUS2DSIZ2; - halfxdim16 = xres >> 1; - midydim16 = ydim16 >> 1; // scale(200,yres,480); + ydim16 = ydim - STATUS2DSIZ2; + halfxdim16 = xdim >> 1; + midydim16 = ydim16 >> 1; // scale(200,ydim,480); videoBeginDrawing(); //{{{ - Bmemset((char *)frameplace, 0, yres*bytesperline); + Bmemset((char *)frameplace, 0, ydim*bytesperline); videoEndDrawing(); //}}} } diff --git a/source/build/src/glsurface.cpp b/source/build/src/glsurface.cpp index 1150a1263..4bde7d503 100644 --- a/source/build/src/glsurface.cpp +++ b/source/build/src/glsurface.cpp @@ -56,14 +56,14 @@ static GLuint compileShader(GLenum shaderType, const char* const source) return shaderID; } -bool glsurface_initialize(vec2_t inputBufferResolution) +bool glsurface_initialize(vec2_t bufferResolution) { if (buffer) glsurface_destroy(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - bufferRes = inputBufferResolution; + bufferRes = bufferResolution; buffer = Xaligned_alloc(16, bufferRes.x * bufferRes.y); glGenBuffers(1, &quadVertsID); diff --git a/source/build/src/palette.cpp b/source/build/src/palette.cpp index 85f6bb44c..fa54cdb72 100644 --- a/source/build/src/palette.cpp +++ b/source/build/src/palette.cpp @@ -8,10 +8,6 @@ #include "a.h" #include "xxhash.h" -#ifdef USE_OPENGL -# include "glsurface.h" -#endif - uint8_t *basepaltable[MAXBASEPALS] = { palette }; uint8_t basepalreset=1; uint8_t curbasepal; @@ -742,7 +738,6 @@ void videoSetPalette(char dabrightness, uint8_t dapalid, uint8_t flags) if (palsumdidchange || newpalettesum != g_lastpalettesum) { - glsurface_setPalette(curpalettefaded); // if ((flags&1) == 0) videoUpdatePalette(0, 256); } @@ -826,7 +821,6 @@ void videoFadePalette(uint8_t r, uint8_t g, uint8_t b, uint8_t offset) if (newpalettesum != lastpalettesum || newpalettesum != g_lastpalettesum) { - glsurface_setPalette(curpalettefaded); videoUpdatePalette(0, 256); } diff --git a/source/build/src/polymer.cpp b/source/build/src/polymer.cpp index bd1acc80f..93eea908e 100644 --- a/source/build/src/polymer.cpp +++ b/source/build/src/polymer.cpp @@ -924,7 +924,7 @@ void polymer_glinit(void) glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearStencil(0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - glViewport(windowxy1.x, yres-(windowxy2.y+1),windowxy2.x-windowxy1.x+1, windowxy2.y-windowxy1.y+1); + glViewport(windowxy1.x, ydim-(windowxy2.y+1),windowxy2.x-windowxy1.x+1, windowxy2.y-windowxy1.y+1); // texturing glEnable(GL_TEXTURE_2D); @@ -2029,7 +2029,7 @@ static void polymer_displayrooms(const int16_t dacursectnum) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prrts[0].fbo); glPushAttrib(GL_VIEWPORT_BIT); - glViewport(windowxy1.x, yres-(windowxy2.y+1),windowxy2.x-windowxy1.x+1, windowxy2.y-windowxy1.y+1); + glViewport(windowxy1.x, ydim-(windowxy2.y+1),windowxy2.x-windowxy1.x+1, windowxy2.y-windowxy1.y+1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 9eeefe0d5..ca3476004 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -1503,7 +1503,7 @@ static void resizeglcheck(void) glox1 = (float)windowxy1.x; gloy1 = (float)windowxy1.y; glox2 = (float)windowxy2.x; gloy2 = (float)windowxy2.y; - glViewport(windowxy1.x-(fovcorrect/2), yres-(windowxy2.y+1), + glViewport(windowxy1.x-(fovcorrect/2), ydim-(windowxy2.y+1), ourxdimen+fovcorrect, windowxy2.y-windowxy1.y+1); glMatrixMode(GL_PROJECTION); @@ -6950,7 +6950,7 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a, tspr.cstat = globalorientation = (dastat&RS_TRANS1) | ((dastat&RS_TRANS2)<<4) | ((dastat&RS_YFLIP)<<1); if ((dastat&(RS_AUTO|RS_NOCLIP)) == RS_AUTO) - glViewport(windowxy1.x, yres-(windowxy2.y+1), windowxy2.x-windowxy1.x+1, windowxy2.y-windowxy1.y+1); + glViewport(windowxy1.x, ydim-(windowxy2.y+1), windowxy2.x-windowxy1.x+1, windowxy2.y-windowxy1.y+1); else { glViewport(0, 0, xdim, ydim); @@ -7870,7 +7870,7 @@ static int32_t osdcmd_cvar_set_polymost(osdfuncparm_t const * const parm) { texcache_invalidate(); videoResetMode(); - if (videoSetGameMode(fullscreen,xdim,ydim,bpp)) + if (videoSetGameMode(fullscreen,xres,yres,bpp,upscalefactor)) OSD_Printf("restartvid: Reset failed...\n"); } diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index 8e6ddaadd..7fa9a1378 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -13,6 +13,7 @@ #include "engine_priv.h" #include "palette.h" +#include "softsurface.h" #ifdef USE_OPENGL # include "glad/glad.h" # include "glbuild.h" @@ -37,7 +38,6 @@ # include "wiibits.h" # include # include -# define SDL_DISABLE_8BIT_BUFFER #endif #if SDL_MAJOR_VERSION != 1 @@ -69,18 +69,10 @@ char quitevent=0, appactive=1, novideo=0; // video static SDL_Surface *sdl_surface/*=NULL*/; -#if !defined SDL_DISABLE_8BIT_BUFFER -static SDL_Surface *sdl_buffersurface=NULL; -#else -# define sdl_buffersurface sdl_surface -#endif #if SDL_MAJOR_VERSION==2 -static SDL_Palette *sdl_palptr=NULL; static SDL_Window *sdl_window=NULL; static SDL_GLContext sdl_context=NULL; -static SDL_Texture *sdl_texture=NULL; -static SDL_Renderer *sdl_renderer=NULL; #endif int32_t xres=-1, yres=-1, bpp=0, fullscreen=0, bytesperline; @@ -99,7 +91,9 @@ char nogl=0; #endif static int32_t vsync_renderlayer; int32_t maxrefreshfreq=0; +#if SDL_MAJOR_VERSION==2 static uint32_t currentVBlankInterval=0; +#endif // last gamma, contrast, brightness static float lastvidgcb[3]; @@ -547,7 +541,7 @@ int32_t videoSetVsync(int32_t newSync) vsync_renderlayer = newSync; videoResetMode(); - if (videoSetGameMode(fullscreen, xdim, ydim, bpp)) + if (videoSetGameMode(fullscreen, xres, yres, bpp, upscalefactor)) OSD_Printf("restartvid: Reset failed...\n"); } @@ -675,10 +669,12 @@ void uninitsystem(void) #endif #ifdef USE_OPENGL +# if SDL_MAJOR_VERSION!=1 SDL_GL_UnloadLibrary(); -#ifdef POLYMER +# endif +# ifdef POLYMER unloadglulibrary(); -#endif +# endif #endif } @@ -1265,33 +1261,15 @@ int32_t videoCheckMode(int32_t *x, int32_t *y, int32_t c, int32_t fs, int32_t fo return nearest; } -static int32_t needpalupdate; -static SDL_Color sdlayer_pal[256]; - static void destroy_window_resources() { -#if !defined SDL_DISABLE_8BIT_BUFFER - if (sdl_buffersurface) - SDL_FreeSurface(sdl_buffersurface); - - sdl_buffersurface = NULL; -#endif /* We should NOT destroy the window surface. This is done automatically when SDL_DestroyWindow or SDL_SetVideoMode is called. */ #if SDL_MAJOR_VERSION == 2 - if (sdl_renderer && sdl_texture && sdl_surface) - SDL_FreeSurface(sdl_surface); - sdl_surface = NULL; if (sdl_context) SDL_GL_DeleteContext(sdl_context); sdl_context = NULL; - if (sdl_texture) - SDL_DestroyTexture(sdl_texture); - sdl_texture = NULL; - if (sdl_renderer) - SDL_DestroyRenderer(sdl_renderer); - sdl_renderer = NULL; if (sdl_window) SDL_DestroyWindow(sdl_window); sdl_window = NULL; @@ -1425,10 +1403,7 @@ void sdlayer_setvideomode_opengl(void) int32_t setvideomode_sdlcommon(int32_t *x, int32_t *y, int32_t c, int32_t fs, int32_t *regrab) { if ((fs == fullscreen) && (*x == xres) && (*y == yres) && (c == bpp) && !videomodereset) - { - OSD_ResizeDisplay(xres, yres); return 0; - } if (videoCheckMode(x, y, c, fs, 0) < 0) return -1; @@ -1461,7 +1436,11 @@ int32_t setvideomode_sdlcommon(int32_t *x, int32_t *y, int32_t c, int32_t fs, in if ((fs == fullscreen) && (*x == xres) && (*y == yres) && (bpp != 0) && !videomodereset) return 0; } + else #endif + { + softsurface_destroy(); + } // clear last gamma/contrast/brightness so that it will be set anew lastvidgcb[0] = lastvidgcb[1] = lastvidgcb[2] = 0.0f; @@ -1488,7 +1467,6 @@ void setvideomode_sdlcommonpost(int32_t x, int32_t y, int32_t c, int32_t fs, int lockcount = 0; modechange = 1; videomodereset = 0; - OSD_ResizeDisplay(xres, yres); // save the current system gamma to determine if gamma is available #ifndef EDUKE32_GLES @@ -1537,55 +1515,6 @@ void setrefreshrate(void) currentVBlankInterval = 1000/newmode.refresh_rate; } -static void sdl_trycreaterenderer_fail(char const * const failurepoint) -{ - initprintf("Falling back to SDL_GetWindowSurface: %s failed: %s\n", failurepoint, SDL_GetError()); - SDL_DestroyRenderer(sdl_renderer); - sdl_renderer = NULL; -} - -static void sdl_trycreaterenderer(int32_t const x, int32_t const y) -{ - int const flags = SDL_RENDERER_ACCELERATED | (vsync_renderlayer ? SDL_RENDERER_PRESENTVSYNC : 0); - - sdl_renderer = SDL_CreateRenderer(sdl_window, -1, flags); - if (!sdl_renderer) - { - sdl_trycreaterenderer_fail("SDL_CreateRenderer"); - return; - } - - SDL_RendererInfo sdl_rendererinfo; - SDL_GetRendererInfo(sdl_renderer, &sdl_rendererinfo); - - if (sdl_rendererinfo.flags & SDL_RENDERER_SOFTWARE) // this would be useless - { - initprintf("Falling back to SDL_GetWindowSurface: software SDL_Renderer \"%s\" provides no benefit.\n", sdl_rendererinfo.name); - SDL_DestroyRenderer(sdl_renderer); - sdl_renderer = NULL; - return; - } - - initprintf("Trying SDL_Renderer \"%s\"\n", sdl_rendererinfo.name); - - sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, x, y); - if (!sdl_texture) - { - sdl_trycreaterenderer_fail("SDL_CreateTexture"); - return; - } - - sdl_surface = SDL_CreateRGBSurface(0, x, y, 32, 0, 0, 0, 0); - - if (!sdl_surface) - { - SDL_DestroyTexture(sdl_texture); - sdl_texture = NULL; - sdl_trycreaterenderer_fail("SDL_CreateRGBSurface"); - return; - } -} - int32_t videoSetMode(int32_t x, int32_t y, int32_t c, int32_t fs) { int32_t regrab = 0, ret; @@ -1684,8 +1613,6 @@ int32_t videoSetMode(int32_t x, int32_t y, int32_t c, int32_t fs) setrefreshrate(); - sdl_trycreaterenderer(x, y); - if (!sdl_surface) { sdl_surface = SDL_GetWindowSurface(sdl_window); @@ -1693,19 +1620,6 @@ int32_t videoSetMode(int32_t x, int32_t y, int32_t c, int32_t fs) SDL2_VIDEO_ERR("SDL_GetWindowSurface"); } -#if !defined SDL_DISABLE_8BIT_BUFFER - sdl_buffersurface = SDL_CreateRGBSurface(0, x, y, c, 0, 0, 0, 0); - - if (!sdl_buffersurface) - SDL2_VIDEO_ERR("SDL_CreateRGBSurface"); -#endif - - if (!sdl_palptr) - sdl_palptr = SDL_AllocPalette(256); - - if (SDL_SetSurfacePalette(sdl_buffersurface, sdl_palptr) < 0) - initprintf("SDL_SetSurfacePalette failed: %s\n", SDL_GetError()); - SDL_SetWindowFullscreen(sdl_window, ((fs & 1) ? SDL_WINDOW_FULLSCREEN : 0)); } @@ -1752,6 +1666,7 @@ void videoBeginDrawing(void) if (offscreenrendering) return; +#ifdef USE_OPENGL if (!nogl) { frameplace = (intptr_t)glsurface_getBuffer(); @@ -1763,16 +1678,13 @@ void videoBeginDrawing(void) } return; } +#endif - if (SDL_MUSTLOCK(sdl_buffersurface)) SDL_LockSurface(sdl_buffersurface); - frameplace = (intptr_t)sdl_buffersurface->pixels; - - if (sdl_buffersurface->pitch != bytesperline || modechange) + frameplace = (intptr_t)softsurface_getBuffer(); + if (modechange) { - bytesperline = sdl_buffersurface->pitch; - + bytesperline = xdim; calc_ylookup(bytesperline, ydim); - modechange=0; } } @@ -1794,10 +1706,6 @@ void videoEndDrawing(void) if (!offscreenrendering) frameplace = 0; if (lockcount == 0) return; lockcount = 0; - - if (offscreenrendering || !nogl) return; - - if (SDL_MUSTLOCK(sdl_buffersurface)) SDL_UnlockSurface(sdl_buffersurface); } // @@ -1854,27 +1762,11 @@ void videoShowFrame(int32_t w) while (lockcount) videoEndDrawing(); } - // deferred palette updating - if (needpalupdate) - { - if (SDL_SetPaletteColors(sdl_palptr, sdlayer_pal, 0, 256) < 0) - initprintf("SDL_SetPaletteColors failed: %s\n", SDL_GetError()); - needpalupdate = 0; - } + if (SDL_MUSTLOCK(sdl_surface)) SDL_LockSurface(sdl_surface); + softsurface_blitBuffer((uint32_t*) sdl_surface->pixels, sdl_surface->format->BitsPerPixel); + if (SDL_MUSTLOCK(sdl_surface)) SDL_UnlockSurface(sdl_surface); -#if !defined SDL_DISABLE_8BIT_BUFFER - SDL_BlitSurface(sdl_buffersurface, NULL, sdl_surface, NULL); -#endif - - if (sdl_renderer && sdl_texture) - { - SDL_UpdateTexture(sdl_texture, NULL, sdl_surface->pixels, sdl_surface->pitch); - - SDL_RenderClear(sdl_renderer); - SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL); - SDL_RenderPresent(sdl_renderer); - } - else if (SDL_UpdateWindowSurface(sdl_window)) + if (SDL_UpdateWindowSurface(sdl_window)) { // If a fullscreen X11 window is minimized then this may be required. // FIXME: What to do if this fails... @@ -1888,21 +1780,24 @@ void videoShowFrame(int32_t w) // int32_t videoUpdatePalette(int32_t start, int32_t num) { + UNREFERENCED_PARAMETER(start); + UNREFERENCED_PARAMETER(num); + if (bpp > 8) return 0; // no palette in opengl - Bmemcpy(sdlayer_pal, curpalettefaded, 256 * 4); - - for (native_t i = start, n = num; n > 0; i++, n--) - curpalettefaded[i].f = -#if SDL_MAJOR_VERSION == 1 - sdlayer_pal[i].unused -#else - sdlayer_pal[i].a +#ifdef USE_OPENGL + if (!nogl) + glsurface_setPalette(curpalettefaded); + else #endif - = 0; - - needpalupdate = 1; + { + if (sdl_surface) + softsurface_setPalette(curpalettefaded, + sdl_surface->format->Rmask, + sdl_surface->format->Gmask, + sdl_surface->format->Bmask); + } return 0; } diff --git a/source/build/src/sdlayer12.cpp b/source/build/src/sdlayer12.cpp index a1e3d8ab3..e0789387a 100644 --- a/source/build/src/sdlayer12.cpp +++ b/source/build/src/sdlayer12.cpp @@ -26,7 +26,7 @@ int32_t videoSetVsync(int32_t newSync) vsync_renderlayer = newSync; videoResetMode(); - if (videoSetGameMode(fullscreen, xdim, ydim, bpp)) + if (videoSetGameMode(fullscreen, xres, yres, bpp, upscalefactor)) OSD_Printf("restartvid: Reset failed...\n"); return newSync; @@ -251,12 +251,8 @@ void videoGetModes(void) pf.BitsPerPixel = cdepths[j]; pf.BytesPerPixel = cdepths[j] >> 3; -#if !defined SDL_DISABLE_8BIT_BUFFER // We convert paletted contents to non-paletted modes = SDL_ListModes((cdepths[j] == 8) ? NULL : &pf, SURFACE_FLAGS | SDL_FULLSCREEN); -#else - modes = SDL_ListModes(&pf, SURFACE_FLAGS | SDL_FULLSCREEN); -#endif if (modes == (SDL_Rect **)0) { @@ -325,7 +321,14 @@ int32_t videoSetMode(int32_t x, int32_t y, int32_t c, int32_t fs) #endif ret = setvideomode_sdlcommon(&x, &y, c, fs, ®rab); - if (ret != 1) return ret; + if (ret != 1) + { + if (ret == 0) + { + setvideomode_sdlcommonpost(x, y, c, fs, regrab); + } + return ret; + } // restore gamma before we change video modes if it was changed if (sdl_surface && gammabrightness) @@ -340,7 +343,7 @@ int32_t videoSetMode(int32_t x, int32_t y, int32_t c, int32_t fs) initprintf("Setting video mode %dx%d (%d-bpp %s)\n", x, y, c, ((fs & 1) ? "fullscreen" : "windowed")); #ifdef USE_OPENGL - if (c > 8) + if (c > 8 || !nogl) { int32_t i, j, multisamplecheck = (glmultisample > 0); @@ -395,34 +398,21 @@ int32_t videoSetMode(int32_t x, int32_t y, int32_t c, int32_t fs) initprintf("Unable to set video mode!\n"); return -1; } - -#ifdef _WIN32 - loadglextensions(); -#endif } while (multisamplecheck--); + + gladLoadGLLoader(SDL_GL_GetProcAddress); } else #endif // defined USE_OPENGL { -#if !defined SDL_DISABLE_8BIT_BUFFER // We convert paletted contents to non-paletted sdl_surface = SDL_SetVideoMode(x, y, 0, SURFACE_FLAGS | ((fs & 1) ? SDL_FULLSCREEN : 0)); -#else - sdl_surface = SDL_SetVideoMode(x, y, c, SURFACE_FLAGS | ((fs & 1) ? SDL_FULLSCREEN : 0)); -#endif + if (!sdl_surface) { initprintf("Unable to set video mode!\n"); return -1; } -#if !defined SDL_DISABLE_8BIT_BUFFER - sdl_buffersurface = SDL_CreateRGBSurface(SURFACE_FLAGS, x, y, c, 0, 0, 0, 0); - if (!sdl_buffersurface) - { - initprintf("Unable to set video mode: SDL_CreateRGBSurface failed: %s\n", SDL_GetError()); - return -1; - } -#endif } setvideomode_sdlcommonpost(x, y, c, fs, regrab); @@ -438,10 +428,17 @@ void videoShowFrame(int32_t w) UNREFERENCED_PARAMETER(w); #ifdef USE_OPENGL - if (bpp > 8) + if (!nogl) { - if (palfadedelta) - fullscreen_tint_gl(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta); + if (bpp > 8) + { + if (palfadedelta) + fullscreen_tint_gl(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta); + } + else + { + glsurface_blitBuffer(); + } SDL_GL_SwapBuffers(); return; @@ -456,16 +453,10 @@ void videoShowFrame(int32_t w) while (lockcount) videoEndDrawing(); } - // deferred palette updating - if (needpalupdate) - { - SDL_SetColors(sdl_buffersurface, sdlayer_pal, 0, 256); - needpalupdate = 0; - } + if (SDL_MUSTLOCK(sdl_surface)) SDL_LockSurface(sdl_surface); + softsurface_blitBuffer((uint32_t*) sdl_surface->pixels, sdl_surface->format->BitsPerPixel); + if (SDL_MUSTLOCK(sdl_surface)) SDL_UnlockSurface(sdl_surface); -#if !defined SDL_DISABLE_8BIT_BUFFER - SDL_BlitSurface(sdl_buffersurface, NULL, sdl_surface, NULL); -#endif SDL_Flip(sdl_surface); } diff --git a/source/build/src/softsurface.cpp b/source/build/src/softsurface.cpp new file mode 100644 index 000000000..4d1487803 --- /dev/null +++ b/source/build/src/softsurface.cpp @@ -0,0 +1,207 @@ +/* + * softsurface.cpp + * An 8-bit rendering surface that can quickly upscale and blit 8-bit paletted buffers to an external 32-bit buffer. + * + * Copyright © 2018, Alex Dawson. All rights reserved. + */ + +#include "softsurface.h" + +#include "pragmas.h" +#include "build.h" + +static uint8_t* buffer; +static vec2_t bufferRes; + +static vec2_t destBufferRes; + +static uint32_t xScale16; +static uint32_t yScale16; +static uint32_t recXScale16; + +static uint32_t pPal[256]; + +// lookup table to find the source position within a scanline +static uint16_t* scanPosLookupTable; + +static uint32_t roundUp(uint32_t num, uint32_t multiple) +{ + return (num+multiple-1)/multiple * multiple; +} + +static uint32_t countTrailingZeros(uint32_t u) +{ +#if (defined __GNUC__ && __GNUC__>=3) || defined __clang__ + return __builtin_ctz(u); +#elif defined _MSC_VER + uint32_t result; + _BitScanForward(&result, u); + return result; +#else + uint32_t last = u; + for (; u != 0; last = u, u >>= 1); + return last; +#endif +} + +bool softsurface_initialize(vec2_t bufferResolution, + vec2_t destBufferResolution) +{ + if (buffer) + softsurface_destroy(); + + bufferRes = bufferResolution; + destBufferRes = destBufferResolution; + + xScale16 = divscale16(destBufferRes.x, bufferRes.x); + yScale16 = divscale16(destBufferRes.y, bufferRes.y); + recXScale16 = divscale16(bufferRes.x, destBufferRes.x); + + // allocate one continuous block of memory large enough to hold the buffer, the palette, + // and the scanPosLookupTable while maintaining alignment for each + uint32_t bufferSize = roundUp(bufferRes.x * bufferRes.y, 16); + buffer = (uint8_t*) Xaligned_alloc(16, bufferSize + sizeof(uint16_t)*destBufferRes.x); + scanPosLookupTable = (uint16_t*) (buffer + bufferSize); + + // calculate the scanPosLookupTable for horizontal scaling + uint32_t incr = recXScale16; + for (int32_t i = 0; i < destBufferRes.x; ++i) + { + scanPosLookupTable[i] = incr >> 16; + incr += recXScale16; + } + + return true; +} + +void softsurface_destroy() +{ + if (!buffer) + return; + + ALIGNED_FREE_AND_NULL(buffer); + scanPosLookupTable = 0; + + xScale16 = 0; + yScale16 = 0; + recXScale16 = 0; + + bufferRes = {}; + destBufferRes = {}; +} + +void softsurface_setPalette(void* pPalette, + uint32_t destRedMask, + uint32_t destGreenMask, + uint32_t destBlueMask) +{ + if (!buffer) + return; + if (!pPalette) + return; + + uint32_t destRedShift = countTrailingZeros(destRedMask); + uint32_t destRedLoss = 8 - countTrailingZeros((destRedMask>>destRedShift)+1); + uint32_t destGreenShift = countTrailingZeros(destGreenMask); + uint32_t destGreenLoss = 8 - countTrailingZeros((destGreenMask>>destGreenShift)+1); + uint32_t destBlueShift = countTrailingZeros(destBlueMask); + uint32_t destBlueLoss = 8 - countTrailingZeros((destBlueMask>>destBlueShift)+1); + + uint8_t* pUI8Palette = (uint8_t*) pPalette; + for (int i = 0; i < 256; ++i) + { + pPal[i] = ((pUI8Palette[sizeof(uint32_t)*i] >> destRedLoss << destRedShift) & destRedMask) | + ((pUI8Palette[sizeof(uint32_t)*i+1] >> destGreenLoss << destGreenShift) & destGreenMask) | + ((pUI8Palette[sizeof(uint32_t)*i+2] >> destBlueLoss << destBlueShift) & destBlueMask); + } +} + +uint8_t* softsurface_getBuffer() +{ + return buffer; +} + +vec2_t softsurface_getBufferResolution() +{ + return bufferRes; +} + +vec2_t softsurface_getDestinationBufferResolution() +{ + return destBufferRes; +} + +#define BLIT(x) pDst[x] = *((UINTTYPE*)(pPal+pSrc[pScanPos[x]])) +#define BLIT2(x) BLIT(x); BLIT(x+1) +#define BLIT4(x) BLIT2(x); BLIT2(x+2) +#define BLIT8(x) BLIT4(x); BLIT4(x+4) +#define BLIT16(x) BLIT8(x); BLIT8(x+8) +#define BLIT32(x) BLIT16(x); BLIT16(x+16) +#define BLIT64(x) BLIT32(x); BLIT32(x+32) +template +void softsurface_blitBufferInternal(UINTTYPE* destBuffer) +{ + const uint8_t* __restrict pSrc = buffer; + UINTTYPE* __restrict pDst = destBuffer; + const UINTTYPE* const pEnd = destBuffer+destBufferRes.x*mulscale16(yScale16, bufferRes.y); + uint32_t remainder = 0; + while (pDst < pEnd) + { + uint16_t* __restrict pScanPos = scanPosLookupTable; + UINTTYPE* const pScanEnd = pDst+destBufferRes.x; + while (pDst < pScanEnd-64) + { + BLIT64(0); + pDst += 64; + pScanPos += 64; + } + while (pDst < pScanEnd) + { + BLIT(0); + ++pDst; + ++pScanPos; + } + pSrc += bufferRes.x; + + static const uint32_t MASK16 = (1<<16)-1; + uint32_t linesCopied = 1; + uint32_t linesToCopy = yScale16+remainder; + remainder = linesToCopy & MASK16; + linesToCopy = (linesToCopy >> 16)-1; + const UINTTYPE* const __restrict pScanLineSrc = pDst-destBufferRes.x; + while (linesToCopy) + { + uint32_t lines = min(linesCopied, linesToCopy); + memcpy(pDst, pScanLineSrc, sizeof(UINTTYPE)*lines*destBufferRes.x); + pDst += lines*destBufferRes.x; + linesToCopy -= lines; + } + } +} + +void softsurface_blitBuffer(uint32_t* destBuffer, + uint32_t destBpp) +{ + if (!buffer) + return; + if (!destBuffer) + return; + + switch (destBpp) + { + case 15: + softsurface_blitBufferInternal((uint16_t*) destBuffer); + break; + case 16: + softsurface_blitBufferInternal((uint16_t*) destBuffer); + break; + case 24: + softsurface_blitBufferInternal(destBuffer); + break; + case 32: + softsurface_blitBufferInternal(destBuffer); + break; + default: + return; + } +} diff --git a/source/build/src/winlayer.cpp b/source/build/src/winlayer.cpp index 7178b483c..eb10f7beb 100644 --- a/source/build/src/winlayer.cpp +++ b/source/build/src/winlayer.cpp @@ -1592,10 +1592,7 @@ int32_t videoSetMode(int32_t x, int32_t y, int32_t c, int32_t fs) int32_t modenum; if ((fs == fullscreen) && (x == xres) && (y == yres) && (c == bpp) && !videomodereset) - { - OSD_ResizeDisplay(xres,yres); return 0; - } modenum = videoCheckMode(&x,&y,c,fs,0); if (modenum < 0) return -1; @@ -1637,7 +1634,6 @@ int32_t videoSetMode(int32_t x, int32_t y, int32_t c, int32_t fs) if (inp) AcquireInputDevices(1); modechange=1; videomodereset = 0; - OSD_ResizeDisplay(xres,yres); return 0; } @@ -3190,7 +3186,6 @@ static BOOL CreateAppWindow(int32_t modenum) //bytesperline = width; modechange = 1; - OSD_ResizeDisplay(xres,yres); UpdateWindow(hWindow); @@ -3522,7 +3517,7 @@ static LRESULT CALLBACK WndProcCallback(HWND hWnd, UINT uMsg, WPARAM wParam, LPA } realfs = fullscreen; silentvideomodeswitch = 1; - videoSetGameMode(!fullscreen,xdim,ydim,bpp); + videoSetGameMode(!fullscreen,xres,yres,bpp,upscalefactor); ShowWindow(hWindow, SW_MINIMIZE); } else if (appactive && realfs) @@ -3535,7 +3530,7 @@ static LRESULT CALLBACK WndProcCallback(HWND hWnd, UINT uMsg, WPARAM wParam, LPA ShowWindow(hWindow, SW_RESTORE); SetForegroundWindow(hWindow); SetFocus(hWindow); - videoSetGameMode(realfs,xdim,ydim,bpp); + videoSetGameMode(realfs,xres,yres,bpp,upscalefactor); silentvideomodeswitch = 0; realfs = 0; } diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index da14fb97d..c2b753818 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -187,10 +187,10 @@ void G_HandleSpecialKeys(void) if (g_networkMode != NET_DEDICATED_SERVER && ALT_IS_PRESSED && KB_KeyPressed(sc_Enter)) { - if (videoSetGameMode(!ud.config.ScreenMode,ud.config.ScreenWidth,ud.config.ScreenHeight,ud.config.ScreenBPP)) + if (videoSetGameMode(!ud.config.ScreenMode,ud.config.ScreenWidth,ud.config.ScreenHeight,ud.config.ScreenBPP,ud.detail)) { OSD_Printf(OSD_ERROR "Failed setting fullscreen video mode.\n"); - if (videoSetGameMode(ud.config.ScreenMode, ud.config.ScreenWidth, ud.config.ScreenHeight, ud.config.ScreenBPP)) + if (videoSetGameMode(ud.config.ScreenMode, ud.config.ScreenWidth, ud.config.ScreenHeight, ud.config.ScreenBPP, ud.detail)) G_GameExit("Failed to recover from failure to set fullscreen video mode.\n"); } else ud.config.ScreenMode = !ud.config.ScreenMode; @@ -281,7 +281,7 @@ void G_GameExit(const char *msg) g_mostConcurrentPlayers > 1 && g_player[myconnectindex].ps->gm&MODE_GAME && GTFLAGS(GAMETYPE_SCORESHEET) && *msg == ' ') { G_BonusScreen(1); - videoSetGameMode(ud.config.ScreenMode,ud.config.ScreenWidth,ud.config.ScreenHeight,ud.config.ScreenBPP); + videoSetGameMode(ud.config.ScreenMode,ud.config.ScreenWidth,ud.config.ScreenHeight,ud.config.ScreenBPP,ud.detail); } // shareware and TEN screens @@ -772,7 +772,6 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio) int32_t floorZ, ceilZ; int32_t tiltcx, tiltcy, tiltcs=0; // JBF 20030807 - int pixelDoubling = 0; int const vr = divscale22(1, sprite[pPlayer->i].yrepeat + 28); int screenTilting = (videoGetRenderMode() == REND_CLASSIC && ((ud.screen_tilting && pPlayer->rotscrnang #ifdef SPLITSCREEN_MOD_HACKS @@ -896,12 +895,6 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio) #endif pPlayer->orotscrnang = pPlayer->rotscrnang; } - else if (ud.detail && videoGetRenderMode()==REND_CLASSIC) - { - pixelDoubling = 1; - g_halveScreenArea = 1; - G_UpdateScreenArea(); - } if (pPlayer->newowner < 0) { @@ -1107,39 +1100,6 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio) walock[TILE_TILT] = 199; } } - else if (pixelDoubling) - { - Bassert(g_halfScreen.xdimen!=0); - g_halveScreenArea = 0; - G_UpdateScreenArea(); - - videoBeginDrawing(); - { - uint8_t *const f = (uint8_t *)frameplace; - const int32_t x1=g_halfScreen.x1, y1=g_halfScreen.y1; - const int32_t xd=g_halfScreen.xdimen, yd=g_halfScreen.ydimen; - int32_t dx, dy; - - // Commented out: naive, per-byte access version. - // Live: optimized version: may access memory unaligned, relies - // on little-endian byte ordering. - - for (dy=2*yd-1; dy>=0; dy--) -// for (dx=2*xd-1; dx>=0; dx--) - for (dx=2*xd-4; dx>=0; dx-=4) - { - const int32_t ylsrc = ylookup[y1+(dy>>1)]; - const int32_t yldst = ylookup[y1+dy]; - -// f[yldst+x1+dx] = f[ylsrc+x1+(dx>>1)]; - uint8_t pixr = f[ylsrc+x1+((dx+3)>>1)]; - uint8_t pixl = f[ylsrc+x1+((dx+1)>>1)]; - - B_BUF32(&f[yldst+x1+dx], pixl|(pixl<<8)|(pixr<<16)|(pixr<<24)); - } - } - videoEndDrawing(); - } } G_RestoreInterpolations(); @@ -6549,7 +6509,7 @@ int app_main(int argc, char const * const * argv) if (g_networkMode != NET_DEDICATED_SERVER) { - if (videoSetGameMode(ud.config.ScreenMode,ud.config.ScreenWidth,ud.config.ScreenHeight,ud.config.ScreenBPP) < 0) + if (videoSetGameMode(ud.config.ScreenMode,ud.config.ScreenWidth,ud.config.ScreenHeight,ud.config.ScreenBPP,ud.detail) < 0) { vec2_t const res[] = { { ud.config.ScreenWidth, ud.config.ScreenHeight }, { 800, 600 }, { 640, 480 }, { 320, 240 }, @@ -6567,7 +6527,7 @@ int app_main(int argc, char const * const * argv) int resIdx = 0; int bppIdx = 0; - while (videoSetGameMode(0, res[resIdx].x, res[resIdx].y, bpp[bppIdx]) < 0) + while (videoSetGameMode(0, res[resIdx].x, res[resIdx].y, bpp[bppIdx], ud.detail) < 0) { initprintf("Failure setting video mode %dx%dx%d windowed! Attempting safer mode...\n", res[resIdx].x, res[resIdx].y, bpp[bppIdx]); diff --git a/source/duke3d/src/gamestructures.cpp b/source/duke3d/src/gamestructures.cpp index b5642f989..de2369e1a 100644 --- a/source/duke3d/src/gamestructures.cpp +++ b/source/duke3d/src/gamestructures.cpp @@ -308,8 +308,8 @@ void __fastcall VM_SetUserdef(int32_t const labelNum, int32_t const lParm2, int3 case USERDEFS_M_RESPAWN_INVENTORY: ud.m_respawn_inventory = iSet; break; case USERDEFS_M_RECSTAT: ud.m_recstat = iSet; break; case USERDEFS_M_MONSTERS_OFF: ud.m_monsters_off = iSet; break; - // REMINDER: must implement "boolean" setters like this in Lunatic, too. - case USERDEFS_DETAIL: ud.detail = !!iSet; break; + // REMINDER: must implement "boolean" setters like "!!iSet" in Lunatic, too. + case USERDEFS_DETAIL: ud.detail = clamp(iSet, 1, 16); break; case USERDEFS_M_FFIRE: ud.m_ffire = iSet; break; case USERDEFS_FFIRE: ud.ffire = iSet; break; case USERDEFS_M_PLAYER_SKILL: ud.m_player_skill = iSet; break; diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 5cf29548f..3b068274c 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -548,8 +548,11 @@ static MenuLink_t MEO_DISPLAYSETUP_COLORCORR = { MENU_COLCORR, MA_Advance, }; static MenuEntry_t ME_DISPLAYSETUP_COLORCORR = MAKE_MENUENTRY( "Color Correction", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_COLORCORR, Link ); -static MenuOption_t MEO_DISPLAYSETUP_PIXELDOUBLING = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &ud.detail ); -static MenuEntry_t ME_DISPLAYSETUP_PIXELDOUBLING = MAKE_MENUENTRY( "Pixel Doubling:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_PIXELDOUBLING, Option ); +static char const *MEOSN_DISPLAYSETUP_UPSCALING[] = { "None", "2x", "4x", "8x", "16x", }; +static int32_t MEOSV_DISPLAYSETUP_UPSCALING[] = { 1, 2, 4, 8, 16, }; +static MenuOptionSet_t MEOS_DISPLAYSETUP_UPSCALING = MAKE_MENUOPTIONSET( MEOSN_DISPLAYSETUP_UPSCALING, MEOSV_DISPLAYSETUP_UPSCALING, 0x0 ); +static MenuOption_t MEO_DISPLAYSETUP_UPSCALING = MAKE_MENUOPTION( &MF_Redfont, &MEOS_DISPLAYSETUP_UPSCALING, &ud.detail ); +static MenuEntry_t ME_DISPLAYSETUP_UPSCALING = MAKE_MENUENTRY( "Upscaling:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_UPSCALING, Option ); #ifndef EDUKE32_ANDROID_MENU @@ -733,7 +736,7 @@ static MenuEntry_t *MEL_DISPLAYSETUP[] = { &ME_DISPLAYSETUP_VIDEOSETUP, &ME_DISPLAYSETUP_ASPECTRATIO, #endif - &ME_DISPLAYSETUP_PIXELDOUBLING, + &ME_DISPLAYSETUP_UPSCALING, }; #ifdef USE_OPENGL @@ -1992,7 +1995,7 @@ static void Menu_Pre(MenuID_t cm) MenuEntry_DisableOnCondition(&ME_VIDEOSETUP_FULLSCREEN, !(resolution[nr].flags & RES_FS)); MenuEntry_DisableOnCondition(&ME_VIDEOSETUP_APPLY, - (xdim == resolution[nr].xdim && ydim == resolution[nr].ydim && + (xres == resolution[nr].xdim && yres == resolution[nr].ydim && videoGetRenderMode() == newrendermode && fullscreen == newfullscreen && vsync == newvsync ) @@ -3031,7 +3034,7 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry) if (entry == &ME_VIDEOSETUP_APPLY) { - resolution_t p = { xdim, ydim, fullscreen, bpp, 0 }; + resolution_t p = { xres, yres, fullscreen, bpp, 0 }; int32_t prend = videoGetRenderMode(); int32_t pvsync = vsync; @@ -3041,9 +3044,9 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry) int32_t nrend = newrendermode; int32_t nvsync = newvsync; - if (videoSetGameMode(n.flags, n.xdim, n.ydim, n.bppmax) < 0) + if (videoSetGameMode(n.flags, n.xdim, n.ydim, n.bppmax, upscalefactor) < 0) { - if (videoSetGameMode(p.flags, p.xdim, p.ydim, p.bppmax) < 0) + if (videoSetGameMode(p.flags, p.xdim, p.ydim, p.bppmax, upscalefactor) < 0) { videoSetRenderMode(prend); G_GameExit("Failed restoring old video mode."); @@ -3061,8 +3064,8 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry) videoSetRenderMode(nrend); vsync = videoSetVsync(nvsync); ud.config.ScreenMode = fullscreen; - ud.config.ScreenWidth = xdim; - ud.config.ScreenHeight = ydim; + ud.config.ScreenWidth = xres; + ud.config.ScreenHeight = yres; ud.config.ScreenBPP = bpp; } else if (entry == &ME_SOUND_RESTART) @@ -3271,6 +3274,13 @@ static void Menu_EntryOptionDidModify(MenuEntry_t *entry) entry == &ME_PLAYER_COLOR || entry == &ME_PLAYER_TEAM) G_UpdatePlayerFromMenu(); + else if (entry == &ME_DISPLAYSETUP_UPSCALING) + { + if (in3dmode()) + { + videoSetGameMode(fullscreen, xres, yres, bpp, ud.detail); + } + } #ifdef USE_OPENGL else if (entry == &ME_DISPLAYSETUP_ANISOTROPY || entry == &ME_DISPLAYSETUP_TEXFILTER) gltexapplyprops(); @@ -3290,7 +3300,7 @@ static void Menu_EntryOptionDidModify(MenuEntry_t *entry) if (domodechange) { videoResetMode(); - if (videoSetGameMode(fullscreen, xdim, ydim, bpp)) + if (videoSetGameMode(fullscreen, xres, yres, bpp, upscalefactor)) OSD_Printf("restartvid: Reset failed...\n"); onvideomodechange(ud.config.ScreenBPP>8); G_RefreshLights(); @@ -4048,7 +4058,7 @@ static void Menu_AboutToStartDisplaying(Menu_t * m) newresolution = 0; for (size_t i = 0; i < MAXVALIDMODES; ++i) { - if (resolution[i].xdim == xdim && resolution[i].ydim == ydim) + if (resolution[i].xdim == xres && resolution[i].ydim == yres) { newresolution = i; break; diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index 66ab6067c..01557ecd9 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -420,7 +420,7 @@ int32_t osdcmd_restartvid(osdfuncparm_t const * const UNUSED(parm)) { UNREFERENCED_CONST_PARAMETER(parm); videoResetMode(); - if (videoSetGameMode(ud.config.ScreenMode,ud.config.ScreenWidth,ud.config.ScreenHeight,ud.config.ScreenBPP)) + if (videoSetGameMode(ud.config.ScreenMode,ud.config.ScreenWidth,ud.config.ScreenHeight,ud.config.ScreenBPP,ud.detail)) G_GameExit("restartvid: Reset failed...\n"); onvideomodechange(ud.config.ScreenBPP>8); G_UpdateScreenArea(); @@ -471,10 +471,10 @@ static int32_t osdcmd_vidmode(osdfuncparm_t const * const parm) break; } - if (videoSetGameMode(newfs,newwidth,newheight,newbpp)) + if (videoSetGameMode(newfs,newwidth,newheight,newbpp,upscalefactor)) { initprintf("vidmode: Mode change failed!\n"); - if (videoSetGameMode(ud.config.ScreenMode, ud.config.ScreenWidth, ud.config.ScreenHeight, ud.config.ScreenBPP)) + if (videoSetGameMode(ud.config.ScreenMode, ud.config.ScreenWidth, ud.config.ScreenHeight, ud.config.ScreenBPP, upscalefactor)) G_GameExit("vidmode: Reset failed!\n"); } ud.config.ScreenBPP = newbpp; @@ -1490,7 +1490,14 @@ static int32_t osdcmd_cvar_set_game(osdfuncparm_t const * const parm) if (r != OSDCMD_OK) return r; - if (!Bstrcasecmp(parm->name, "r_size")) + if (!Bstrcasecmp(parm->name, "r_upscalefactor")) + { + if (in3dmode()) + { + videoSetGameMode(fullscreen, xres, yres, bpp, ud.detail); + } + } + else if (!Bstrcasecmp(parm->name, "r_size")) { ud.statusbarmode = (ud.screen_size < 8); G_UpdateScreenArea(); @@ -1709,7 +1716,7 @@ int32_t registerosdcommands(void) { "r_shadows", "enable/disable sprite and model shadows", (void *)&ud.shadows, CVAR_BOOL, 0, 1 }, { "r_size", "change size of viewable area", (void *)&ud.screen_size, CVAR_INT|CVAR_FUNCPTR, 0, 64 }, { "r_rotatespritenowidescreen", "pass bit 1024 to all CON rotatesprite calls", (void *)&g_rotatespriteNoWidescreen, CVAR_BOOL|CVAR_FUNCPTR, 0, 1 }, - { "r_pixeldoubling", "enable/disable pixel doubling in the software renderer", (void *) &ud.detail, CVAR_BOOL, 0, 1 }, + { "r_upscalefactor", "increase performance by rendering at upscalefactor less than the screen resolution and upscale to the full resolution in the software renderer", (void *)&ud.detail, CVAR_INT|CVAR_FUNCPTR, 1, 16 }, { "r_precache", "enable/disable the pre-level caching routine", (void *)&ud.config.useprecache, CVAR_BOOL, 0, 1 }, { "r_ambientlight", "sets the global map light level",(void *)&r_ambientlight, CVAR_FLOAT|CVAR_FUNCPTR, 0, 10 }, diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index c9eb2ccff..645822a8a 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -30,9 +30,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # include "lunatic_game.h" #endif -halfdimen_t g_halfScreen; -int32_t g_halveScreenArea = 0; - static int32_t g_whichPalForPlayer = 9; static uint8_t precachehightile[2][MAXTILES>>3]; @@ -566,19 +563,6 @@ void G_UpdateScreenArea(void) y2 = ud.returnvar[2]; } - if (g_halveScreenArea) - { - int32_t ourxdimen=x2-x1, ourydimen=y2-y1; - - g_halfScreen.x1 = x1; - g_halfScreen.y1 = y1; - g_halfScreen.xdimen = (ourxdimen>>1); - g_halfScreen.ydimen = (ourydimen>>1); - - x2 = x1 + (ourxdimen>>1); - y2 = y1 + (ourydimen>>1); - } - videoSetViewableArea(x1,y1,x2-1,y2-1); } @@ -1772,7 +1756,7 @@ int G_EnterLevel(int gameMode) FX_StopAllSounds(); S_ClearSoundLocks(); FX_SetReverb(0); - videoSetGameMode(ud.config.ScreenMode, ud.config.ScreenWidth, ud.config.ScreenHeight, ud.config.ScreenBPP); + videoSetGameMode(ud.config.ScreenMode, ud.config.ScreenWidth, ud.config.ScreenHeight, ud.config.ScreenBPP, upscalefactor); } if (Menu_HaveUserMap()) diff --git a/source/duke3d/src/premap.h b/source/duke3d/src/premap.h index 0a0d51e7e..5b554cd51 100644 --- a/source/duke3d/src/premap.h +++ b/source/duke3d/src/premap.h @@ -27,14 +27,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. extern "C" { #endif -typedef struct { - int32_t x1, y1; - int32_t xdimen, ydimen; -} halfdimen_t; - -extern halfdimen_t g_halfScreen; -extern int32_t g_halveScreenArea; - extern int32_t g_levelTextTime; extern int32_t voting,vote_map,vote_episode; extern palette_t CrosshairColors; diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index fd27c1929..46a60ba79 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -1212,7 +1212,7 @@ void G_DisplayRest(int32_t smoothratio) int32_t a = VM_OnEventWithReturn(EVENT_DISPLAYPOINTER, g_player[screenpeek].ps->i, screenpeek, CROSSHAIR); if ((unsigned) a < MAXTILES) { - vec2_t pointerpos = { ud.returnvar[0], ud.returnvar[1] }; + vec2_t pointerpos = { tabledivide32(ud.returnvar[0], upscalefactor), tabledivide32(ud.returnvar[1], upscalefactor) }; uint8_t pointer_pal = CROSSHAIR_PAL; uint32_t pointer_o = 1|2; uint32_t pointer_scale = 65536;