2019-12-25 19:22:01 +00:00
|
|
|
// SONIC ROBO BLAST 2
|
2014-03-15 16:59:03 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
2021-05-07 15:45:56 +00:00
|
|
|
// Copyright (C) 1999-2021 by Sonic Team Junior.
|
2014-03-15 16:59:03 +00:00
|
|
|
//
|
2019-12-25 19:22:01 +00:00
|
|
|
// This program is free software distributed under the
|
|
|
|
// terms of the GNU General Public License, version 2.
|
|
|
|
// See the 'LICENSE' file for more details.
|
2014-03-15 16:59:03 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2020-01-23 23:12:15 +00:00
|
|
|
/// \file hw_draw.c
|
2014-03-15 16:59:03 +00:00
|
|
|
/// \brief miscellaneous drawing (mainly 2d)
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "../doomdef.h"
|
|
|
|
|
|
|
|
#ifdef HWRENDER
|
2019-12-25 19:22:01 +00:00
|
|
|
#include "hw_main.h"
|
2014-03-15 16:59:03 +00:00
|
|
|
#include "hw_glob.h"
|
|
|
|
#include "hw_drv.h"
|
|
|
|
|
|
|
|
#include "../m_misc.h" //FIL_WriteFile()
|
|
|
|
#include "../r_draw.h" //viewborderlump
|
|
|
|
#include "../r_main.h"
|
|
|
|
#include "../w_wad.h"
|
|
|
|
#include "../z_zone.h"
|
|
|
|
#include "../v_video.h"
|
|
|
|
#include "../st_stuff.h"
|
2018-01-20 22:14:24 +00:00
|
|
|
#include "../p_local.h" // stplyr
|
|
|
|
#include "../g_game.h" // players
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include "../i_video.h" // for rendermode != render_glide
|
|
|
|
|
|
|
|
#ifndef O_BINARY
|
|
|
|
#define O_BINARY 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(_MSC_VER)
|
|
|
|
#pragma pack(1)
|
|
|
|
#endif
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
UINT8 id_field_length ; // 1
|
|
|
|
UINT8 color_map_type ; // 2
|
|
|
|
UINT8 image_type ; // 3
|
|
|
|
UINT8 dummy[5] ; // 4, 8
|
|
|
|
INT16 x_origin ; // 9, 10
|
|
|
|
INT16 y_origin ; //11, 12
|
|
|
|
INT16 width ; //13, 14
|
|
|
|
INT16 height ; //15, 16
|
|
|
|
UINT8 image_pix_size ; //17
|
|
|
|
UINT8 image_descriptor; //18
|
|
|
|
} ATTRPACK TGAHeader; // sizeof is 18
|
|
|
|
#if defined(_MSC_VER)
|
|
|
|
#pragma pack()
|
|
|
|
#endif
|
|
|
|
|
2014-03-21 18:42:55 +00:00
|
|
|
static UINT8 softwaretranstogl[11] = { 0, 25, 51, 76,102,127,153,178,204,229,255};
|
|
|
|
static UINT8 softwaretranstogl_hi[11] = { 0, 51,102,153,204,255,255,255,255,255,255};
|
|
|
|
static UINT8 softwaretranstogl_lo[11] = { 0, 12, 24, 36, 48, 60, 71, 83, 95,111,127};
|
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
//
|
|
|
|
// -----------------+
|
|
|
|
// HWR_DrawPatch : Draw a 'tile' graphic
|
|
|
|
// Notes : x,y : positions relative to the original Doom resolution
|
|
|
|
// : textes(console+score) + menus + status bar
|
|
|
|
// -----------------+
|
2020-08-08 08:16:47 +00:00
|
|
|
void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option)
|
2014-03-15 16:59:03 +00:00
|
|
|
{
|
|
|
|
FOutVector v[4];
|
|
|
|
FBITFIELD flags;
|
2020-08-08 08:16:47 +00:00
|
|
|
GLPatch_t *hwrPatch;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// 3--2
|
|
|
|
// | /|
|
|
|
|
// |/ |
|
|
|
|
// 0--1
|
|
|
|
float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f;
|
|
|
|
float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
|
|
|
|
float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f;
|
|
|
|
float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
|
|
|
|
|
|
|
|
// make patch ready in hardware cache
|
|
|
|
HWR_GetPatch(gpatch);
|
2020-08-08 08:16:47 +00:00
|
|
|
hwrPatch = ((GLPatch_t *)gpatch->hardware);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
switch (option & V_SCALEPATCHMASK)
|
|
|
|
{
|
|
|
|
case V_NOSCALEPATCH:
|
|
|
|
pdupx = pdupy = 2.0f;
|
|
|
|
break;
|
|
|
|
case V_SMALLSCALEPATCH:
|
|
|
|
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx);
|
|
|
|
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy);
|
|
|
|
break;
|
|
|
|
case V_MEDSCALEPATCH:
|
|
|
|
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx);
|
|
|
|
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (option & V_NOSCALESTART)
|
|
|
|
sdupx = sdupy = 2.0f;
|
|
|
|
|
2020-08-08 08:16:47 +00:00
|
|
|
v[0].x = v[3].x = (x*sdupx-(gpatch->leftoffset)*pdupx)/vid.width - 1;
|
|
|
|
v[2].x = v[1].x = (x*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1;
|
|
|
|
v[0].y = v[1].y = 1-(y*sdupy-(gpatch->topoffset)*pdupy)/vid.height;
|
|
|
|
v[2].y = v[3].y = 1-(y*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
v[0].s = v[3].s = 0.0f;
|
2020-08-08 08:16:47 +00:00
|
|
|
v[2].s = v[1].s = hwrPatch->max_s;
|
2019-12-25 19:22:01 +00:00
|
|
|
v[0].t = v[1].t = 0.0f;
|
2020-08-08 08:16:47 +00:00
|
|
|
v[2].t = v[3].t = hwrPatch->max_t;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
flags = PF_Translucent|PF_NoDepthTest;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
if (option & V_WRAPX)
|
|
|
|
flags |= PF_ForceWrapX;
|
|
|
|
if (option & V_WRAPY)
|
|
|
|
flags |= PF_ForceWrapY;
|
|
|
|
|
|
|
|
// clip it since it is used for bunny scroll in doom I
|
2014-03-21 18:42:55 +00:00
|
|
|
HWD.pfnDrawPolygon(NULL, v, 4, flags);
|
2014-03-15 16:59:03 +00:00
|
|
|
}
|
|
|
|
|
2020-08-08 08:16:47 +00:00
|
|
|
void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap)
|
2014-03-15 16:59:03 +00:00
|
|
|
{
|
|
|
|
FOutVector v[4];
|
|
|
|
FBITFIELD flags;
|
|
|
|
float cx = FIXED_TO_FLOAT(x);
|
|
|
|
float cy = FIXED_TO_FLOAT(y);
|
2014-03-21 18:42:55 +00:00
|
|
|
UINT8 alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT);
|
2020-08-08 08:16:47 +00:00
|
|
|
GLPatch_t *hwrPatch;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// 3--2
|
|
|
|
// | /|
|
|
|
|
// |/ |
|
|
|
|
// 0--1
|
2018-04-06 18:38:19 +00:00
|
|
|
float dupx, dupy, fscalew, fscaleh, fwidth, fheight;
|
|
|
|
|
|
|
|
UINT8 perplayershuffle = 0;
|
2014-03-21 18:42:55 +00:00
|
|
|
|
2018-02-12 17:47:31 +00:00
|
|
|
if (alphalevel >= 10 && alphalevel < 13)
|
2014-03-21 18:42:55 +00:00
|
|
|
return;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// make patch ready in hardware cache
|
2014-03-21 18:42:55 +00:00
|
|
|
if (!colormap)
|
|
|
|
HWR_GetPatch(gpatch);
|
|
|
|
else
|
|
|
|
HWR_GetMappedPatch(gpatch, colormap);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2020-08-08 08:16:47 +00:00
|
|
|
hwrPatch = ((GLPatch_t *)gpatch->hardware);
|
|
|
|
|
2018-03-16 18:08:24 +00:00
|
|
|
dupx = (float)vid.dupx;
|
|
|
|
dupy = (float)vid.dupy;
|
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
switch (option & V_SCALEPATCHMASK)
|
|
|
|
{
|
|
|
|
case V_NOSCALEPATCH:
|
2018-03-16 18:08:24 +00:00
|
|
|
dupx = dupy = 1.0f;
|
2014-03-15 16:59:03 +00:00
|
|
|
break;
|
|
|
|
case V_SMALLSCALEPATCH:
|
2018-03-16 18:08:24 +00:00
|
|
|
dupx = (float)vid.smalldupx;
|
|
|
|
dupy = (float)vid.smalldupy;
|
2014-03-15 16:59:03 +00:00
|
|
|
break;
|
|
|
|
case V_MEDSCALEPATCH:
|
2018-03-16 18:08:24 +00:00
|
|
|
dupx = (float)vid.meddupx;
|
|
|
|
dupy = (float)vid.meddupy;
|
2014-03-15 16:59:03 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-03-16 18:08:24 +00:00
|
|
|
dupx = dupy = (dupx < dupy ? dupx : dupy);
|
2018-04-06 18:38:19 +00:00
|
|
|
fscalew = fscaleh = FIXED_TO_FLOAT(pscale);
|
Sound test is cool now!
https://cdn.discordapp.com/attachments/405336003239477249/641295998395613224/srb20042.gif
* Port MUSICDEFs from Kart.
* Safe to modify without modifying game, so we can put it in music.dta eventually.
* "Title", "AltTitle", "Authors" fields are self-evident.
* "Soundtestpage" and "Soundtestcond" are used to determine which sound test unlockable can play them (set with Unlockable's variable, just like Level Select).
* "Stoppingtime" and "BPM" both accept floats, and are used for presentation stuff on the sound test.
* Ironically, we don't share a single field name with them. Such is the case of differing foci, though, and I expect they'll change their implementation to match (since this is necessary for a sound test).
* Change how S_AddSoundFx works to avoid iterating through all of them, and to allow cv_soundtest to only scroll through defined slots (instead of the infinite wall of thok sounds when scrolling to the left).
* Change V_DrawFixedPatch to allow scaling on two seperate axes.
* Now called "V_DrawStretchyFixedPatch".
* "V_DrawFixedPatch" is a macro to V_DrawStretchyFixedPatch now (same scale on both axes).
* Available to Lua under v.drawStretched!
* Even works in GL!
* Bugfix: Add SR_PLAYER to SOC's menutypes_list.
Stay tuned for the merge request, where I put the onus on the Music Team to finish this off...
2019-11-05 16:23:46 +00:00
|
|
|
if (vscale != pscale)
|
|
|
|
fscaleh = FIXED_TO_FLOAT(vscale);
|
2018-03-16 18:08:24 +00:00
|
|
|
|
2018-10-29 13:29:16 +00:00
|
|
|
// See my comments in v_video.c's V_DrawFixedPatch
|
|
|
|
// -- Monster Iestyn 29/10/18
|
2018-03-16 18:08:24 +00:00
|
|
|
{
|
2018-10-29 13:29:16 +00:00
|
|
|
float offsetx = 0.0f, offsety = 0.0f;
|
|
|
|
|
|
|
|
// left offset
|
2018-03-16 18:08:24 +00:00
|
|
|
if (option & V_FLIP)
|
2020-08-08 08:16:47 +00:00
|
|
|
offsetx = (float)(gpatch->width - gpatch->leftoffset) * fscalew;
|
2018-03-16 18:08:24 +00:00
|
|
|
else
|
2020-08-08 08:16:47 +00:00
|
|
|
offsetx = (float)(gpatch->leftoffset) * fscalew;
|
2018-10-29 13:29:16 +00:00
|
|
|
|
|
|
|
// top offset
|
|
|
|
// TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!?
|
2020-08-08 08:16:47 +00:00
|
|
|
offsety = (float)(gpatch->topoffset) * fscaleh;
|
2018-10-29 13:29:16 +00:00
|
|
|
|
|
|
|
if ((option & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs
|
|
|
|
{
|
|
|
|
offsetx *= dupx;
|
|
|
|
offsety *= dupy;
|
|
|
|
}
|
|
|
|
|
|
|
|
cx -= offsetx;
|
|
|
|
cy -= offsety;
|
2018-03-16 18:08:24 +00:00
|
|
|
}
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2018-01-20 22:14:24 +00:00
|
|
|
if (splitscreen && (option & V_PERPLAYER))
|
|
|
|
{
|
|
|
|
float adjusty = ((option & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
|
2018-04-06 18:38:19 +00:00
|
|
|
fscaleh /= 2;
|
2018-01-20 22:14:24 +00:00
|
|
|
cy /= 2;
|
|
|
|
#ifdef QUADS
|
|
|
|
if (splitscreen > 1) // 3 or 4 players
|
|
|
|
{
|
|
|
|
float adjustx = ((option & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f;
|
2018-04-06 18:38:19 +00:00
|
|
|
fscalew /= 2;
|
2018-01-20 22:14:24 +00:00
|
|
|
cx /= 2;
|
2018-04-06 18:38:19 +00:00
|
|
|
if (stplyr == &players[displayplayer])
|
|
|
|
{
|
|
|
|
if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 1;
|
|
|
|
if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 4;
|
|
|
|
option &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT;
|
|
|
|
}
|
|
|
|
else if (stplyr == &players[secondarydisplayplayer])
|
|
|
|
{
|
|
|
|
if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 1;
|
|
|
|
if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 8;
|
2018-01-20 22:14:24 +00:00
|
|
|
cx += adjustx;
|
2018-04-06 18:38:19 +00:00
|
|
|
option &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT;
|
|
|
|
}
|
2018-01-20 22:14:24 +00:00
|
|
|
else if (stplyr == &players[thirddisplayplayer])
|
2018-04-06 18:38:19 +00:00
|
|
|
{
|
|
|
|
if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 2;
|
|
|
|
if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 4;
|
2018-01-20 22:14:24 +00:00
|
|
|
cy += adjusty;
|
2018-04-06 18:38:19 +00:00
|
|
|
option &= ~V_SNAPTOTOP|V_SNAPTORIGHT;
|
|
|
|
}
|
2018-01-21 12:56:38 +00:00
|
|
|
else if (stplyr == &players[fourthdisplayplayer])
|
2018-01-20 22:14:24 +00:00
|
|
|
{
|
2018-04-06 18:38:19 +00:00
|
|
|
if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 2;
|
|
|
|
if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 8;
|
2018-01-20 22:14:24 +00:00
|
|
|
cx += adjustx;
|
|
|
|
cy += adjusty;
|
2018-04-06 18:38:19 +00:00
|
|
|
option &= ~V_SNAPTOTOP|V_SNAPTOLEFT;
|
2018-01-20 22:14:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
// 2 players
|
|
|
|
{
|
2018-04-06 18:38:19 +00:00
|
|
|
if (stplyr == &players[displayplayer])
|
|
|
|
{
|
|
|
|
if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle = 1;
|
|
|
|
option &= ~V_SNAPTOBOTTOM;
|
|
|
|
}
|
|
|
|
else //if (stplyr == &players[secondarydisplayplayer])
|
|
|
|
{
|
|
|
|
if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle = 2;
|
2018-01-20 22:14:24 +00:00
|
|
|
cy += adjusty;
|
2018-04-06 18:38:19 +00:00
|
|
|
option &= ~V_SNAPTOTOP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-04-19 17:41:29 +00:00
|
|
|
|
2018-03-16 18:08:24 +00:00
|
|
|
if (!(option & V_NOSCALESTART))
|
2014-03-23 23:37:44 +00:00
|
|
|
{
|
2018-03-16 18:08:24 +00:00
|
|
|
cx = cx * dupx;
|
|
|
|
cy = cy * dupy;
|
|
|
|
|
|
|
|
if (!(option & V_SCALEPATCHMASK))
|
|
|
|
{
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
// if it's meant to cover the whole screen, black out the rest (ONLY IF TOP LEFT ISN'T TRANSPARENT)
|
2018-03-17 13:26:43 +00:00
|
|
|
// cx and cy are possibly *slightly* off from float maths
|
|
|
|
// This is done before here compared to software because we directly alter cx and cy to centre
|
2020-11-22 23:02:47 +00:00
|
|
|
if (cx >= -0.1f && cx <= 0.1f && gpatch->width == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && gpatch->height == BASEVIDHEIGHT)
|
2018-03-17 13:26:43 +00:00
|
|
|
{
|
2020-08-08 08:16:47 +00:00
|
|
|
const column_t *column = (const column_t *)((const UINT8 *)(gpatch->columns) + (gpatch->columnofs[0]));
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
if (!column->topdelta)
|
|
|
|
{
|
|
|
|
const UINT8 *source = (const UINT8 *)(column) + 3;
|
|
|
|
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
|
|
|
|
}
|
2018-03-17 13:26:43 +00:00
|
|
|
}
|
2018-03-16 18:08:24 +00:00
|
|
|
// centre screen
|
2018-12-15 00:33:40 +00:00
|
|
|
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
|
2018-03-16 18:08:24 +00:00
|
|
|
{
|
|
|
|
if (option & V_SNAPTORIGHT)
|
|
|
|
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
|
|
|
else if (!(option & V_SNAPTOLEFT))
|
|
|
|
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
|
2018-04-06 18:38:19 +00:00
|
|
|
if (perplayershuffle & 4)
|
|
|
|
cx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/4;
|
|
|
|
else if (perplayershuffle & 8)
|
|
|
|
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/4;
|
2018-03-16 18:08:24 +00:00
|
|
|
}
|
2018-12-15 00:33:40 +00:00
|
|
|
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
2018-03-16 18:08:24 +00:00
|
|
|
{
|
2018-04-06 18:38:19 +00:00
|
|
|
if (option & V_SNAPTOBOTTOM)
|
2018-03-16 18:08:24 +00:00
|
|
|
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
|
|
|
else if (!(option & V_SNAPTOTOP))
|
|
|
|
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
|
2018-04-06 18:38:19 +00:00
|
|
|
if (perplayershuffle & 1)
|
|
|
|
cy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/4;
|
|
|
|
else if (perplayershuffle & 2)
|
|
|
|
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/4;
|
2018-03-16 18:08:24 +00:00
|
|
|
}
|
2018-01-20 22:14:24 +00:00
|
|
|
}
|
|
|
|
}
|
2014-04-19 17:41:29 +00:00
|
|
|
|
2018-04-06 18:38:19 +00:00
|
|
|
if (pscale != FRACUNIT || (splitscreen && option & V_PERPLAYER))
|
2014-03-23 23:37:44 +00:00
|
|
|
{
|
2020-08-08 08:16:47 +00:00
|
|
|
fwidth = (float)(gpatch->width) * fscalew * dupx;
|
|
|
|
fheight = (float)(gpatch->height) * fscaleh * dupy;
|
2014-03-23 23:37:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-08 08:16:47 +00:00
|
|
|
fwidth = (float)(gpatch->width) * dupx;
|
|
|
|
fheight = (float)(gpatch->height) * dupy;
|
2014-03-23 23:37:44 +00:00
|
|
|
}
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2018-03-16 18:08:24 +00:00
|
|
|
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
|
|
|
|
cx = -1 + (cx / (vid.width/2));
|
|
|
|
cy = 1 - (cy / (vid.height/2));
|
|
|
|
|
|
|
|
// fwidth and fheight are similar
|
|
|
|
fwidth /= vid.width / 2;
|
|
|
|
fheight /= vid.height / 2;
|
|
|
|
|
|
|
|
// set the polygon vertices to the right positions
|
|
|
|
v[0].x = v[3].x = cx;
|
|
|
|
v[2].x = v[1].x = cx + fwidth;
|
|
|
|
|
|
|
|
v[0].y = v[1].y = cy;
|
|
|
|
v[2].y = v[3].y = cy - fheight;
|
2014-04-14 05:14:58 +00:00
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
|
|
|
|
2014-03-23 23:37:44 +00:00
|
|
|
if (option & V_FLIP)
|
|
|
|
{
|
2020-08-08 08:16:47 +00:00
|
|
|
v[0].s = v[3].s = hwrPatch->max_s;
|
2019-12-25 19:22:01 +00:00
|
|
|
v[2].s = v[1].s = 0.0f;
|
2014-03-23 23:37:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-12-25 19:22:01 +00:00
|
|
|
v[0].s = v[3].s = 0.0f;
|
2020-08-08 08:16:47 +00:00
|
|
|
v[2].s = v[1].s = hwrPatch->max_s;
|
2014-03-23 23:37:44 +00:00
|
|
|
}
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
v[0].t = v[1].t = 0.0f;
|
2020-08-08 08:16:47 +00:00
|
|
|
v[2].t = v[3].t = hwrPatch->max_t;
|
2014-04-14 05:14:58 +00:00
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
flags = PF_Translucent|PF_NoDepthTest;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
if (option & V_WRAPX)
|
|
|
|
flags |= PF_ForceWrapX;
|
|
|
|
if (option & V_WRAPY)
|
|
|
|
flags |= PF_ForceWrapY;
|
|
|
|
|
|
|
|
// clip it since it is used for bunny scroll in doom I
|
2014-03-21 18:42:55 +00:00
|
|
|
if (alphalevel)
|
2014-03-15 16:59:03 +00:00
|
|
|
{
|
2014-03-19 23:10:37 +00:00
|
|
|
FSurfaceInfo Surf;
|
2019-12-25 19:22:01 +00:00
|
|
|
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
|
2020-01-24 02:52:11 +00:00
|
|
|
if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency];
|
|
|
|
else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency];
|
|
|
|
else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency];
|
2019-12-25 19:22:01 +00:00
|
|
|
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
|
2014-03-19 23:10:37 +00:00
|
|
|
flags |= PF_Modulated;
|
|
|
|
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
HWD.pfnDrawPolygon(NULL, v, 4, flags);
|
|
|
|
}
|
|
|
|
|
2020-08-08 08:16:47 +00:00
|
|
|
void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h)
|
2014-03-19 23:10:37 +00:00
|
|
|
{
|
|
|
|
FOutVector v[4];
|
|
|
|
FBITFIELD flags;
|
|
|
|
float cx = FIXED_TO_FLOAT(x);
|
|
|
|
float cy = FIXED_TO_FLOAT(y);
|
2014-03-21 18:42:55 +00:00
|
|
|
UINT8 alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT);
|
2020-08-08 08:16:47 +00:00
|
|
|
GLPatch_t *hwrPatch;
|
2014-03-19 23:10:37 +00:00
|
|
|
|
|
|
|
// 3--2
|
|
|
|
// | /|
|
|
|
|
// |/ |
|
|
|
|
// 0--1
|
2018-03-17 13:58:44 +00:00
|
|
|
float dupx, dupy, fscale, fwidth, fheight;
|
2014-03-21 18:42:55 +00:00
|
|
|
|
2018-02-12 17:47:31 +00:00
|
|
|
if (alphalevel >= 10 && alphalevel < 13)
|
2014-03-21 18:42:55 +00:00
|
|
|
return;
|
2014-03-19 23:10:37 +00:00
|
|
|
|
|
|
|
// make patch ready in hardware cache
|
|
|
|
HWR_GetPatch(gpatch);
|
2020-08-08 08:16:47 +00:00
|
|
|
hwrPatch = ((GLPatch_t *)gpatch->hardware);
|
2014-03-19 23:10:37 +00:00
|
|
|
|
2018-03-17 13:58:44 +00:00
|
|
|
dupx = (float)vid.dupx;
|
|
|
|
dupy = (float)vid.dupy;
|
|
|
|
|
2014-03-19 23:10:37 +00:00
|
|
|
switch (option & V_SCALEPATCHMASK)
|
|
|
|
{
|
|
|
|
case V_NOSCALEPATCH:
|
2018-03-17 13:58:44 +00:00
|
|
|
dupx = dupy = 1.0f;
|
2014-03-19 23:10:37 +00:00
|
|
|
break;
|
|
|
|
case V_SMALLSCALEPATCH:
|
2018-03-17 13:58:44 +00:00
|
|
|
dupx = (float)vid.smalldupx;
|
|
|
|
dupy = (float)vid.smalldupy;
|
2014-03-19 23:10:37 +00:00
|
|
|
break;
|
|
|
|
case V_MEDSCALEPATCH:
|
2018-03-17 13:58:44 +00:00
|
|
|
dupx = (float)vid.meddupx;
|
|
|
|
dupy = (float)vid.meddupy;
|
2014-03-19 23:10:37 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-03-17 13:58:44 +00:00
|
|
|
dupx = dupy = (dupx < dupy ? dupx : dupy);
|
|
|
|
fscale = FIXED_TO_FLOAT(pscale);
|
2014-03-19 23:10:37 +00:00
|
|
|
|
2018-04-06 18:38:19 +00:00
|
|
|
// fuck it, no GL support for croppedpatch v_perplayer right now. it's not like it's accessible to Lua or anything, and we only use it for menus...
|
|
|
|
|
2020-11-22 23:02:47 +00:00
|
|
|
cy -= (float)(gpatch->topoffset) * fscale;
|
|
|
|
cx -= (float)(gpatch->leftoffset) * fscale;
|
2018-03-17 13:58:44 +00:00
|
|
|
|
|
|
|
if (!(option & V_NOSCALESTART))
|
2018-01-21 12:56:38 +00:00
|
|
|
{
|
2018-03-17 13:58:44 +00:00
|
|
|
cx = cx * dupx;
|
|
|
|
cy = cy * dupy;
|
|
|
|
|
|
|
|
if (!(option & V_SCALEPATCHMASK))
|
2018-01-21 12:56:38 +00:00
|
|
|
{
|
2021-02-21 21:16:38 +00:00
|
|
|
// if it's meant to cover the whole screen, black out the rest
|
|
|
|
// no the patch is cropped do not do this ever
|
|
|
|
|
2018-03-17 13:58:44 +00:00
|
|
|
// centre screen
|
2018-12-15 00:33:40 +00:00
|
|
|
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
|
2018-03-17 13:58:44 +00:00
|
|
|
{
|
|
|
|
if (option & V_SNAPTORIGHT)
|
|
|
|
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
|
|
|
else if (!(option & V_SNAPTOLEFT))
|
|
|
|
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
|
|
|
|
}
|
2018-12-15 00:33:40 +00:00
|
|
|
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
2018-03-17 13:58:44 +00:00
|
|
|
{
|
2018-04-06 18:38:19 +00:00
|
|
|
if (option & V_SNAPTOBOTTOM)
|
2018-03-17 13:58:44 +00:00
|
|
|
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
|
|
|
else if (!(option & V_SNAPTOTOP))
|
|
|
|
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
|
2018-01-21 12:56:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-17 13:58:44 +00:00
|
|
|
fwidth = w;
|
|
|
|
fheight = h;
|
|
|
|
|
2021-02-21 21:16:38 +00:00
|
|
|
if (sx + w > gpatch->width)
|
|
|
|
fwidth = gpatch->width - sx;
|
2018-03-17 13:58:44 +00:00
|
|
|
|
2021-02-21 21:16:38 +00:00
|
|
|
if (sy + h > gpatch->height)
|
|
|
|
fheight = gpatch->height - sy;
|
2014-03-19 23:10:37 +00:00
|
|
|
|
2018-03-17 13:58:44 +00:00
|
|
|
if (pscale != FRACUNIT)
|
|
|
|
{
|
|
|
|
fwidth *= fscale * dupx;
|
|
|
|
fheight *= fscale * dupy;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fwidth *= dupx;
|
|
|
|
fheight *= dupy;
|
|
|
|
}
|
|
|
|
|
|
|
|
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
|
|
|
|
cx = -1 + (cx / (vid.width/2));
|
|
|
|
cy = 1 - (cy / (vid.height/2));
|
|
|
|
|
|
|
|
// fwidth and fheight are similar
|
|
|
|
fwidth /= vid.width / 2;
|
|
|
|
fheight /= vid.height / 2;
|
|
|
|
|
|
|
|
// set the polygon vertices to the right positions
|
|
|
|
v[0].x = v[3].x = cx;
|
|
|
|
v[2].x = v[1].x = cx + fwidth;
|
2014-03-19 23:10:37 +00:00
|
|
|
|
2018-03-17 13:58:44 +00:00
|
|
|
v[0].y = v[1].y = cy;
|
|
|
|
v[2].y = v[3].y = cy - fheight;
|
2014-03-19 23:10:37 +00:00
|
|
|
|
|
|
|
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
|
|
|
|
2020-08-08 08:16:47 +00:00
|
|
|
v[0].s = v[3].s = ((sx)/(float)(gpatch->width))*hwrPatch->max_s;
|
|
|
|
if (sx + w > gpatch->width)
|
2021-02-21 21:16:38 +00:00
|
|
|
v[2].s = v[1].s = hwrPatch->max_s;
|
2018-04-06 17:42:07 +00:00
|
|
|
else
|
2020-08-08 08:16:47 +00:00
|
|
|
v[2].s = v[1].s = ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s;
|
2018-04-06 17:42:07 +00:00
|
|
|
|
2020-08-08 08:16:47 +00:00
|
|
|
v[0].t = v[1].t = ((sy)/(float)(gpatch->height))*hwrPatch->max_t;
|
|
|
|
if (sy + h > gpatch->height)
|
2021-02-21 21:16:38 +00:00
|
|
|
v[2].t = v[3].t = hwrPatch->max_t;
|
2018-04-06 17:42:07 +00:00
|
|
|
else
|
2020-08-08 08:16:47 +00:00
|
|
|
v[2].t = v[3].t = ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t;
|
2014-03-19 23:10:37 +00:00
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
flags = PF_Translucent|PF_NoDepthTest;
|
2014-03-19 23:10:37 +00:00
|
|
|
|
|
|
|
if (option & V_WRAPX)
|
|
|
|
flags |= PF_ForceWrapX;
|
|
|
|
if (option & V_WRAPY)
|
|
|
|
flags |= PF_ForceWrapY;
|
|
|
|
|
|
|
|
// clip it since it is used for bunny scroll in doom I
|
2014-03-21 18:42:55 +00:00
|
|
|
if (alphalevel)
|
2014-03-19 23:10:37 +00:00
|
|
|
{
|
2014-03-15 16:59:03 +00:00
|
|
|
FSurfaceInfo Surf;
|
2019-12-25 19:22:01 +00:00
|
|
|
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
|
2020-01-24 02:52:11 +00:00
|
|
|
if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency];
|
|
|
|
else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency];
|
|
|
|
else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency];
|
2019-12-25 19:22:01 +00:00
|
|
|
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
|
2014-03-15 16:59:03 +00:00
|
|
|
flags |= PF_Modulated;
|
|
|
|
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
HWD.pfnDrawPolygon(NULL, v, 4, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)
|
|
|
|
{
|
|
|
|
FOutVector v[4];
|
2020-08-08 08:16:47 +00:00
|
|
|
const patch_t *patch;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// make pic ready in hardware cache
|
|
|
|
patch = HWR_GetPic(lumpnum);
|
|
|
|
|
|
|
|
// 3--2
|
|
|
|
// | /|
|
|
|
|
// |/ |
|
|
|
|
// 0--1
|
|
|
|
|
|
|
|
v[0].x = v[3].x = 2.0f * (float)x/vid.width - 1;
|
|
|
|
v[2].x = v[1].x = 2.0f * (float)(x + patch->width*FIXED_TO_FLOAT(vid.fdupx))/vid.width - 1;
|
|
|
|
v[0].y = v[1].y = 1.0f - 2.0f * (float)y/vid.height;
|
|
|
|
v[2].y = v[3].y = 1.0f - 2.0f * (float)(y + patch->height*FIXED_TO_FLOAT(vid.fdupy))/vid.height;
|
|
|
|
|
|
|
|
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
|
|
|
|
2020-08-08 08:16:47 +00:00
|
|
|
v[0].s = v[3].s = 0;
|
|
|
|
v[2].s = v[1].s = ((GLPatch_t *)patch->hardware)->max_s;
|
|
|
|
v[0].t = v[1].t = 0;
|
|
|
|
v[2].t = v[3].t = ((GLPatch_t *)patch->hardware)->max_t;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
//Hurdler: Boris, the same comment as above... but maybe for pics
|
|
|
|
// it not a problem since they don't have any transparent pixel
|
|
|
|
// if I'm right !?
|
|
|
|
// But then, the question is: why not 0 instead of PF_Masked ?
|
|
|
|
// or maybe PF_Environment ??? (like what I said above)
|
|
|
|
// BP: PF_Environment don't change anything ! and 0 is undifined
|
2020-10-27 03:03:41 +00:00
|
|
|
HWD.pfnDrawPolygon(NULL, v, 4, PF_Translucent | PF_NoDepthTest);
|
2014-03-15 16:59:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ==========================================================================
|
|
|
|
// V_VIDEO.C STUFF
|
|
|
|
// ==========================================================================
|
|
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
// Fills a box of pixels using a flat texture as a pattern
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum)
|
|
|
|
{
|
|
|
|
FOutVector v[4];
|
|
|
|
double dflatsize;
|
|
|
|
INT32 flatflag;
|
|
|
|
const size_t len = W_LumpLength(flatlumpnum);
|
|
|
|
|
|
|
|
switch (len)
|
|
|
|
{
|
|
|
|
case 4194304: // 2048x2048 lump
|
|
|
|
dflatsize = 2048.0f;
|
|
|
|
flatflag = 2047;
|
|
|
|
break;
|
|
|
|
case 1048576: // 1024x1024 lump
|
|
|
|
dflatsize = 1024.0f;
|
|
|
|
flatflag = 1023;
|
|
|
|
break;
|
|
|
|
case 262144:// 512x512 lump
|
|
|
|
dflatsize = 512.0f;
|
|
|
|
flatflag = 511;
|
|
|
|
break;
|
|
|
|
case 65536: // 256x256 lump
|
|
|
|
dflatsize = 256.0f;
|
|
|
|
flatflag = 255;
|
|
|
|
break;
|
|
|
|
case 16384: // 128x128 lump
|
|
|
|
dflatsize = 128.0f;
|
|
|
|
flatflag = 127;
|
|
|
|
break;
|
|
|
|
case 1024: // 32x32 lump
|
|
|
|
dflatsize = 32.0f;
|
|
|
|
flatflag = 31;
|
|
|
|
break;
|
|
|
|
default: // 64x64 lump
|
|
|
|
dflatsize = 64.0f;
|
|
|
|
flatflag = 63;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 3--2
|
|
|
|
// | /|
|
|
|
|
// |/ |
|
|
|
|
// 0--1
|
|
|
|
|
|
|
|
v[0].x = v[3].x = (x - 160.0f)/160.0f;
|
|
|
|
v[2].x = v[1].x = ((x+w) - 160.0f)/160.0f;
|
|
|
|
v[0].y = v[1].y = -(y - 100.0f)/100.0f;
|
|
|
|
v[2].y = v[3].y = -((y+h) - 100.0f)/100.0f;
|
|
|
|
|
|
|
|
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
|
|
|
|
|
|
|
// flat is 64x64 lod and texture offsets are [0.0, 1.0]
|
2019-12-25 19:22:01 +00:00
|
|
|
v[0].s = v[3].s = (float)((x & flatflag)/dflatsize);
|
|
|
|
v[2].s = v[1].s = (float)(v[0].s + w/dflatsize);
|
|
|
|
v[0].t = v[1].t = (float)((y & flatflag)/dflatsize);
|
|
|
|
v[2].t = v[3].t = (float)(v[0].t + h/dflatsize);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2020-12-14 05:07:12 +00:00
|
|
|
HWR_GetRawFlat(flatlumpnum);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
//Hurdler: Boris, the same comment as above... but maybe for pics
|
|
|
|
// it not a problem since they don't have any transparent pixel
|
|
|
|
// if I'm right !?
|
|
|
|
// BTW, I see we put 0 for PFs, and If I'm right, that
|
|
|
|
// means we take the previous PFs as default
|
|
|
|
// how can we be sure they are ok?
|
|
|
|
HWD.pfnDrawPolygon(NULL, v, 4, PF_NoDepthTest); //PF_Translucent);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
// Fade down the screen so that the menu drawn on top of it looks brighter
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
// 3--2
|
|
|
|
// | /|
|
|
|
|
// |/ |
|
|
|
|
// 0--1
|
2018-02-12 17:47:31 +00:00
|
|
|
void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
|
2014-03-15 16:59:03 +00:00
|
|
|
{
|
|
|
|
FOutVector v[4];
|
|
|
|
FSurfaceInfo Surf;
|
|
|
|
|
|
|
|
v[0].x = v[3].x = -1.0f;
|
|
|
|
v[2].x = v[1].x = 1.0f;
|
2018-02-12 17:47:31 +00:00
|
|
|
v[0].y = v[1].y = -1.0f;
|
2014-03-15 16:59:03 +00:00
|
|
|
v[2].y = v[3].y = 1.0f;
|
|
|
|
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
v[0].s = v[3].s = 0.0f;
|
|
|
|
v[2].s = v[1].s = 1.0f;
|
|
|
|
v[0].t = v[1].t = 1.0f;
|
|
|
|
v[2].t = v[3].t = 0.0f;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2018-02-12 17:47:31 +00:00
|
|
|
if (color & 0xFF00) // Do COLORMAP fade.
|
|
|
|
{
|
2019-12-25 19:22:01 +00:00
|
|
|
Surf.PolyColor.rgba = UINT2RGBA(0x01010160);
|
|
|
|
Surf.PolyColor.s.alpha = (strength*8);
|
2018-02-12 17:47:31 +00:00
|
|
|
}
|
|
|
|
else // Do TRANSMAP** fade.
|
|
|
|
{
|
2019-12-25 19:22:01 +00:00
|
|
|
Surf.PolyColor.rgba = V_GetColor(color).rgba;
|
|
|
|
Surf.PolyColor.s.alpha = softwaretranstogl[strength];
|
2018-02-12 17:47:31 +00:00
|
|
|
}
|
2014-03-15 16:59:03 +00:00
|
|
|
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
|
|
|
}
|
|
|
|
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
// -----------------+
|
|
|
|
// HWR_DrawFadeFill : draw flat coloured rectangle, with transparency
|
|
|
|
// -----------------+
|
|
|
|
void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 actualcolor, UINT8 strength)
|
|
|
|
{
|
|
|
|
FOutVector v[4];
|
|
|
|
FSurfaceInfo Surf;
|
|
|
|
float fx, fy, fw, fh;
|
|
|
|
|
|
|
|
UINT8 perplayershuffle = 0;
|
|
|
|
|
|
|
|
// 3--2
|
|
|
|
// | /|
|
|
|
|
// |/ |
|
|
|
|
// 0--1
|
|
|
|
|
|
|
|
if (splitscreen && (color & V_PERPLAYER))
|
|
|
|
{
|
|
|
|
fixed_t adjusty = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
|
|
|
|
h >>= 1;
|
|
|
|
y >>= 1;
|
|
|
|
#ifdef QUADS
|
|
|
|
if (splitscreen > 1) // 3 or 4 players
|
|
|
|
{
|
|
|
|
fixed_t adjustx = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
|
|
|
|
w >>= 1;
|
|
|
|
x >>= 1;
|
|
|
|
if (stplyr == &players[displayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 1;
|
|
|
|
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 4;
|
|
|
|
color &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT;
|
|
|
|
}
|
|
|
|
else if (stplyr == &players[secondarydisplayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 1;
|
|
|
|
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 8;
|
|
|
|
x += adjustx;
|
|
|
|
color &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT;
|
|
|
|
}
|
|
|
|
else if (stplyr == &players[thirddisplayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 2;
|
|
|
|
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 4;
|
|
|
|
y += adjusty;
|
|
|
|
color &= ~V_SNAPTOTOP|V_SNAPTORIGHT;
|
|
|
|
}
|
|
|
|
else //if (stplyr == &players[fourthdisplayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 2;
|
|
|
|
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 8;
|
|
|
|
x += adjustx;
|
|
|
|
y += adjusty;
|
|
|
|
color &= ~V_SNAPTOTOP|V_SNAPTOLEFT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
// 2 players
|
|
|
|
{
|
|
|
|
if (stplyr == &players[displayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 1;
|
|
|
|
color &= ~V_SNAPTOBOTTOM;
|
|
|
|
}
|
|
|
|
else //if (stplyr == &players[secondarydisplayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 2;
|
|
|
|
y += adjusty;
|
|
|
|
color &= ~V_SNAPTOTOP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fx = (float)x;
|
|
|
|
fy = (float)y;
|
|
|
|
fw = (float)w;
|
|
|
|
fh = (float)h;
|
|
|
|
|
|
|
|
if (!(color & V_NOSCALESTART))
|
|
|
|
{
|
|
|
|
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
|
|
|
|
|
|
|
|
fx *= dupx;
|
|
|
|
fy *= dupy;
|
|
|
|
fw *= dupx;
|
|
|
|
fh *= dupy;
|
|
|
|
|
|
|
|
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
|
|
|
|
{
|
|
|
|
if (color & V_SNAPTORIGHT)
|
|
|
|
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
|
|
|
else if (!(color & V_SNAPTOLEFT))
|
|
|
|
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
|
|
|
|
if (perplayershuffle & 4)
|
|
|
|
fx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
|
|
|
else if (perplayershuffle & 8)
|
|
|
|
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
|
|
|
}
|
|
|
|
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
|
|
|
{
|
|
|
|
// same thing here
|
|
|
|
if (color & V_SNAPTOBOTTOM)
|
|
|
|
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
|
|
|
else if (!(color & V_SNAPTOTOP))
|
|
|
|
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
|
|
|
|
if (perplayershuffle & 1)
|
|
|
|
fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
|
|
|
else if (perplayershuffle & 2)
|
|
|
|
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fx >= vid.width || fy >= vid.height)
|
|
|
|
return;
|
|
|
|
if (fx < 0)
|
|
|
|
{
|
|
|
|
fw += fx;
|
|
|
|
fx = 0;
|
|
|
|
}
|
|
|
|
if (fy < 0)
|
|
|
|
{
|
|
|
|
fh += fy;
|
|
|
|
fy = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fw <= 0 || fh <= 0)
|
|
|
|
return;
|
|
|
|
if (fx + fw > vid.width)
|
|
|
|
fw = (float)vid.width - fx;
|
|
|
|
if (fy + fh > vid.height)
|
|
|
|
fh = (float)vid.height - fy;
|
|
|
|
|
|
|
|
fx = -1 + fx / (vid.width / 2);
|
|
|
|
fy = 1 - fy / (vid.height / 2);
|
|
|
|
fw = fw / (vid.width / 2);
|
|
|
|
fh = fh / (vid.height / 2);
|
|
|
|
|
|
|
|
v[0].x = v[3].x = fx;
|
|
|
|
v[2].x = v[1].x = fx + fw;
|
|
|
|
v[0].y = v[1].y = fy;
|
|
|
|
v[2].y = v[3].y = fy - fh;
|
|
|
|
|
|
|
|
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
v[0].s = v[3].s = 0.0f;
|
|
|
|
v[2].s = v[1].s = 1.0f;
|
|
|
|
v[0].t = v[1].t = 0.0f;
|
|
|
|
v[2].t = v[3].t = 1.0f;
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
|
|
|
|
if (actualcolor & 0xFF00) // Do COLORMAP fade.
|
|
|
|
{
|
2019-12-25 19:22:01 +00:00
|
|
|
Surf.PolyColor.rgba = UINT2RGBA(0x01010160);
|
|
|
|
Surf.PolyColor.s.alpha = (strength*8);
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
}
|
|
|
|
else // Do TRANSMAP** fade.
|
|
|
|
{
|
2019-12-25 19:22:01 +00:00
|
|
|
Surf.PolyColor.rgba = V_GetColor(actualcolor).rgba;
|
|
|
|
Surf.PolyColor.s.alpha = softwaretranstogl[strength];
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
}
|
|
|
|
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
|
|
|
}
|
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
// Draw the console background with translucency support
|
|
|
|
void HWR_DrawConsoleBack(UINT32 color, INT32 height)
|
|
|
|
{
|
|
|
|
FOutVector v[4];
|
|
|
|
FSurfaceInfo Surf;
|
|
|
|
|
|
|
|
// setup some neat-o translucency effect
|
|
|
|
if (!height) //cool hack 0 height is full height
|
|
|
|
height = vid.height;
|
|
|
|
|
|
|
|
v[0].x = v[3].x = -1.0f;
|
|
|
|
v[2].x = v[1].x = 1.0f;
|
|
|
|
v[0].y = v[1].y = 1.0f-((height<<1)/(float)vid.height);
|
|
|
|
v[2].y = v[3].y = 1.0f;
|
|
|
|
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
v[0].s = v[3].s = 0.0f;
|
|
|
|
v[2].s = v[1].s = 1.0f;
|
|
|
|
v[0].t = v[1].t = 1.0f;
|
|
|
|
v[2].t = v[3].t = 0.0f;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
Surf.PolyColor.rgba = UINT2RGBA(color);
|
|
|
|
Surf.PolyColor.s.alpha = 0x80;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
|
|
|
}
|
|
|
|
|
2018-11-03 21:14:17 +00:00
|
|
|
// Very similar to HWR_DrawConsoleBack, except we draw from the middle(-ish) of the screen to the bottom.
|
|
|
|
void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight)
|
|
|
|
{
|
|
|
|
FOutVector v[4];
|
|
|
|
FSurfaceInfo Surf;
|
Introducing Marathon Run. (I was going to call it Marathon Mode, but NiGHTS Mode being right next to it on the menu looked terrible.)
Basically a dedicated Record Attack-like experience for speedrunning the game as a continuous chunk rather than ILs. Has several quality of life features.
Benefits include:
* An unambiguous real-time bar across the bottom of the screen, always displaying the current time, ticking up until you reach the ending.
* Disable the console (pausing is still allowed, but the timer will still increment).
* Automatically skip intermissions as if you're holding down the spin button.
* Show centiseconds on HUD automatically, like record attack.
* "Live Event Backups" - a category of run fit for major events like GDQ, where recovery from crashes or chokes makes for better entertainment. Essentially a modified SP savefile, down to using the same basic functions, but has its own filename and tweaked internal layout.
* "spmarathon_start" MainCfg block parameter and "marathonnext" mapheader parameter, allowing for a customised flow (makes this fit for purpose for an eventual SUGOI port).
* Disabling inter-level custom cutscenes by default with a menu option to toggle this (won't show up if the mod doesn't *have* any custom cutscenes), although either way ending cutscenes (vanilla or custom) remain intact since is time is called before them.
* Won't show up if you have a mod that consists of only one level (determined by spmarathon_start's nextlevel; this won't trip if you manually set its marathonnext).
* Unconditional gratitude on the evaluation screen, instead of a negging "Try again..." if you didn't get all the emeralds (which you may not have been aiming for).
* Gorgeous new menu (no new assets required, unless you wanna give it a header later).
Changes which were required for the above but affect other areas of the game include:
* "useBlackRock" MainCFG block parameter, which can be used to disable the presence of the Black Rock or Egg Rock in both the Evaluation screen and the Marathon Run menu (for total conversions with different stories).
* Disabling Continues in NiGHTS mode, to match the most common singleplayer experience post 2.2.4's release (is reverted if useContinues is set to true).
* Hiding the exitmove "powerup" outside of multiplayer. (Okay, this isn't really related, I just saw this bug in action a lot while doing test runs and got annoyed enough to fix it here.)
* The ability to use V_DrawPromptBack (in hardcode only at the moment, but) to draw in terms of pixels rather than rows of text, by providing negative instead of positive inputs).
* A refactoring of redundant game saves smattered across the ending, credits, and evaluation - in addition to saving the game slightly earlier.
* Minor m_menu.c touchups and refactorings here and there.
Built using feedback from the official server's #speedruns channel, among other places.
2020-05-14 22:10:00 +00:00
|
|
|
INT32 height;
|
|
|
|
if (boxheight < 0)
|
|
|
|
height = -boxheight;
|
|
|
|
else
|
|
|
|
height = (boxheight * 4) + (boxheight/2)*5; // 4 lines of space plus gaps between and some leeway
|
2018-11-03 21:14:17 +00:00
|
|
|
|
|
|
|
// setup some neat-o translucency effect
|
|
|
|
|
|
|
|
v[0].x = v[3].x = -1.0f;
|
|
|
|
v[2].x = v[1].x = 1.0f;
|
|
|
|
v[0].y = v[1].y = -1.0f;
|
|
|
|
v[2].y = v[3].y = -1.0f+((height<<1)/(float)vid.height);
|
|
|
|
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
v[0].s = v[3].s = 0.0f;
|
|
|
|
v[2].s = v[1].s = 1.0f;
|
|
|
|
v[0].t = v[1].t = 1.0f;
|
|
|
|
v[2].t = v[3].t = 0.0f;
|
2018-11-03 21:14:17 +00:00
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
Surf.PolyColor.rgba = UINT2RGBA(color);
|
|
|
|
Surf.PolyColor.s.alpha = (color == 0 ? 0xC0 : 0x80); // make black darker, like software
|
2018-11-03 21:14:17 +00:00
|
|
|
|
|
|
|
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
|
|
|
}
|
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// ==========================================================================
|
|
|
|
// R_DRAW.C STUFF
|
|
|
|
// ==========================================================================
|
|
|
|
|
|
|
|
// ------------------
|
|
|
|
// HWR_DrawViewBorder
|
|
|
|
// Fill the space around the view window with a Doom flat texture, draw the
|
|
|
|
// beveled edges.
|
|
|
|
// 'clearlines' is useful to clear the heads up messages, when the view
|
|
|
|
// window is reduced, it doesn't refresh all the view borders.
|
|
|
|
// ------------------
|
|
|
|
void HWR_DrawViewBorder(INT32 clearlines)
|
|
|
|
{
|
|
|
|
INT32 x, y;
|
|
|
|
INT32 top, side;
|
|
|
|
INT32 baseviewwidth, baseviewheight;
|
|
|
|
INT32 basewindowx, basewindowy;
|
2020-08-08 08:16:47 +00:00
|
|
|
patch_t *patch;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2020-07-06 04:15:08 +00:00
|
|
|
// if (gl_viewwidth == vid.width)
|
2014-03-15 16:59:03 +00:00
|
|
|
// return;
|
|
|
|
|
|
|
|
if (!clearlines)
|
|
|
|
clearlines = BASEVIDHEIGHT; // refresh all
|
|
|
|
|
|
|
|
// calc view size based on original game resolution
|
2020-07-06 04:15:08 +00:00
|
|
|
baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwidth), vid.fdupx)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7;
|
|
|
|
baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewheight), vid.fdupy));
|
|
|
|
top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowy), vid.fdupy));
|
|
|
|
side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwindowx), vid.fdupx));
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// top
|
|
|
|
HWR_DrawFlatFill(0, 0,
|
|
|
|
BASEVIDWIDTH, (top < clearlines ? top : clearlines),
|
|
|
|
st_borderpatchnum);
|
|
|
|
|
|
|
|
// left
|
|
|
|
if (top < clearlines)
|
|
|
|
HWR_DrawFlatFill(0, top, side,
|
|
|
|
(clearlines-top < baseviewheight ? clearlines-top : baseviewheight),
|
|
|
|
st_borderpatchnum);
|
|
|
|
|
|
|
|
// right
|
|
|
|
if (top < clearlines)
|
|
|
|
HWR_DrawFlatFill(side + baseviewwidth, top, side,
|
|
|
|
(clearlines-top < baseviewheight ? clearlines-top : baseviewheight),
|
|
|
|
st_borderpatchnum);
|
|
|
|
|
|
|
|
// bottom
|
|
|
|
if (top + baseviewheight < clearlines)
|
|
|
|
HWR_DrawFlatFill(0, top + baseviewheight,
|
|
|
|
BASEVIDWIDTH, BASEVIDHEIGHT, st_borderpatchnum);
|
|
|
|
|
|
|
|
//
|
|
|
|
// draw the view borders
|
|
|
|
//
|
|
|
|
|
|
|
|
basewindowx = (BASEVIDWIDTH - baseviewwidth)>>1;
|
|
|
|
if (baseviewwidth == BASEVIDWIDTH)
|
|
|
|
basewindowy = 0;
|
|
|
|
else
|
|
|
|
basewindowy = top;
|
|
|
|
|
|
|
|
// top edge
|
|
|
|
if (clearlines > basewindowy - 8)
|
|
|
|
{
|
2019-09-08 21:27:35 +00:00
|
|
|
patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH);
|
2014-03-15 16:59:03 +00:00
|
|
|
for (x = 0; x < baseviewwidth; x += 8)
|
|
|
|
HWR_DrawPatch(patch, basewindowx + x, basewindowy - 8,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// bottom edge
|
|
|
|
if (clearlines > basewindowy + baseviewheight)
|
|
|
|
{
|
2019-09-08 21:27:35 +00:00
|
|
|
patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH);
|
2014-03-15 16:59:03 +00:00
|
|
|
for (x = 0; x < baseviewwidth; x += 8)
|
|
|
|
HWR_DrawPatch(patch, basewindowx + x,
|
|
|
|
basewindowy + baseviewheight, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// left edge
|
|
|
|
if (clearlines > basewindowy)
|
|
|
|
{
|
2019-09-08 21:27:35 +00:00
|
|
|
patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH);
|
2014-03-15 16:59:03 +00:00
|
|
|
for (y = 0; y < baseviewheight && basewindowy + y < clearlines;
|
|
|
|
y += 8)
|
|
|
|
{
|
|
|
|
HWR_DrawPatch(patch, basewindowx - 8, basewindowy + y,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// right edge
|
|
|
|
if (clearlines > basewindowy)
|
|
|
|
{
|
2019-09-08 21:27:35 +00:00
|
|
|
patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH);
|
2014-03-15 16:59:03 +00:00
|
|
|
for (y = 0; y < baseviewheight && basewindowy+y < clearlines;
|
|
|
|
y += 8)
|
|
|
|
{
|
|
|
|
HWR_DrawPatch(patch, basewindowx + baseviewwidth,
|
|
|
|
basewindowy + y, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw beveled corners.
|
|
|
|
if (clearlines > basewindowy - 8)
|
|
|
|
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TL],
|
2019-09-08 21:27:35 +00:00
|
|
|
PU_PATCH),
|
2014-03-15 16:59:03 +00:00
|
|
|
basewindowx - 8, basewindowy - 8, 0);
|
|
|
|
|
|
|
|
if (clearlines > basewindowy - 8)
|
|
|
|
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TR],
|
2019-09-08 21:27:35 +00:00
|
|
|
PU_PATCH),
|
2014-03-15 16:59:03 +00:00
|
|
|
basewindowx + baseviewwidth, basewindowy - 8, 0);
|
|
|
|
|
|
|
|
if (clearlines > basewindowy+baseviewheight)
|
|
|
|
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BL],
|
2019-09-08 21:27:35 +00:00
|
|
|
PU_PATCH),
|
2014-03-15 16:59:03 +00:00
|
|
|
basewindowx - 8, basewindowy + baseviewheight, 0);
|
|
|
|
|
|
|
|
if (clearlines > basewindowy + baseviewheight)
|
|
|
|
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BR],
|
2019-09-08 21:27:35 +00:00
|
|
|
PU_PATCH),
|
2014-03-15 16:59:03 +00:00
|
|
|
basewindowx + baseviewwidth,
|
|
|
|
basewindowy + baseviewheight, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ==========================================================================
|
|
|
|
// AM_MAP.C DRAWING STUFF
|
|
|
|
// ==========================================================================
|
|
|
|
|
|
|
|
// -----------------+
|
|
|
|
// HWR_drawAMline : draw a line of the automap (the clipping is already done in automap code)
|
|
|
|
// Arg : color is a RGB 888 value
|
|
|
|
// -----------------+
|
|
|
|
void HWR_drawAMline(const fline_t *fl, INT32 color)
|
|
|
|
{
|
|
|
|
F2DCoord v1, v2;
|
|
|
|
RGBA_t color_rgba;
|
|
|
|
|
|
|
|
color_rgba = V_GetColor(color);
|
|
|
|
|
|
|
|
v1.x = ((float)fl->a.x-(vid.width/2.0f))*(2.0f/vid.width);
|
|
|
|
v1.y = ((float)fl->a.y-(vid.height/2.0f))*(2.0f/vid.height);
|
|
|
|
|
|
|
|
v2.x = ((float)fl->b.x-(vid.width/2.0f))*(2.0f/vid.width);
|
|
|
|
v2.y = ((float)fl->b.y-(vid.height/2.0f))*(2.0f/vid.height);
|
|
|
|
|
|
|
|
HWD.pfnDraw2DLine(&v1, &v2, color_rgba);
|
|
|
|
}
|
|
|
|
|
2018-07-31 09:10:02 +00:00
|
|
|
// -------------------+
|
|
|
|
// HWR_DrawConsoleFill : draw flat coloured transparent rectangle because that's cool, and hw sucks less than sw for that.
|
|
|
|
// -------------------+
|
2019-08-04 09:27:09 +00:00
|
|
|
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32 actualcolor)
|
2018-07-31 09:10:02 +00:00
|
|
|
{
|
|
|
|
FOutVector v[4];
|
|
|
|
FSurfaceInfo Surf;
|
|
|
|
float fx, fy, fw, fh;
|
|
|
|
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
UINT8 perplayershuffle = 0;
|
|
|
|
|
2018-07-31 09:10:02 +00:00
|
|
|
// 3--2
|
|
|
|
// | /|
|
|
|
|
// |/ |
|
|
|
|
// 0--1
|
|
|
|
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
if (splitscreen && (color & V_PERPLAYER))
|
|
|
|
{
|
|
|
|
fixed_t adjusty = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
|
|
|
|
h >>= 1;
|
|
|
|
y >>= 1;
|
|
|
|
#ifdef QUADS
|
|
|
|
if (splitscreen > 1) // 3 or 4 players
|
|
|
|
{
|
|
|
|
fixed_t adjustx = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
|
|
|
|
w >>= 1;
|
|
|
|
x >>= 1;
|
|
|
|
if (stplyr == &players[displayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 1;
|
|
|
|
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 4;
|
|
|
|
color &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT;
|
|
|
|
}
|
|
|
|
else if (stplyr == &players[secondarydisplayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 1;
|
|
|
|
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 8;
|
|
|
|
x += adjustx;
|
|
|
|
color &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT;
|
|
|
|
}
|
|
|
|
else if (stplyr == &players[thirddisplayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 2;
|
|
|
|
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 4;
|
|
|
|
y += adjusty;
|
|
|
|
color &= ~V_SNAPTOTOP|V_SNAPTORIGHT;
|
|
|
|
}
|
|
|
|
else //if (stplyr == &players[fourthdisplayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 2;
|
|
|
|
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 8;
|
|
|
|
x += adjustx;
|
|
|
|
y += adjusty;
|
|
|
|
color &= ~V_SNAPTOTOP|V_SNAPTOLEFT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
// 2 players
|
|
|
|
{
|
|
|
|
if (stplyr == &players[displayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 1;
|
|
|
|
color &= ~V_SNAPTOBOTTOM;
|
|
|
|
}
|
|
|
|
else //if (stplyr == &players[secondarydisplayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 2;
|
|
|
|
y += adjusty;
|
|
|
|
color &= ~V_SNAPTOTOP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-31 09:10:02 +00:00
|
|
|
fx = (float)x;
|
|
|
|
fy = (float)y;
|
|
|
|
fw = (float)w;
|
|
|
|
fh = (float)h;
|
|
|
|
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
if (!(color & V_NOSCALESTART))
|
2018-07-31 09:10:02 +00:00
|
|
|
{
|
|
|
|
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
|
|
|
|
|
|
|
|
fx *= dupx;
|
|
|
|
fy *= dupy;
|
|
|
|
fw *= dupx;
|
|
|
|
fh *= dupy;
|
|
|
|
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
|
2018-07-31 09:10:02 +00:00
|
|
|
{
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
if (color & V_SNAPTORIGHT)
|
2018-07-31 09:10:02 +00:00
|
|
|
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
else if (!(color & V_SNAPTOLEFT))
|
2018-07-31 09:10:02 +00:00
|
|
|
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
if (perplayershuffle & 4)
|
|
|
|
fx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
|
|
|
else if (perplayershuffle & 8)
|
|
|
|
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
2018-07-31 09:10:02 +00:00
|
|
|
}
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
2018-07-31 09:10:02 +00:00
|
|
|
{
|
|
|
|
// same thing here
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
if (color & V_SNAPTOBOTTOM)
|
2018-07-31 09:10:02 +00:00
|
|
|
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
else if (!(color & V_SNAPTOTOP))
|
2018-07-31 09:10:02 +00:00
|
|
|
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
|
A good and bad ending cutscene now exist.
Also:
* SPR2_XTRA - instead of defining lumpnames in S_SKIN, those kinds of assets can just be bundled into the spriteset. Required for ending cutscene stuff, I guess, but also done for HUD life icon and character select image (aside from Sonic&Tails, still SOC'd in).
* Minor oversights in SPR2 support corrected.
* Better evaluation, featuring ending assets.
* Intro has warping-in blackrock, reusing ending assets.
* Cutscene text now supports lowercase (intro and custom).
* Disable the asset-fucking "gamma correction" I put in over two years ago when implementing colour cube. (This is the only thing I could move into another branch if you MUST, but it's basically invisble in the diff so w/e.)
* Don't blank the screen if the top left pixel of a screen-covering patch is transparent. (Checked via nonzero topdelta for first column)
Bugs:
* OPENGL ONLY: The first ~20 frames of both endings are fucked. A little help here? Might be HWR_DrawFadeFill's fault, which I just created. OR it could be in f_finale, but I doubt it, since it doesn't appear in Software.
2019-07-27 23:32:57 +00:00
|
|
|
if (perplayershuffle & 1)
|
|
|
|
fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
|
|
|
else if (perplayershuffle & 2)
|
|
|
|
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
2018-07-31 09:10:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fx >= vid.width || fy >= vid.height)
|
|
|
|
return;
|
|
|
|
if (fx < 0)
|
|
|
|
{
|
|
|
|
fw += fx;
|
|
|
|
fx = 0;
|
|
|
|
}
|
|
|
|
if (fy < 0)
|
|
|
|
{
|
|
|
|
fh += fy;
|
|
|
|
fy = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fw <= 0 || fh <= 0)
|
|
|
|
return;
|
|
|
|
if (fx + fw > vid.width)
|
|
|
|
fw = (float)vid.width - fx;
|
|
|
|
if (fy + fh > vid.height)
|
|
|
|
fh = (float)vid.height - fy;
|
|
|
|
|
|
|
|
fx = -1 + fx / (vid.width / 2);
|
|
|
|
fy = 1 - fy / (vid.height / 2);
|
|
|
|
fw = fw / (vid.width / 2);
|
|
|
|
fh = fh / (vid.height / 2);
|
|
|
|
|
|
|
|
v[0].x = v[3].x = fx;
|
|
|
|
v[2].x = v[1].x = fx + fw;
|
|
|
|
v[0].y = v[1].y = fy;
|
|
|
|
v[2].y = v[3].y = fy - fh;
|
|
|
|
|
|
|
|
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
v[0].s = v[3].s = 0.0f;
|
|
|
|
v[2].s = v[1].s = 1.0f;
|
|
|
|
v[0].t = v[1].t = 0.0f;
|
|
|
|
v[2].t = v[3].t = 1.0f;
|
2018-12-21 14:38:28 +00:00
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
Surf.PolyColor.rgba = UINT2RGBA(actualcolor);
|
|
|
|
Surf.PolyColor.s.alpha = 0x80;
|
2018-07-31 09:10:02 +00:00
|
|
|
|
|
|
|
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
|
|
|
}
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// -----------------+
|
|
|
|
// HWR_DrawFill : draw flat coloured rectangle, with no texture
|
|
|
|
// -----------------+
|
|
|
|
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
|
|
|
|
{
|
|
|
|
FOutVector v[4];
|
|
|
|
FSurfaceInfo Surf;
|
2018-03-16 19:46:45 +00:00
|
|
|
float fx, fy, fw, fh;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2018-04-06 18:38:19 +00:00
|
|
|
UINT8 perplayershuffle = 0;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// 3--2
|
|
|
|
// | /|
|
|
|
|
// |/ |
|
|
|
|
// 0--1
|
2016-11-15 20:33:07 +00:00
|
|
|
|
2018-01-21 12:56:38 +00:00
|
|
|
if (splitscreen && (color & V_PERPLAYER))
|
|
|
|
{
|
2018-04-06 18:38:19 +00:00
|
|
|
fixed_t adjusty = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
|
|
|
|
h >>= 1;
|
2018-01-21 12:56:38 +00:00
|
|
|
y >>= 1;
|
|
|
|
#ifdef QUADS
|
|
|
|
if (splitscreen > 1) // 3 or 4 players
|
|
|
|
{
|
2018-04-06 18:38:19 +00:00
|
|
|
fixed_t adjustx = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f;
|
2018-01-21 12:56:38 +00:00
|
|
|
w >>= 1;
|
|
|
|
x >>= 1;
|
2018-04-06 18:38:19 +00:00
|
|
|
if (stplyr == &players[displayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 1;
|
|
|
|
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 4;
|
|
|
|
color &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT;
|
|
|
|
}
|
|
|
|
else if (stplyr == &players[secondarydisplayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 1;
|
|
|
|
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 8;
|
2018-01-21 12:56:38 +00:00
|
|
|
x += adjustx;
|
2018-04-06 18:38:19 +00:00
|
|
|
color &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT;
|
|
|
|
}
|
2018-01-21 12:56:38 +00:00
|
|
|
else if (stplyr == &players[thirddisplayplayer])
|
2018-04-06 18:38:19 +00:00
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 2;
|
|
|
|
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 4;
|
2018-01-21 12:56:38 +00:00
|
|
|
y += adjusty;
|
2018-04-06 18:38:19 +00:00
|
|
|
color &= ~V_SNAPTOTOP|V_SNAPTORIGHT;
|
|
|
|
}
|
|
|
|
else //if (stplyr == &players[fourthdisplayplayer])
|
2018-01-21 12:56:38 +00:00
|
|
|
{
|
2018-04-06 18:38:19 +00:00
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 2;
|
|
|
|
if (!(color & (V_SNAPTOLEFT|V_SNAPTORIGHT)))
|
|
|
|
perplayershuffle |= 8;
|
2018-01-21 12:56:38 +00:00
|
|
|
x += adjustx;
|
|
|
|
y += adjusty;
|
2018-04-06 18:38:19 +00:00
|
|
|
color &= ~V_SNAPTOTOP|V_SNAPTOLEFT;
|
2018-01-21 12:56:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
// 2 players
|
|
|
|
{
|
2018-04-06 18:38:19 +00:00
|
|
|
if (stplyr == &players[displayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 1;
|
|
|
|
color &= ~V_SNAPTOBOTTOM;
|
|
|
|
}
|
|
|
|
else //if (stplyr == &players[secondarydisplayplayer])
|
|
|
|
{
|
|
|
|
if (!(color & (V_SNAPTOTOP|V_SNAPTOBOTTOM)))
|
|
|
|
perplayershuffle |= 2;
|
2018-01-21 12:56:38 +00:00
|
|
|
y += adjusty;
|
2018-04-06 18:38:19 +00:00
|
|
|
color &= ~V_SNAPTOTOP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-16 19:46:45 +00:00
|
|
|
fx = (float)x;
|
|
|
|
fy = (float)y;
|
|
|
|
fw = (float)w;
|
|
|
|
fh = (float)h;
|
2016-11-15 20:33:07 +00:00
|
|
|
|
2018-03-16 19:46:45 +00:00
|
|
|
if (!(color & V_NOSCALESTART))
|
|
|
|
{
|
|
|
|
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
|
|
|
|
|
|
|
|
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
|
|
|
|
{
|
|
|
|
RGBA_t rgbaColour = V_GetColor(color);
|
|
|
|
FRGBAFloat clearColour;
|
|
|
|
clearColour.red = (float)rgbaColour.s.red / 255;
|
|
|
|
clearColour.green = (float)rgbaColour.s.green / 255;
|
|
|
|
clearColour.blue = (float)rgbaColour.s.blue / 255;
|
|
|
|
clearColour.alpha = 1;
|
|
|
|
HWD.pfnClearBuffer(true, false, &clearColour);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
fx *= dupx;
|
|
|
|
fy *= dupy;
|
|
|
|
fw *= dupx;
|
|
|
|
fh *= dupy;
|
|
|
|
|
2018-12-15 00:33:40 +00:00
|
|
|
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
|
2018-03-16 19:46:45 +00:00
|
|
|
{
|
|
|
|
if (color & V_SNAPTORIGHT)
|
|
|
|
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
|
|
|
|
else if (!(color & V_SNAPTOLEFT))
|
|
|
|
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
|
2018-04-06 18:38:19 +00:00
|
|
|
if (perplayershuffle & 4)
|
|
|
|
fx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
|
|
|
else if (perplayershuffle & 8)
|
|
|
|
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 4;
|
2018-03-16 19:46:45 +00:00
|
|
|
}
|
2018-12-15 00:33:40 +00:00
|
|
|
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
|
2018-03-16 19:46:45 +00:00
|
|
|
{
|
|
|
|
// same thing here
|
|
|
|
if (color & V_SNAPTOBOTTOM)
|
|
|
|
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
|
|
|
|
else if (!(color & V_SNAPTOTOP))
|
|
|
|
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
|
2018-04-06 18:38:19 +00:00
|
|
|
if (perplayershuffle & 1)
|
|
|
|
fy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
|
|
|
else if (perplayershuffle & 2)
|
|
|
|
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 4;
|
2018-01-21 12:56:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-16 19:46:45 +00:00
|
|
|
if (fx >= vid.width || fy >= vid.height)
|
|
|
|
return;
|
|
|
|
if (fx < 0)
|
|
|
|
{
|
|
|
|
fw += fx;
|
|
|
|
fx = 0;
|
|
|
|
}
|
|
|
|
if (fy < 0)
|
|
|
|
{
|
|
|
|
fh += fy;
|
|
|
|
fy = 0;
|
|
|
|
}
|
2016-11-15 20:33:07 +00:00
|
|
|
|
2018-03-16 19:46:45 +00:00
|
|
|
if (fw <= 0 || fh <= 0)
|
|
|
|
return;
|
|
|
|
if (fx + fw > vid.width)
|
|
|
|
fw = (float)vid.width - fx;
|
|
|
|
if (fy + fh > vid.height)
|
|
|
|
fh = (float)vid.height - fy;
|
|
|
|
|
|
|
|
fx = -1 + fx / (vid.width / 2);
|
|
|
|
fy = 1 - fy / (vid.height / 2);
|
|
|
|
fw = fw / (vid.width / 2);
|
|
|
|
fh = fh / (vid.height / 2);
|
|
|
|
|
|
|
|
v[0].x = v[3].x = fx;
|
|
|
|
v[2].x = v[1].x = fx + fw;
|
|
|
|
v[0].y = v[1].y = fy;
|
|
|
|
v[2].y = v[3].y = fy - fh;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
v[0].s = v[3].s = 0.0f;
|
|
|
|
v[2].s = v[1].s = 1.0f;
|
|
|
|
v[0].t = v[1].t = 0.0f;
|
|
|
|
v[2].t = v[3].t = 1.0f;
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2019-12-25 19:22:01 +00:00
|
|
|
Surf.PolyColor = V_GetColor(color);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
HWD.pfnDrawPolygon(&Surf, v, 4,
|
|
|
|
PF_Modulated|PF_NoTexture|PF_NoDepthTest);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_PNG
|
|
|
|
|
|
|
|
#ifndef _MSC_VER
|
|
|
|
#ifndef _LARGEFILE64_SOURCE
|
|
|
|
#define _LARGEFILE64_SOURCE
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _LFS64_LARGEFILE
|
|
|
|
#define _LFS64_LARGEFILE
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _FILE_OFFSET_BITS
|
|
|
|
#define _FILE_OFFSET_BITS 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "png.h"
|
|
|
|
#ifdef PNG_WRITE_SUPPORTED
|
|
|
|
#define USE_PNG // PNG is only used if write is supported (see ../m_misc.c)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef USE_PNG
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
// save screenshots with TGA format
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
static inline boolean saveTGA(const char *file_name, void *buffer,
|
|
|
|
INT32 width, INT32 height)
|
|
|
|
{
|
|
|
|
INT32 fd;
|
|
|
|
TGAHeader tga_hdr;
|
|
|
|
INT32 i;
|
|
|
|
UINT8 *buf8 = buffer;
|
|
|
|
|
|
|
|
fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
|
|
|
|
if (fd < 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
memset(&tga_hdr, 0, sizeof (tga_hdr));
|
|
|
|
tga_hdr.width = SHORT(width);
|
|
|
|
tga_hdr.height = SHORT(height);
|
|
|
|
tga_hdr.image_pix_size = 24;
|
|
|
|
tga_hdr.image_type = 2;
|
|
|
|
tga_hdr.image_descriptor = 32;
|
|
|
|
|
2015-01-10 22:26:29 +00:00
|
|
|
if ( -1 == write(fd, &tga_hdr, sizeof (TGAHeader)))
|
|
|
|
{
|
|
|
|
close(fd);
|
|
|
|
return false;
|
|
|
|
}
|
2014-03-15 16:59:03 +00:00
|
|
|
// format to 888 BGR
|
|
|
|
for (i = 0; i < width * height * 3; i+=3)
|
|
|
|
{
|
|
|
|
const UINT8 temp = buf8[i];
|
|
|
|
buf8[i] = buf8[i+2];
|
|
|
|
buf8[i+2] = temp;
|
|
|
|
}
|
2015-01-10 22:26:29 +00:00
|
|
|
if ( -1 == write(fd, buffer, width * height * 3))
|
|
|
|
{
|
|
|
|
close(fd);
|
|
|
|
return false;
|
|
|
|
}
|
2014-03-15 16:59:03 +00:00
|
|
|
close(fd);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
// screen shot
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
UINT8 *HWR_GetScreenshot(void)
|
|
|
|
{
|
|
|
|
UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf));
|
|
|
|
|
|
|
|
if (!buf)
|
|
|
|
return NULL;
|
|
|
|
// returns 24bit 888 RGB
|
|
|
|
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
2019-01-02 04:01:57 +00:00
|
|
|
boolean HWR_Screenshot(const char *pathname)
|
2014-03-15 16:59:03 +00:00
|
|
|
{
|
|
|
|
boolean ret;
|
|
|
|
UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf));
|
|
|
|
|
|
|
|
if (!buf)
|
2019-01-02 03:41:52 +00:00
|
|
|
{
|
2019-01-02 04:01:57 +00:00
|
|
|
CONS_Debug(DBG_RENDER, "HWR_Screenshot: Failed to allocate memory\n");
|
2014-03-15 16:59:03 +00:00
|
|
|
return false;
|
2019-01-02 03:41:52 +00:00
|
|
|
}
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// returns 24bit 888 RGB
|
|
|
|
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
|
|
|
|
|
|
|
|
#ifdef USE_PNG
|
2019-01-02 04:01:57 +00:00
|
|
|
ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL);
|
2014-03-15 16:59:03 +00:00
|
|
|
#else
|
2019-01-02 03:41:52 +00:00
|
|
|
ret = saveTGA(pathname, buf, vid.width, vid.height);
|
2014-03-15 16:59:03 +00:00
|
|
|
#endif
|
|
|
|
free(buf);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif //HWRENDER
|