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;