Reimplement pixel doubling by drawing scene at 1/(2*2) resolution and expanding.

The pixel doubling now only applies to the area where the world scene is drawn,
i.e. it may be smaller than the physical screen / WM window size. The optimized
version is slightly faster than for non-doubled pixels for me (optimized build),
but see code for caveats. Some other minor issues:
- won't work when the world is drawn from demo cameras (and offscreen, but that
  matters less)
- will leave a few pixels empty when running with x resolutions not evenly
  divisible by 4

git-svn-id: https://svn.eduke32.com/eduke32@3421 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-01-20 21:17:31 +00:00
parent f132c9230f
commit cbb4d3c6eb
3 changed files with 64 additions and 20 deletions

View file

@ -3584,6 +3584,7 @@ void G_DrawRooms(int32_t snum, int32_t smoothratio)
const int32_t vr = divscale22(1,sprite[p->i].yrepeat+28); const int32_t vr = divscale22(1,sprite[p->i].yrepeat+28);
const int32_t software_screen_tilting = const int32_t software_screen_tilting =
(getrendermode() == REND_CLASSIC && ((ud.screen_tilting && p->rotscrnang && !g_fakeMultiMode))); (getrendermode() == REND_CLASSIC && ((ud.screen_tilting && p->rotscrnang && !g_fakeMultiMode)));
int32_t pixelDoubling = 0;
if (!r_usenewaspect) if (!r_usenewaspect)
{ {
@ -3667,13 +3668,19 @@ void G_DrawRooms(int32_t snum, int32_t smoothratio)
tmpvr = i>>1; tmpvr = i>>1;
tmpyx = (65536*ydim*8)/(xdim*5); tmpyx = (65536*ydim*8)/(xdim*5);
} }
else if (getrendermode() >= REND_POLYMOST && (ud.screen_tilting && !g_fakeMultiMode) /*&& (p->rotscrnang || p->orotscrnang)*/) else if (getrendermode() >= REND_POLYMOST && (ud.screen_tilting && !g_fakeMultiMode))
{ {
#ifdef USE_OPENGL #ifdef USE_OPENGL
setrollangle(p->orotscrnang + mulscale16(((p->rotscrnang - p->orotscrnang + 1024)&2047)-1024, smoothratio)); setrollangle(p->orotscrnang + mulscale16(((p->rotscrnang - p->orotscrnang + 1024)&2047)-1024, smoothratio));
#endif #endif
p->orotscrnang = p->rotscrnang; // JBF: save it for next time p->orotscrnang = p->rotscrnang; // JBF: save it for next time
} }
else if (!ud.detail && getrendermode()==REND_CLASSIC)
{
pixelDoubling = 1;
g_halveScreenArea = 1;
G_UpdateScreenArea();
}
if (p->newowner < 0) if (p->newowner < 0)
{ {
@ -3837,27 +3844,40 @@ void G_DrawRooms(int32_t snum, int32_t smoothratio)
rotatesprite_win(160<<16,100<<16,i,tang+512,TILE_TILT,0,0,4+2+64); rotatesprite_win(160<<16,100<<16,i,tang+512,TILE_TILT,0,0,4+2+64);
walock[TILE_TILT] = 199; walock[TILE_TILT] = 199;
} }
} else if (pixelDoubling)
if (!ud.detail && getrendermode()==REND_CLASSIC && ((xdim|ydim)&1)==0)
{ {
Bassert(g_halfScreen.xdimen!=0);
g_halveScreenArea = 0;
G_UpdateScreenArea();
begindrawing(); begindrawing();
{ {
uint8_t *const f = (uint8_t *)frameplace; uint8_t *const f = (uint8_t *)frameplace;
int32_t x, y; 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;
for (x=0; x<xdim; x+=2) // Commented out: naive, per-byte access version.
for (y=0; y<ydim; y+=2) // 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 yl0 = ylookup[y]; const int32_t ylsrc = ylookup[y1+(dy>>1)];
const int32_t yl1 = ylookup[y+1]; const int32_t yldst = ylookup[y1+dy];
uint8_t newpal = f[yl0+x]; // f[yldst+x1+dx] = f[ylsrc+x1+(dx>>1)];
f[yl0+x] = f[yl0+x+1] = f[yl1+x] = f[yl1+x+1] = newpal; uint8_t pixr = f[ylsrc+x1+((dx+3)>>1)];
uint8_t pixl = f[ylsrc+x1+((dx+1)>>1)];
*(uint32_t *)&f[yldst+x1+dx] = pixl|(pixl<<8)|(pixr<<16)|(pixr<<24);
} }
} }
enddrawing(); enddrawing();
} }
}
G_RestoreInterpolations(); G_RestoreInterpolations();

View file

@ -43,6 +43,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
int32_t g_testLua = 0; int32_t g_testLua = 0;
#endif #endif
halfdimen_t g_halfScreen;
int32_t g_halveScreenArea = 0;
static int32_t g_whichPalForPlayer = 9; static int32_t g_whichPalForPlayer = 9;
static uint8_t precachehightile[2][MAXTILES>>3]; static uint8_t precachehightile[2][MAXTILES>>3];
@ -589,7 +592,7 @@ void G_UpdateScreenArea(void)
const int32_t ss = max(ud.screen_size-8,0); const int32_t ss = max(ud.screen_size-8,0);
const int32_t x1 = scale(ss,xdim,160); const int32_t x1 = scale(ss,xdim,160);
const int32_t x2 = xdim-x1; int32_t x2 = xdim-x1;
int32_t y1 = ss; int32_t y1 = ss;
int32_t y2 = 200; int32_t y2 = 200;
@ -611,9 +614,22 @@ void G_UpdateScreenArea(void)
y2 -= (ss+scale(tilesizy[BOTTOMSTATUSBAR],ud.statusbarscale,100)); y2 -= (ss+scale(tilesizy[BOTTOMSTATUSBAR],ud.statusbarscale,100));
y1 = scale(y1,ydim,200); y1 = scale(y1,ydim,200);
y2 = scale(y2,ydim,200); y2 = scale(y2,ydim,200)+(getrendermode() != REND_CLASSIC);
setview(x1,y1,x2-1,y2-(getrendermode() == REND_CLASSIC)); 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);
}
setview(x1,y1,x2-1,y2-1);
} }
G_GetCrosshairColor(); G_GetCrosshairColor();

View file

@ -23,6 +23,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __premap_h__ #ifndef __premap_h__
#define __premap_h__ #define __premap_h__
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 g_levelTextTime;
extern int32_t g_numRealPalettes; extern int32_t g_numRealPalettes;
extern int32_t voting,vote_map,vote_episode; extern int32_t voting,vote_map,vote_episode;