Widescreen mode based on Crispy Doom (#107)

* Partial widescreen implementation

* Draw patch fullscreen and various fixes

* Fix bunny scroll with wide assets

* Fix offsets in menu and automap widget

* Few fixes
This commit is contained in:
Roman Fomin 2021-01-25 19:52:25 +07:00 committed by GitHub
parent ee91e136e3
commit 25ac96403b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 353 additions and 88 deletions

View File

@ -635,14 +635,16 @@ void AM_Stop (void)
// //
void AM_Start() void AM_Start()
{ {
static int lastlevel = -1, lastepisode = -1, last_hires = -1; static int lastlevel = -1, lastepisode = -1, last_hires = -1, last_widescreen = -1;
if (!stopped) if (!stopped)
AM_Stop(); AM_Stop();
stopped = false; stopped = false;
if (lastlevel != gamemap || lastepisode != gameepisode || hires!=last_hires) if (lastlevel != gamemap || lastepisode != gameepisode || hires!=last_hires
|| widescreen != last_widescreen)
{ {
last_hires = hires; // killough 11/98 last_hires = hires; // killough 11/98
last_widescreen = widescreen;
AM_LevelInit(); AM_LevelInit();
lastlevel = gamemap; lastlevel = gamemap;
lastepisode = gameepisode; lastepisode = gameepisode;

View File

@ -372,7 +372,7 @@ void D_PageDrawer(void)
unsigned c = 0; unsigned c = 0;
while (s--) while (s--)
c = c*3 + t[s]; c = c*3 + t[s];
V_DrawPatch(0, 0, 0, (patch_t *) t); V_DrawPatchFullScreen(0, (patch_t *) t);
if (c==2119826587u || c==2391756584u) if (c==2119826587u || c==2391756584u)
// [FG] removed the embedded DOGOVRLY title pic overlay graphic lump // [FG] removed the embedded DOGOVRLY title pic overlay graphic lump
if (W_CheckNumForName("DOGOVRLY") > 0) if (W_CheckNumForName("DOGOVRLY") > 0)

View File

@ -104,11 +104,11 @@ extern int bfgedition;
// allows us to avoid the overhead of dynamic allocation // allows us to avoid the overhead of dynamic allocation
// when multiple screen sizes are supported // when multiple screen sizes are supported
#define MAX_SCREENWIDTH 640 #define ORIGWIDTH 320 // [crispy]
#define MAX_SCREENHEIGHT 400 #define ORIGHEIGHT 200 // [crispy]
#define SCREENWIDTH 320 #define MAX_SCREENWIDTH (ORIGWIDTH << 2) // [crispy]
#define SCREENHEIGHT 200 #define MAX_SCREENHEIGHT (ORIGHEIGHT << 1) // [crispy]
// The maximum number of players, multiplayer/networking. // The maximum number of players, multiplayer/networking.
#define MAXPLAYERS 4 #define MAXPLAYERS 4

View File

@ -607,7 +607,8 @@ void F_CastDrawer (void)
patch_t* patch; patch_t* patch;
// erase the entire screen to a background // erase the entire screen to a background
V_DrawPatch (0,0,0, W_CacheLumpName (bgcastcall, PU_CACHE)); // Ty 03/30/98 bg texture extern //V_DrawPatch (0,0,0, W_CacheLumpName (bgcastcall, PU_CACHE)); // Ty 03/30/98 bg texture extern
V_DrawPatchFullScreen(0, W_CacheLumpName (bgcastcall, PU_CACHE));
F_CastPrint (castorder[castnum].name); F_CastPrint (castorder[castnum].name);
@ -674,6 +675,7 @@ void F_BunnyScroll (void)
char name[10]; char name[10];
int stage; int stage;
static int laststage; static int laststage;
int p2offset, p1offset, pillar_width;
p1 = W_CacheLumpName ("PFUB2", PU_LEVEL); p1 = W_CacheLumpName ("PFUB2", PU_LEVEL);
p2 = W_CacheLumpName ("PFUB1", PU_LEVEL); p2 = W_CacheLumpName ("PFUB1", PU_LEVEL);
@ -686,20 +688,50 @@ void F_BunnyScroll (void)
if (scrolled < 0) if (scrolled < 0)
scrolled = 0; scrolled = 0;
for ( x=0 ; x<SCREENWIDTH ; x++) pillar_width = (SCREENWIDTH - p1->width) / 2;
if (pillar_width > 0)
{ {
if (x+scrolled < 320) // [crispy] fill pillarboxes in widescreen mode
F_DrawPatchCol (x, p1, x+scrolled); memset(screens[0], 0, (SCREENWIDTH<<hires) * (SCREENHEIGHT<<hires));
}
else else
F_DrawPatchCol (x, p2, x+scrolled - 320); {
pillar_width = 0;
}
// Calculate the portion of PFUB2 that would be offscreen at original res.
p1offset = (ORIGWIDTH - p1->width) / 2;
if (p2->width == ORIGWIDTH)
{
// Unity or original PFUBs.
// PFUB1 only contains the pixels that scroll off.
p2offset = ORIGWIDTH - p1offset;
}
else
{
// Widescreen mod PFUBs.
// Right side of PFUB2 and left side of PFUB1 are identical.
p2offset = ORIGWIDTH + p1offset;
}
for (x = pillar_width; x < SCREENWIDTH - pillar_width; x++)
{
int x2 = x - WIDESCREENDELTA + scrolled;
if (x2 < p2offset)
F_DrawPatchCol (x, p1, x2 - p1offset);
else
F_DrawPatchCol (x, p2, x2 - p2offset);
} }
if (finalecount < 1130) if (finalecount < 1130)
return; return;
if (finalecount < 1180) if (finalecount < 1180)
{ {
V_DrawPatch ((SCREENWIDTH-13*8)/2, V_DrawPatch ((ORIGWIDTH-13*8)/2,
(SCREENHEIGHT-8*8)/2,0, (ORIGHEIGHT-8*8)/2,0,
W_CacheLumpName ("END0",PU_CACHE)); W_CacheLumpName ("END0",PU_CACHE));
laststage = 0; laststage = 0;
return; return;
@ -715,8 +747,8 @@ void F_BunnyScroll (void)
} }
sprintf (name,"END%i",stage); sprintf (name,"END%i",stage);
V_DrawPatch ((SCREENWIDTH-13*8)/2, V_DrawPatch ((ORIGWIDTH-13*8)/2,
(SCREENHEIGHT-8*8)/2,0, (ORIGHEIGHT-8*8)/2,0,
W_CacheLumpName (name,PU_CACHE)); W_CacheLumpName (name,PU_CACHE));
} }

View File

@ -56,12 +56,12 @@ int hud_graph_keys=1; //jff 3/7/98 display HUD keys as graphics
#define HU_TITLEP (*mapnamesp[gamemap-1]) #define HU_TITLEP (*mapnamesp[gamemap-1])
#define HU_TITLET (*mapnamest[gamemap-1]) #define HU_TITLET (*mapnamest[gamemap-1])
#define HU_TITLEHEIGHT 1 #define HU_TITLEHEIGHT 1
#define HU_TITLEX 0 #define HU_TITLEX (0 - WIDESCREENDELTA)
//jff 2/16/98 change 167 to ST_Y-1 //jff 2/16/98 change 167 to ST_Y-1
#define HU_TITLEY (ST_Y - 1 - SHORT(hu_font[0]->height)) #define HU_TITLEY (ST_Y - 1 - SHORT(hu_font[0]->height))
//jff 2/16/98 add coord text widget coordinates //jff 2/16/98 add coord text widget coordinates
#define HU_COORDX (SCREENWIDTH - 13*SHORT(hu_font2['A'-HU_FONTSTART]->width)) #define HU_COORDX ((ORIGWIDTH - 13*SHORT(hu_font2['A'-HU_FONTSTART]->width)) + WIDESCREENDELTA)
//jff 3/3/98 split coord widget into three lines in upper right of screen //jff 3/3/98 split coord widget into three lines in upper right of screen
#define HU_COORDX_Y (1 + 0*SHORT(hu_font['A'-HU_FONTSTART]->height)) #define HU_COORDX_Y (1 + 0*SHORT(hu_font['A'-HU_FONTSTART]->height))
#define HU_COORDY_Y (2 + 1*SHORT(hu_font['A'-HU_FONTSTART]->height)) #define HU_COORDY_Y (2 + 1*SHORT(hu_font['A'-HU_FONTSTART]->height))
@ -557,13 +557,13 @@ void HU_Start(void)
HUlib_addCharToTextLine(&w_coordz, *s++); HUlib_addCharToTextLine(&w_coordz, *s++);
// [FG] initialize the level stats and level time widgets // [FG] initialize the level stats and level time widgets
HUlib_initTextLine(&w_lstatk, 0, HU_LSTATK_Y, hu_font, HUlib_initTextLine(&w_lstatk, 0-WIDESCREENDELTA, HU_LSTATK_Y, hu_font,
HU_FONTSTART, colrngs[hudcolor_mesg]); HU_FONTSTART, colrngs[hudcolor_mesg]);
HUlib_initTextLine(&w_lstati, 0, HU_LSTATI_Y, hu_font, HUlib_initTextLine(&w_lstati, 0-WIDESCREENDELTA, HU_LSTATI_Y, hu_font,
HU_FONTSTART, colrngs[hudcolor_mesg]); HU_FONTSTART, colrngs[hudcolor_mesg]);
HUlib_initTextLine(&w_lstats, 0, HU_LSTATS_Y, hu_font, HUlib_initTextLine(&w_lstats, 0-WIDESCREENDELTA, HU_LSTATS_Y, hu_font,
HU_FONTSTART, colrngs[hudcolor_mesg]); HU_FONTSTART, colrngs[hudcolor_mesg]);
HUlib_initTextLine(&w_ltime, 0, HU_LTIME_Y, hu_font, HUlib_initTextLine(&w_ltime, 0-WIDESCREENDELTA, HU_LTIME_Y, hu_font,
HU_FONTSTART, colrngs[hudcolor_mesg]); HU_FONTSTART, colrngs[hudcolor_mesg]);
sprintf(hud_lstatk, "K: %d/%d", 0, 0); sprintf(hud_lstatk, "K: %d/%d", 0, 0);

View File

@ -40,7 +40,7 @@
#define HU_BROADCAST 5 #define HU_BROADCAST 5
//#define HU_MSGREFRESH KEYD_ENTER // phares //#define HU_MSGREFRESH KEYD_ENTER // phares
#define HU_MSGX 0 #define HU_MSGX (0 - WIDESCREENDELTA)
#define HU_MSGY 0 #define HU_MSGY 0
#define HU_MSGWIDTH 64 /* in characters */ #define HU_MSGWIDTH 64 /* in characters */
#define HU_MSGHEIGHT 1 /* in lines */ #define HU_MSGHEIGHT 1 /* in lines */

View File

@ -47,6 +47,10 @@
#include "icon.c" #include "icon.c"
int SCREENWIDTH, SCREENHEIGHT;
int NONWIDEWIDTH; // [crispy] non-widescreen SCREENWIDTH
int WIDESCREENDELTA; // [crispy] horizontal widescreen offset
static SDL_Surface *sdlscreen; static SDL_Surface *sdlscreen;
// [FG] rendering window, renderer, intermediate ARGB frame buffer and texture // [FG] rendering window, renderer, intermediate ARGB frame buffer and texture
@ -689,6 +693,7 @@ static int useaspect, actualheight; // [FG] aspect ratio correction
int uncapped; // [FG] uncapped rendering frame rate int uncapped; // [FG] uncapped rendering frame rate
int integer_scaling; // [FG] force integer scales int integer_scaling; // [FG] force integer scales
int fps; // [FG] FPS counter widget int fps; // [FG] FPS counter widget
int widescreen; // widescreen mode
void I_FinishUpdate(void) void I_FinishUpdate(void)
{ {
@ -974,6 +979,62 @@ int cfg_aspectratio; // haleyjd 05/11/09: aspect ratio correction
// haleyjd 05/11/09: true if called from I_ResetScreen // haleyjd 05/11/09: true if called from I_ResetScreen
static boolean changeres = false; static boolean changeres = false;
// [crispy] re-calculate SCREENWIDTH, SCREENHEIGHT, NONWIDEWIDTH and WIDESCREENDELTA
void I_GetScreenDimensions(void)
{
SDL_DisplayMode mode;
int w = 16, h = 10;
int ah;
SCREENWIDTH = ORIGWIDTH;
SCREENHEIGHT = ORIGHEIGHT;
NONWIDEWIDTH = SCREENWIDTH;
ah = useaspect ? (6 * SCREENHEIGHT / 5) : SCREENHEIGHT;
if (SDL_GetCurrentDisplayMode(0/*video_display*/, &mode) == 0)
{
// [crispy] sanity check: really widescreen display?
if (mode.w * ah >= mode.h * SCREENWIDTH)
{
w = mode.w;
h = mode.h;
}
}
// [crispy] widescreen rendering makes no sense without aspect ratio correction
if (widescreen && useaspect)
{
// switch(crispy->widescreen)
// {
// case RATIO_16_10:
// w = 16;
// h = 10;
// break;
// case RATIO_16_9:
// w = 16;
// h = 9;
// break;
// case RATIO_21_9:
// w = 21;
// h = 9;
// break;
// default:
// break;
// }
SCREENWIDTH = w * ah / h;
// [crispy] make sure SCREENWIDTH is an integer multiple of 4 ...
SCREENWIDTH = (SCREENWIDTH + (hires ? 0 : 3)) & (int)~3;
// [crispy] ... but never exceeds MAXWIDTH (array size!)
SCREENWIDTH = MIN(SCREENWIDTH, MAX_SCREENWIDTH);
}
WIDESCREENDELTA = (SCREENWIDTH - NONWIDEWIDTH) / 2;
}
// //
// killough 11/98: New routine, for setting hires and page flipping // killough 11/98: New routine, for setting hires and page flipping
// //
@ -983,8 +1044,8 @@ static void I_InitGraphicsMode(void)
static boolean firsttime = true; static boolean firsttime = true;
// haleyjd // haleyjd
int v_w = SCREENWIDTH; int v_w = ORIGWIDTH;
int v_h = SCREENHEIGHT; int v_h = ORIGHEIGHT;
int flags = 0; int flags = 0;
int scalefactor = cfg_scalefactor; int scalefactor = cfg_scalefactor;
int usehires = hires; int usehires = hires;
@ -1005,11 +1066,22 @@ static void I_InitGraphicsMode(void)
usehires = hires = false; // grrr... usehires = hires = false; // grrr...
} }
useaspect = cfg_aspectratio;
if(M_CheckParm("-aspect"))
useaspect = true;
I_GetScreenDimensions();
if(usehires) if(usehires)
{ {
v_w = SCREENWIDTH*2; v_w = SCREENWIDTH*2;
v_h = SCREENHEIGHT*2; v_h = SCREENHEIGHT*2;
} }
else
{
v_w = SCREENWIDTH;
v_h = SCREENHEIGHT;
}
blit_rect.w = v_w; blit_rect.w = v_w;
blit_rect.h = v_h; blit_rect.h = v_h;
@ -1049,10 +1121,6 @@ static void I_InitGraphicsMode(void)
else if(M_CheckParm("-5")) else if(M_CheckParm("-5"))
scalefactor = 5; scalefactor = 5;
useaspect = cfg_aspectratio;
if(M_CheckParm("-aspect"))
useaspect = true;
actualheight = useaspect ? (6 * v_h / 5) : v_h; actualheight = useaspect ? (6 * v_h / 5) : v_h;
// [FG] create rendering window // [FG] create rendering window

View File

@ -32,6 +32,12 @@
#include "doomtype.h" #include "doomtype.h"
extern int SCREENWIDTH;
extern int SCREENHEIGHT;
extern int NONWIDEWIDTH; // [crispy] non-widescreen SCREENWIDTH
extern int WIDESCREENDELTA; // [crispy] horizontal widescreen offset
void I_GetScreenDimensions (void); // [crispy] re-calculate WIDESCREENDELTA
// [FG] support more joystick and mouse buttons // [FG] support more joystick and mouse buttons
#define MAX_JSB 12 #define MAX_JSB 12
#define MAX_MB 5 #define MAX_MB 5
@ -68,6 +74,7 @@ extern int hires; // killough 11/98
extern int uncapped; // [FG] uncapped rendering frame rate extern int uncapped; // [FG] uncapped rendering frame rate
extern int integer_scaling; // [FG] force integer scales extern int integer_scaling; // [FG] force integer scales
extern int widescreen; // widescreen mode
boolean I_WritePNGfile(char *filename); // [FG] screenshots in PNG format boolean I_WritePNGfile(char *filename); // [FG] screenshots in PNG format
#endif #endif

View File

@ -1784,6 +1784,7 @@ void M_DrawBackground(char* patchname, byte *back_dest)
back_dest += 64; back_dest += 64;
} }
#else // while this pixel-doubles it #else // while this pixel-doubles it
/*
for (y = 0 ; y < SCREENHEIGHT ; src = ((++y & 63)<<6) + back_src, for (y = 0 ; y < SCREENHEIGHT ; src = ((++y & 63)<<6) + back_src,
back_dest += SCREENWIDTH*2) back_dest += SCREENWIDTH*2)
for (x = 0 ; x < SCREENWIDTH/64 ; x++) for (x = 0 ; x < SCREENWIDTH/64 ; x++)
@ -1795,14 +1796,30 @@ void M_DrawBackground(char* patchname, byte *back_dest)
while (--i>=0); while (--i>=0);
back_dest += 128; back_dest += 128;
} }
*/
for (int y = 0; y < SCREENHEIGHT<<1; y++)
for (int x = 0; x < SCREENWIDTH<<1; x += 2)
{
const byte dot = src[(((y>>1)&63)<<6) + ((x>>1)&63)];
*back_dest++ = dot;
*back_dest++ = dot;
}
#endif #endif
else else
/*
for (y = 0 ; y < SCREENHEIGHT ; src = ((++y & 63)<<6) + back_src) for (y = 0 ; y < SCREENHEIGHT ; src = ((++y & 63)<<6) + back_src)
for (x = 0 ; x < SCREENWIDTH/64 ; x++) for (x = 0 ; x < SCREENWIDTH/64 ; x++)
{ {
memcpy (back_dest,back_src+((y & 63)<<6),64); memcpy (back_dest,back_src+((y & 63)<<6),64);
back_dest += 64; back_dest += 64;
} }
*/
for (y = 0; y < SCREENHEIGHT; y++)
for (x = 0; x < SCREENWIDTH; x++)
{
*back_dest++ = src[((y&63)<<6) + (x&63)];
}
} }
///////////////////////////// /////////////////////////////
@ -2051,7 +2068,7 @@ void M_DrawSetting(setup_menu_t* s)
for (i = 0 ; i < (CHIP_SIZE+2)*(CHIP_SIZE+2) ; i++) for (i = 0 ; i < (CHIP_SIZE+2)*(CHIP_SIZE+2) ; i++)
*ptr++ = PAL_BLACK; *ptr++ = PAL_BLACK;
V_DrawBlock(x,y-1,0,CHIP_SIZE+2,CHIP_SIZE+2,colorblock); V_DrawBlock(x+WIDESCREENDELTA,y-1,0,CHIP_SIZE+2,CHIP_SIZE+2,colorblock);
// draw the paint chip // draw the paint chip
@ -2063,7 +2080,7 @@ void M_DrawSetting(setup_menu_t* s)
ptr = colorblock; ptr = colorblock;
for (i = 0 ; i < CHIP_SIZE*CHIP_SIZE ; i++) for (i = 0 ; i < CHIP_SIZE*CHIP_SIZE ; i++)
*ptr++ = ch; *ptr++ = ch;
V_DrawBlock(x+1,y,0,CHIP_SIZE,CHIP_SIZE,colorblock); V_DrawBlock(x+1+WIDESCREENDELTA,y,0,CHIP_SIZE,CHIP_SIZE,colorblock);
} }
// [FG] print a blinking "arrow" next to the currently highlighted menu item // [FG] print a blinking "arrow" next to the currently highlighted menu item
if (s == current_setup_menu + set_menu_itemon && whichSkull && !setup_select) if (s == current_setup_menu + set_menu_itemon && whichSkull && !setup_select)
@ -3155,6 +3172,8 @@ enum {
general_fullscreen, general_fullscreen,
// [FG] uncapped rendering frame rate // [FG] uncapped rendering frame rate
general_uncapped, general_uncapped,
// widescreen mode
general_widescreen
}; };
enum { enum {
@ -3172,7 +3191,7 @@ enum {
#define G_X 250 #define G_X 250
#define G_Y 44 #define G_Y 44
#define G_Y2 (G_Y+82+16) // [FG] remove sound and music card items #define G_Y2 (G_Y+92+16) // [FG] remove sound and music card items
#define G_Y3 (G_Y+44) #define G_Y3 (G_Y+44)
#define G_Y4 (G_Y3+52) #define G_Y4 (G_Y3+52)
#define GF_X 76 #define GF_X 76
@ -3215,6 +3234,9 @@ setup_menu_t gen_settings1[] = { // General Settings screen1
{"Uncapped Rendering Frame Rate", S_YESNO, m_null, G_X, G_Y + general_uncapped*8, {"Uncapped Rendering Frame Rate", S_YESNO, m_null, G_X, G_Y + general_uncapped*8,
{"uncapped"}}, {"uncapped"}},
{"Widescreen Mode", S_YESNO, m_null, G_X, G_Y + general_widescreen*8,
{"widescreen"}, 0, 0, I_ResetScreen},
{"Sound & Music", S_SKIP|S_TITLE, m_null, G_X, G_Y2 - 12}, {"Sound & Music", S_SKIP|S_TITLE, m_null, G_X, G_Y2 - 12},
// [FG] remove sound and music card items // [FG] remove sound and music card items

View File

@ -1859,6 +1859,14 @@ default_t defaults[] = {
"1 to force integer scales" "1 to force integer scales"
}, },
// widescreen mode
{
"widescreen",
(config_t *) &widescreen, NULL,
{0}, {0, 1}, number, ss_none, wad_no,
"1 to enable widescreen mode"
},
{NULL} // last entry {NULL} // last entry
}; };

View File

@ -57,7 +57,7 @@ int viewwindowx;
int viewwindowy; int viewwindowy;
byte *ylookup[MAXHEIGHT]; byte *ylookup[MAXHEIGHT];
int columnofs[MAXWIDTH]; int columnofs[MAXWIDTH];
int linesize = SCREENWIDTH; // killough 11/98 int linesize = ORIGWIDTH; // killough 11/98
// Color tables for different players, // Color tables for different players,
// translate a limited part to another // translate a limited part to another
@ -592,39 +592,39 @@ void R_FillBackScreen (void)
patch = W_CacheLumpName("brdr_t", PU_CACHE); patch = W_CacheLumpName("brdr_t", PU_CACHE);
for (x=0; x<scaledviewwidth; x+=8) for (x=0; x<scaledviewwidth; x+=8)
V_DrawPatch(viewwindowx+x,viewwindowy-8,1,patch); V_DrawPatch(viewwindowx+x-WIDESCREENDELTA,viewwindowy-8,1,patch);
patch = W_CacheLumpName("brdr_b",PU_CACHE); patch = W_CacheLumpName("brdr_b",PU_CACHE);
for (x=0; x<scaledviewwidth; x+=8) // killough 11/98: for (x=0; x<scaledviewwidth; x+=8) // killough 11/98:
V_DrawPatch (viewwindowx+x,viewwindowy+scaledviewheight,1,patch); V_DrawPatch (viewwindowx+x-WIDESCREENDELTA,viewwindowy+scaledviewheight,1,patch);
patch = W_CacheLumpName("brdr_l",PU_CACHE); patch = W_CacheLumpName("brdr_l",PU_CACHE);
for (y=0; y<scaledviewheight; y+=8) // killough 11/98 for (y=0; y<scaledviewheight; y+=8) // killough 11/98
V_DrawPatch (viewwindowx-8,viewwindowy+y,1,patch); V_DrawPatch (viewwindowx-8-WIDESCREENDELTA,viewwindowy+y,1,patch);
patch = W_CacheLumpName("brdr_r",PU_CACHE); patch = W_CacheLumpName("brdr_r",PU_CACHE);
for (y=0; y<scaledviewheight; y+=8) // killough 11/98 for (y=0; y<scaledviewheight; y+=8) // killough 11/98
V_DrawPatch(viewwindowx+scaledviewwidth,viewwindowy+y,1,patch); V_DrawPatch(viewwindowx+scaledviewwidth-WIDESCREENDELTA,viewwindowy+y,1,patch);
// Draw beveled edge. // Draw beveled edge.
V_DrawPatch(viewwindowx-8, V_DrawPatch(viewwindowx-8-WIDESCREENDELTA,
viewwindowy-8, viewwindowy-8,
1, 1,
W_CacheLumpName("brdr_tl",PU_CACHE)); W_CacheLumpName("brdr_tl",PU_CACHE));
V_DrawPatch(viewwindowx+scaledviewwidth, V_DrawPatch(viewwindowx+scaledviewwidth-WIDESCREENDELTA,
viewwindowy-8, viewwindowy-8,
1, 1,
W_CacheLumpName("brdr_tr",PU_CACHE)); W_CacheLumpName("brdr_tr",PU_CACHE));
V_DrawPatch(viewwindowx-8, V_DrawPatch(viewwindowx-8-WIDESCREENDELTA,
viewwindowy+scaledviewheight, // killough 11/98 viewwindowy+scaledviewheight, // killough 11/98
1, 1,
W_CacheLumpName("brdr_bl",PU_CACHE)); W_CacheLumpName("brdr_bl",PU_CACHE));
V_DrawPatch(viewwindowx+scaledviewwidth, V_DrawPatch(viewwindowx+scaledviewwidth-WIDESCREENDELTA,
viewwindowy+scaledviewheight, // killough 11/98 viewwindowy+scaledviewheight, // killough 11/98
1, 1,
W_CacheLumpName("brdr_br",PU_CACHE)); W_CacheLumpName("brdr_br",PU_CACHE));

View File

@ -37,6 +37,7 @@
#include "m_bbox.h" #include "m_bbox.h"
#include "r_sky.h" #include "r_sky.h"
#include "v_video.h" #include "v_video.h"
#include "st_stuff.h"
// Fineangles in the SCREENWIDTH wide window. // Fineangles in the SCREENWIDTH wide window.
#define FIELDOFVIEW 2048 #define FIELDOFVIEW 2048
@ -238,6 +239,11 @@ fixed_t R_ScaleFromGlobalAngle(angle_t visangle)
64*FRACUNIT : num < 256 ? 256 : num : 64*FRACUNIT; 64*FRACUNIT : num < 256 ? 256 : num : 64*FRACUNIT;
} }
// [crispy] in widescreen mode, make sure the same number of horizontal
// pixels shows the same part of the game scene as in regular rendering mode
static int scaledviewwidth_nonwide, viewwidth_nonwide;
static fixed_t centerxfrac_nonwide;
// //
// R_InitTextureMapping // R_InitTextureMapping
// //
@ -255,7 +261,7 @@ static void R_InitTextureMapping (void)
// Calc focallength // Calc focallength
// so FIELDOFVIEW angles covers SCREENWIDTH. // so FIELDOFVIEW angles covers SCREENWIDTH.
focallength = FixedDiv(centerxfrac, finetangent[FINEANGLES/4+FIELDOFVIEW/2]); focallength = FixedDiv(centerxfrac_nonwide, finetangent[FINEANGLES/4+FIELDOFVIEW/2]);
for (i=0 ; i<FINEANGLES/2 ; i++) for (i=0 ; i<FINEANGLES/2 ; i++)
{ {
@ -323,7 +329,7 @@ void R_InitLightTables (void)
int j, startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS; int j, startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
for (j=0; j<MAXLIGHTZ; j++) for (j=0; j<MAXLIGHTZ; j++)
{ {
int scale = FixedDiv ((SCREENWIDTH/2*FRACUNIT), (j+1)<<LIGHTZSHIFT); int scale = FixedDiv ((ORIGWIDTH/2*FRACUNIT), (j+1)<<LIGHTZSHIFT);
int t, level = startmap - (scale >>= LIGHTSCALESHIFT)/DISTMAP; int t, level = startmap - (scale >>= LIGHTSCALESHIFT)/DISTMAP;
if (level < 0) if (level < 0)
@ -368,31 +374,54 @@ void R_ExecuteSetViewSize (void)
if (setblocks == 11) if (setblocks == 11)
{ {
scaledviewwidth_nonwide = NONWIDEWIDTH;
scaledviewwidth = SCREENWIDTH; scaledviewwidth = SCREENWIDTH;
scaledviewheight = SCREENHEIGHT; // killough 11/98 scaledviewheight = SCREENHEIGHT; // killough 11/98
} }
// [crispy] hard-code to SCREENWIDTH and SCREENHEIGHT minus status bar height
else if (setblocks == 10)
{
scaledviewwidth_nonwide = NONWIDEWIDTH;
scaledviewwidth = SCREENWIDTH;
scaledviewheight = SCREENHEIGHT-ST_HEIGHT;
}
else else
{ {
scaledviewwidth = setblocks*32; scaledviewwidth_nonwide = setblocks*32;
scaledviewheight = (setblocks*168/10) & ~7; // killough 11/98 scaledviewheight = (setblocks*168/10) & ~7; // killough 11/98
if (widescreen)
{
const int widescreen_edge_aligner = (8 << hires) - 1;
scaledviewwidth = scaledviewheight*SCREENWIDTH/(SCREENHEIGHT-ST_HEIGHT);
// [crispy] make sure scaledviewwidth is an integer multiple of the bezel patch width
scaledviewwidth = (scaledviewwidth + widescreen_edge_aligner) & (int)~widescreen_edge_aligner;
scaledviewwidth = MIN(scaledviewwidth, SCREENWIDTH);
}
else
{
scaledviewwidth = scaledviewwidth_nonwide;
}
} }
viewwidth = scaledviewwidth << hires; // killough 11/98 viewwidth = scaledviewwidth << hires; // killough 11/98
viewheight = scaledviewheight << hires; // killough 11/98 viewheight = scaledviewheight << hires; // killough 11/98
viewwidth_nonwide = scaledviewwidth_nonwide << hires;
centery = viewheight/2; centery = viewheight/2;
centerx = viewwidth/2; centerx = viewwidth/2;
centerxfrac = centerx<<FRACBITS; centerxfrac = centerx<<FRACBITS;
centeryfrac = centery<<FRACBITS; centeryfrac = centery<<FRACBITS;
projection = centerxfrac; centerxfrac_nonwide = (viewwidth_nonwide/2)<<FRACBITS;
projection = centerxfrac_nonwide;
R_InitBuffer(scaledviewwidth, scaledviewheight); // killough 11/98 R_InitBuffer(scaledviewwidth, scaledviewheight); // killough 11/98
R_InitTextureMapping(); R_InitTextureMapping();
// psprite scales // psprite scales
pspritescale = FixedDiv(viewwidth, SCREENWIDTH); // killough 11/98 pspritescale = FixedDiv(viewwidth_nonwide, ORIGWIDTH); // killough 11/98
pspriteiscale= FixedDiv(SCREENWIDTH, viewwidth); // killough 11/98 pspriteiscale= FixedDiv(ORIGWIDTH, viewwidth_nonwide); // killough 11/98
// thing clipping // thing clipping
for (i=0 ; i<viewwidth ; i++) for (i=0 ; i<viewwidth ; i++)
@ -402,7 +431,7 @@ void R_ExecuteSetViewSize (void)
for (i=0 ; i<viewheight ; i++) for (i=0 ; i<viewheight ; i++)
{ // killough 5/2/98: reformatted { // killough 5/2/98: reformatted
fixed_t dy = abs(((i-viewheight/2)<<FRACBITS)+FRACUNIT/2); fixed_t dy = abs(((i-viewheight/2)<<FRACBITS)+FRACUNIT/2);
yslope[i] = FixedDiv(viewwidth*(FRACUNIT/2), dy); yslope[i] = FixedDiv(viewwidth_nonwide*(FRACUNIT/2), dy);
} }
for (i=0 ; i<viewwidth ; i++) for (i=0 ; i<viewwidth ; i++)
@ -418,7 +447,7 @@ void R_ExecuteSetViewSize (void)
int j, startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS; int j, startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
for (j=0 ; j<MAXLIGHTSCALE ; j++) for (j=0 ; j<MAXLIGHTSCALE ; j++)
{ // killough 11/98: { // killough 11/98:
int t, level = startmap - j*SCREENWIDTH/scaledviewwidth/DISTMAP; int t, level = startmap - j*NONWIDEWIDTH/scaledviewwidth_nonwide/DISTMAP;
if (level < 0) if (level < 0)
level = 0; level = 0;
@ -433,6 +462,9 @@ void R_ExecuteSetViewSize (void)
c_scalelight[t][i][j] = colormaps[t] + level; c_scalelight[t][i][j] = colormaps[t] + level;
} }
} }
// [crispy] forcefully initialize the status bar backing screen
ST_refreshBackground(true);
} }
// //

View File

@ -128,7 +128,7 @@ void STlib_drawNum
if (n->y - ST_Y < 0) if (n->y - ST_Y < 0)
I_Error("drawNum: n->y - ST_Y < 0"); I_Error("drawNum: n->y - ST_Y < 0");
V_CopyRect(x, n->y - ST_Y, BG, w*numdigits, h, x, n->y, FG); V_CopyRect(x + WIDESCREENDELTA, n->y - ST_Y, BG, w*numdigits, h, x + WIDESCREENDELTA, n->y, FG);
// if non-number, do not draw it // if non-number, do not draw it
if (num == 1994) if (num == 1994)
@ -297,7 +297,7 @@ void STlib_updateMultIcon
if (y - ST_Y < 0) if (y - ST_Y < 0)
I_Error("updateMultIcon: y - ST_Y < 0"); I_Error("updateMultIcon: y - ST_Y < 0");
V_CopyRect(x, y-ST_Y, BG, w, h, x, y, FG); V_CopyRect(x + WIDESCREENDELTA, y-ST_Y, BG, w, h, x + WIDESCREENDELTA, y, FG);
} }
if (*mi->inum != -1) // killough 2/16/98: redraw only if != -1 if (*mi->inum != -1) // killough 2/16/98: redraw only if != -1
V_DrawPatch(mi->x, mi->y, FG, mi->p[*mi->inum]); V_DrawPatch(mi->x, mi->y, FG, mi->p[*mi->inum]);
@ -366,7 +366,7 @@ void STlib_updateBinIcon
if (*bi->val) if (*bi->val)
V_DrawPatch(bi->x, bi->y, FG, bi->p); V_DrawPatch(bi->x, bi->y, FG, bi->p);
else else
V_CopyRect(x, y-ST_Y, BG, w, h, x, y, FG); V_CopyRect(x + WIDESCREENDELTA, y-ST_Y, BG, w, h, x + WIDESCREENDELTA, y, FG);
bi->oldval = *bi->val; bi->oldval = *bi->val;
} }

View File

@ -323,17 +323,85 @@ extern char *mapnames[];
void ST_Stop(void); void ST_Stop(void);
void ST_refreshBackground(void) void ST_refreshBackground(boolean force)
{ {
if (st_statusbaron) if (st_statusbaron)
{
// [crispy] this is our own local copy of R_FillBackScreen() to
// fill the entire background of st_backing_screen with the bezel pattern,
// so it appears to the left and right of the status bar in widescreen mode
if (SCREENWIDTH != ST_WIDTH)
{
int x, y;
byte *src;
byte *dest;
const char *name = (gamemode == commercial) ? "GRNROCK" : "FLOOR7_2";
src = W_CacheLumpNum(firstflat + R_FlatNumForName(name), PU_CACHE);
dest = screens[BG];
if (hires)
{
for (y = (SCREENHEIGHT-ST_HEIGHT)<<1; y < SCREENHEIGHT<<1; y++)
for (x = 0; x < SCREENWIDTH<<1; x += 2)
{
const byte dot = src[(((y>>1)&63)<<6) + ((x>>1)&63)];
*dest++ = dot;
*dest++ = dot;
}
}
else
{
for (y = SCREENHEIGHT-ST_HEIGHT; y < SCREENHEIGHT; y++)
for (x = 0; x < SCREENWIDTH; x++)
{
*dest++ = src[((y&63)<<6) + (x&63)];
}
}
// [crispy] preserve bezel bottom edge
if (scaledviewwidth == SCREENWIDTH)
{
patch_t *const patch = W_CacheLumpName("brdr_b", PU_CACHE);
for (x = 0; x < WIDESCREENDELTA; x += 8)
{
V_DrawPatch(x - WIDESCREENDELTA, 0, BG, patch);
V_DrawPatch(ORIGWIDTH + WIDESCREENDELTA - x - 8, 0, BG, patch);
}
}
}
// [crispy] center unity rerelease wide status bar
if (sbar->width > ORIGWIDTH && sbar->leftoffset == 0)
{
V_DrawPatch(ST_X + (ORIGWIDTH - sbar->width) / 2, 0, BG, sbar);
}
else
{ {
V_DrawPatch(ST_X, 0, BG, sbar); V_DrawPatch(ST_X, 0, BG, sbar);
}
// killough 3/7/98: make face background change with displayplayer // killough 3/7/98: make face background change with displayplayer
if (netgame) if (netgame)
V_DrawPatch(ST_FX, 0, BG, faceback[displayplayer]); V_DrawPatch(ST_FX, 0, BG, faceback[displayplayer]);
V_CopyRect(ST_X, 0, BG, ST_WIDTH, ST_HEIGHT, ST_X, ST_Y, FG); // [crispy] copy entire SCREENWIDTH, to preserve the pattern
// to the left and right of the status bar in widescren mode
if (!force)
{
V_CopyRect(ST_X, 0, BG, SCREENWIDTH, ST_HEIGHT, ST_X, ST_Y, FG);
}
else
{
if (WIDESCREENDELTA > 0 && !st_firsttime)
{
V_CopyRect(0, 0, BG, WIDESCREENDELTA, ST_HEIGHT, 0, ST_Y, FG);
V_CopyRect(ORIGWIDTH + WIDESCREENDELTA, 0, BG, WIDESCREENDELTA, ST_HEIGHT, ORIGWIDTH + WIDESCREENDELTA, ST_Y, FG);
}
}
} }
} }
@ -755,7 +823,7 @@ void ST_doRefresh(void)
st_firsttime = false; st_firsttime = false;
// draw status bar background to off-screen buff // draw status bar background to off-screen buff
ST_refreshBackground(); ST_refreshBackground(false);
// and refresh all widgets // and refresh all widgets
ST_drawWidgets(true); ST_drawWidgets(true);
@ -1116,7 +1184,7 @@ void ST_Init(void)
veryfirsttime = 0; veryfirsttime = 0;
ST_loadData(); ST_loadData();
// killough 11/98: allocate enough for hires // killough 11/98: allocate enough for hires
screens[4] = Z_Malloc(ST_WIDTH*ST_HEIGHT*4, PU_STATIC, 0); screens[4] = Z_Malloc(MAX_SCREENWIDTH*ST_HEIGHT*4, PU_STATIC, 0);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -38,8 +38,8 @@
// Now sensitive for scaling. // Now sensitive for scaling.
#define ST_HEIGHT (32*SCREEN_MUL) #define ST_HEIGHT (32*SCREEN_MUL)
#define ST_WIDTH SCREENWIDTH #define ST_WIDTH ORIGWIDTH
#define ST_Y (SCREENHEIGHT - ST_HEIGHT) #define ST_Y (ORIGHEIGHT - ST_HEIGHT)
// //
// STATUS BAR // STATUS BAR
@ -60,6 +60,9 @@ void ST_Start(void);
// Called by startup code. // Called by startup code.
void ST_Init(void); void ST_Init(void);
// [crispy] forcefully initialize the status bar backing screen
extern void ST_refreshBackground(boolean force);
// States for status bar code. // States for status bar code.
typedef enum typedef enum
{ {

View File

@ -302,6 +302,8 @@ void V_DrawPatchGeneral(int x, int y, int scrn, patch_t *patch,
y -= SHORT(patch->topoffset); y -= SHORT(patch->topoffset);
x -= SHORT(patch->leftoffset); x -= SHORT(patch->leftoffset);
x += WIDESCREENDELTA; // [crispy] horizontal widescreen offset
#ifdef RANGECHECK_NOTHANKS #ifdef RANGECHECK_NOTHANKS
if (x<0 if (x<0
||x+SHORT(patch->width) >SCREENWIDTH ||x+SHORT(patch->width) >SCREENWIDTH
@ -495,6 +497,8 @@ void V_DrawPatchTranslated(int x, int y, int scrn, patch_t *patch,
y -= SHORT(patch->topoffset); y -= SHORT(patch->topoffset);
x -= SHORT(patch->leftoffset); x -= SHORT(patch->leftoffset);
x += WIDESCREENDELTA; // [crispy] horizontal widescreen offset
#ifdef RANGECHECK #ifdef RANGECHECK
if (x<0 if (x<0
||x+SHORT(patch->width) >SCREENWIDTH ||x+SHORT(patch->width) >SCREENWIDTH
@ -630,6 +634,22 @@ void V_DrawPatchTranslated(int x, int y, int scrn, patch_t *patch,
} }
} }
void V_DrawPatchFullScreen(int scrn, patch_t *patch)
{
int x = (SCREENWIDTH - patch->width) / 2 - WIDESCREENDELTA;
patch->leftoffset = 0;
patch->topoffset = 0;
// [crispy] fill pillarboxes in widescreen mode
if (SCREENWIDTH != NONWIDEWIDTH)
{
memset(screens[scrn], 0, (SCREENWIDTH<<hires) * (SCREENHEIGHT<<hires));
}
V_DrawPatch(x, 0, scrn, patch);
}
// //
// V_DrawBlock // V_DrawBlock
// //

View File

@ -110,6 +110,8 @@ void V_DrawPatchGeneral(int x,int y,int scrn,patch_t *patch, boolean flipped);
void V_DrawPatchTranslated(int x, int y, int scrn, patch_t *patch, char *outr, void V_DrawPatchTranslated(int x, int y, int scrn, patch_t *patch, char *outr,
int cm); int cm);
void V_DrawPatchFullScreen(int scrn, patch_t *patch);
// Draw a linear block of pixels into the view buffer. // Draw a linear block of pixels into the view buffer.
void V_DrawBlock(int x, int y, int scrn, int width, int height, byte *src); void V_DrawBlock(int x, int y, int scrn, int width, int height, byte *src);

View File

@ -399,7 +399,8 @@ static int num_lnames;
// //
static void WI_slamBackground(void) static void WI_slamBackground(void)
{ {
V_CopyRect(0, 0, 1, SCREENWIDTH, SCREENHEIGHT, 0, 0, 0); // killough 11/98 //V_CopyRect(0, 0, 1, SCREENWIDTH, SCREENHEIGHT, 0, 0, 0); // killough 11/98
V_DrawPatchFullScreen(0, bg);
} }
// ==================================================================== // ====================================================================
@ -430,14 +431,14 @@ static void WI_drawLF(void)
if (wbs->last < num_lnames) if (wbs->last < num_lnames)
{ {
// draw <LevelName> // draw <LevelName>
V_DrawPatch((SCREENWIDTH - SHORT(lnames[wbs->last]->width))/2, V_DrawPatch((ORIGWIDTH - SHORT(lnames[wbs->last]->width))/2,
y, FB, lnames[wbs->last]); y, FB, lnames[wbs->last]);
// draw "Finished!" // draw "Finished!"
y += (5*SHORT(lnames[wbs->last]->height))/4; y += (5*SHORT(lnames[wbs->last]->height))/4;
} }
V_DrawPatch((SCREENWIDTH - SHORT(finished->width))/2, V_DrawPatch((ORIGWIDTH - SHORT(finished->width))/2,
y, FB, finished); y, FB, finished);
} }
@ -453,7 +454,7 @@ static void WI_drawEL(void)
int y = WI_TITLEY; int y = WI_TITLEY;
// draw "Entering" // draw "Entering"
V_DrawPatch((SCREENWIDTH - SHORT(entering->width))/2, V_DrawPatch((ORIGWIDTH - SHORT(entering->width))/2,
y, FB, entering); y, FB, entering);
// [FG] prevent crashes for levels without name graphics // [FG] prevent crashes for levels without name graphics
@ -462,7 +463,7 @@ static void WI_drawEL(void)
// draw level // draw level
y += (5*SHORT(lnames[wbs->next]->height))/4; y += (5*SHORT(lnames[wbs->next]->height))/4;
V_DrawPatch((SCREENWIDTH - SHORT(lnames[wbs->next]->width))/2, V_DrawPatch((ORIGWIDTH - SHORT(lnames[wbs->next]->width))/2,
y, FB, lnames[wbs->next]); y, FB, lnames[wbs->next]);
} }
} }
@ -1700,16 +1701,16 @@ static void WI_drawStats(void)
WI_drawLF(); WI_drawLF();
V_DrawPatch(SP_STATSX, SP_STATSY, FB, kills); V_DrawPatch(SP_STATSX, SP_STATSY, FB, kills);
WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY, cnt_kills[0]); WI_drawPercent(ORIGWIDTH - SP_STATSX, SP_STATSY, cnt_kills[0]);
V_DrawPatch(SP_STATSX, SP_STATSY+lh, FB, items); V_DrawPatch(SP_STATSX, SP_STATSY+lh, FB, items);
WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY+lh, cnt_items[0]); WI_drawPercent(ORIGWIDTH - SP_STATSX, SP_STATSY+lh, cnt_items[0]);
V_DrawPatch(SP_STATSX, SP_STATSY+2*lh, FB, sp_secret); V_DrawPatch(SP_STATSX, SP_STATSY+2*lh, FB, sp_secret);
WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY+2*lh, cnt_secret[0]); WI_drawPercent(ORIGWIDTH - SP_STATSX, SP_STATSY+2*lh, cnt_secret[0]);
V_DrawPatch(SP_TIMEX, SP_TIMEY, FB, time); V_DrawPatch(SP_TIMEX, SP_TIMEY, FB, time);
WI_drawTime(SCREENWIDTH/2 - SP_TIMEX, SP_TIMEY, cnt_time, true); WI_drawTime(ORIGWIDTH/2 - SP_TIMEX, SP_TIMEY, cnt_time, true);
// Ty 04/11/98: redid logic: should skip only if with pwad but // Ty 04/11/98: redid logic: should skip only if with pwad but
// without deh patch // without deh patch
@ -1719,19 +1720,19 @@ static void WI_drawStats(void)
if (!modifiedgame || deh_pars) if (!modifiedgame || deh_pars)
if (wbs->epsd < 3) if (wbs->epsd < 3)
{ {
V_DrawPatch(SCREENWIDTH/2 + SP_TIMEX, SP_TIMEY, FB, par); V_DrawPatch(ORIGWIDTH/2 + SP_TIMEX, SP_TIMEY, FB, par);
WI_drawTime(SCREENWIDTH - SP_TIMEX, SP_TIMEY, cnt_par, true); WI_drawTime(ORIGWIDTH - SP_TIMEX, SP_TIMEY, cnt_par, true);
} }
// [FG] draw total time after level time and par time // [FG] draw total time after level time and par time
if (sp_state > 8) if (sp_state > 8)
{ {
const int ttime = wbs->totaltimes / TICRATE; const int ttime = wbs->totaltimes / TICRATE;
const boolean wide = (ttime > 61*59) || (SP_TIMEX + SHORT(total->width) >= SCREENWIDTH/4); const boolean wide = (ttime > 61*59) || (SP_TIMEX + SHORT(total->width) >= ORIGWIDTH/4);
V_DrawPatch(SP_TIMEX, SP_TIMEY + 16, FB, total); V_DrawPatch(SP_TIMEX, SP_TIMEY + 16, FB, total);
// [FG] choose x-position depending on width of time string // [FG] choose x-position depending on width of time string
WI_drawTime((wide ? SCREENWIDTH : SCREENWIDTH/2) - SP_TIMEX, SP_TIMEY + 16, ttime, false); WI_drawTime((wide ? ORIGWIDTH : ORIGWIDTH/2) - SP_TIMEX, SP_TIMEY + 16, ttime, false);
} }
} }