Backported the new aspect ratio code (and related fixes) from mainline...

Backported the new aspect ratio code (and related fixes) from mainline EDuke32. Too many revisions pulled from to list.
parent 251bb5d1
......@@ -27,6 +27,8 @@ extern int startwin_settitle(const char *);
extern int startwin_idle(void *);
// video
extern int32_t r_usenewaspect, newaspect_enable;
extern uint32_t r_screenxy;
extern int xres, yres, bpp, fullscreen, bytesperline, imageSize;
extern intptr_t frameplace;
extern char offscreenrendering;
......@@ -42,13 +44,13 @@ struct glinfo {
const char *version;
const char *extensions;
float maxanisotropy;
char bgra;
char clamptoedge;
char texcompr;
char texnpot;
char multisample;
char nvmultisamplehint;
float maxanisotropy;
char bgra;
char clamptoedge;
char texcompr;
char texnpot;
char multisample;
char nvmultisamplehint;
char arbfp;
char depthtex;
char shadow;
......
......@@ -464,6 +464,7 @@ void squarerotatetile(short tilenume);
int setgamemode(char davidoption, int daxdim, int daydim, int dabpp);
void nextpage(void);
void setaspect_new();
void setview(int x1, int y1, int x2, int y2);
void setaspect(int daxrange, int daaspect);
void flushperms(void);
......
......@@ -492,5 +492,33 @@ char *Bstrupr(char *);
}
#endif
////////// Language tricks that depend on size_t //////////
#if defined _MSC_VER
# define ARRAY_SIZE(arr) _countof(arr)
#elif defined HAVE_CONSTEXPR
template <typename T, size_t N>
static FORCE_INLINE constexpr size_t ARRAY_SIZE(T const (&)[N]) noexcept
{
return N;
}
#elif defined __cplusplus
struct bad_arg_to_ARRAY_SIZE
{
class Is_pointer; // incomplete
class Is_array {};
template <typename T>
static Is_pointer check_type(const T*, const T* const*);
static Is_array check_type(const void*, const void*);
};
# define ARRAY_SIZE(arr) ( \
0 * sizeof(reinterpret_cast<const ::bad_arg_to_ARRAY_SIZE*>(arr)) + \
0 * sizeof(::bad_arg_to_ARRAY_SIZE::check_type((arr), &(arr))) + \
sizeof(arr) / sizeof((arr)[0]) )
#else
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
#define ARRAY_SSIZE(arr) (signed)ARRAY_SIZE(arr)
#endif // __compat_h__
......@@ -218,6 +218,16 @@ static int osdcmd_vars(const osdfuncparm_t *parm)
if (showval) { OSD_Printf("r_voxels is %d\n", usevoxels); }
else { usevoxels = (atoi(parm->parms[0]) != 0); }
}
else if (!Bstrcasecmp(parm->name, "r_usenewaspect"))
{
if (showval) { OSD_Printf("r_usenewaspect is %d\n", r_usenewaspect); }
else { r_usenewaspect = (atoi(parm->parms[0]) != 0); }
}
else if (!Bstrcasecmp(parm->name, "r_screenaspect"))
{
if (showval) { OSD_Printf("r_screenaspect is %d\n", r_screenxy); }
else { r_screenxy = (atoi(parm->parms[0]) != 0); }
}
#endif
return OSDCMD_SHOWHELP;
}
......@@ -239,6 +249,8 @@ int baselayer_init(void)
#endif
OSD_RegisterFunction("r_scrcaptureformat","r_scrcaptureformat: sets the output format for screenshots (TGA or PCX)",osdcmd_vars);
#ifdef SUPERBUILD
OSD_RegisterFunction("r_usenewaspect", "r_usenewaspect: enable/disable new screen aspect ratio determination code", osdcmd_vars);
OSD_RegisterFunction("r_screenaspect", "r_screenaspect: if using the new aspect code and in fullscreen, screen aspect ratio in the form XXYY, e.g. 1609 for 16:9", osdcmd_vars);
OSD_RegisterFunction("r_novoxmips","r_novoxmips: turn off/on the use of mipmaps when rendering 8-bit voxels",osdcmd_vars);
OSD_RegisterFunction("r_voxels","r_voxels: enable/disable automatic sprite->voxel rendering",osdcmd_vars);
#endif
......
......@@ -76,6 +76,10 @@ int dommxoverlay = 1, beforedrawrooms = 1, indrawroomsandmasks = 0;
static int oxdimen = -1, oviewingrange = -1, oxyaspect = -1;
// r_usenewaspect is the cvar, newaspect_enable to trigger the new behaviour in the code
int32_t r_usenewaspect = 1, newaspect_enable = 0;
uint32_t r_screenxy = 403; // 4:3 aspect ratio
int curbrightness = 0, gammabrightness = 0;
double vid_gamma = DEFAULT_GAMMA;
......@@ -3557,7 +3561,7 @@ static void drawsprite(int snum)
x = (xp1-globalposx) + scale(xp2-xp1,z1,z1-z2);
y = (yp1-globalposy) + scale(yp2-yp1,z1,z1-z2);
yp1 = dmulscale14(x,cosglobalang,y,singlobalang);
yp1 = dmulscale14(x, cosviewingrangeglobalang, y, sinviewingrangeglobalang);
if (yp1 > 0)
{
xp1 = dmulscale14(y,cosglobalang,-x,singlobalang);
......@@ -5917,7 +5921,9 @@ void drawrooms(int daposx, int daposy, int daposz,
globalposx = daposx; globalposy = daposy; globalposz = daposz;
globalang = (daang&2047);
globalhoriz = mulscale16(dahoriz-100,xdimenscale)+(ydimen>>1);
// xdimenscale is scale(xdimen,yxaspect,320);
// normalization by viewingrange so that center-of-aim doesn't depend on it
globalhoriz = mulscale16(dahoriz - 100, divscale16(xdimenscale, viewingrange)) + (ydimen >> 1);
globaluclip = (0-globalhoriz)*xdimscale;
globaldclip = (ydimen-globalhoriz)*xdimscale;
......@@ -6552,6 +6558,8 @@ void drawmapview(int dax, int day, int zoome, short ang)
int xvect, yvect, xvect2, yvect2, daslope;
int32_t oydim = ydim;
int32_t oyxaspect = yxaspect, oviewingrange = viewingrange;
ydim = (int32_t)((double)xdim * 0.625f);
setaspect(65536L, (int32_t)divscale16(ydim * 320L, xdim * 200L));
ydim = oydim;
......@@ -6831,7 +6839,10 @@ void drawmapview(int dax, int day, int zoome, short ang)
}
enddrawing(); //}}}
setaspect(65536L, (int32_t)divscale16(ydim * 320L, xdim * 200L));
if (r_usenewaspect)
setaspect(oviewingrange, oyxaspect);
else
setaspect(65536L, (int32_t)divscale16(ydim * 320L, xdim * 200L));
}
......@@ -9830,6 +9841,43 @@ void getzrange(int x, int y, int z, short sectnum,
}
}
int32_t setaspect_new_use_dimen = 0;
void setaspect_new()
{
if (r_usenewaspect && newaspect_enable && getrendermode() != 4)
{
// the correction factor 100/107 has been found
// out experimentally. squares ftw!
int32_t vr, yx = (65536 * 4 * 100) / (3 * 107);
int32_t y, x;
const int32_t xd = setaspect_new_use_dimen ? xdimen : xdim;
const int32_t yd = setaspect_new_use_dimen ? ydimen : ydim;
if (fullscreen)
{
int32_t pixratio;
x = r_screenxy / 100; y = r_screenxy % 100;
if (y == 0 || x == 0) { x = 4; y = 3; }
pixratio = divscale16(xd*y, yd*x);
yx = divscale16(yx, pixratio);
}
else
{
x = xd;
y = yd;
}
vr = divscale16(x * 3, y * 4);
setaspect(vr, yx);
}
else
setaspect(65536, divscale16(ydim * 320, xdim * 200));
}
//
// setview
......@@ -9847,7 +9895,7 @@ void setview(int x1, int y1, int x2, int y2)
xdimenrecip = divscale32(1L,xdimen);
ydimen = (y2-y1)+1;
setaspect(65536L,(int)divscale16(ydim*320L,xdim*200L));
setaspect_new();
for (i=0;i<windowx1;i++) { startumost[i] = 1, startdmost[i] = 0; }
for (i=windowx1;i<=windowx2;i++)
......
......@@ -1038,7 +1038,7 @@ void resizeglcheck()
{
double ratio = 1.05;
if (glwidescreen == 1)
if (glwidescreen && !r_usenewaspect)
ratio = 1.2f;
else if (glprojectionhacks == 1)
{
......@@ -1056,9 +1056,12 @@ void resizeglcheck()
glox1 = windowx1; gloy1 = windowy1;
glox2 = windowx2; gloy2 = windowy2;
fovcorrect = glprojectionhacks?(glwidescreen?0:(((windowx2-windowx1+1) * ratio) - (windowx2-windowx1+1))):0;
fovcorrect = (int32_t)(glprojectionhacks ?
((glwidescreen && !r_usenewaspect) ? 0 :
(((windowx2 - windowx1 + 1) * ratio) - (windowx2 - windowx1 + 1))) : 0);
bglViewport(windowx1 - (fovcorrect / 2), yres-(windowy2+1),windowx2-windowx1+1 + fovcorrect, windowy2-windowy1+1);
bglViewport(windowx1 - (fovcorrect / 2), yres - (windowy2 + 1),
windowx2 - windowx1 + 1 + fovcorrect, windowy2 - windowy1 + 1);
bglMatrixMode(GL_PROJECTION);
memset(m,0,sizeof(m));
......@@ -4431,7 +4434,7 @@ void polymost_drawrooms()
int cz, fz;
double ratio = 1.05;
if (glwidescreen == 1)
if (glwidescreen)
ratio = 1.2f;
else if (glprojectionhacks == 1)
{
......@@ -5485,10 +5488,11 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16
{
x = xdimenscale; //= scale(xdimen,yxaspect,320);
if (!(dastat & 1024) && ((double)ydim / (double)xdim) <= .75f)
if (!(dastat & 1024) && 4 * ydim <= 3 * xdim)
{
xdim = (int32_t)((double)ydim * 1.33333333333333334f);
setaspect(65536L, (int32_t)divscale16(ydim * 320L, xdim * 200L));
xdim = (4 * ydim) / 3;
// aspect is divscale16(ydim*320, xdim*200)
setaspect(65536, (12 << 16) / 10);
}
if (dastat & 512)
......@@ -5505,10 +5509,10 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16
//If not clipping to startmosts, & auto-scaling on, as a
//hard-coded bonus, scale to full screen instead
if (!(dastat & 1024) && ((double)ydim / (double)xdim) <= .75f)
if (!(dastat & 1024) && 4 * ydim <= 3 * xdim)
{
xdim = (int32_t)((double)ydim * 1.33333333333333334f);
setaspect(65536L, (int32_t)divscale16(ydim * 320L, xdim * 200L));
xdim = (4 * ydim) / 3;
setaspect(65536, (12 << 16) / 10);
}
x = scale(xdim, yxaspect, 320);
......@@ -5524,8 +5528,7 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16
}
else if (!(dastat & 1024) && ((double)ydim / (double)xdim) <= .75f)
{
ydim = (int32_t)((double)xdim * 0.75f);
setaspect(65536L, (int32_t)divscale16(ydim * 320L, xdim * 200L));
setaspect(65536, (12 << 16) / 10);
}
d = (double)z/(65536.0*16384.0);
......@@ -5631,7 +5634,8 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16
gstang = ogstang;
xdim = oxdim;
ydim = oydim;
setaspect(65536L, (int32_t)divscale16(ydim * 320L, xdim * 200L));
setaspect_new();
}
#ifdef USE_OPENGL
......
......@@ -565,6 +565,30 @@ static void print_os_version(void)
}
}
static void divcommon(int32_t *ap, int32_t *bp)
{
const int32_t p[] = { 2,3,5,7,11,13,17,19 };
const int32_t N = (int32_t)ARRAY_SIZE(p);
int32_t a = *ap, b = *bp;
while (1)
{
int32_t i;
for (i = 0; i<N; i++)
if (a%p[i] == 0 && b%p[i] == 0)
{
a /= p[i];
b /= p[i];
break;
}
if (i == N)
break;
}
*ap = a;
*bp = b;
}
int initsystem(void)
{
......@@ -602,6 +626,22 @@ int initsystem(void)
}
#endif
// determine physical screen size
{
const int32_t oscreenx = GetSystemMetrics(SM_CXSCREEN);
const int32_t oscreeny = GetSystemMetrics(SM_CYSCREEN);
int32_t screenx = oscreenx, screeny = oscreeny, good = 0;
divcommon(&screenx, &screeny);
if (screenx >= 1 && screenx <= 99 && screeny >= 1 && screeny <= 99)
r_screenxy = screenx * 100 + screeny, good = 1;
if (!good)
initprintf("Automatic fullscreen size determination failed! %d %d -> %d %d.\n",
oscreenx, oscreeny, screenx, screeny);
}
// try and start DirectDraw
if (InitDirectDraw())
initprintf("DirectDraw initialization failed. Fullscreen modes will be unavailable.\n");
......@@ -787,11 +827,11 @@ static struct _joydevicedefn *thisjoydef = NULL, joyfeatures[] =
// I don't see any pressing need to store the key-up events yet
#define SetKey(key,state) { \
keystatus[remap[key]] = state; \
if (state) { \
if (state) { \
keyfifo[keyfifoend] = remap[key]; \
keyfifo[(keyfifoend+1)&(KEYFIFOSIZ-1)] = state; \
keyfifoend = ((keyfifoend+2)&(KEYFIFOSIZ-1)); \
} \
keyfifo[(keyfifoend+1)&(KEYFIFOSIZ-1)] = state; \
keyfifoend = ((keyfifoend+2)&(KEYFIFOSIZ-1)); \
} \
}
char map_dik_code(int scanCode)
......@@ -1283,13 +1323,13 @@ static BOOL CALLBACK InitDirectInput_enum(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRe
// Outputs the GUID of the joystick to the console
/*
initprintf("GUID = {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
lpddi->guidProduct.Data1,
lpddi->guidProduct.Data2, lpddi->guidProduct.Data3,
lpddi->guidProduct.Data4[0], lpddi->guidProduct.Data4[1],
lpddi->guidProduct.Data4[2], lpddi->guidProduct.Data4[3],
lpddi->guidProduct.Data4[4], lpddi->guidProduct.Data4[5],
lpddi->guidProduct.Data4[6], lpddi->guidProduct.Data4[7]
);
lpddi->guidProduct.Data1,
lpddi->guidProduct.Data2, lpddi->guidProduct.Data3,
lpddi->guidProduct.Data4[0], lpddi->guidProduct.Data4[1],
lpddi->guidProduct.Data4[2], lpddi->guidProduct.Data4[3],
lpddi->guidProduct.Data4[4], lpddi->guidProduct.Data4[5],
lpddi->guidProduct.Data4[6], lpddi->guidProduct.Data4[7]
);
*/
}
break;
......@@ -1356,9 +1396,9 @@ static BOOL CALLBACK InitDirectInput_enumobjects(LPCDIDEVICEOBJECTINSTANCE lpddo
}
#define HorribleDInputDeath( x, y ) \
ShowDInputErrorBox(x,y); \
UninitDirectInput(); \
return TRUE
ShowDInputErrorBox(x,y); \
UninitDirectInput(); \
return TRUE
static BOOL InitDirectInput(void)
{
......@@ -2245,15 +2285,15 @@ int setvideomode(int x, int y, int c, int fs)
// getvalidmodes() -- figure out what video modes are available
//
#define ADDMODE(x,y,c,f,n) if (validmodecnt<MAXVALIDMODES) { \
validmode[validmodecnt].xdim=x; \
validmode[validmodecnt].ydim=y; \
validmode[validmodecnt].bpp=c; \
validmode[validmodecnt].fs=f; \
validmode[validmodecnt].extra=n; \
validmodecnt++; \
validmode[validmodecnt].xdim=x; \
validmode[validmodecnt].ydim=y; \
validmode[validmodecnt].bpp=c; \
validmode[validmodecnt].fs=f; \
validmode[validmodecnt].extra=n; \
validmodecnt++; \
}
/* initprintf(" - %dx%d %d-bit %s\n", x, y, c, (f&1)?"fullscreen":"windowed"); \
} */
} */
#define CHECK(w,h) if ((w < maxx) && (h < maxy))
......@@ -2725,16 +2765,16 @@ int setpalette(int start, int num)
/*
int getpalette(int start, int num, char *dapal)
{
int i;
int i;
for (i=num; i>0; i--, start++) {
dapal[0] = curpalette[start].b >> 2;
dapal[1] = curpalette[start].g >> 2;
dapal[2] = curpalette[start].r >> 2;
dapal += 4;
}
for (i=num; i>0; i--, start++) {
dapal[0] = curpalette[start].b >> 2;
dapal[1] = curpalette[start].g >> 2;
dapal[2] = curpalette[start].r >> 2;
dapal += 4;
}
return 0;
return 0;
}*/
......
......@@ -255,6 +255,17 @@ static inline int sbarsc(int sc)
return scale(sc,ud.statusbarscale,100);
}
int32_t sbarx16(int32_t x)
{
if (ud.screen_size == 4) return sbarsc(x);
return (((320 << 16) - sbarsc(320 << 16)) >> 1) + sbarsc(x);
}
int32_t sbary16(int32_t y)
{
return (200 << 16) - sbarsc(200 << 16) + sbarsc(y);
}
static inline int textsc(int sc)
{
// prevent ridiculousness to a degree
......@@ -265,25 +276,17 @@ static inline int textsc(int sc)
return scale(sc,ud.textscale,100);
}
static void G_PatchStatusBar(int x1, int y1, int x2, int y2)
static void G_PatchStatusBar(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
{
int scl, tx, ty;
int clx1,cly1,clx2,cly2,clofx,clofy;
int32_t const scl = sbarsc(65536);
int32_t const tx = sbarx16((160 << 16) - (tilesizx[BOTTOMSTATUSBAR] << 15)); // centered
int32_t const ty = sbary(200 - tilesizy[BOTTOMSTATUSBAR]);
scl = sbarsc(65536);
tx = sbarx(0);
ty = sbary(200-tilesizy[BOTTOMSTATUSBAR]);
int32_t const clx1 = sbarsc(scale(x1, xdim, 320)), cly1 = sbarsc(scale(y1, ydim, 200));
int32_t const clx2 = sbarsc(scale(x2, xdim, 320)), cly2 = sbarsc(scale(y2, ydim, 200));
int32_t const clofx = (xdim - sbarsc(xdim)) >> 1, clofy = (ydim - sbarsc(ydim));
clx1 = scale(scale(x1,xdim,320),ud.statusbarscale,100);
cly1 = scale(scale(y1,ydim,200),ud.statusbarscale,100);
clx2 = scale(scale(x2,xdim,320),ud.statusbarscale,100);
cly2 = scale(scale(y2,ydim,200),ud.statusbarscale,100);
clofx = (xdim - scale(xdim,ud.statusbarscale,100)) >> 1;
clofy = (ydim - scale(ydim,ud.statusbarscale,100));
// if (ud.statusbarmode == 0)
rotatesprite(tx,ty,scl,0,BOTTOMSTATUSBAR,4,0,10+16+64,clx1+clofx,cly1+clofy,clx2+clofx-1,cly2+clofy-1);
// else rotatesprite(tx,ty,scl,0,BOTTOMSTATUSBAR,4,0,10+16+64,clx1,cly1,clx2+clofx-1,cly2+clofy-1);
rotatesprite(tx, ty, scl, 0, BOTTOMSTATUSBAR, 4, 0, 10 + 16 + 64, clx1 + clofx, cly1 + clofy, clx2 + clofx - 1, cly2 + clofy - 1);
}
void P_SetGamePalette(DukePlayer_t *player, char *pal, int set)
......@@ -4262,6 +4265,8 @@ static void G_DrawOverheadMap(int cposx, int cposy, int czoom, short cang)
}
}
setaspect_new();
TRAVERSE_CONNECT(p)
{
if (ud.scrollmode && p == screenpeek) continue;
......@@ -5173,9 +5178,11 @@ void G_DrawRooms(int snum,int smoothratio)
short tang;
int tiltcx,tiltcy,tiltcs=0; // JBF 20030807
int32_t tmpyx = yxaspect, tmpvr = viewingrange;
if (pub > 0 || getrendermode() >= 3) // JBF 20040101: redraw background always
{
if (getrendermode() >= 3 || ud.screen_size > 8 || (ud.screen_size == 8 && ud.statusbarscale<100))
if (ud.screen_size >= 8)
G_DrawBackground();
pub = 0;
}
......@@ -5183,6 +5190,12 @@ void G_DrawRooms(int snum,int smoothratio)
if (ud.overhead_on == 2 || ud.show_help || (p->cursectnum == -1 && getrendermode() < 3))
return;
if (r_usenewaspect)
{
newaspect_enable = 1;
setaspect_new();
}
// smoothratio = min(max(smoothratio,0),65536);
smoothratio = min(max((totalclock - ototalclock) * (65536 / TICSPERFRAME),0),65536);
......@@ -5220,10 +5233,21 @@ void G_DrawRooms(int snum,int smoothratio)
else
{
i = divscale22(1,sprite[p->i].yrepeat+28);
if (i != oyrepeat)
if (!r_usenewaspect)
{
// if (i != oyrepeat)
{
oyrepeat = i;
setaspect(oyrepeat, yxaspect);
}
}
else
{
oyrepeat = i;
setaspect(oyrepeat,yxaspect);
tmpvr = i;
tmpyx = (65536 * ydim * 8) / (xdim * 5);
setaspect(mulscale16(tmpvr, viewingrange), yxaspect);
}
if (g_screenCapture)
......@@ -5235,6 +5259,8 @@ void G_DrawRooms(int snum,int smoothratio)
}
else if (getrendermode() == 0 && ((ud.screen_tilting && p->rotscrnang) || ud.detail==0))
{
int32_t oviewingrange = viewingrange; // save it from setviewtotile()
if (ud.screen_tilting) tang = p->rotscrnang;
else tang = 0;
......@@ -5274,8 +5300,11 @@ void G_DrawRooms(int snum,int smoothratio)
i = (tang&511);
if (i > 256) i = 512-i;
i = sintable[i+512]*8 + sintable[i]*5L;
setaspect(i>>1,yxaspect);
i = sintable[i+512]*8 + sintable[i]*5;
setaspect(mulscale16(oviewingrange, i >> 1), yxaspect);
tmpvr = i >> 1;
tmpyx = (65536 * ydim * 8) / (xdim * 5);
}
else if (getrendermode() > 0 && ud.screen_tilting /*&& (p->rotscrnang || p->orotscrnang)*/)
{
......@@ -5415,7 +5444,7 @@ void G_DrawRooms(int snum,int smoothratio)
picanm[TILE_TILT] &= 0xff0000ff;
i = (tang&511);
if (i > 256) i = 512-i;
i = sintable[i+512]*8 + sintable[i]*5L;
i = sintable[i+512]*8 + sintable[i]*5;
if ((1-ud.detail) == 0) i >>= 1;
i>>=(tiltcs-1); // JBF 20030807
rotatesprite(160<<16,100<<16,i,tang+512,TILE_TILT,0,0,4+2+64,windowx1,windowy1,windowx2,windowy2);
......@@ -5432,6 +5461,12 @@ void G_DrawRooms(int snum,int smoothratio)
p->visibility += (ud.const_visibility-p->visibility)>>2;
}
else p->visibility = ud.const_visibility;
if (r_usenewaspect)
{
newaspect_enable = 0;
setaspect(tmpvr, tmpyx);
}
}
static void G_DumpDebugInfo(void)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment