initial implementation of any resolution

Partially taken from Eternity Engine.

* Introduce video_t structure.

* Use modified R_DrawColumn for patches scaling.

* Remove ORIGWIDTH and ORIGHEIGHT.

* Move WIDESCREENDELTA and FOV to the video_t.
This commit is contained in:
Roman Fomin 2023-12-02 14:35:19 +07:00
parent 9ba20351a6
commit b944f58067
24 changed files with 1019 additions and 930 deletions

View File

@ -612,11 +612,11 @@ static void AM_LevelInit(void)
//
// killough 11/98: ... finally add hires support :)
f_w = (SCREENWIDTH) << hires;
f_w = video.width;
if (automapoverlay && scaledviewheight == SCREENHEIGHT)
f_h = (SCREENHEIGHT) << hires;
f_h = video.height;
else
f_h = (SCREENHEIGHT-ST_HEIGHT) << hires;
f_h = video.height - ((ST_HEIGHT * video.yscale) >> FRACBITS);
AM_enableSmoothLines();
@ -689,16 +689,17 @@ void AM_Stop (void)
//
void AM_Start()
{
static int lastlevel = -1, lastepisode = -1, last_hires = -1, last_widescreen = -1, last_viewheight = -1;
static int lastlevel = -1, lastepisode = -1, last_width = -1, last_height = -1, last_viewheight = -1;
if (!stopped)
AM_Stop();
stopped = false;
if (lastlevel != gamemap || lastepisode != gameepisode || hires!=last_hires
|| widescreen != last_widescreen || viewheight != last_viewheight)
if (lastlevel != gamemap || lastepisode != gameepisode ||
last_width != video.width || last_height != video.height ||
viewheight != last_viewheight)
{
last_hires = hires; // killough 11/98
last_widescreen = widescreen;
last_height = video.height;
last_width = video.width;
last_viewheight = viewheight;
AM_LevelInit();
lastlevel = gamemap;
@ -899,9 +900,9 @@ boolean AM_Responder
}
if (automapoverlay && scaledviewheight == SCREENHEIGHT)
f_h = (SCREENHEIGHT) << hires;
f_h = video.height;
else
f_h = (SCREENHEIGHT-ST_HEIGHT) << hires;
f_h = video.height - ((ST_HEIGHT * video.yscale) >> FRACBITS);
AM_activateNewScale();
}
@ -956,15 +957,17 @@ boolean AM_Responder
if (!followplayer)
{
int scaled_f_paninc = (f_paninc * video.xscale) >> FRACBITS;
if (buttons_state[PAN_RIGHT])
m_paninc.x += FTOM(f_paninc << hires);
m_paninc.x += FTOM(scaled_f_paninc);
if (buttons_state[PAN_LEFT])
m_paninc.x += -FTOM(f_paninc << hires);
m_paninc.x += -FTOM(scaled_f_paninc);
scaled_f_paninc = (f_paninc * video.yscale) >> FRACBITS;
if (buttons_state[PAN_UP])
m_paninc.y += FTOM(f_paninc << hires);
m_paninc.y += FTOM(scaled_f_paninc);
if (buttons_state[PAN_DOWN])
m_paninc.y += -FTOM(f_paninc << hires);
m_paninc.y += -FTOM(scaled_f_paninc);
}
if (!mousewheelzoom)
@ -2179,8 +2182,8 @@ static void AM_drawMarks(void)
for (i=0;i<markpointnum;i++) // killough 2/22/98: remove automap mark limit
if (markpoints[i].x != -1)
{
int w = 5 << hires;
int h = 6 << hires;
int w = (5 * video.xscale) >> FRACBITS;
int h = (6 * video.yscale) >> FRACBITS;
int fx;
int fy;
int j = i;
@ -2199,13 +2202,15 @@ static void AM_drawMarks(void)
{
int d = j % 10;
if (d==1) // killough 2/22/98: less spacing for '1'
fx += 1<<hires;
if (d == 1) // killough 2/22/98: less spacing for '1'
fx += (video.xscale >> FRACBITS);
if (fx >= f_x && fx < f_w - w && fy >= f_y && fy < f_h - h)
V_DrawPatch((fx >> hires) - WIDESCREENDELTA, fy >> hires, marknums[d]);
V_DrawPatch(((fx << FRACBITS) / video.xscale) - video.deltaw,
(fy << FRACBITS) / video.yscale,
marknums[d]);
fx -= w - (1<<hires); // killough 2/22/98: 1 space backwards
fx -= w - (video.yscale >> FRACBITS); // killough 2/22/98: 1 space backwards
j /= 10;
}

View File

@ -247,7 +247,7 @@ void D_Display (void)
// save the current screen if about to wipe
if ((wipe = gamestate != wipegamestate) && NOTSTRICTMODE(screen_melt))
wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
wipe_StartScreen(0, 0, video.unscaledw, video.unscaledh);
if (gamestate == GS_LEVEL && gametic)
HU_Erase();
@ -299,7 +299,7 @@ void D_Display (void)
}
// see if the border needs to be updated to the screen
if (gamestate == GS_LEVEL && automap_off && scaledviewwidth != SCREENWIDTH)
if (gamestate == GS_LEVEL && automap_off && scaledviewwidth != video.unscaledw)
{
if (menuactive || menuactivestate || !viewactivestate)
borderdrawcount = 3;
@ -329,14 +329,16 @@ void D_Display (void)
// draw pause pic
if (paused)
{
int x = scaledviewx;
int y = 4;
int x = (viewwindowx>>hires);
patch_t *patch = W_CacheLumpName("M_PAUSE", PU_CACHE);
x += (scaledviewwidth - SHORT(patch->width)) / 2 - video.deltaw;
if (!automapactive)
y += (viewwindowy>>hires);
V_DrawPatchDirect(x + (scaledviewwidth - SHORT(patch->width)) / 2 - WIDESCREENDELTA,
y, patch);
y += scaledviewy;
V_DrawPatch(x, y, patch);
}
// menus go directly to the screen
@ -354,7 +356,7 @@ void D_Display (void)
}
// wipe update
wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
wipe_EndScreen(0, 0, video.unscaledw, video.unscaledh);
wipestart = I_GetTime () - 1;
@ -368,7 +370,7 @@ void D_Display (void)
}
while (!tics);
wipestart = nowtime;
done = wipe_ScreenWipe(wipe_Melt,0,0,SCREENWIDTH,SCREENHEIGHT,tics);
done = wipe_ScreenWipe(wipe_Melt, 0, 0, video.unscaledw, video.unscaledh, tics);
M_Drawer(); // menu is drawn even on top of wipes
I_FinishUpdate(); // page flip or blit buffer
}
@ -2488,8 +2490,6 @@ void D_DoomMain(void)
// 1/18/98 killough: Z_Init call moved to i_main.c
// init subsystems
I_Printf(VB_INFO, "V_Init: allocate screens."); // killough 11/98: moved down to here
V_Init();
I_Printf(VB_INFO, "W_Init: Init WADfiles.");
W_InitMultipleFiles(wadfiles);
@ -2646,6 +2646,9 @@ void D_DoomMain(void)
I_Printf(VB_INFO, "S_Init: Setting up sound.");
S_Init(snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/ );
// [FG] init graphics (video.widedelta) before HUD widgets
I_InitGraphics();
I_Printf(VB_INFO, "HU_Init: Setting up heads up display.");
HU_Init();
M_SetMenuFontSpacing();
@ -2804,9 +2807,6 @@ void D_DoomMain(void)
I_SetFastdemoTimer(true);
}
// [FG] init graphics (WIDESCREENDELTA) before HUD widgets
I_InitGraphics();
if (startloadgame >= 0)
{
char *file;

View File

@ -81,11 +81,11 @@ typedef enum
// allows us to avoid the overhead of dynamic allocation
// when multiple screen sizes are supported
#define ORIGWIDTH 320 // [crispy]
#define ORIGHEIGHT 200 // [crispy]
#define SCREENWIDTH 320
#define SCREENHEIGHT 200
#define MAX_SCREENWIDTH 1152 // [FG] corresponds to 2.4:1 in hires mode
#define MAX_SCREENHEIGHT (ORIGHEIGHT << 1) // [crispy]
#define MAX_SCREENWIDTH (1152 * 8) // [FG] corresponds to 2.4:1 in hires mode
#define MAX_SCREENHEIGHT (400 * 8) // [crispy]
// The maximum number of players, multiplayer/networking.
#define MAXPLAYERS 4

View File

@ -713,6 +713,8 @@ void F_CastDrawer (void)
static void F_DrawPatchCol(int x, patch_t *patch, int col)
{
// TODO
#if 0
const column_t *column =
(const column_t *)((byte *) patch + LONG(patch->columnofs[col]));
@ -740,6 +742,7 @@ static void F_DrawPatchCol(int x, patch_t *patch, int col)
*dest = *source++;
column = (column_t *)(source+1);
}
#endif
}
@ -771,7 +774,7 @@ void F_BunnyScroll (void)
if (pillar_width > 0)
{
// [crispy] fill pillarboxes in widescreen mode
memset(I_VideoBuffer, 0, (SCREENWIDTH<<hires) * (SCREENHEIGHT<<hires));
memset(I_VideoBuffer, 0, video.width * video.height);
}
else
{
@ -779,24 +782,24 @@ void F_BunnyScroll (void)
}
// Calculate the portion of PFUB2 that would be offscreen at original res.
p1offset = (ORIGWIDTH - SHORT(p1->width)) / 2;
p1offset = (SCREENWIDTH - SHORT(p1->width)) / 2;
if (SHORT(p2->width) == ORIGWIDTH)
if (SHORT(p2->width) == SCREENWIDTH)
{
// Unity or original PFUBs.
// PFUB1 only contains the pixels that scroll off.
p2offset = ORIGWIDTH - p1offset;
p2offset = SCREENWIDTH - p1offset;
}
else
{
// Widescreen mod PFUBs.
// Right side of PFUB2 and left side of PFUB1 are identical.
p2offset = ORIGWIDTH + p1offset;
p2offset = SCREENWIDTH + p1offset;
}
for (x = pillar_width; x < SCREENWIDTH - pillar_width; x++)
{
int x2 = x - WIDESCREENDELTA + scrolled;
int x2 = x - video.deltaw + scrolled;
if (x2 < p2offset)
F_DrawPatchCol (x, p1, x2 - p1offset);
@ -808,8 +811,8 @@ void F_BunnyScroll (void)
return;
if (finalecount < 1180)
{
V_DrawPatch ((ORIGWIDTH-13*8)/2,
(ORIGHEIGHT-8*8)/2,
V_DrawPatch ((SCREENWIDTH-13*8)/2,
(SCREENHEIGHT-8*8)/2,
W_CacheLumpName ("END0",PU_CACHE));
laststage = 0;
return;
@ -825,8 +828,8 @@ void F_BunnyScroll (void)
}
sprintf (name,"END%i",stage);
V_DrawPatch ((ORIGWIDTH-13*8)/2,
(ORIGHEIGHT-8*8)/2,
V_DrawPatch ((SCREENWIDTH-13*8)/2,
(SCREENHEIGHT-8*8)/2,
W_CacheLumpName (name,PU_CACHE));
}

View File

@ -78,7 +78,7 @@ static int *y;
static int wipe_initMelt(int width, int height, int ticks)
{
int i;
const int hires_size = 1 << hires;
const int hires_size = (video.yscale >> FRACBITS);
// copy start screen to main screen
memcpy(wipe_scr, wipe_scr_start, width*height);
@ -159,7 +159,7 @@ static int wipe_exitMelt(int width, int height, int ticks)
int wipe_StartScreen(int x, int y, int width, int height)
{
int size = (hires ? SCREENWIDTH * SCREENHEIGHT * 4 : SCREENWIDTH * SCREENHEIGHT);
int size = video.width * video.height;
wipe_scr_start = Z_Malloc(size * sizeof(*wipe_scr_start), PU_STATIC, NULL);
I_ReadScreen(wipe_scr_start);
return 0;
@ -167,7 +167,7 @@ int wipe_StartScreen(int x, int y, int width, int height)
int wipe_EndScreen(int x, int y, int width, int height)
{
int size = (hires ? SCREENWIDTH * SCREENHEIGHT * 4 : SCREENWIDTH * SCREENHEIGHT);
int size = video.width * video.height;
wipe_scr_end = Z_Malloc(size * sizeof(*wipe_scr_end), PU_STATIC, NULL);
I_ReadScreen(wipe_scr_end);
V_DrawBlock(x, y, width, height, wipe_scr_start); // restore start scr.
@ -188,8 +188,9 @@ int wipe_ScreenWipe(int wipeno, int x, int y, int width, int height, int ticks)
{
static boolean go; // when zero, stop the wipe
if (hires) // killough 11/98: hires support
width <<= 1, height <<= 1, ticks <<= 1;
width = video.width;
height = video.height;
ticks = (ticks * video.yscale) >> FRACBITS;
if (!go) // initial stuff
{

View File

@ -35,10 +35,10 @@ void HUlib_set_margins (void)
if (hud_widescreen_widgets)
{
left_margin -= WIDESCREENDELTA;
left_margin -= video.deltaw;
}
right_margin = ORIGWIDTH - left_margin;
right_margin = SCREENWIDTH - left_margin;
}
// [FG] vertical alignment
@ -57,7 +57,7 @@ static int align_offset[num_offsets];
void HUlib_reset_align_offsets (void)
{
int bottom = ORIGHEIGHT - 1;
int bottom = SCREENHEIGHT - 1;
if (scaledviewheight < SCREENHEIGHT ||
(crispy_hud && hud_active > 0) ||
@ -224,19 +224,19 @@ static int horz_align_widget(const hu_widget_t *const w, const hu_line_t *const
}
else if (h_align == align_center)
{
return ORIGWIDTH/2 - l->width/2;
return SCREENWIDTH/2 - l->width/2;
}
// [FG] align_direct
if (hud_widescreen_widgets)
{
if (w->x < ORIGWIDTH/2)
if (w->x < SCREENWIDTH/2)
{
return w->x - WIDESCREENDELTA;
return w->x - video.deltaw;
}
else
{
return w->x + WIDESCREENDELTA;
return w->x + video.deltaw;
}
}

View File

@ -572,9 +572,6 @@ void HU_Start(void)
message_count = (message_timer * TICRATE) / 1000 + 1;
chat_count = (chat_msg_timer * TICRATE) / 1000 + 1;
// [crispy] re-calculate WIDESCREENDELTA
I_GetScreenDimensions();
// create the message widget
HUlib_init_multiline(&w_message, message_list ? hud_msg_lines : 1,
&doom_font, colrngs[hudcolor_mesg],
@ -1318,8 +1315,8 @@ mobj_t *crosshair_target; // [Alaux] Lock crosshair on target
static void HU_UpdateCrosshair(void)
{
crosshair.x = ORIGWIDTH/2;
crosshair.y = (screenblocks <= 10) ? (ORIGHEIGHT-ST_HEIGHT)/2 : ORIGHEIGHT/2;
crosshair.x = SCREENWIDTH/2;
crosshair.y = (screenblocks <= 10) ? (SCREENHEIGHT-ST_HEIGHT)/2 : SCREENHEIGHT/2;
if (hud_crosshair_health)
crosshair.cr = ColorByHealth(plr->health, 100, st_invul);
@ -1366,14 +1363,14 @@ static void HU_UpdateCrosshair(void)
void HU_UpdateCrosshairLock(int x, int y)
{
int w = (crosshair.w << hires);
int h = (crosshair.h << hires);
int w = (crosshair.w * video.xscale) >> FRACBITS;
int h = (crosshair.h * video.yscale) >> FRACBITS;
x = viewwindowx + BETWEEN(w, viewwidth - w - 1, x);
y = viewwindowy + BETWEEN(h, viewheight - h - 1, y);
crosshair.x = (x >> hires) - WIDESCREENDELTA;
crosshair.y = (y >> hires);
crosshair.x = (x << FRACBITS) / video.xscale - video.deltaw;
crosshair.y = (y << FRACBITS) / video.yscale;
}
void HU_DrawCrosshair(void)
@ -1396,7 +1393,7 @@ void HU_DrawCrosshair(void)
// [crispy] print a bar indicating demo progress at the bottom of the screen
boolean HU_DemoProgressBar(boolean force)
{
const int progress = SCREENWIDTH * playback_tic / playback_totaltics;
const int progress = video.unscaledw * playback_tic / playback_totaltics;
static int old_progress = 0;
if (old_progress < progress)
@ -1408,8 +1405,8 @@ boolean HU_DemoProgressBar(boolean force)
return false;
}
V_DrawHorizLine(0, SCREENHEIGHT - 2, progress, v_darkest_color);
V_DrawHorizLine(0, SCREENHEIGHT - 1, progress, v_lightest_color);
V_DrawHorizLine(0, video.unscaledh - 2, progress, v_darkest_color);
V_DrawHorizLine(0, video.unscaledh - 1, progress, v_lightest_color);
return true;
}
@ -2007,14 +2004,14 @@ static boolean HU_AddHUDCoords (char *name, int hud, int x, int y)
// [FG] relative alignment to the edges
if (x < 0)
{
x += ORIGWIDTH;
x += SCREENWIDTH;
}
if (y < 0)
{
y += ORIGHEIGHT;
y += SCREENHEIGHT;
}
if (x < 0 || x >= ORIGWIDTH || y < 0 || y >= ORIGHEIGHT)
if (x < 0 || x >= SCREENWIDTH || y < 0 || y >= SCREENHEIGHT)
{
return false;
}

View File

@ -25,12 +25,6 @@
#define HU_BROADCAST 5
//#define HU_MSGREFRESH KEY_ENTER // phares
#define HU_MSGX (0 - WIDESCREENDELTA)
#define HU_MSGY 0
#define HU_MSGWIDTH 64 /* in characters */
#define HU_MSGHEIGHT 1 /* in lines */
#define HU_MSGTIMEOUT (4*TICRATE)
//

View File

@ -44,10 +44,7 @@
#include "icon.c"
int SCREENWIDTH, SCREENHEIGHT;
int NONWIDEWIDTH; // [crispy] non-widescreen SCREENWIDTH
int WIDESCREENDELTA; // [crispy] horizontal widescreen offset
angle_t FOV;
video_t video;
boolean use_vsync; // killough 2/8/98: controls whether vsync is called
int hires, default_hires; // killough 11/98
@ -421,7 +418,7 @@ static inline void I_UpdateRender (void)
}
static void I_DrawDiskIcon(), I_RestoreDiskBackground();
static unsigned int disk_to_draw, disk_to_restore;
//static unsigned int disk_to_draw, disk_to_restore;
static void CreateUpscaledTexture(boolean force);
@ -456,6 +453,8 @@ void I_FinishUpdate(void)
toggle_exclusive_fullscreen = false;
}
// TODO
#if 0
// draws little dots on the bottom of the screen
if (devparm)
{
@ -490,6 +489,7 @@ void I_FinishUpdate(void)
s[(SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0;
}
}
#endif
// [FG] [AM] Real FPS counter
{
@ -556,7 +556,7 @@ void I_FinishUpdate(void)
void I_ReadScreen(byte *scr)
{
int size = hires ? SCREENWIDTH*SCREENHEIGHT*4 : SCREENWIDTH*SCREENHEIGHT;
int size = video.width * video.height;
// haleyjd
memcpy(scr, I_VideoBuffer, size);
@ -566,10 +566,12 @@ void I_ReadScreen(byte *scr)
// killough 10/98: init disk icon
//
static pixel_t *diskflash, *old_data;
//static pixel_t *diskflash, *old_data;
static void I_InitDiskFlash(void)
{
// TODO
#if 0
pixel_t temp[32*32];
if (diskflash)
@ -582,9 +584,10 @@ static void I_InitDiskFlash(void)
old_data = Z_Malloc((16<<hires) * (16<<hires) * sizeof(*old_data), PU_STATIC, 0);
V_GetBlock(0, 0, 16, 16, temp);
V_DrawPatchDirect(0-WIDESCREENDELTA, 0, W_CacheLumpName("STDISK", PU_CACHE));
V_DrawPatchDirect(0-video.widedelta, 0, W_CacheLumpName("STDISK", PU_CACHE));
V_GetBlock(0, 0, 16, 16, diskflash);
V_DrawBlock(0, 0, 16, 16, temp);
#endif
}
//
@ -593,11 +596,13 @@ static void I_InitDiskFlash(void)
void I_BeginRead(unsigned int bytes)
{
disk_to_draw += bytes;
//disk_to_draw += bytes;
}
static void I_DrawDiskIcon(void)
{
// TODO
#if 0
if (!disk_icon || PLAYBACK_SKIP)
return;
@ -608,6 +613,7 @@ static void I_DrawDiskIcon(void)
disk_to_restore = 1;
}
#endif
}
//
@ -621,6 +627,8 @@ void I_EndRead(void)
static void I_RestoreDiskBackground(void)
{
// TODO
#if 0
if (!disk_icon || PLAYBACK_SKIP)
return;
@ -632,6 +640,7 @@ static void I_RestoreDiskBackground(void)
}
disk_to_draw = 0;
#endif
}
static const float gammalevels[9] =
@ -731,7 +740,6 @@ boolean I_WritePNGfile(char *filename)
{
SDL_Rect rect = {0};
SDL_PixelFormat *format;
const int screen_width = (SCREENWIDTH << hires);
int pitch;
byte *pixels;
boolean ret = false;
@ -749,24 +757,24 @@ boolean I_WritePNGfile(char *filename)
int temp1, temp2, scale;
temp1 = rect.w;
temp2 = rect.h;
scale = MIN(rect.w / screen_width, rect.h / actualheight);
scale = MIN(rect.w / video.width, rect.h / actualheight);
rect.w = screen_width * scale;
rect.w = video.width * scale;
rect.h = actualheight * scale;
rect.x = (temp1 - rect.w) / 2;
rect.y = (temp2 - rect.h) / 2;
}
else if (rect.w * actualheight > rect.h * screen_width)
else if (rect.w * actualheight > rect.h * video.width)
{
int temp = rect.w;
rect.w = rect.h * screen_width / actualheight;
rect.w = rect.h * video.width / actualheight;
rect.x = (temp - rect.w) / 2;
}
else if (rect.h * screen_width > rect.w * actualheight)
else if (rect.h * video.width > rect.w * actualheight)
{
int temp = rect.h;
rect.h = rect.w * actualheight / screen_width;
rect.h = rect.w * actualheight / video.width;
rect.y = (temp - rect.h) / 2;
}
@ -887,30 +895,36 @@ static void I_GetWindowPosition(int *x, int *y, int w, int h)
}
}
// [crispy] re-calculate SCREENWIDTH, SCREENHEIGHT, NONWIDEWIDTH and WIDESCREENDELTA
void I_GetScreenDimensions(void)
{
SDL_DisplayMode mode;
int w = 16, h = 9;
int ah;
SCREENWIDTH = ORIGWIDTH;
SCREENHEIGHT = ORIGHEIGHT;
NONWIDEWIDTH = SCREENWIDTH;
ah = use_aspect ? (6 * SCREENHEIGHT / 5) : SCREENHEIGHT;
int unscaled_ah = use_aspect ? (6 * SCREENHEIGHT / 5) : SCREENHEIGHT;
if (SDL_GetCurrentDisplayMode(video_display, &mode) == 0)
{
// [crispy] sanity check: really widescreen display?
if (mode.w * ah >= mode.h * SCREENWIDTH)
if (mode.w * unscaled_ah >= mode.h * SCREENWIDTH)
{
w = mode.w;
h = mode.h;
}
}
if (hires)
{
video.height = use_aspect ? (5 * mode.h / 6) : mode.h;
actualheight = mode.h;
}
else
{
video.height = SCREENHEIGHT;
actualheight = unscaled_ah;
}
video.unscaledh = SCREENHEIGHT;
if (widescreen)
{
switch(widescreen)
@ -931,38 +945,36 @@ void I_GetScreenDimensions(void)
break;
}
SCREENWIDTH = w * ah / h;
// [crispy] make sure SCREENWIDTH is an integer multiple of 4 ...
// [FG] For performance reasons, SDL2 insists that the screen pitch,
// i.e. the *number of bytes* that one horizontal row of pixels
// occupy in memory, must be a multiple of 4.
// And for a paletted framebuffer with only one byte per pixel
// this means we need to keep the *number of pixels* a multiple of 4.
//
// Now, in widescreen mode, 240 px * 16 / 9 = 426.7 px.
// The widescreen status bar graphic of the Unity port is 426 px wide.
// This, however, is not a multiple of 4, so we have to *round up*
// to 428 px for it to fit on screen (with one blank px left and right).
// In hires mode, 480 px * 16 / 9 = 853.3 px.
// In order to fit the widescreen status bar graphic exactly twice on
// screen, we *round down* to 2 * 426 px = 852 px.
if (hires)
{
SCREENWIDTH = ((2 * SCREENWIDTH) & (int)~3) / 2;
}
else
{
SCREENWIDTH = (SCREENWIDTH + 3) & (int)~3;
}
// [crispy] ... but never exceeds MAX_SCREENWIDTH (array size!)
SCREENWIDTH = MIN(SCREENWIDTH, MAX_SCREENWIDTH / 2);
video.unscaledw = w * unscaled_ah / h;
video.width = w * actualheight / h;
}
else
{
video.unscaledw = SCREENWIDTH;
video.width = 4 * actualheight / 3;
}
WIDESCREENDELTA = (SCREENWIDTH - NONWIDEWIDTH) / 2;
// [FG] For performance reasons, SDL2 insists that the screen pitch, i.e.
// the *number of bytes* that one horizontal row of pixels occupy in
// memory, must be a multiple of 4.
video.unscaledw = (video.unscaledw + 3) & ~3;
video.width = (video.width + 3) & ~3;
video.height = (video.height + 3) & ~3;
FOV = 2 * atan(SCREENWIDTH / (1.2 * SCREENHEIGHT) * 3 / 4) / M_PI * ANG180;
// [crispy] ... but never exceeds MAX_SCREENWIDTH (array size!)
video.width = MIN(video.width, MAX_SCREENWIDTH);
video.height = MIN(video.height, MAX_SCREENHEIGHT);
video.deltaw = (video.unscaledw - NONWIDEWIDTH) / 2;
video.fov = 2 * atan(video.unscaledw / (1.2 * video.unscaledh) * 3 / 4) / M_PI * ANG180;
video.xscale = (video.width << FRACBITS) / video.unscaledw;
video.yscale = (video.height << FRACBITS) / video.unscaledh;
video.xstep = ((video.unscaledw << FRACBITS) / video.width) + 1;
video.ystep = ((video.unscaledh << FRACBITS) / video.height) + 1;
printf("render resolution: %dx%d\n", video.width, video.height);
}
static void CreateUpscaledTexture(boolean force)
@ -971,8 +983,8 @@ static void CreateUpscaledTexture(boolean force)
int w, h, w_upscale, h_upscale;
static int h_upscale_old, w_upscale_old;
const int screen_width = (SCREENWIDTH << hires);
const int screen_height = (SCREENHEIGHT << hires);
const int screen_width = video.width;
const int screen_height = video.height;
SDL_GetRendererInfo(renderer, &info);
@ -1066,24 +1078,28 @@ static int scalefactor;
static void I_ResetGraphicsMode(void)
{
int w, h;
static int old_w, old_h;
int window_w, window_h;
//static int old_w, old_h;
uint32_t pixel_format;
I_GetScreenDimensions();
w = (SCREENWIDTH << hires);
h = (SCREENHEIGHT << hires);
w = video.width;
h = video.height;
window_w = SCREENWIDTH * 2;
window_h = SCREENHEIGHT * 2;
blit_rect.w = w;
blit_rect.h = h;
actualheight = use_aspect ? (6 * h / 5) : h;
I_Printf(VB_DEBUG, "I_ResetGraphicsMode: Rendering resolution %dx%d",
w, actualheight);
SDL_SetWindowMinimumSize(screen, w, actualheight);
SDL_SetWindowMinimumSize(screen, window_w, window_h);
// TODO
#if 0
if (!fullscreen)
{
SDL_GetWindowSize(screen, &window_width, &window_height);
@ -1110,6 +1126,7 @@ static void I_ResetGraphicsMode(void)
old_w = w;
old_h = actualheight;
#endif
if (!fullscreen)
{
@ -1145,10 +1162,6 @@ static void I_ResetGraphicsMode(void)
I_VideoBuffer = sdlscreen->pixels;
V_RestoreBuffer();
// Clear the screen to black.
memset(I_VideoBuffer, 0, w * h * sizeof(*I_VideoBuffer));
pixel_format = SDL_GetWindowPixelFormat(screen);
// [FG] create intermediate ARGB frame buffer

View File

@ -23,16 +23,30 @@
#include "doomtype.h"
#include "doomdef.h"
#include "tables.h"
extern int SCREENWIDTH;
extern int SCREENHEIGHT;
extern int NONWIDEWIDTH; // [crispy] non-widescreen SCREENWIDTH
extern int WIDESCREENDELTA; // [crispy] horizontal widescreen offset
#define NONWIDEWIDTH SCREENWIDTH // [crispy] non-widescreen SCREENWIDTH
extern angle_t FOV;
typedef struct
{
int width;
int height;
int unscaledw;
int unscaledh;
int deltaw;
void I_GetScreenDimensions (void); // [crispy] re-calculate WIDESCREENDELTA
fixed_t xscale;
fixed_t yscale;
fixed_t xstep;
fixed_t ystep;
angle_t fov;
} video_t;
extern video_t video;
void I_GetScreenDimensions(void);
enum
{

View File

@ -814,22 +814,22 @@ static void M_DrawBorderedSnapshot (int n)
{
const char *txt = "n/a";
const int snapshot_x = MAX((WIDESCREENDELTA + SaveDef.x + SKULLXOFF - snapshot_width) / 2, 8);
const int snapshot_x = MAX((video.deltaw + SaveDef.x + SKULLXOFF - snapshot_width) / 2, 8);
const int snapshot_y = LoadDef.y + MAX((load_end * LINEHEIGHT - snapshot_height) * n / load_end, 0);
// [FG] a snapshot window smaller than 80*48 px is considered too small
if (snapshot_width < ORIGWIDTH/4)
if (snapshot_width < SCREENWIDTH/4)
return;
if (!M_DrawSnapshot(n, snapshot_x, snapshot_y, snapshot_width, snapshot_height))
{
M_WriteText(snapshot_x + snapshot_width/2 - M_StringWidth(txt)/2 - WIDESCREENDELTA,
M_WriteText(snapshot_x + snapshot_width/2 - M_StringWidth(txt)/2 - video.deltaw,
snapshot_y + snapshot_height/2 - M_StringHeight(txt)/2,
txt);
}
txt = M_GetSavegameTime(n);
M_DrawString(snapshot_x + snapshot_width/2 - M_GetPixelWidth(txt)/2 - WIDESCREENDELTA,
M_DrawString(snapshot_x + snapshot_width/2 - M_GetPixelWidth(txt)/2 - video.deltaw,
snapshot_y + snapshot_height + M_StringHeight(txt),
CR_GOLD, txt);
@ -1026,11 +1026,11 @@ void M_ReadSaveStrings(void)
// [FG] shift savegame descriptions a bit to the right
// to make room for the snapshots on the left
SaveDef.x = LoadDef.x = M_X_LOADSAVE + MIN(M_LOADSAVE_WIDTH/2, WIDESCREENDELTA);
SaveDef.x = LoadDef.x = M_X_LOADSAVE + MIN(M_LOADSAVE_WIDTH/2, video.deltaw);
// [FG] fit the snapshots into the resulting space
snapshot_width = MIN((WIDESCREENDELTA + SaveDef.x + 2 * SKULLXOFF) & ~7, ORIGWIDTH/2); // [FG] multiple of 8
snapshot_height = MIN((snapshot_width * ORIGHEIGHT / ORIGWIDTH) & ~7, ORIGHEIGHT/2);
snapshot_width = MIN((video.deltaw + SaveDef.x + 2 * SKULLXOFF) & ~7, SCREENWIDTH/2); // [FG] multiple of 8
snapshot_height = MIN((snapshot_width * SCREENHEIGHT / SCREENWIDTH) & ~7, SCREENHEIGHT/2);
for (i = 0 ; i < load_end ; i++)
{
@ -2422,8 +2422,8 @@ void M_DrawSetting(setup_menu_t* s)
for (i = 0 ; i < char_width ; i++)
colorblock[i] = PAL_WHITE;
if (x+cursor_start-1+WIDESCREENDELTA+char_width < SCREENWIDTH)
V_DrawBlock(x+cursor_start-1+WIDESCREENDELTA,y+7,char_width,1,colorblock);
if (x+cursor_start-1+video.deltaw+char_width < video.unscaledw)
V_DrawBlock(x+cursor_start-1+video.deltaw,y+7,char_width,1,colorblock);
}
// Draw the setting for the item
@ -2545,7 +2545,7 @@ void M_DrawScreenItems(setup_menu_t* src)
strcpy(menu_buffer, "Warning: Changes are pending until next game");
}
x_warn = ORIGWIDTH/2 - M_GetPixelWidth(menu_buffer)/2;
x_warn = SCREENWIDTH/2 - M_GetPixelWidth(menu_buffer)/2;
M_DrawMenuString(x_warn, M_Y_WARN, CR_RED);
}
@ -6977,7 +6977,7 @@ void M_DrawTitle(int x, int y, const char *patch, const char *alttext, int pages
{
// patch doesn't exist, draw some text in place of it
M_snprintf(menu_buffer, sizeof(menu_buffer), "%s", alttext);
M_DrawMenuString(ORIGWIDTH/2 - M_StringWidth(alttext)/2,
M_DrawMenuString(SCREENWIDTH/2 - M_StringWidth(alttext)/2,
y + 8 - M_StringHeight(alttext)/2, // assumes patch height 16
CR_TITLE);
}
@ -6986,7 +6986,7 @@ void M_DrawTitle(int x, int y, const char *patch, const char *alttext, int pages
{
M_snprintf(menu_buffer, sizeof(menu_buffer), "page %d/%d",
mult_screens_index + 1, pages - 1);
M_DrawMenuString(ORIGWIDTH/2 - M_StringWidth(menu_buffer)/2,
M_DrawMenuString(SCREENWIDTH/2 - M_StringWidth(menu_buffer)/2,
M_Y_PREVNEXT, CR_TITLE);
}
}
@ -7094,7 +7094,7 @@ void M_Init(void)
if (W_CheckNumForName("M_GDHIGH") != -1)
{
patch_t *patch = W_CacheLumpName("M_GDHIGH", PU_CACHE);
if (OptionsDef.x + 175 + SHORT(patch->width) >= ORIGWIDTH)
if (OptionsDef.x + 175 + SHORT(patch->width) >= SCREENWIDTH)
{
if (W_CheckNumForName("M_DISP") != -1)
strcpy(OptionsMenu[scrnsize].name, "M_DISP");

View File

@ -28,7 +28,7 @@
static const char snapshot_str[] = "WOOF_SNAPSHOT";
static const int snapshot_len = arrlen(snapshot_str);
static const int snapshot_size = ORIGWIDTH * ORIGHEIGHT;
static const int snapshot_size = SCREENWIDTH * SCREENHEIGHT;
static byte *snapshots[10];
static byte *current_snapshot;
@ -97,12 +97,14 @@ char *M_GetSavegameTime (int i)
return savegametimes[i];
}
// [FG] take a snapshot in ORIGWIDTH*ORIGHEIGHT resolution, i.e.
// [FG] take a snapshot in SCREENWIDTH*SCREENHEIGHT resolution, i.e.
// in hires mode only only each second pixel in each second row is saved,
// in widescreen mode only the non-widescreen part in the middle is saved
static void M_TakeSnapshot (void)
{
// TODO
#if 0
const int inc = hires ? 2 : 1;
int x, y;
byte *p;
@ -123,11 +125,12 @@ static void M_TakeSnapshot (void)
{
for (x = 0; x < (NONWIDEWIDTH << hires); x += inc)
{
*p++ = s[y * (SCREENWIDTH << hires) + (WIDESCREENDELTA << hires) + x];
*p++ = s[y * (SCREENWIDTH << hires) + (video.widedelta << hires) + x];
}
}
R_SetViewSize(old_screenblocks);
#endif
}
void M_WriteSnapshot (byte *p)
@ -146,6 +149,8 @@ void M_WriteSnapshot (byte *p)
boolean M_DrawSnapshot (int n, int x, int y, int w, int h)
{
// TODO
#if 0
byte *dest = I_VideoBuffer + y * (SCREENWIDTH << (2 * hires)) + (x << hires);
if (!snapshots[n])
@ -162,8 +167,8 @@ boolean M_DrawSnapshot (int n, int x, int y, int w, int h)
}
else
{
const fixed_t step_x = (ORIGWIDTH << FRACBITS) / (w << hires);
const fixed_t step_y = (ORIGHEIGHT << FRACBITS) / (h << hires);
const fixed_t step_x = (SCREENWIDTH << FRACBITS) / (w << hires);
const fixed_t step_y = (SCREENHEIGHT << FRACBITS) / (h << hires);
int destx, desty;
fixed_t srcx, srcy;
byte *destline, *srcline;
@ -171,7 +176,7 @@ boolean M_DrawSnapshot (int n, int x, int y, int w, int h)
for (desty = 0, srcy = 0; desty < (h << hires); desty++, srcy += step_y)
{
destline = dest + desty * (SCREENWIDTH << hires);
srcline = snapshots[n] + (srcy >> FRACBITS) * ORIGWIDTH;
srcline = snapshots[n] + (srcy >> FRACBITS) * SCREENWIDTH;
for (destx = 0, srcx = 0; destx < (w << hires); destx++, srcx += step_x)
{
@ -179,6 +184,7 @@ boolean M_DrawSnapshot (int n, int x, int y, int w, int h)
}
}
}
#endif
return true;
}

View File

@ -29,8 +29,6 @@
#define MAXWIDTH MAX_SCREENWIDTH /* kilough 2/8/98 */
#define MAXHEIGHT MAX_SCREENHEIGHT
#define SBARHEIGHT 32 /* status bar height at bottom of screen */
//
// All drawing to the view buffer is accomplished in this file.
// The other refresh files only know about ccordinates,
@ -44,12 +42,14 @@ byte *viewimage;
int viewwidth;
int scaledviewwidth;
int scaledviewheight; // killough 11/98
int scaledviewx;
int scaledviewy;
int viewheight;
int viewwindowx;
int viewwindowy;
byte *ylookup[MAXHEIGHT];
int columnofs[MAXWIDTH];
int linesize = ORIGWIDTH; // killough 11/98
static byte *ylookup[MAXHEIGHT];
static int columnofs[MAXWIDTH];
static int linesize = SCREENWIDTH; // killough 11/98
// Color tables for different players,
// translate a limited part to another
@ -524,6 +524,8 @@ static void R_DrawFuzzColumn_orig(void)
// draw only even pixels as 2x2 squares
// using the same fuzzoffset value
// TODO
#if 0
static void R_DrawFuzzColumn_block(void)
{
int count;
@ -595,6 +597,7 @@ static void R_DrawFuzzColumn_block(void)
dest[1] = fuzz;
}
}
#endif
// [FG] spectre drawing mode: 0 original, 1 blocky (hires)
@ -602,9 +605,12 @@ int fuzzcolumn_mode;
void (*R_DrawFuzzColumn) (void) = R_DrawFuzzColumn_orig;
void R_SetFuzzColumnMode (void)
{
// TODO
#if 0
if (fuzzcolumn_mode && hires)
R_DrawFuzzColumn = R_DrawFuzzColumn_block;
else
#endif
R_DrawFuzzColumn = R_DrawFuzzColumn_orig;
}
@ -802,34 +808,34 @@ void R_DrawSpan (void)
// of a pixel to draw.
//
void R_InitBuffer(int width, int height)
{
int i;
void R_InitBuffer(void)
{
int i;
linesize = SCREENWIDTH << hires; // killough 11/98
linesize = video.width; // killough 11/98
// Handle resize,
// e.g. smaller view windows
// with border and/or status bar.
viewwindowx = (SCREENWIDTH-width) >> !hires; // killough 11/98
// Column offset. For windows.
for (i = width << hires ; i--; ) // killough 11/98
for (i = viewwidth; i--; ) // killough 11/98
columnofs[i] = viewwindowx + i;
// Same with base row offset.
viewwindowy = width==SCREENWIDTH ? 0 : (SCREENHEIGHT-SBARHEIGHT-height)>>1;
viewwindowy <<= hires; // killough 11/98
// Preclaculate all row offsets.
for (i = height << hires; i--; )
ylookup[i] = I_VideoBuffer + (i+viewwindowy)*linesize; // killough 11/98
}
for (i = viewheight; i--; )
ylookup[i] = I_VideoBuffer + (i + viewwindowy) * linesize; // killough 11/98
if (background_buffer != NULL)
{
Z_Free(background_buffer);
background_buffer = NULL;
}
}
void R_DrawBorder (int x, int y, int w, int h)
{
@ -838,47 +844,47 @@ void R_DrawBorder (int x, int y, int w, int h)
patch = W_CacheLumpName("brdr_t", PU_CACHE);
for (i = 0; i < w; i += 8)
V_DrawPatch(x + i - WIDESCREENDELTA, y - 8, patch);
V_DrawPatch(x + i - video.deltaw, y - 8, patch);
patch = W_CacheLumpName("brdr_b", PU_CACHE);
for (i = 0; i < w; i += 8)
V_DrawPatch(x + i - WIDESCREENDELTA, y + h, patch);
V_DrawPatch(x + i - video.deltaw, y + h, patch);
patch = W_CacheLumpName("brdr_l", PU_CACHE);
for (j = 0; j < h; j += 8)
V_DrawPatch(x - 8 - WIDESCREENDELTA, y + j, patch);
V_DrawPatch(x - 8 - video.deltaw, y + j, patch);
patch = W_CacheLumpName("brdr_r", PU_CACHE);
for (j = 0; j < h; j += 8)
V_DrawPatch(x + w - WIDESCREENDELTA, y + j, patch);
V_DrawPatch(x + w - video.deltaw, y + j, patch);
// Draw beveled edge.
V_DrawPatch(x - 8 - WIDESCREENDELTA,
V_DrawPatch(x - 8 - video.deltaw,
y - 8,
W_CacheLumpName("brdr_tl", PU_CACHE));
V_DrawPatch(x + w - WIDESCREENDELTA,
V_DrawPatch(x + w - video.deltaw,
y - 8,
W_CacheLumpName("brdr_tr", PU_CACHE));
V_DrawPatch(x - 8 - WIDESCREENDELTA,
V_DrawPatch(x - 8 - video.deltaw,
y + h,
W_CacheLumpName("brdr_bl", PU_CACHE));
V_DrawPatch(x + w - WIDESCREENDELTA,
V_DrawPatch(x + w - video.deltaw,
y + h,
W_CacheLumpName("brdr_br", PU_CACHE));
}
void R_FillBackScreen (void)
{
if (scaledviewwidth == SCREENWIDTH)
if (scaledviewwidth == video.unscaledw)
return;
// Allocate the background buffer if necessary
if (background_buffer == NULL)
{
int size = (hires ? SCREENWIDTH * SCREENHEIGHT * 4 : SCREENWIDTH * SCREENHEIGHT);
int size = video.width * video.height;
background_buffer = Z_Malloc(size * sizeof(*background_buffer), PU_STATIC, NULL);
}
@ -886,7 +892,7 @@ void R_FillBackScreen (void)
V_DrawBackground(gamemode == commercial ? "GRNROCK" : "FLOOR7_2");
R_DrawBorder(viewwindowx >> hires, viewwindowy >> hires, scaledviewwidth, scaledviewheight);
R_DrawBorder(scaledviewx, scaledviewy, scaledviewwidth, scaledviewheight);
V_RestoreBuffer();
}
@ -895,16 +901,10 @@ void R_FillBackScreen (void)
// Copy a screen buffer.
//
static void R_VideoErase(unsigned ofs, int count)
{
if (hires) // killough 11/98: hires support
{
ofs = ofs*4 - (ofs % SCREENWIDTH)*2; // recompose offset
memcpy(I_VideoBuffer + ofs, background_buffer + ofs, count *= 2); // LFB copy.
ofs += SCREENWIDTH*2;
}
memcpy(I_VideoBuffer + ofs, background_buffer + ofs, count); // LFB copy.
}
static void R_VideoErase(int x, int y, int w, int h)
{
V_CopyRect(x, y, background_buffer, w, h, x, y);
}
//
// R_DrawViewBorder
@ -917,28 +917,23 @@ static void R_VideoErase(unsigned ofs, int count)
//
void R_DrawViewBorder(void)
{
int side, ofs, i;
if (scaledviewwidth == SCREENWIDTH || background_buffer == NULL)
return;
{
int side;
// copy top
for (ofs = 0, i = viewwindowy >> hires; i--; ofs += SCREENWIDTH)
R_VideoErase(ofs, SCREENWIDTH);
if (scaledviewwidth == video.unscaledw || background_buffer == NULL)
return;
// copy sides
for (side = viewwindowx >> hires, i = scaledviewheight; i--;)
{
R_VideoErase(ofs, side);
ofs += SCREENWIDTH;
R_VideoErase(ofs - side, side);
}
// copy top
R_VideoErase(0, 0, video.unscaledw, scaledviewy);
// copy bottom
for (i = viewwindowy >> hires; i--; ofs += SCREENWIDTH)
R_VideoErase(ofs, SCREENWIDTH);
}
// copy sides
side = scaledviewx;
R_VideoErase(0, scaledviewy, side, scaledviewheight);
R_VideoErase(video.unscaledw - side, scaledviewy, side, scaledviewheight);
// copy bottom
R_VideoErase(0, scaledviewy + scaledviewheight, video.unscaledw, scaledviewy);
}
//----------------------------------------------------------------------------
//

View File

@ -30,7 +30,6 @@ extern fixed_t dc_iscale;
extern fixed_t dc_texturemid;
extern int dc_texheight; // killough
extern byte dc_skycolor;
extern int linesize; // killough 11/98
// first pixel in a column
extern byte *dc_source;
@ -77,7 +76,7 @@ extern const byte *ds_brightmap;
// Span blitting for rows, floor/ceiling. No Spectre effect needed.
void R_DrawSpan(void);
void R_InitBuffer(int width, int height);
void R_InitBuffer(void);
// Initialize color translation tables, for player rendering etc.
void R_InitTranslationTables(void);

View File

@ -29,6 +29,7 @@
#include "r_voxel.h"
#include "m_bbox.h"
#include "v_video.h"
#include "am_map.h"
#include "st_stuff.h"
#include "hu_stuff.h"
@ -307,7 +308,7 @@ static void R_InitTextureMapping (void)
clipangle = xtoviewangle[0];
vx_clipangle = clipangle - (FOV - ANG90);
vx_clipangle = clipangle - (video.fov - ANG90);
}
//
@ -397,7 +398,7 @@ void R_InitLightTables (void)
for (j=0; j<MAXLIGHTZ; j++)
{
int scale = FixedDiv ((ORIGWIDTH/2*FRACUNIT), (j+1)<<LIGHTZSHIFT);
int scale = FixedDiv ((SCREENWIDTH/2*FRACUNIT), (j+1)<<LIGHTZSHIFT);
int t, level = startmap - (scale >>= LIGHTSCALESHIFT)/DISTMAP;
if (level < 0)
@ -439,47 +440,59 @@ void R_SetViewSize(int blocks)
void R_ExecuteSetViewSize (void)
{
int i, j;
extern void AM_Start(void);
vrect_t view;
setsizeneeded = false;
if (setblocks == 11)
{
scaledviewwidth_nonwide = NONWIDEWIDTH;
scaledviewwidth = SCREENWIDTH;
scaledviewheight = SCREENHEIGHT; // killough 11/98
scaledviewwidth = video.unscaledw;
scaledviewheight = video.unscaledh; // 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;
scaledviewwidth = video.unscaledw;
scaledviewheight = video.unscaledh - ST_HEIGHT;
}
else
{
scaledviewwidth_nonwide = setblocks*32;
scaledviewheight = (setblocks*168/10) & ~7; // killough 11/98
if (widescreen)
{
const int widescreen_edge_aligner = (8 << hires) - 1;
const int st_screen = video.unscaledh - ST_HEIGHT;
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);
}
scaledviewwidth_nonwide = setblocks * 32;
scaledviewheight = (setblocks * st_screen / 10) & ~7; // killough 11/98
if (widescreen)
scaledviewwidth = (scaledviewheight * video.unscaledw / st_screen) & ~7;
else
{
scaledviewwidth = scaledviewwidth_nonwide;
}
}
viewwidth = scaledviewwidth << hires; // killough 11/98
viewheight = scaledviewheight << hires; // killough 11/98
viewwidth_nonwide = scaledviewwidth_nonwide << hires;
scaledviewx = (video.unscaledw - scaledviewwidth) / 2;
viewblocks = MIN(setblocks, 10) << hires;
if (scaledviewwidth == video.unscaledw)
scaledviewy = 0;
else
scaledviewy = (video.unscaledh - ST_HEIGHT - scaledviewheight) / 2;
view.x = scaledviewx;
view.y = scaledviewy;
view.w = scaledviewwidth;
view.h = scaledviewheight;
V_ClipRect(&view);
V_ScaleRect(&view);
viewwidth = view.sw;
viewheight = view.sh;
viewwidth_nonwide = (scaledviewwidth_nonwide * video.xscale) >> FRACBITS;
viewwindowx = view.sx;
viewwindowy = view.sy;
viewblocks = (MIN(setblocks, 10) * video.yscale) >> FRACBITS;
centery = viewheight/2;
centerx = viewwidth/2;
@ -489,13 +502,13 @@ void R_ExecuteSetViewSize (void)
projection = centerxfrac_nonwide;
viewheightfrac = viewheight<<(FRACBITS+1); // [FG] sprite clipping optimizations
R_InitBuffer(scaledviewwidth, scaledviewheight); // killough 11/98
R_InitBuffer(); // killough 11/98
R_InitTextureMapping();
// psprite scales
pspritescale = FixedDiv(viewwidth_nonwide, ORIGWIDTH); // killough 11/98
pspriteiscale= FixedDiv(ORIGWIDTH, viewwidth_nonwide); // killough 11/98
pspritescale = FixedDiv(viewwidth_nonwide, SCREENWIDTH); // killough 11/98
pspriteiscale= FixedDiv(SCREENWIDTH, viewwidth_nonwide); // killough 11/98
// thing clipping
for (i=0 ; i<viewwidth ; i++)
@ -740,7 +753,9 @@ void R_RenderPlayerView (player_t* player)
R_ClearPlanes ();
R_ClearSprites ();
VX_ClearVoxels ();
// TODO
#if 0
if (autodetect_hom)
{ // killough 2/10/98: add flashing red HOM indicators
pixel_t c[47*47];
@ -811,6 +826,7 @@ void R_RenderPlayerView (player_t* player)
(viewwindowy + viewheight/2 - 24)>>hires, 47, 47, c);
R_DrawViewBorder();
}
#endif
// check for new console commands.
NetUpdate ();

View File

@ -408,12 +408,12 @@ static void do_draw_plane(visplane_t *pl)
else if (!vertically_scrolling)
{
// Make sure the fade-to-color effect doesn't happen too early
fixed_t diff = dc_texturemid - ORIGHEIGHT / 2 * FRACUNIT;
fixed_t diff = dc_texturemid - SCREENHEIGHT / 2 * FRACUNIT;
if (diff < 0)
{
diff += textureheight[texture];
diff %= textureheight[texture];
dc_texturemid = ORIGHEIGHT / 2 * FRACUNIT + diff;
dc_texturemid = SCREENHEIGHT / 2 * FRACUNIT + diff;
}
dc_skycolor = R_GetSkyColor(texture);
colfunc = R_DrawSkyColumn;

View File

@ -157,7 +157,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2)
{
if (!fixedcolormap) // calculate lighting
{ // killough 11/98:
unsigned index = spryscale>>(LIGHTSCALESHIFT+hires);
unsigned index = spryscale >> (LIGHTSCALESHIFT + (video.xscale >> FRACBITS));
if (index >= MAXLIGHTSCALE )
index = MAXLIGHTSCALE-1;
@ -374,7 +374,7 @@ static void R_RenderSegLoop (void)
texturecolumn >>= FRACBITS;
// calculate lighting
index = rw_scale>>(LIGHTSCALESHIFT+hires); // killough 11/98
index = rw_scale >> (LIGHTSCALESHIFT + (video.xscale >> FRACBITS)); // killough 11/98
if (index >= MAXLIGHTSCALE )
index = MAXLIGHTSCALE-1;

View File

@ -44,8 +44,10 @@ extern lighttable_t *fullcolormap; // killough 3/20/98
extern int viewwidth;
extern int scaledviewwidth;
extern int scaledviewx;
extern int viewheight;
extern int scaledviewheight; // killough 11/98
extern int scaledviewy;
extern int firstflat;

View File

@ -813,6 +813,7 @@ static void VX_DrawColumn (vissprite_t * spr, int x, int y)
boolean shadow = ((spr->mobjflags & MF_SHADOW) != 0);
int linesize = video.width;
byte * dest = I_VideoBuffer + viewwindowy * linesize + viewwindowx;
// iterate over screen columns

View File

@ -24,6 +24,7 @@
#include "doomstat.h"
#include "m_random.h"
#include "i_video.h"
#include "v_video.h"
#include "w_wad.h"
#include "st_stuff.h"
#include "hu_stuff.h" // [FG] hud_displayed
@ -182,7 +183,7 @@ extern boolean inhelpscreens;
// killough 2/8/98: weapon info position macros UNUSED, removed here
// graphics are drawn to a backing screen and blitted to the real screen
pixel_t *st_backing_screen = NULL;
static pixel_t *st_backing_screen = NULL;
// main player in game
static player_t *plyr;
@ -317,153 +318,157 @@ void ST_Stop(void);
int st_solidbackground;
void ST_refreshBackground(boolean force)
static void ST_DrawSolidBackground(void)
{
if (st_classicstatusbar)
// TODO
#if 0
// [FG] calculate average color of the 16px left and right of the status bar
const int vstep[][2] = {{0, 1}, {1, 2}, {2, ST_HEIGHT}};
const int hstep = video.width;
const int lo = MAX(st_x + video.widedelta - SHORT(sbar->leftoffset), 0);
const int w = MIN(SHORT(sbar->width), SCREENWIDTH);
const int depth = 16;
byte *pal = W_CacheLumpName("PLAYPAL", PU_STATIC);
int v;
// [FG] temporarily draw status bar to background buffer
V_DrawPatch(st_x, 0, sbar);
// [FG] separate colors for the top rows
for (v = 0; v < arrlen(vstep); v++)
{
int x, y;
const int v0 = vstep[v][0], v1 = vstep[v][1];
unsigned r = 0, g = 0, b = 0;
byte col;
for (y = v0; y < v1; y++)
{
const int st_x = (SHORT(sbar->width) > ORIGWIDTH && SHORT(sbar->leftoffset) == 0) ?
ST_X + (ORIGWIDTH - SHORT(sbar->width)) / 2 :
ST_X;
V_UseBuffer(st_backing_screen);
if (SCREENWIDTH != ST_WIDTH)
for (x = 0; x < depth; x++)
{
int x, y;
byte *dest = st_backing_screen;
byte *c = st_backing_screen + y * hstep + ((x + lo) << hires);
r += pal[3 * c[0] + 0];
g += pal[3 * c[0] + 1];
b += pal[3 * c[0] + 2];
if (st_solidbackground)
{
// [FG] calculate average color of the 16px left and right of the status bar
const int vstep[][2] = {{0, 1}, {1, 2}, {2, ST_HEIGHT}};
const int hstep = hires ? (4 * SCREENWIDTH) : SCREENWIDTH;
const int lo = MAX(st_x + WIDESCREENDELTA - SHORT(sbar->leftoffset), 0);
const int w = MIN(SHORT(sbar->width), SCREENWIDTH);
const int depth = 16;
byte *pal = W_CacheLumpName("PLAYPAL", PU_STATIC);
int v;
// [FG] temporarily draw status bar to background buffer
V_DrawPatch(st_x, 0, sbar);
// [FG] separate colors for the top rows
for (v = 0; v < arrlen(vstep); v++)
{
const int v0 = vstep[v][0], v1 = vstep[v][1];
unsigned r = 0, g = 0, b = 0;
byte col;
for (y = v0; y < v1; y++)
{
for (x = 0; x < depth; x++)
{
byte *c = dest + y * hstep + ((x + lo) << hires);
r += pal[3 * c[0] + 0];
g += pal[3 * c[0] + 1];
b += pal[3 * c[0] + 2];
c += (w - 2 * x - 1) << hires;
r += pal[3 * c[0] + 0];
g += pal[3 * c[0] + 1];
b += pal[3 * c[0] + 2];
}
}
r /= 2 * depth * (v1 - v0);
g /= 2 * depth * (v1 - v0);
b /= 2 * depth * (v1 - v0);
// [FG] tune down to half saturation (for empiric reasons)
col = I_GetPaletteIndex(pal, r/2, g/2, b/2);
// [FG] fill background buffer with average status bar color
for (y = (v0 << hires); y < (v1 << hires); y++)
{
memset(dest + y * (SCREENWIDTH << hires), col, (SCREENWIDTH << hires));
}
}
Z_ChangeTag (pal, PU_CACHE);
}
else
{
// [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
byte *src;
const char *name = (gamemode == commercial) ? "GRNROCK" : "FLOOR7_2";
src = W_CacheLumpNum(firstflat + R_FlatNumForName(name), PU_CACHE);
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, patch);
V_DrawPatch(ORIGWIDTH + WIDESCREENDELTA - x - 8, 0, patch);
}
}
}
c += (w - 2 * x - 1) << hires;
r += pal[3 * c[0] + 0];
g += pal[3 * c[0] + 1];
b += pal[3 * c[0] + 2];
}
// [crispy] center unity rerelease wide status bar
V_DrawPatch(st_x, 0, sbar);
// draw right side of bar if needed (Doom 1.0)
if (sbarr)
V_DrawPatch(ST_ARMSBGX, 0, sbarr);
if (st_notdeathmatch)
V_DrawPatch(ST_ARMSBGX, 0, armsbg);
// killough 3/7/98: make face background change with displayplayer
if (netgame)
V_DrawPatch(ST_FX, 0, faceback[displayplayer]);
V_RestoreBuffer();
// [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, st_backing_screen, SCREENWIDTH, ST_HEIGHT, ST_X, ST_Y);
}
else
{
if (WIDESCREENDELTA > 0 && !st_firsttime)
{
V_CopyRect(0, 0, st_backing_screen, WIDESCREENDELTA, ST_HEIGHT, 0, ST_Y);
V_CopyRect(ORIGWIDTH + WIDESCREENDELTA, 0, st_backing_screen,
WIDESCREENDELTA, ST_HEIGHT, ORIGWIDTH + WIDESCREENDELTA, ST_Y);
}
}
}
r /= 2 * depth * (v1 - v0);
g /= 2 * depth * (v1 - v0);
b /= 2 * depth * (v1 - v0);
// [FG] tune down to half saturation (for empiric reasons)
col = I_GetPaletteIndex(pal, r/2, g/2, b/2);
// [FG] fill background buffer with average status bar color
for (y = (v0 << hires); y < (v1 << hires); y++)
{
memset(dest + y * (SCREENWIDTH << hires), col, (SCREENWIDTH << hires));
}
}
Z_ChangeTag (pal, PU_CACHE);
#endif
}
void ST_refreshBackground(boolean force)
{
int st_x;
if (!st_classicstatusbar)
{
return;
}
if (SHORT(sbar->width) > video.unscaledw && SHORT(sbar->leftoffset) == 0)
{
st_x = ST_X + (video.unscaledw - SHORT(sbar->width)) / 2;
}
else
{
st_x = ST_X;
}
V_UseBuffer(st_backing_screen);
if (video.unscaledw != ST_WIDTH)
{
// TODO
#if 0
if (st_solidbackground)
{
ST_DrawSolidBackground();
}
else
#endif
{
// [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
const char *name = (gamemode == commercial) ? "GRNROCK" : "FLOOR7_2";
const byte *src = W_CacheLumpNum(firstflat + R_FlatNumForName(name), PU_CACHE);
V_TileBlock64(video.unscaledh - ST_HEIGHT, video.unscaledw, ST_HEIGHT, src);
// [crispy] preserve bezel bottom edge
if (scaledviewwidth == video.unscaledw)
{
int x;
patch_t *patch = W_CacheLumpName("brdr_b", PU_CACHE);
for (x = 0; x < video.deltaw; x += 8)
{
V_DrawPatch(x - video.deltaw, 0, patch);
V_DrawPatch(video.unscaledw - x - 8 - video.deltaw, 0, patch);
}
}
}
}
// [crispy] center unity rerelease wide status bar
V_DrawPatch(st_x, 0, sbar);
// draw right side of bar if needed (Doom 1.0)
if (sbarr)
V_DrawPatch(ST_ARMSBGX, 0, sbarr);
if (st_notdeathmatch)
V_DrawPatch(ST_ARMSBGX, 0, armsbg);
// killough 3/7/98: make face background change with displayplayer
if (netgame)
V_DrawPatch(ST_FX, 0, faceback[displayplayer]);
V_RestoreBuffer();
// [crispy] copy entire video.unscaledw, to preserve the pattern to the left
// and right of the status bar in widescren mode
if (!force)
{
V_CopyRect(ST_X, 0, st_backing_screen,
video.unscaledw, ST_HEIGHT,
ST_X, ST_Y);
}
else
{
if (video.deltaw > 0 && !st_firsttime)
{
V_CopyRect(0, 0, st_backing_screen,
video.deltaw, ST_HEIGHT,
0, ST_Y);
V_CopyRect(video.unscaledw - video.deltaw, 0, st_backing_screen,
video.deltaw, ST_HEIGHT,
video.unscaledw - video.deltaw, ST_Y);
}
}
}
// Respond to keyboard input events,
// intercept cheats.
@ -881,8 +886,8 @@ void ST_drawWidgets(void)
// clear area
if (!st_crispyhud && st_statusbaron)
{
V_CopyRect(WIDESCREENDELTA, 0, st_backing_screen, ST_WIDTH, ST_HEIGHT,
WIDESCREENDELTA, ST_Y);
V_CopyRect(video.deltaw, 0, st_backing_screen, ST_WIDTH, ST_HEIGHT,
video.deltaw, ST_Y);
}
// used by w_arms[] widgets
@ -1277,7 +1282,7 @@ static void ST_MoveHud (void)
static int odelta = 0;
if (st_crispyhud && hud_active == 2)
distributed_delta = WIDESCREENDELTA;
distributed_delta = video.deltaw;
else
distributed_delta = 0;
@ -1333,12 +1338,17 @@ static int StatusBarBufferHeight(void)
void ST_Init(void)
{
int st_height, size;
vrect_t rect;
ST_loadData();
st_height = StatusBarBufferHeight();
size = SCREENWIDTH * (st_height << (2 * hires));
rect.x = 0;
rect.y = 0;
rect.w = video.unscaledw;
rect.h = StatusBarBufferHeight();
V_ClipRect(&rect);
V_ScaleRect(&rect);
if (st_backing_screen)
{
@ -1346,7 +1356,7 @@ void ST_Init(void)
}
// killough 11/98: allocate enough for hires
st_backing_screen = Z_Malloc(size, PU_STATIC, 0);
st_backing_screen = Z_Malloc(rect.sw * rect.sh * sizeof(*st_backing_screen), PU_STATIC, 0);
}
void ST_Warnings(void)

View File

@ -29,8 +29,8 @@
// Now sensitive for scaling.
#define ST_HEIGHT 32
#define ST_WIDTH ORIGWIDTH
#define ST_Y (ORIGHEIGHT - ST_HEIGHT)
#define ST_WIDTH SCREENWIDTH
#define ST_Y (SCREENHEIGHT - ST_HEIGHT)
//
// STATUS BAR

File diff suppressed because it is too large Load Diff

View File

@ -90,6 +90,30 @@ extern byte gammatable[5][256];
//jff 4/24/98 loads color translation lumps
void V_InitColorTranslation(void);
typedef struct
{
int x; // original x coordinate for upper left corner
int y; // original y coordinate for upper left corner
int w; // original width
int h; // original height
int cx1; // clipped x coordinate for left edge
int cx2; // clipped x coordinate for right edge
int cy1; // clipped y coordinate for upper edge
int cy2; // clipped y coordinate for lower edge
int cw; // clipped width
int ch; // clipped height
int sx; // scaled x
int sy; // scaled y
int sw; // scaled width
int sh; // scaled height
} vrect_t;
void V_ClipRect(vrect_t *rect);
void V_ScaleRect(vrect_t *rect);
// Allocates buffer screens, call before R_Init.
void V_Init (void);
@ -131,6 +155,8 @@ void V_DrawHorizLine(int x, int y, int width, byte color);
void V_ShadeScreen(void);
void V_TileBlock64(int line, int width, int height, const byte *src);
void V_DrawBackground(const char *patchname);
// [FG] colored blood and gibs

View File

@ -454,7 +454,7 @@ static void WI_drawLF(void)
{
patch_t* lpic = W_CacheLumpName(wbs->lastmapinfo->levelpic, PU_CACHE);
V_DrawPatch((ORIGWIDTH - SHORT(lpic->width))/2,
V_DrawPatch((SCREENWIDTH - SHORT(lpic->width))/2,
y, lpic);
y += (5 * SHORT(lpic->height)) / 4;
@ -464,14 +464,14 @@ static void WI_drawLF(void)
if (wbs->last >= 0 && wbs->last < num_lnames && lnames[wbs->last] != NULL )
{
// draw <LevelName>
V_DrawPatch((ORIGWIDTH - SHORT(lnames[wbs->last]->width))/2,
V_DrawPatch((SCREENWIDTH - SHORT(lnames[wbs->last]->width))/2,
y, lnames[wbs->last]);
// draw "Finished!"
y += (5*SHORT(lnames[wbs->last]->height))/4;
}
V_DrawPatch((ORIGWIDTH - SHORT(finished->width))/2,
V_DrawPatch((SCREENWIDTH - SHORT(finished->width))/2,
y, finished);
}
@ -487,7 +487,7 @@ static void WI_drawEL(void)
int y = WI_TITLEY;
// draw "Entering"
V_DrawPatch((ORIGWIDTH - SHORT(entering->width))/2,
V_DrawPatch((SCREENWIDTH - SHORT(entering->width))/2,
y, entering);
// The level defines a new name but no texture for the name
@ -510,7 +510,7 @@ static void WI_drawEL(void)
y += (5 * SHORT(lpic->height)) / 4;
V_DrawPatch((ORIGWIDTH - SHORT(lpic->width))/2,
V_DrawPatch((SCREENWIDTH - SHORT(lpic->width))/2,
y, lpic);
}
// [FG] prevent crashes for levels without name graphics
@ -518,10 +518,10 @@ static void WI_drawEL(void)
{
// draw level
// haleyjd: corrected to use height of entering, not map name
if (SHORT(lnames[wbs->next]->height) < ORIGHEIGHT)
if (SHORT(lnames[wbs->next]->height) < SCREENHEIGHT)
y += (5 * SHORT(entering->height)) / 4;
V_DrawPatch((ORIGWIDTH - SHORT(lnames[wbs->next]->width))/2,
V_DrawPatch((SCREENWIDTH - SHORT(lnames[wbs->next]->width))/2,
y, lnames[wbs->next]);
}
}
@ -1817,16 +1817,16 @@ static void WI_drawStats(void)
WI_drawLF();
V_DrawPatch(SP_STATSX, SP_STATSY, kills);
WI_drawPercent(ORIGWIDTH - SP_STATSX, SP_STATSY, cnt_kills[0]);
WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY, cnt_kills[0]);
V_DrawPatch(SP_STATSX, SP_STATSY+lh, items);
WI_drawPercent(ORIGWIDTH - SP_STATSX, SP_STATSY+lh, cnt_items[0]);
WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY+lh, cnt_items[0]);
V_DrawPatch(SP_STATSX, SP_STATSY+2*lh, sp_secret);
WI_drawPercent(ORIGWIDTH - SP_STATSX, SP_STATSY+2*lh, cnt_secret[0]);
WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY+2*lh, cnt_secret[0]);
V_DrawPatch(SP_TIMEX, SP_TIMEY, witime);
WI_drawTime(ORIGWIDTH/2 - SP_TIMEX, SP_TIMEY, cnt_time, true);
WI_drawTime(SCREENWIDTH/2 - SP_TIMEX, SP_TIMEY, cnt_time, true);
// Ty 04/11/98: redid logic: should skip only if with pwad but
// without deh patch
@ -1836,17 +1836,17 @@ static void WI_drawStats(void)
if (W_IsIWADLump(maplump) || deh_pars || um_pars)
if (wbs->epsd < 3 || um_pars)
{
V_DrawPatch(ORIGWIDTH/2 + SP_TIMEX, SP_TIMEY, par);
WI_drawTime(ORIGWIDTH - SP_TIMEX, SP_TIMEY, cnt_par, true);
V_DrawPatch(SCREENWIDTH/2 + SP_TIMEX, SP_TIMEY, par);
WI_drawTime(SCREENWIDTH - SP_TIMEX, SP_TIMEY, cnt_par, true);
}
// [FG] draw total time alongside level time and par time
{
const boolean wide = (wbs->totaltimes / TICRATE > 61*59) || (SP_TIMEX + SHORT(total->width) >= ORIGWIDTH/4);
const boolean wide = (wbs->totaltimes / TICRATE > 61*59) || (SP_TIMEX + SHORT(total->width) >= SCREENWIDTH/4);
V_DrawPatch(SP_TIMEX, SP_TIMEY + 16, total);
// [FG] choose x-position depending on width of time string
WI_drawTime((wide ? ORIGWIDTH : ORIGWIDTH/2) - SP_TIMEX, SP_TIMEY + 16, cnt_total_time, false);
WI_drawTime((wide ? SCREENWIDTH : SCREENWIDTH/2) - SP_TIMEX, SP_TIMEY + 16, cnt_total_time, false);
}
}