mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-18 01:51:39 +00:00
Merge remote-tracking branch 'origin/next' into more-cleanup
This commit is contained in:
commit
5ec326972c
30 changed files with 893 additions and 522 deletions
|
@ -3430,6 +3430,8 @@ static void readextraemblemdata(MYFILE *f, INT32 num)
|
|||
sizeof (extraemblems[num-1].description), va("Extra emblem %d: objective", num));
|
||||
else if (fastcmp(word, "CONDITIONSET"))
|
||||
extraemblems[num-1].conditionset = (UINT8)value;
|
||||
else if (fastcmp(word, "SHOWCONDITIONSET"))
|
||||
extraemblems[num-1].showconditionset = (UINT8)value;
|
||||
else
|
||||
{
|
||||
strupr(word2);
|
||||
|
@ -3516,6 +3518,8 @@ static void readunlockable(MYFILE *f, INT32 num)
|
|||
unlockables[num].height = (UINT16)i;
|
||||
else if (fastcmp(word, "CONDITIONSET"))
|
||||
unlockables[num].conditionset = (UINT8)i;
|
||||
else if (fastcmp(word, "SHOWCONDITIONSET"))
|
||||
unlockables[num].showconditionset = (UINT8)i;
|
||||
else if (fastcmp(word, "NOCECHO"))
|
||||
unlockables[num].nocecho = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
||||
else if (fastcmp(word, "NOCHECKLIST"))
|
||||
|
@ -8669,6 +8673,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_NIGHTSCHIP", // NiGHTS Chip
|
||||
"MT_FLINGNIGHTSCHIP", // Lost NiGHTS Chip
|
||||
"MT_NIGHTSSTAR", // NiGHTS Star
|
||||
"MT_FLINGNIGHTSSTAR", // Lost NiGHTS Star
|
||||
"MT_NIGHTSSUPERLOOP",
|
||||
"MT_NIGHTSDRILLREFILL",
|
||||
"MT_NIGHTSHELPER",
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
#include "../v_video.h"
|
||||
#include "hw_clip.h"
|
||||
#include "hw_glob.h"
|
||||
#include "../r_main.h"
|
||||
#include "../r_state.h"
|
||||
#include "../tables.h"
|
||||
#include "r_opengl/r_opengl.h"
|
||||
|
@ -328,7 +329,7 @@ angle_t gld_FrustumAngle(void)
|
|||
|
||||
// NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function
|
||||
|
||||
float render_fov = FIXED_TO_FLOAT(cv_grfov.value);
|
||||
float render_fov = FIXED_TO_FLOAT(cv_fov.value);
|
||||
float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right?
|
||||
float render_multiplier = 64.0f / render_fovratio / RMUL;
|
||||
|
||||
|
|
|
@ -1026,6 +1026,34 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2)
|
|||
}
|
||||
#endif
|
||||
|
||||
static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y)
|
||||
{
|
||||
INT16 finallight = lightnum;
|
||||
|
||||
if (cv_grfakecontrast.value != 0)
|
||||
{
|
||||
const UINT8 contrast = 8;
|
||||
fixed_t extralight = 0;
|
||||
|
||||
if (v1y == v2y)
|
||||
extralight = -contrast;
|
||||
else if (v1x == v2x)
|
||||
extralight = contrast;
|
||||
|
||||
if (extralight != 0)
|
||||
{
|
||||
finallight += extralight;
|
||||
|
||||
if (finallight < 0)
|
||||
finallight = 0;
|
||||
if (finallight > 255)
|
||||
finallight = 255;
|
||||
}
|
||||
}
|
||||
|
||||
return (FUINT)finallight;
|
||||
}
|
||||
|
||||
//
|
||||
// HWR_SplitWall
|
||||
//
|
||||
|
@ -1044,19 +1072,20 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
|
|||
float endpegt, endpegb, endpegmul;
|
||||
float endheight = 0.0f, endbheight = 0.0f;
|
||||
|
||||
fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x);
|
||||
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo
|
||||
fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x);
|
||||
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo
|
||||
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
|
||||
// use this as a temp var to store P_GetZAt's return value each time
|
||||
fixed_t temp;
|
||||
#endif
|
||||
|
||||
INT32 solid, i;
|
||||
fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x);
|
||||
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo
|
||||
fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x);
|
||||
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo
|
||||
|
||||
INT32 solid, i;
|
||||
lightlist_t * list = sector->lightlist;
|
||||
const UINT8 alpha = Surf->FlatColor.s.alpha;
|
||||
FUINT lightnum = sector->lightlevel;
|
||||
FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y);
|
||||
extracolormap_t *colormap = NULL;
|
||||
|
||||
realtop = top = wallVerts[3].y;
|
||||
|
@ -1086,12 +1115,12 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
|
|||
{
|
||||
if (pfloor && (pfloor->flags & FF_FOG))
|
||||
{
|
||||
lightnum = pfloor->master->frontsector->lightlevel;
|
||||
lightnum = HWR_CalcWallLight(pfloor->master->frontsector->lightlevel, v1x, v1y, v2x, v2y);
|
||||
colormap = pfloor->master->frontsector->extra_colormap;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightnum = *list[i].lightlevel;
|
||||
lightnum = HWR_CalcWallLight(*list[i].lightlevel, v1x, v1y, v2x, v2y);
|
||||
colormap = *list[i].extra_colormap;
|
||||
}
|
||||
}
|
||||
|
@ -1395,7 +1424,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
|||
cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT));
|
||||
}
|
||||
|
||||
lightnum = gr_frontsector->lightlevel;
|
||||
lightnum = HWR_CalcWallLight(gr_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
||||
colormap = gr_frontsector->extra_colormap;
|
||||
|
||||
if (gr_frontsector)
|
||||
|
@ -2150,7 +2179,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
|||
|
||||
blendmode = PF_Fog|PF_NoTexture;
|
||||
|
||||
lightnum = rover->master->frontsector->lightlevel;
|
||||
lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
||||
colormap = rover->master->frontsector->extra_colormap;
|
||||
|
||||
if (rover->master->frontsector->extra_colormap)
|
||||
|
@ -2270,7 +2299,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
|||
|
||||
blendmode = PF_Fog|PF_NoTexture;
|
||||
|
||||
lightnum = rover->master->frontsector->lightlevel;
|
||||
lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
||||
colormap = rover->master->frontsector->extra_colormap;
|
||||
|
||||
if (rover->master->frontsector->extra_colormap)
|
||||
|
@ -5118,7 +5147,12 @@ void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boo
|
|||
|
||||
planeinfo[numplanes].isceiling = isceiling;
|
||||
planeinfo[numplanes].fixedheight = fixedheight;
|
||||
planeinfo[numplanes].lightlevel = lightlevel;
|
||||
|
||||
if (planecolormap && (planecolormap->fog & 1))
|
||||
planeinfo[numplanes].lightlevel = lightlevel;
|
||||
else
|
||||
planeinfo[numplanes].lightlevel = 255;
|
||||
|
||||
planeinfo[numplanes].levelflat = levelflat;
|
||||
planeinfo[numplanes].xsub = xsub;
|
||||
planeinfo[numplanes].alpha = alpha;
|
||||
|
@ -5150,7 +5184,12 @@ void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polyse
|
|||
|
||||
polyplaneinfo[numpolyplanes].isceiling = isceiling;
|
||||
polyplaneinfo[numpolyplanes].fixedheight = fixedheight;
|
||||
polyplaneinfo[numpolyplanes].lightlevel = lightlevel;
|
||||
|
||||
if (planecolormap && (planecolormap->fog & 1))
|
||||
polyplaneinfo[numpolyplanes].lightlevel = lightlevel;
|
||||
else
|
||||
polyplaneinfo[numpolyplanes].lightlevel = 255;
|
||||
|
||||
polyplaneinfo[numpolyplanes].levelflat = levelflat;
|
||||
polyplaneinfo[numpolyplanes].polysector = polysector;
|
||||
polyplaneinfo[numpolyplanes].alpha = alpha;
|
||||
|
@ -5491,9 +5530,10 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
spriteinfo_t *sprinfo;
|
||||
md2_t *md2;
|
||||
size_t lumpoff;
|
||||
unsigned rot;
|
||||
UINT8 flip;
|
||||
UINT16 flip;
|
||||
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP));
|
||||
|
||||
angle_t ang;
|
||||
|
@ -5522,8 +5562,21 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
|
||||
|
||||
// thing is behind view plane?
|
||||
if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmodels.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
|
||||
return;
|
||||
if (tz < ZCLIP_PLANE && !papersprite)
|
||||
{
|
||||
if (cv_grmodels.value) //Yellow: Only MD2's dont disappear
|
||||
{
|
||||
if (thing->skin && thing->sprite == SPR_PLAY)
|
||||
md2 = &md2_playermodels[( (skin_t *)thing->skin - skins )];
|
||||
else
|
||||
md2 = &md2_models[thing->sprite];
|
||||
|
||||
if (md2->notfound || md2->scale < 0.0f)
|
||||
return;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
// The above can stay as it works for cutting sprites that are too close
|
||||
tr_x = FIXED_TO_FLOAT(thing->x);
|
||||
|
@ -5579,12 +5632,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
flip = sprframe->flip; // Will only be 0x00 or 0xFF
|
||||
|
||||
if (papersprite && ang < ANGLE_180)
|
||||
{
|
||||
if (flip)
|
||||
flip = 0;
|
||||
else
|
||||
flip = 255;
|
||||
}
|
||||
flip ^= 0xFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5593,6 +5641,11 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
rot = 6; // F7 slot
|
||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||
rot = 2; // F3 slot
|
||||
else if (sprframe->rotate & SRF_3DGE) // 16-angle mode
|
||||
{
|
||||
rot = (ang+ANGLE_180+ANGLE_11hh)>>28;
|
||||
rot = ((rot & 1)<<3)|(rot>>1);
|
||||
}
|
||||
else // Normal behaviour
|
||||
rot = (ang+ANGLE_202h)>>29;
|
||||
|
||||
|
@ -5601,12 +5654,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
flip = sprframe->flip & (1<<rot);
|
||||
|
||||
if (papersprite && ang < ANGLE_180)
|
||||
{
|
||||
if (flip)
|
||||
flip = 0;
|
||||
else
|
||||
flip = 1<<rot;
|
||||
}
|
||||
flip ^= (1<<rot);
|
||||
}
|
||||
|
||||
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
|
||||
|
@ -5621,7 +5669,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
if (thing->rollangle)
|
||||
{
|
||||
rollangle = R_GetRollAngle(thing->rollangle);
|
||||
if (!sprframe->rotsprite.cached[rot])
|
||||
if (!(sprframe->rotsprite.cached & (1<<rot)))
|
||||
R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip);
|
||||
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
|
||||
if (rotsprite != NULL)
|
||||
|
@ -5896,7 +5944,7 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
if (cv_grskydome.value)
|
||||
{
|
||||
FTransform dometransform;
|
||||
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
|
||||
const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
|
||||
postimg_t *type;
|
||||
|
||||
if (splitscreen && player == &players[secondarydisplayplayer])
|
||||
|
@ -6074,7 +6122,7 @@ void HWR_SetViewSize(void)
|
|||
// ==========================================================================
|
||||
void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
|
||||
{
|
||||
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
|
||||
const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
|
||||
postimg_t *type;
|
||||
|
||||
if (splitscreen && player == &players[secondarydisplayplayer])
|
||||
|
@ -6200,7 +6248,7 @@ if (0)
|
|||
viewangle = localaiming2;
|
||||
|
||||
// Handle stuff when you are looking farther up or down.
|
||||
if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT))
|
||||
if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
|
||||
{
|
||||
dup_viewangle += ANGLE_90;
|
||||
HWR_ClearClipSegs();
|
||||
|
@ -6278,7 +6326,7 @@ if (0)
|
|||
// ==========================================================================
|
||||
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
||||
{
|
||||
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
|
||||
const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
|
||||
postimg_t *type;
|
||||
|
||||
const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on
|
||||
|
@ -6420,7 +6468,7 @@ if (0)
|
|||
viewangle = localaiming2;
|
||||
|
||||
// Handle stuff when you are looking farther up or down.
|
||||
if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT))
|
||||
if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
|
||||
{
|
||||
dup_viewangle += ANGLE_90;
|
||||
HWR_ClearClipSegs();
|
||||
|
@ -6549,9 +6597,7 @@ static void CV_grmodellighting_OnChange(void);
|
|||
static void CV_grfiltermode_OnChange(void);
|
||||
static void CV_granisotropic_OnChange(void);
|
||||
static void CV_grfogdensity_OnChange(void);
|
||||
static void CV_grfov_OnChange(void);
|
||||
|
||||
static CV_PossibleValue_t grfov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
|
||||
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
|
||||
{HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"},
|
||||
|
@ -6560,7 +6606,7 @@ static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA
|
|||
{0, NULL}};
|
||||
CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}};
|
||||
|
||||
consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_fovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -6578,9 +6624,9 @@ consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_O
|
|||
|
||||
consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfakecontrast = {"gr_fakecontrast", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grfov_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned,
|
||||
CV_grfogdensity_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
|
@ -6616,17 +6662,10 @@ static void CV_granisotropic_OnChange(void)
|
|||
HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value);
|
||||
}
|
||||
|
||||
static void CV_grfov_OnChange(void)
|
||||
{
|
||||
if ((netgame || multiplayer) && !cv_debug && cv_grfov.value != 90*FRACUNIT)
|
||||
CV_Set(&cv_grfov, cv_grfov.defaultvalue);
|
||||
}
|
||||
|
||||
//added by Hurdler: console varibale that are saved
|
||||
void HWR_AddCommands(void)
|
||||
{
|
||||
CV_RegisterVar(&cv_grfovchange);
|
||||
CV_RegisterVar(&cv_grfov);
|
||||
CV_RegisterVar(&cv_fovchange);
|
||||
|
||||
CV_RegisterVar(&cv_grfogdensity);
|
||||
CV_RegisterVar(&cv_grfogcolor);
|
||||
|
@ -6646,6 +6685,7 @@ void HWR_AddCommands(void)
|
|||
|
||||
CV_RegisterVar(&cv_grskydome);
|
||||
CV_RegisterVar(&cv_grspritebillboarding);
|
||||
CV_RegisterVar(&cv_grfakecontrast);
|
||||
|
||||
CV_RegisterVar(&cv_grfiltermode);
|
||||
CV_RegisterVar(&cv_grrounddown);
|
||||
|
|
|
@ -84,7 +84,6 @@ extern consvar_t cv_grstaticlighting;
|
|||
extern consvar_t cv_grcoronas;
|
||||
extern consvar_t cv_grcoronasize;
|
||||
#endif
|
||||
extern consvar_t cv_grfov;
|
||||
extern consvar_t cv_grmodels;
|
||||
extern consvar_t cv_grmodelinterpolation;
|
||||
extern consvar_t cv_grmodellighting;
|
||||
|
@ -95,10 +94,11 @@ extern consvar_t cv_grsoftwarefog;
|
|||
extern consvar_t cv_grfiltermode;
|
||||
extern consvar_t cv_granisotropicmode;
|
||||
extern consvar_t cv_grcorrecttricks;
|
||||
extern consvar_t cv_grfovchange;
|
||||
extern consvar_t cv_fovchange;
|
||||
extern consvar_t cv_grsolvetjoin;
|
||||
extern consvar_t cv_grspritebillboarding;
|
||||
extern consvar_t cv_grskydome;
|
||||
extern consvar_t cv_grfakecontrast;
|
||||
|
||||
extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowy;
|
||||
|
||||
|
|
|
@ -654,10 +654,14 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
|
|||
UINT16 w = gpatch->width, h = gpatch->height;
|
||||
UINT32 size = w*h;
|
||||
RGBA_t *image, *blendimage, *cur, blendcolor;
|
||||
UINT8 translation[16]; // First the color index
|
||||
UINT8 cutoff[16]; // Brightness cutoff before using the next color
|
||||
UINT8 translen = 0;
|
||||
UINT8 i;
|
||||
|
||||
// vanilla port
|
||||
UINT8 translation[16];
|
||||
blendcolor = V_GetColor(0); // initialize
|
||||
memset(translation, 0, sizeof(translation));
|
||||
memset(cutoff, 0, sizeof(cutoff));
|
||||
|
||||
if (grmip->width == 0)
|
||||
{
|
||||
|
@ -681,17 +685,46 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
|
|||
|
||||
image = gpatch->mipmap->grInfo.data;
|
||||
blendimage = blendgpatch->mipmap->grInfo.data;
|
||||
blendcolor = V_GetColor(0); // initialize
|
||||
|
||||
// TC_METALSONIC includes an actual skincolor translation, on top of its flashing.
|
||||
if (skinnum == TC_METALSONIC)
|
||||
color = SKINCOLOR_COBALT;
|
||||
|
||||
if (color != SKINCOLOR_NONE)
|
||||
memcpy(&translation, &Color_Index[color - 1], 16);
|
||||
{
|
||||
UINT8 numdupes = 1;
|
||||
|
||||
translation[translen] = Color_Index[color-1][0];
|
||||
cutoff[translen] = 255;
|
||||
|
||||
for (i = 1; i < 16; i++)
|
||||
{
|
||||
if (translation[translen] == Color_Index[color-1][i])
|
||||
{
|
||||
numdupes++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (translen > 0)
|
||||
{
|
||||
cutoff[translen] = cutoff[translen-1] - (256 / (16 / numdupes));
|
||||
}
|
||||
|
||||
numdupes = 1;
|
||||
translen++;
|
||||
|
||||
translation[translen] = (UINT8)Color_Index[color-1][i];
|
||||
}
|
||||
|
||||
translen++;
|
||||
}
|
||||
|
||||
while (size--)
|
||||
{
|
||||
if (skinnum == TC_BOSS)
|
||||
{
|
||||
// Turn everything below a certain threshold white
|
||||
if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue <= 82)
|
||||
if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue < 127)
|
||||
{
|
||||
// Lactozilla: Invert the colors
|
||||
cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue);
|
||||
|
@ -705,53 +738,6 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
|
|||
|
||||
cur->s.alpha = image->s.alpha;
|
||||
}
|
||||
else if (skinnum == TC_METALSONIC)
|
||||
{
|
||||
// Turn everything below a certain blue threshold white
|
||||
if (image->s.red == 0 && image->s.green == 0 && image->s.blue <= 82)
|
||||
{
|
||||
cur->s.red = cur->s.green = cur->s.blue = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur->s.red = image->s.red;
|
||||
cur->s.green = image->s.green;
|
||||
cur->s.blue = image->s.blue;
|
||||
}
|
||||
|
||||
cur->s.alpha = image->s.alpha;
|
||||
}
|
||||
else if (skinnum == TC_DASHMODE)
|
||||
{
|
||||
if (image->s.alpha == 0 && blendimage->s.alpha == 0)
|
||||
{
|
||||
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
|
||||
cur->rgba = image->rgba;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 ialpha = 255 - blendimage->s.alpha, balpha = blendimage->s.alpha;
|
||||
RGBA_t icolor = *image, bcolor;
|
||||
|
||||
memset(&bcolor, 0x00, sizeof(RGBA_t));
|
||||
|
||||
if (blendimage->s.alpha)
|
||||
{
|
||||
bcolor.s.blue = 0;
|
||||
bcolor.s.red = 255;
|
||||
bcolor.s.green = (blendimage->s.red + blendimage->s.green + blendimage->s.blue) / 3;
|
||||
}
|
||||
if (image->s.alpha && image->s.red > image->s.green << 1) // this is pretty arbitrary, but it works well for Metal Sonic
|
||||
{
|
||||
icolor.s.red = image->s.blue;
|
||||
icolor.s.blue = image->s.red;
|
||||
}
|
||||
cur->s.red = (ialpha * icolor.s.red + balpha * bcolor.s.red)/255;
|
||||
cur->s.green = (ialpha * icolor.s.green + balpha * bcolor.s.green)/255;
|
||||
cur->s.blue = (ialpha * icolor.s.blue + balpha * bcolor.s.blue)/255;
|
||||
cur->s.alpha = image->s.alpha;
|
||||
}
|
||||
}
|
||||
else if (skinnum == TC_ALLWHITE)
|
||||
{
|
||||
// Turn everything white
|
||||
|
@ -760,185 +746,268 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
|
|||
}
|
||||
else
|
||||
{
|
||||
UINT16 brightness;
|
||||
// Everything below requires a blend image
|
||||
if (blendimage == NULL)
|
||||
{
|
||||
cur->rgba = image->rgba;
|
||||
goto skippixel;
|
||||
}
|
||||
|
||||
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
|
||||
if (skinnum == TC_RAINBOW)
|
||||
// Metal Sonic dash mode
|
||||
if (skinnum == TC_DASHMODE)
|
||||
{
|
||||
if (image->s.alpha == 0 && blendimage->s.alpha == 0)
|
||||
{
|
||||
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
|
||||
cur->rgba = image->rgba;
|
||||
cur++; image++; blendimage++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT16 imagebright, blendbright;
|
||||
SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue);
|
||||
SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
|
||||
// slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway
|
||||
brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255;
|
||||
UINT8 ialpha = 255 - blendimage->s.alpha, balpha = blendimage->s.alpha;
|
||||
RGBA_t icolor = *image, bcolor;
|
||||
|
||||
memset(&bcolor, 0x00, sizeof(RGBA_t));
|
||||
|
||||
if (blendimage->s.alpha)
|
||||
{
|
||||
bcolor.s.blue = 0;
|
||||
bcolor.s.red = 255;
|
||||
bcolor.s.green = (blendimage->s.red + blendimage->s.green + blendimage->s.blue) / 3;
|
||||
}
|
||||
|
||||
if (image->s.alpha && image->s.red > image->s.green << 1) // this is pretty arbitrary, but it works well for Metal Sonic
|
||||
{
|
||||
icolor.s.red = image->s.blue;
|
||||
icolor.s.blue = image->s.red;
|
||||
}
|
||||
|
||||
cur->s.red = (ialpha * icolor.s.red + balpha * bcolor.s.red)/255;
|
||||
cur->s.green = (ialpha * icolor.s.green + balpha * bcolor.s.green)/255;
|
||||
cur->s.blue = (ialpha * icolor.s.blue + balpha * bcolor.s.blue)/255;
|
||||
cur->s.alpha = image->s.alpha;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (blendimage->s.alpha == 0)
|
||||
// All settings that use skincolors!
|
||||
UINT16 brightness;
|
||||
|
||||
if (translen <= 0)
|
||||
{
|
||||
cur->rgba = image->rgba;
|
||||
cur++; image++; blendimage++;
|
||||
continue;
|
||||
goto skippixel;
|
||||
}
|
||||
else
|
||||
{
|
||||
SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate a sort of "gradient" for the skincolor
|
||||
// (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...)
|
||||
{
|
||||
RGBA_t nextcolor;
|
||||
UINT8 firsti, secondi, mul;
|
||||
UINT32 r, g, b;
|
||||
|
||||
// Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors.
|
||||
// Ensue horrible mess.
|
||||
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
|
||||
if (skinnum == TC_RAINBOW)
|
||||
{
|
||||
UINT16 brightdif = 256;
|
||||
UINT8 colorbrightnesses[16];
|
||||
INT32 compare, m, d;
|
||||
UINT8 i;
|
||||
|
||||
// Ignore pure white & pitch black
|
||||
if (brightness > 253 || brightness < 2)
|
||||
if (image->s.alpha == 0 && blendimage->s.alpha == 0)
|
||||
{
|
||||
cur->rgba = image->rgba;
|
||||
cur++; image++; blendimage++;
|
||||
continue;
|
||||
}
|
||||
|
||||
firsti = 0;
|
||||
mul = 0;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
RGBA_t tempc = V_GetColor(translation[i]);
|
||||
SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is)
|
||||
continue;
|
||||
compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness));
|
||||
if (compare < brightdif)
|
||||
{
|
||||
brightdif = (UINT16)compare;
|
||||
firsti = i; // best matching color that's equal brightness or darker
|
||||
}
|
||||
}
|
||||
|
||||
secondi = firsti+1; // next color in line
|
||||
if (secondi == 16)
|
||||
{
|
||||
m = (INT16)brightness; // - 0;
|
||||
d = (INT16)colorbrightnesses[firsti]; // - 0;
|
||||
goto skippixel;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = (INT16)brightness - (INT16)colorbrightnesses[secondi];
|
||||
d = (INT16)colorbrightnesses[firsti] - (INT16)colorbrightnesses[secondi];
|
||||
UINT16 imagebright, blendbright;
|
||||
SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue);
|
||||
SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
|
||||
// slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway
|
||||
brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255;
|
||||
}
|
||||
|
||||
if (m >= d)
|
||||
m = d-1;
|
||||
|
||||
// calculate the "gradient" multiplier based on how close this color is to the one next in line
|
||||
if (m <= 0 || d <= 0)
|
||||
mul = 0;
|
||||
else
|
||||
mul = 15 - ((m * 16) / d);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Thankfully, it's normally way more simple.
|
||||
// Just convert brightness to a skincolor value, use remainder to find the gradient multipler
|
||||
firsti = ((UINT8)(255-brightness) / 16);
|
||||
secondi = firsti+1;
|
||||
mul = ((UINT8)(255-brightness) % 16);
|
||||
}
|
||||
|
||||
blendcolor = V_GetColor(translation[firsti]);
|
||||
|
||||
if (mul > 0 // If it's 0, then we only need the first color.
|
||||
&& translation[firsti] != translation[secondi]) // Some colors have duplicate colors in a row, so let's just save the process
|
||||
{
|
||||
if (secondi == 16) // blend to black
|
||||
nextcolor = V_GetColor(31);
|
||||
if (blendimage->s.alpha == 0)
|
||||
{
|
||||
cur->rgba = image->rgba;
|
||||
goto skippixel; // for metal sonic blend
|
||||
}
|
||||
else
|
||||
nextcolor = V_GetColor(translation[secondi]);
|
||||
|
||||
// Find difference between points
|
||||
r = (UINT32)(nextcolor.s.red - blendcolor.s.red);
|
||||
g = (UINT32)(nextcolor.s.green - blendcolor.s.green);
|
||||
b = (UINT32)(nextcolor.s.blue - blendcolor.s.blue);
|
||||
|
||||
// Find the gradient of the two points
|
||||
r = ((mul * r) / 16);
|
||||
g = ((mul * g) / 16);
|
||||
b = ((mul * b) / 16);
|
||||
|
||||
// Add gradient value to color
|
||||
blendcolor.s.red += r;
|
||||
blendcolor.s.green += g;
|
||||
blendcolor.s.blue += b;
|
||||
{
|
||||
SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (skinnum == TC_RAINBOW)
|
||||
{
|
||||
UINT32 tempcolor;
|
||||
UINT16 colorbright;
|
||||
// Calculate a sort of "gradient" for the skincolor
|
||||
// (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...)
|
||||
{
|
||||
RGBA_t nextcolor;
|
||||
UINT8 firsti, secondi, mul, mulmax;
|
||||
INT32 r, g, b;
|
||||
|
||||
SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue);
|
||||
if (colorbright == 0)
|
||||
colorbright = 1; // no dividing by 0 please
|
||||
// Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors.
|
||||
// Ensue horrible mess.
|
||||
if (skinnum == TC_RAINBOW)
|
||||
{
|
||||
UINT16 brightdif = 256;
|
||||
UINT8 colorbrightnesses[16];
|
||||
INT32 compare, m, d;
|
||||
|
||||
tempcolor = (brightness * blendcolor.s.red) / colorbright;
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.red = (UINT8)tempcolor;
|
||||
// Ignore pure white & pitch black
|
||||
if (brightness > 253 || brightness < 2)
|
||||
{
|
||||
cur->rgba = image->rgba;
|
||||
cur++; image++; blendimage++;
|
||||
continue;
|
||||
}
|
||||
|
||||
tempcolor = (brightness * blendcolor.s.green) / colorbright;
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.green = (UINT8)tempcolor;
|
||||
firsti = 0;
|
||||
mul = 0;
|
||||
mulmax = 1;
|
||||
|
||||
tempcolor = (brightness * blendcolor.s.blue) / colorbright;
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.blue = (UINT8)tempcolor;
|
||||
cur->s.alpha = image->s.alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Color strength depends on image alpha
|
||||
INT32 tempcolor;
|
||||
for (i = 0; i < translen; i++)
|
||||
{
|
||||
RGBA_t tempc = V_GetColor(translation[i]);
|
||||
SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison
|
||||
}
|
||||
|
||||
tempcolor = ((image->s.red * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.red * blendimage->s.alpha) / 255);
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.red = (UINT8)tempcolor;
|
||||
for (i = 0; i < translen; i++)
|
||||
{
|
||||
if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is)
|
||||
continue;
|
||||
|
||||
tempcolor = ((image->s.green * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.green * blendimage->s.alpha) / 255);
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.green = (UINT8)tempcolor;
|
||||
compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness));
|
||||
|
||||
tempcolor = ((image->s.blue * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.blue * blendimage->s.alpha) / 255);
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.blue = (UINT8)tempcolor;
|
||||
cur->s.alpha = image->s.alpha;
|
||||
if (compare < brightdif)
|
||||
{
|
||||
brightdif = (UINT16)compare;
|
||||
firsti = i; // best matching color that's equal brightness or darker
|
||||
}
|
||||
}
|
||||
|
||||
secondi = firsti+1; // next color in line
|
||||
if (secondi >= translen)
|
||||
{
|
||||
m = (INT16)brightness; // - 0;
|
||||
d = (INT16)colorbrightnesses[firsti]; // - 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = (INT16)brightness - (INT16)colorbrightnesses[secondi];
|
||||
d = (INT16)colorbrightnesses[firsti] - (INT16)colorbrightnesses[secondi];
|
||||
}
|
||||
|
||||
if (m >= d)
|
||||
m = d-1;
|
||||
|
||||
mulmax = 16;
|
||||
|
||||
// calculate the "gradient" multiplier based on how close this color is to the one next in line
|
||||
if (m <= 0 || d <= 0)
|
||||
mul = 0;
|
||||
else
|
||||
mul = (mulmax-1) - ((m * mulmax) / d);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just convert brightness to a skincolor value, use distance to next position to find the gradient multipler
|
||||
firsti = 0;
|
||||
|
||||
for (i = 1; i < translen; i++)
|
||||
{
|
||||
if (brightness >= cutoff[i])
|
||||
break;
|
||||
firsti = i;
|
||||
}
|
||||
|
||||
secondi = firsti+1;
|
||||
|
||||
mulmax = cutoff[firsti];
|
||||
if (secondi < translen)
|
||||
mulmax -= cutoff[secondi];
|
||||
|
||||
mul = cutoff[firsti] - brightness;
|
||||
}
|
||||
|
||||
blendcolor = V_GetColor(translation[firsti]);
|
||||
|
||||
if (mul > 0) // If it's 0, then we only need the first color.
|
||||
{
|
||||
if (secondi >= translen) // blend to black
|
||||
nextcolor = V_GetColor(31);
|
||||
else
|
||||
nextcolor = V_GetColor(translation[secondi]);
|
||||
|
||||
// Find difference between points
|
||||
r = (INT32)(nextcolor.s.red - blendcolor.s.red);
|
||||
g = (INT32)(nextcolor.s.green - blendcolor.s.green);
|
||||
b = (INT32)(nextcolor.s.blue - blendcolor.s.blue);
|
||||
|
||||
// Find the gradient of the two points
|
||||
r = ((mul * r) / mulmax);
|
||||
g = ((mul * g) / mulmax);
|
||||
b = ((mul * b) / mulmax);
|
||||
|
||||
// Add gradient value to color
|
||||
blendcolor.s.red += r;
|
||||
blendcolor.s.green += g;
|
||||
blendcolor.s.blue += b;
|
||||
}
|
||||
}
|
||||
|
||||
if (skinnum == TC_RAINBOW)
|
||||
{
|
||||
UINT32 tempcolor;
|
||||
UINT16 colorbright;
|
||||
|
||||
SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue);
|
||||
if (colorbright == 0)
|
||||
colorbright = 1; // no dividing by 0 please
|
||||
|
||||
tempcolor = (brightness * blendcolor.s.red) / colorbright;
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.red = (UINT8)tempcolor;
|
||||
|
||||
tempcolor = (brightness * blendcolor.s.green) / colorbright;
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.green = (UINT8)tempcolor;
|
||||
|
||||
tempcolor = (brightness * blendcolor.s.blue) / colorbright;
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.blue = (UINT8)tempcolor;
|
||||
cur->s.alpha = image->s.alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Color strength depends on image alpha
|
||||
INT32 tempcolor;
|
||||
|
||||
tempcolor = ((image->s.red * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.red * blendimage->s.alpha) / 255);
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.red = (UINT8)tempcolor;
|
||||
|
||||
tempcolor = ((image->s.green * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.green * blendimage->s.alpha) / 255);
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.green = (UINT8)tempcolor;
|
||||
|
||||
tempcolor = ((image->s.blue * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.blue * blendimage->s.alpha) / 255);
|
||||
tempcolor = min(255, tempcolor);
|
||||
cur->s.blue = (UINT8)tempcolor;
|
||||
cur->s.alpha = image->s.alpha;
|
||||
}
|
||||
|
||||
skippixel:
|
||||
|
||||
// *Now* we can do Metal Sonic's flashing
|
||||
if (skinnum == TC_METALSONIC)
|
||||
{
|
||||
// Blend dark blue into white
|
||||
if (cur->s.alpha > 0 && cur->s.red == 0 && cur->s.green == 0 && cur->s.blue < 255 && cur->s.blue > 31)
|
||||
{
|
||||
// Sal: Invert non-blue
|
||||
cur->s.red = cur->s.green = (255 - cur->s.blue);
|
||||
cur->s.blue = 255;
|
||||
}
|
||||
|
||||
cur->s.alpha = image->s.alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur++; image++; blendimage++;
|
||||
cur++; image++;
|
||||
|
||||
if (blendimage != NULL)
|
||||
blendimage++;
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -977,6 +1046,14 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT
|
|||
// If here, the blended texture has not been created
|
||||
// So we create it
|
||||
|
||||
if ((blendgpatch && blendgpatch->mipmap->grInfo.format)
|
||||
&& (gpatch->width != blendgpatch->width || gpatch->height != blendgpatch->height))
|
||||
{
|
||||
// Blend image exists, but it's bad.
|
||||
HWD.pfnSetTexture(gpatch->mipmap);
|
||||
return;
|
||||
}
|
||||
|
||||
//BP: WARNING: don't free it manually without clearing the cache of harware renderer
|
||||
// (it have a liste of mipmap)
|
||||
// this malloc is cleared in HWR_FreeTextureCache
|
||||
|
@ -1221,50 +1298,44 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
|
|||
|
||||
if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
|
||||
{
|
||||
if (md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format
|
||||
&& gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height)
|
||||
{
|
||||
INT32 skinnum = INT32_MAX;
|
||||
if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
|
||||
{
|
||||
if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized)
|
||||
skinnum = TC_ALLWHITE;
|
||||
else if (spr->mobj->type == MT_METALSONIC_BATTLE)
|
||||
skinnum = TC_METALSONIC;
|
||||
else
|
||||
skinnum = TC_BOSS;
|
||||
}
|
||||
else if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE)
|
||||
{
|
||||
if (spr->mobj->colorized)
|
||||
skinnum = TC_RAINBOW;
|
||||
else if (spr->mobj->player && spr->mobj->player->dashmode >= DASHMODE_THRESHOLD
|
||||
&& (spr->mobj->player->charflags & SF_DASHMODE)
|
||||
&& ((leveltime/2) & 1))
|
||||
{
|
||||
if (spr->mobj->player->charflags & SF_MACHINE)
|
||||
skinnum = TC_DASHMODE;
|
||||
else
|
||||
skinnum = TC_RAINBOW;
|
||||
}
|
||||
else if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
||||
skinnum = (INT32)((skin_t*)spr->mobj->skin-skins);
|
||||
else
|
||||
skinnum = TC_DEFAULT;
|
||||
}
|
||||
INT32 skinnum = INT32_MAX;
|
||||
|
||||
// Translation or skin number found
|
||||
if (skinnum != INT32_MAX)
|
||||
HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color);
|
||||
if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
|
||||
{
|
||||
if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized)
|
||||
skinnum = TC_ALLWHITE;
|
||||
else if (spr->mobj->type == MT_METALSONIC_BATTLE)
|
||||
skinnum = TC_METALSONIC;
|
||||
else
|
||||
skinnum = TC_BOSS;
|
||||
}
|
||||
else if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE)
|
||||
{
|
||||
if (spr->mobj->colorized)
|
||||
skinnum = TC_RAINBOW;
|
||||
else if (spr->mobj->player && spr->mobj->player->dashmode >= DASHMODE_THRESHOLD
|
||||
&& (spr->mobj->player->charflags & SF_DASHMODE)
|
||||
&& ((leveltime/2) & 1))
|
||||
{
|
||||
// Sorry nothing
|
||||
HWD.pfnSetTexture(gpatch->mipmap);
|
||||
if (spr->mobj->player->charflags & SF_MACHINE)
|
||||
skinnum = TC_DASHMODE;
|
||||
else
|
||||
skinnum = TC_RAINBOW;
|
||||
}
|
||||
else if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
||||
skinnum = (INT32)((skin_t*)spr->mobj->skin-skins);
|
||||
else
|
||||
skinnum = TC_DEFAULT;
|
||||
}
|
||||
|
||||
// Translation or skin number found
|
||||
if (skinnum != INT32_MAX)
|
||||
{
|
||||
HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is safe, since we know the texture has been downloaded
|
||||
// Sorry nothing
|
||||
HWD.pfnSetTexture(gpatch->mipmap);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2222,11 +2222,11 @@ EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration,
|
|||
EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
|
||||
{
|
||||
static boolean special_splitscreen;
|
||||
float used_fov;
|
||||
pglLoadIdentity();
|
||||
if (stransform)
|
||||
{
|
||||
boolean fovx90;
|
||||
|
||||
used_fov = stransform->fovxangle;
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
// mirroring from Kart
|
||||
if (stransform->mirror)
|
||||
|
@ -2242,32 +2242,28 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
|
|||
pglRotatef(stransform->angley+270.0f, 0.0f, 1.0f, 0.0f);
|
||||
pglTranslatef(-stransform->x, -stransform->z, -stransform->y);
|
||||
|
||||
pglMatrixMode(GL_PROJECTION);
|
||||
pglLoadIdentity();
|
||||
fovx90 = stransform->fovxangle > 0.0f && fabsf(stransform->fovxangle - 90.0f) < 0.5f;
|
||||
special_splitscreen = (stransform->splitscreen && fovx90);
|
||||
if (special_splitscreen)
|
||||
GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
|
||||
else
|
||||
GLPerspective(stransform->fovxangle, ASPECT_RATIO);
|
||||
pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
|
||||
pglMatrixMode(GL_MODELVIEW);
|
||||
special_splitscreen = stransform->splitscreen;
|
||||
}
|
||||
else
|
||||
{
|
||||
used_fov = fov;
|
||||
pglScalef(1.0f, 1.0f, -1.0f);
|
||||
|
||||
pglMatrixMode(GL_PROJECTION);
|
||||
pglLoadIdentity();
|
||||
if (special_splitscreen)
|
||||
GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
|
||||
else
|
||||
//Hurdler: is "fov" correct?
|
||||
GLPerspective(fov, ASPECT_RATIO);
|
||||
pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
|
||||
pglMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
pglMatrixMode(GL_PROJECTION);
|
||||
pglLoadIdentity();
|
||||
|
||||
if (special_splitscreen)
|
||||
{
|
||||
used_fov = atan(tan(used_fov*M_PI/360)*0.8)*360/M_PI;
|
||||
GLPerspective(used_fov, 2*ASPECT_RATIO);
|
||||
}
|
||||
else
|
||||
GLPerspective(used_fov, ASPECT_RATIO);
|
||||
|
||||
pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
|
||||
pglMatrixMode(GL_MODELVIEW);
|
||||
|
||||
pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer)
|
||||
}
|
||||
|
||||
|
|
35
src/info.c
35
src/info.c
|
@ -19760,14 +19760,14 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
|
||||
{ // MT_FLINGNIGHTSCHIP
|
||||
-1, // doomednum
|
||||
S_NIGHTSCHIP, // spawnstate
|
||||
S_NIGHTSCHIP, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
MT_FLINGNIGHTSCHIP, // reactiontime
|
||||
MT_FLINGNIGHTSCHIP, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
MT_NIGHTSCHIP, // painchance
|
||||
MT_NIGHTSCHIP, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
|
@ -19791,7 +19791,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
1000, // spawnhealth
|
||||
S_NIGHTSSTARXMAS, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
MT_FLINGNIGHTSSTAR, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
|
@ -19811,6 +19811,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_FLINGNIGHTSSTAR
|
||||
-1, // doomednum
|
||||
S_NIGHTSSTAR, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NIGHTSSTARXMAS, // seestate
|
||||
sfx_None, // seesound
|
||||
MT_FLINGNIGHTSSTAR, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
MT_NIGHTSSTAR, // painchance
|
||||
sfx_s3k33, // painsound
|
||||
S_RING, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_SPRK1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_ncitem, // deathsound
|
||||
38*FRACUNIT, // speed
|
||||
16*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SLIDEME|MF_SPECIAL, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_NIGHTSSUPERLOOP
|
||||
1707, // doomednum
|
||||
|
|
|
@ -4702,6 +4702,7 @@ typedef enum mobj_type
|
|||
MT_NIGHTSCHIP, // NiGHTS Chip
|
||||
MT_FLINGNIGHTSCHIP, // Lost NiGHTS Chip
|
||||
MT_NIGHTSSTAR, // NiGHTS Star
|
||||
MT_FLINGNIGHTSSTAR, // Lost NiGHTS Star
|
||||
MT_NIGHTSSUPERLOOP,
|
||||
MT_NIGHTSDRILLREFILL,
|
||||
MT_NIGHTSHELPER,
|
||||
|
|
|
@ -57,6 +57,7 @@ enum hook {
|
|||
hook_TeamSwitch,
|
||||
hook_ViewpointSwitch,
|
||||
hook_SeenPlayer,
|
||||
hook_PlayerThink,
|
||||
|
||||
hook_MAX // last hook
|
||||
};
|
||||
|
@ -108,5 +109,6 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean
|
|||
#ifdef SEENAMES
|
||||
boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK
|
||||
#endif
|
||||
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
|
||||
|
||||
#endif
|
||||
|
|
|
@ -68,6 +68,7 @@ const char *const hookNames[hook_MAX+1] = {
|
|||
"TeamSwitch",
|
||||
"ViewpointSwitch",
|
||||
"SeenPlayer",
|
||||
"PlayerThink",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -216,6 +217,7 @@ static int lib_addHook(lua_State *L)
|
|||
case hook_SeenPlayer:
|
||||
case hook_ShieldSpawn:
|
||||
case hook_ShieldSpecial:
|
||||
case hook_PlayerThink:
|
||||
lastp = &playerhooks;
|
||||
break;
|
||||
case hook_LinedefExecute:
|
||||
|
|
|
@ -468,11 +468,11 @@ static int libd_getSpritePatch(lua_State *L)
|
|||
|
||||
// convert WAD editor angle numbers (1-8) to internal angle numbers (0-7)
|
||||
// keep 0 the same since we'll make it default to angle 1 (which is internally 0)
|
||||
// in case somebody didn't know that angle 0 really just maps all 8 angles to the same patch
|
||||
// in case somebody didn't know that angle 0 really just maps all 8/16 angles to the same patch
|
||||
if (angle != 0)
|
||||
angle--;
|
||||
|
||||
if (angle >= 8) // out of range?
|
||||
if (angle >= ((sprframe->rotate & SRF_3DGE) ? 16 : 8)) // out of range?
|
||||
return 0;
|
||||
|
||||
// push both the patch and it's "flip" value
|
||||
|
@ -563,11 +563,11 @@ static int libd_getSprite2Patch(lua_State *L)
|
|||
|
||||
// convert WAD editor angle numbers (1-8) to internal angle numbers (0-7)
|
||||
// keep 0 the same since we'll make it default to angle 1 (which is internally 0)
|
||||
// in case somebody didn't know that angle 0 really just maps all 8 angles to the same patch
|
||||
// in case somebody didn't know that angle 0 really just maps all 8/16 angles to the same patch
|
||||
if (angle != 0)
|
||||
angle--;
|
||||
|
||||
if (angle >= 8) // out of range?
|
||||
if (angle >= ((sprframe->rotate & SRF_3DGE) ? 16 : 8)) // out of range?
|
||||
return 0;
|
||||
|
||||
// push both the patch and it's "flip" value
|
||||
|
|
|
@ -157,13 +157,21 @@ static const char *const side_opt[] = {
|
|||
enum vertex_e {
|
||||
vertex_valid = 0,
|
||||
vertex_x,
|
||||
vertex_y
|
||||
vertex_y,
|
||||
vertex_floorz,
|
||||
vertex_floorzset,
|
||||
vertex_ceilingz,
|
||||
vertex_ceilingzset
|
||||
};
|
||||
|
||||
static const char *const vertex_opt[] = {
|
||||
"valid",
|
||||
"x",
|
||||
"y",
|
||||
"floorz",
|
||||
"floorzset",
|
||||
"ceilingz",
|
||||
"ceilingzset",
|
||||
NULL};
|
||||
|
||||
enum ffloor_e {
|
||||
|
@ -968,6 +976,18 @@ static int vertex_get(lua_State *L)
|
|||
case vertex_y:
|
||||
lua_pushfixed(L, vertex->y);
|
||||
return 1;
|
||||
case vertex_floorzset:
|
||||
lua_pushboolean(L, vertex->floorzset);
|
||||
return 1;
|
||||
case vertex_ceilingzset:
|
||||
lua_pushboolean(L, vertex->ceilingzset);
|
||||
return 1;
|
||||
case vertex_floorz:
|
||||
lua_pushfixed(L, vertex->floorz);
|
||||
return 1;
|
||||
case vertex_ceilingz:
|
||||
lua_pushfixed(L, vertex->ceilingz);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
14
src/m_cond.h
14
src/m_cond.h
|
@ -97,12 +97,13 @@ typedef struct
|
|||
} emblem_t;
|
||||
typedef struct
|
||||
{
|
||||
char name[20]; ///< Name of the goal (used in the "emblem awarded" cecho)
|
||||
char description[40];///< Description of goal (used in statistics)
|
||||
UINT8 conditionset; ///< Condition set that awards this emblem.
|
||||
UINT8 sprite; ///< emblem sprite to use, 0 - 25
|
||||
UINT8 color; ///< skincolor to use
|
||||
UINT8 collected; ///< Do you have this emblem?
|
||||
char name[20]; ///< Name of the goal (used in the "emblem awarded" cecho)
|
||||
char description[40]; ///< Description of goal (used in statistics)
|
||||
UINT8 conditionset; ///< Condition set that awards this emblem.
|
||||
UINT8 showconditionset; ///< Condition set that shows this emblem.
|
||||
UINT8 sprite; ///< emblem sprite to use, 0 - 25
|
||||
UINT8 color; ///< skincolor to use
|
||||
UINT8 collected; ///< Do you have this emblem?
|
||||
} extraemblem_t;
|
||||
|
||||
// Unlockable information
|
||||
|
@ -112,6 +113,7 @@ typedef struct
|
|||
char objective[64];
|
||||
UINT16 height; // menu height
|
||||
UINT8 conditionset;
|
||||
UINT8 showconditionset;
|
||||
INT16 type;
|
||||
INT16 variable;
|
||||
UINT8 nocecho;
|
||||
|
|
59
src/m_menu.c
59
src/m_menu.c
|
@ -1397,7 +1397,7 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
|
|||
{IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32},
|
||||
|
||||
{IT_HEADER, NULL, "General", NULL, 51},
|
||||
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 63},
|
||||
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 63},
|
||||
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 73},
|
||||
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 83},
|
||||
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,93},
|
||||
|
@ -6897,6 +6897,8 @@ static void M_HandleChecklist(INT32 choice)
|
|||
continue;
|
||||
if (unlockables[j].conditionset > MAXCONDITIONSETS)
|
||||
continue;
|
||||
if (!unlockables[j].unlocked && unlockables[j].showconditionset && !M_Achieved(unlockables[j].showconditionset))
|
||||
continue;
|
||||
if (unlockables[j].conditionset == unlockables[check_on].conditionset)
|
||||
continue;
|
||||
break;
|
||||
|
@ -6920,6 +6922,8 @@ static void M_HandleChecklist(INT32 choice)
|
|||
continue;
|
||||
if (unlockables[j].conditionset > MAXCONDITIONSETS)
|
||||
continue;
|
||||
if (!unlockables[j].unlocked && unlockables[j].showconditionset && !M_Achieved(unlockables[j].showconditionset))
|
||||
continue;
|
||||
if (j && unlockables[j].conditionset == unlockables[j-1].conditionset)
|
||||
continue;
|
||||
break;
|
||||
|
@ -6957,7 +6961,8 @@ static void M_DrawChecklist(void)
|
|||
while (i < MAXUNLOCKABLES)
|
||||
{
|
||||
if (unlockables[i].name[0] == 0 //|| unlockables[i].nochecklist
|
||||
|| !unlockables[i].conditionset || unlockables[i].conditionset > MAXCONDITIONSETS)
|
||||
|| !unlockables[i].conditionset || unlockables[i].conditionset > MAXCONDITIONSETS
|
||||
|| (!unlockables[i].unlocked && unlockables[i].showconditionset && !M_Achieved(unlockables[i].showconditionset)))
|
||||
{
|
||||
i += 1;
|
||||
continue;
|
||||
|
@ -6983,10 +6988,11 @@ static void M_DrawChecklist(void)
|
|||
|
||||
if (unlockables[i].objective[0] != '/')
|
||||
{
|
||||
addy(8);
|
||||
V_DrawString(currentMenu->x, y,
|
||||
addy(16);
|
||||
V_DrawString(currentMenu->x, y-8,
|
||||
V_ALLOWLOWERCASE,
|
||||
va("\x1E %s", unlockables[i].objective));
|
||||
y -= 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7227,12 +7233,26 @@ static void M_EmblemHints(INT32 choice)
|
|||
|
||||
static void M_DrawEmblemHints(void)
|
||||
{
|
||||
INT32 i, j = 0;
|
||||
UINT32 collected = 0;
|
||||
INT32 i, j = 0, x, y;
|
||||
UINT32 collected = 0, local = 0;
|
||||
emblem_t *emblem;
|
||||
const char *hint;
|
||||
|
||||
for (i = 0; i < numemblems; i++)
|
||||
{
|
||||
emblem = &emblemlocations[i];
|
||||
if (emblem->level != gamemap || emblem->type > ET_SKIN)
|
||||
continue;
|
||||
if (++local >= NUMHINTS*2)
|
||||
break;
|
||||
}
|
||||
|
||||
x = (local > NUMHINTS ? 4 : 12);
|
||||
y = 8;
|
||||
|
||||
if (!local)
|
||||
V_DrawCenteredString(160, 48, V_YELLOWMAP, "No hidden emblems on this map.");
|
||||
else for (i = 0; i < numemblems; i++)
|
||||
{
|
||||
emblem = &emblemlocations[i];
|
||||
if (emblem->level != gamemap || emblem->type > ET_SKIN)
|
||||
|
@ -7241,27 +7261,35 @@ static void M_DrawEmblemHints(void)
|
|||
if (emblem->collected)
|
||||
{
|
||||
collected = V_GREENMAP;
|
||||
V_DrawMappedPatch(12, 12+(28*j), 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_PATCH),
|
||||
V_DrawMappedPatch(x, y+4, 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_PATCH),
|
||||
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE));
|
||||
}
|
||||
else
|
||||
{
|
||||
collected = 0;
|
||||
V_DrawScaledPatch(12, 12+(28*j), 0, W_CachePatchName("NEEDIT", PU_PATCH));
|
||||
V_DrawScaledPatch(x, y+4, 0, W_CachePatchName("NEEDIT", PU_PATCH));
|
||||
}
|
||||
|
||||
if (emblem->hint[0])
|
||||
hint = emblem->hint;
|
||||
else
|
||||
hint = M_GetText("No hints available.");
|
||||
hint = M_GetText("No hint available for this emblem.");
|
||||
hint = V_WordWrap(40, BASEVIDWIDTH-12, 0, hint);
|
||||
V_DrawString(40, 8+(28*j), V_RETURN8|V_ALLOWLOWERCASE|collected, hint);
|
||||
if (local > NUMHINTS)
|
||||
V_DrawThinString(x+28, y, V_RETURN8|V_ALLOWLOWERCASE|collected, hint);
|
||||
else
|
||||
V_DrawString(x+28, y, V_RETURN8|V_ALLOWLOWERCASE|collected, hint);
|
||||
|
||||
if (++j >= NUMHINTS)
|
||||
y += 28;
|
||||
|
||||
if (++j == NUMHINTS)
|
||||
{
|
||||
x = 4+(BASEVIDWIDTH/2);
|
||||
y = 8;
|
||||
}
|
||||
else if (j >= NUMHINTS*2)
|
||||
break;
|
||||
}
|
||||
if (!j)
|
||||
V_DrawCenteredString(160, 48, V_YELLOWMAP, "No hidden emblems on this map.");
|
||||
|
||||
M_DrawGenericMenu();
|
||||
}
|
||||
|
@ -9196,7 +9224,10 @@ static void M_DrawStatsMaps(int location)
|
|||
else
|
||||
V_DrawSmallScaledPatch(292, y, 0, W_CachePatchName("NEEDIT", PU_PATCH));
|
||||
|
||||
V_DrawString(20, y, V_YELLOWMAP|V_ALLOWLOWERCASE, va("%s", exemblem->description));
|
||||
V_DrawString(20, y, V_YELLOWMAP|V_ALLOWLOWERCASE,
|
||||
(!exemblem->collected && exemblem->showconditionset && !M_Achieved(exemblem->showconditionset))
|
||||
? M_CreateSecretMenuOption(exemblem->description)
|
||||
: exemblem->description);
|
||||
}
|
||||
|
||||
y += 8;
|
||||
|
|
|
@ -14603,12 +14603,9 @@ void A_RolloutRock(mobj_t *actor)
|
|||
if (!actor->tracer || P_MobjWasRemoved(actor->tracer) || !actor->tracer->health)
|
||||
actor->flags |= MF_PUSHABLE;
|
||||
|
||||
if (!(actor->flags & MF_PUSHABLE)) // if being ridden, don't disappear
|
||||
actor->fuse = 0;
|
||||
else if (!actor->fuse && actor->movecount == 1) // otherwise if rock has moved, set its fuse
|
||||
if (!(actor->flags & MF_PUSHABLE) || (actor->movecount != 1)) // if being ridden or haven't moved, don't disappear
|
||||
actor->fuse = actor->info->painchance;
|
||||
|
||||
if (actor->fuse && actor->fuse < 2*TICRATE)
|
||||
else if (actor->fuse < 2*TICRATE)
|
||||
actor->flags2 ^= MF2_DONTDRAW;
|
||||
|
||||
}
|
||||
|
|
|
@ -2005,7 +2005,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
|||
|
||||
if (lowfloor < tmdropoffz)
|
||||
tmdropoffz = lowfloor;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1892,7 +1892,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
#endif
|
||||
|
||||
// Pushables can break some blocks
|
||||
if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE)
|
||||
if (CheckForBustableBlocks && ((mo->flags & MF_PUSHABLE) || ((mo->info->flags & MF_PUSHABLE) && mo->fuse)))
|
||||
P_PushableCheckBustables(mo);
|
||||
|
||||
if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true)
|
||||
|
@ -3127,7 +3127,7 @@ nightsdone:
|
|||
{
|
||||
// DO THE MARIO!
|
||||
if (rover->flags & FF_SHATTERBOTTOM) // Brick block!
|
||||
EV_CrumbleChain(NULL, rover); // node->m_sector
|
||||
EV_CrumbleChain(node->m_sector, rover);
|
||||
else // Question block!
|
||||
EV_MarioBlock(rover, node->m_sector, mo);
|
||||
}
|
||||
|
@ -7977,7 +7977,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
mobj->x = mobj->extravalue1 + P_ReturnThrustX(mobj, mobj->movedir, mobj->cvmem*mobj->scale);
|
||||
mobj->y = mobj->extravalue2 + P_ReturnThrustY(mobj, mobj->movedir, mobj->cvmem*mobj->scale);
|
||||
P_SetThingPosition(mobj);
|
||||
|
||||
|
||||
if (!mobj->fuse)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
|
|
|
@ -845,6 +845,8 @@ static void P_LoadVertices(UINT8 *data)
|
|||
{
|
||||
v->x = SHORT(mv->x)<<FRACBITS;
|
||||
v->y = SHORT(mv->y)<<FRACBITS;
|
||||
v->floorzset = v->ceilingzset = false;
|
||||
v->floorz = v->ceilingz = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1104,8 +1106,8 @@ static void P_LoadSidedefs(UINT8 *data)
|
|||
if (((sd->line->flags & (ML_TWOSIDED|ML_EFFECT5)) == (ML_TWOSIDED|ML_EFFECT5))
|
||||
&& !(sd->special >= 300 && sd->special < 500)) // exempt linedef exec specials
|
||||
{
|
||||
sd->repeatcnt = (INT16)(((unsigned)textureoffset) >> 12);
|
||||
sd->textureoffset = (((unsigned)textureoffset) & 2047) << FRACBITS;
|
||||
sd->repeatcnt = (INT16)(((UINT16)textureoffset) >> 12);
|
||||
sd->textureoffset = (((UINT16)textureoffset) & 2047) << FRACBITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1119,7 +1121,6 @@ static void P_LoadSidedefs(UINT8 *data)
|
|||
// Special info stored in texture fields!
|
||||
switch (sd->special)
|
||||
{
|
||||
case 63: // Fake floor/ceiling planes
|
||||
case 606: //SoM: 4/4/2000: Just colormap transfer
|
||||
case 447: // Change colormap of tagged sectors! -- Monster Iestyn 14/06/18
|
||||
case 455: // Fade colormaps! mazmazz 9/12/2018 (:flag_us:)
|
||||
|
@ -1366,6 +1367,16 @@ static void ParseTextmapVertexParameter(UINT32 i, char *param, char *val)
|
|||
vertexes[i].x = FLOAT_TO_FIXED(atof(val));
|
||||
else if (fastcmp(param, "y"))
|
||||
vertexes[i].y = FLOAT_TO_FIXED(atof(val));
|
||||
else if (fastcmp(param, "zfloor"))
|
||||
{
|
||||
vertexes[i].floorz = FLOAT_TO_FIXED(atof(val));
|
||||
vertexes[i].floorzset = true;
|
||||
}
|
||||
else if (fastcmp(param, "zceiling"))
|
||||
{
|
||||
vertexes[i].ceilingz = FLOAT_TO_FIXED(atof(val));
|
||||
vertexes[i].ceilingzset = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val)
|
||||
|
@ -1573,6 +1584,8 @@ static void P_LoadTextmap(void)
|
|||
{
|
||||
// Defaults.
|
||||
vt->x = vt->y = INT32_MAX;
|
||||
vt->floorzset = vt->ceilingzset = false;
|
||||
vt->floorz = vt->ceilingz = 0;
|
||||
|
||||
TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter);
|
||||
|
||||
|
@ -3567,11 +3580,11 @@ boolean P_LoadLevel(boolean fromnetsave)
|
|||
return false;
|
||||
|
||||
// init gravity, tag lists,
|
||||
// anything that P_ResetDynamicSlopes/P_LoadThings needs to know
|
||||
// anything that P_SpawnSlopes/P_LoadThings needs to know
|
||||
P_InitSpecials();
|
||||
|
||||
#ifdef ESLOPE
|
||||
P_ResetDynamicSlopes(fromnetsave);
|
||||
P_SpawnSlopes(fromnetsave);
|
||||
#endif
|
||||
|
||||
P_SpawnMapThings(!fromnetsave);
|
||||
|
|
|
@ -458,8 +458,8 @@ static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// Create vertex based slopes.
|
||||
static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker)
|
||||
/// Create vertex based slopes using tagged mapthings.
|
||||
static void line_SpawnViaMapthingVertexes(const int linenum, const boolean spawnthinker)
|
||||
{
|
||||
line_t *line = lines + linenum;
|
||||
side_t *side;
|
||||
|
@ -507,6 +507,55 @@ static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker)
|
|||
side->sector->hasslope = true;
|
||||
}
|
||||
|
||||
/// Spawn textmap vertex slopes.
|
||||
static void SpawnVertexSlopes(void)
|
||||
{
|
||||
line_t *l1, *l2;
|
||||
sector_t* sc;
|
||||
vertex_t *v1, *v2, *v3;
|
||||
size_t i;
|
||||
for (i = 0, sc = sectors; i < numsectors; i++, sc++)
|
||||
{
|
||||
// The vertex slopes only work for 3-vertex sectors (and thus 3-sided sectors).
|
||||
if (sc->linecount != 3)
|
||||
continue;
|
||||
|
||||
l1 = sc->lines[0];
|
||||
l2 = sc->lines[1];
|
||||
|
||||
// Determine the vertexes.
|
||||
v1 = l1->v1;
|
||||
v2 = l1->v2;
|
||||
if ((l2->v1 != v1) && (l2->v1 != v2))
|
||||
v3 = l2->v1;
|
||||
else
|
||||
v3 = l2->v2;
|
||||
|
||||
if (v1->floorzset || v2->floorzset || v3->floorzset)
|
||||
{
|
||||
vector3_t vtx[3] = {
|
||||
{v1->x, v1->y, v1->floorzset ? v1->floorz : sc->floorheight},
|
||||
{v2->x, v2->y, v2->floorzset ? v2->floorz : sc->floorheight},
|
||||
{v3->x, v3->y, v3->floorzset ? v3->floorz : sc->floorheight}};
|
||||
pslope_t *slop = Slope_Add(0);
|
||||
sc->f_slope = slop;
|
||||
sc->hasslope = true;
|
||||
ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
|
||||
}
|
||||
|
||||
if (v1->ceilingzset || v2->ceilingzset || v3->ceilingzset)
|
||||
{
|
||||
vector3_t vtx[3] = {
|
||||
{v1->x, v1->y, v1->ceilingzset ? v1->ceilingz : sc->ceilingheight},
|
||||
{v2->x, v2->y, v2->ceilingzset ? v2->ceilingz : sc->ceilingheight},
|
||||
{v3->x, v3->y, v3->ceilingzset ? v3->ceilingz : sc->ceilingheight}};
|
||||
pslope_t *slop = Slope_Add(0);
|
||||
sc->c_slope = slop;
|
||||
sc->hasslope = true;
|
||||
ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_CopySectorSlope
|
||||
|
@ -551,12 +600,16 @@ pslope_t *P_SlopeById(UINT16 id)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// Reset slopes and read them from special lines.
|
||||
void P_ResetDynamicSlopes(const boolean fromsave) {
|
||||
/// Initializes and reads the slopes from the map data.
|
||||
void P_SpawnSlopes(const boolean fromsave) {
|
||||
size_t i;
|
||||
|
||||
slopelist = NULL;
|
||||
slopecount = 0;
|
||||
|
||||
/// Generates vertex slopes.
|
||||
SpawnVertexSlopes();
|
||||
|
||||
/// Generates line special-defined slopes.
|
||||
for (i = 0; i < numlines; i++)
|
||||
{
|
||||
|
@ -577,7 +630,7 @@ void P_ResetDynamicSlopes(const boolean fromsave) {
|
|||
case 705:
|
||||
case 714:
|
||||
case 715:
|
||||
line_SpawnViaVertexes(i, !fromsave);
|
||||
line_SpawnViaMapthingVertexes(i, !fromsave);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -23,7 +23,7 @@ extern UINT16 slopecount;
|
|||
void P_LinkSlopeThinkers (void);
|
||||
|
||||
void P_CalculateSlopeNormal(pslope_t *slope);
|
||||
void P_ResetDynamicSlopes(const boolean fromsave);
|
||||
void P_SpawnSlopes(const boolean fromsave);
|
||||
|
||||
//
|
||||
// P_CopySectorSlope
|
||||
|
|
|
@ -1887,7 +1887,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
|||
while (node)
|
||||
{
|
||||
mo = node->m_thing;
|
||||
if (mo->flags & MF_PUSHABLE)
|
||||
if ((mo->flags & MF_PUSHABLE) || ((mo->info->flags & MF_PUSHABLE) && mo->fuse))
|
||||
numpush++;
|
||||
node = node->m_thinglist_next;
|
||||
}
|
||||
|
@ -6353,7 +6353,7 @@ static void P_RunLevelLoadExecutors(void)
|
|||
}
|
||||
|
||||
/** Before things are loaded, initialises certain stuff in case they're needed
|
||||
* by P_ResetDynamicSlopes or P_LoadThings. This was split off from
|
||||
* by P_SpawnSlopes or P_LoadThings. This was split off from
|
||||
* P_SpawnSpecials, in case you couldn't tell.
|
||||
*
|
||||
* \sa P_SpawnSpecials, P_InitTagLists
|
||||
|
@ -8974,7 +8974,8 @@ void T_Pusher(pusher_t *p)
|
|||
|| thing->type == MT_EXTRALARGEBUBBLE))
|
||||
continue;
|
||||
|
||||
if (!(thing->flags & MF_PUSHABLE) && !(thing->type == MT_PLAYER
|
||||
if (!((thing->flags & MF_PUSHABLE) || ((thing->info->flags & MF_PUSHABLE) && thing->fuse))
|
||||
&& !(thing->type == MT_PLAYER
|
||||
|| thing->type == MT_SMALLBUBBLE
|
||||
|| thing->type == MT_MEDIUMBUBBLE
|
||||
|| thing->type == MT_EXTRALARGEBUBBLE
|
||||
|
|
48
src/p_user.c
48
src/p_user.c
|
@ -349,11 +349,11 @@ void P_GiveEmerald(boolean spawnObj)
|
|||
continue;
|
||||
P_SetTarget(&emmo->target, players[i].mo);
|
||||
P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
|
||||
|
||||
|
||||
// Make sure we're not being carried before our tracer is changed
|
||||
if (players[i].powers[pw_carry] != CR_NIGHTSMODE)
|
||||
players[i].powers[pw_carry] = CR_NONE;
|
||||
|
||||
|
||||
P_SetTarget(&players[i].mo->tracer, emmo);
|
||||
|
||||
if (pnum == 255)
|
||||
|
@ -8672,7 +8672,7 @@ static void P_MovePlayer(player_t *player)
|
|||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft && rendermode != render_none && cv_grfovchange.value)
|
||||
if (rendermode != render_soft && rendermode != render_none && cv_fovchange.value)
|
||||
{
|
||||
fixed_t speed;
|
||||
const fixed_t runnyspeed = 20*FRACUNIT;
|
||||
|
@ -10105,13 +10105,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
{
|
||||
dist = camdist;
|
||||
|
||||
// x1.5 dist for splitscreen
|
||||
if (splitscreen)
|
||||
{
|
||||
dist = FixedMul(dist, 3*FRACUNIT/2);
|
||||
camheight = FixedMul(camheight, 3*FRACUNIT/2);
|
||||
}
|
||||
|
||||
if (sign) // signpost camera has specific placement
|
||||
{
|
||||
camheight = mo->scale << 7;
|
||||
|
@ -10511,13 +10504,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
if (!(multiplayer || netgame) && !splitscreen)
|
||||
{
|
||||
fixed_t vx = thiscam->x, vy = thiscam->y;
|
||||
fixed_t vz = thiscam->z + thiscam->height / 2;
|
||||
if (player->awayviewtics && player->awayviewmobj != NULL && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist
|
||||
{
|
||||
vx = player->awayviewmobj->x;
|
||||
vy = player->awayviewmobj->y;
|
||||
vz = player->awayviewmobj->z + player->awayviewmobj->height / 2;
|
||||
}
|
||||
|
||||
if (P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale))
|
||||
/* check z distance too for orbital camera */
|
||||
if (P_AproxDistance(P_AproxDistance(vx - mo->x, vy - mo->y),
|
||||
vz - ( mo->z + mo->height / 2 )) < FixedMul(48*FRACUNIT, mo->scale))
|
||||
mo->flags2 |= MF2_SHADOW;
|
||||
else
|
||||
mo->flags2 &= ~MF2_SHADOW;
|
||||
|
@ -11572,7 +11569,12 @@ void P_PlayerThink(player_t *player)
|
|||
player->playerstate = PST_REBORN;
|
||||
}
|
||||
if (player->playerstate == PST_REBORN)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerThink(player);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SEENAMES
|
||||
|
@ -11673,7 +11675,12 @@ void P_PlayerThink(player_t *player)
|
|||
player->lives = 0;
|
||||
|
||||
if (player->playerstate == PST_DEAD)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerThink(player);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11792,7 +11799,9 @@ void P_PlayerThink(player_t *player)
|
|||
{
|
||||
player->mo->flags2 &= ~MF2_SHADOW;
|
||||
P_DeathThink(player);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerThink(player);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -11833,7 +11842,12 @@ void P_PlayerThink(player_t *player)
|
|||
if (player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing] && G_GametypeHasSpectators())
|
||||
{
|
||||
if (P_SpectatorJoinGame(player))
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerThink(player);
|
||||
#endif
|
||||
return; // player->mo was removed.
|
||||
}
|
||||
}
|
||||
|
||||
// Even if not NiGHTS, pull in nearby objects when walking around as John Q. Elliot.
|
||||
|
@ -11935,7 +11949,12 @@ void P_PlayerThink(player_t *player)
|
|||
}
|
||||
|
||||
if (!player->mo)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerThink(player);
|
||||
#endif
|
||||
return; // P_MovePlayer removed player->mo.
|
||||
}
|
||||
|
||||
// deez New User eXperiences.
|
||||
{
|
||||
|
@ -12367,6 +12386,11 @@ void P_PlayerThink(player_t *player)
|
|||
dashmode = 0;
|
||||
}
|
||||
#undef dashmode
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerThink(player);
|
||||
#endif
|
||||
|
||||
/*
|
||||
// Colormap verification
|
||||
{
|
||||
|
|
27
src/r_data.c
27
src/r_data.c
|
@ -2710,14 +2710,29 @@ void R_PrecacheLevel(void)
|
|||
for (j = 0; j < sprites[i].numframes; j++)
|
||||
{
|
||||
sf = &sprites[i].spriteframes[j];
|
||||
for (k = 0; k < 8; k++)
|
||||
#define cacheang(a) {\
|
||||
lump = sf->lumppat[a];\
|
||||
if (devparm)\
|
||||
spritememory += W_LumpLength(lump);\
|
||||
W_CachePatchNum(lump, PU_PATCH);\
|
||||
}
|
||||
// see R_InitSprites for more about lumppat,lumpid
|
||||
switch (sf->rotate)
|
||||
{
|
||||
// see R_InitSprites for more about lumppat,lumpid
|
||||
lump = sf->lumppat[k];
|
||||
if (devparm)
|
||||
spritememory += W_LumpLength(lump);
|
||||
W_CachePatchNum(lump, PU_PATCH);
|
||||
case SRF_SINGLE:
|
||||
cacheang(0);
|
||||
break;
|
||||
case SRF_2D:
|
||||
cacheang(2);
|
||||
cacheang(6);
|
||||
break;
|
||||
default:
|
||||
k = (sf->rotate & SRF_3DGE ? 16 : 8);
|
||||
while (k--)
|
||||
cacheang(k);
|
||||
break;
|
||||
}
|
||||
#undef cacheang
|
||||
}
|
||||
}
|
||||
free(spritepresent);
|
||||
|
|
26
src/r_defs.h
26
src/r_defs.h
|
@ -84,6 +84,8 @@ typedef struct extracolormap_s
|
|||
typedef struct
|
||||
{
|
||||
fixed_t x, y;
|
||||
boolean floorzset, ceilingzset;
|
||||
fixed_t floorz, ceilingz;
|
||||
} vertex_t;
|
||||
|
||||
// Forward of linedefs, for sectors.
|
||||
|
@ -727,8 +729,8 @@ typedef struct
|
|||
#ifdef ROTSPRITE
|
||||
typedef struct
|
||||
{
|
||||
patch_t *patch[8][ROTANGLES];
|
||||
boolean cached[8];
|
||||
patch_t *patch[16][ROTANGLES];
|
||||
UINT16 cached;
|
||||
} rotsprite_t;
|
||||
#endif/*ROTSPRITE*/
|
||||
|
||||
|
@ -736,9 +738,11 @@ typedef enum
|
|||
{
|
||||
SRF_SINGLE = 0, // 0-angle for all rotations
|
||||
SRF_3D = 1, // Angles 1-8
|
||||
SRF_LEFT = 2, // Left side uses single patch
|
||||
SRF_RIGHT = 4, // Right side uses single patch
|
||||
SRF_2D = SRF_LEFT|SRF_RIGHT, // 6
|
||||
SRF_3DGE = 2, // 3DGE, ZDoom and Doom Legacy all have 16-angle support. Why not us?
|
||||
SRF_3DMASK = SRF_3D|SRF_3DGE, // 3
|
||||
SRF_LEFT = 4, // Left side uses single patch
|
||||
SRF_RIGHT = 8, // Right side uses single patch
|
||||
SRF_2D = SRF_LEFT|SRF_RIGHT, // 12
|
||||
SRF_NONE = 0xff // Initial value
|
||||
} spriterotateflags_t; // SRF's up!
|
||||
|
||||
|
@ -764,7 +768,7 @@ typedef struct patchinfo_s patchinfo_t;
|
|||
// Sprites are patches with a special naming convention so they can be
|
||||
// recognized by R_InitSprites.
|
||||
// The base name is NNNNFx or NNNNFxFx, with x indicating the rotation,
|
||||
// x = 0, 1-8, L/R
|
||||
// x = 0, 1-8, 9+A-G, L/R
|
||||
// The sprite and frame specified by a thing_t is range checked at run time.
|
||||
// A sprite is a patch_t that is assumed to represent a three dimensional
|
||||
// object and may have multiple rotations predrawn.
|
||||
|
@ -781,12 +785,12 @@ typedef struct
|
|||
// name eight times.
|
||||
UINT8 rotate; // see spriterotateflags_t above
|
||||
|
||||
// Lump to use for view angles 0-7.
|
||||
lumpnum_t lumppat[8]; // lump number 16 : 16 wad : lump
|
||||
size_t lumpid[8]; // id in the spriteoffset, spritewidth, etc. tables
|
||||
// Lump to use for view angles 0-7/15.
|
||||
lumpnum_t lumppat[16]; // lump number 16 : 16 wad : lump
|
||||
size_t lumpid[16]; // id in the spriteoffset, spritewidth, etc. tables
|
||||
|
||||
// Flip bits (1 = flip) to use for view angles 0-7.
|
||||
UINT8 flip;
|
||||
// Flip bits (1 = flip) to use for view angles 0-7/15.
|
||||
UINT16 flip;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
rotsprite_t rotsprite;
|
||||
|
|
35
src/r_main.c
35
src/r_main.c
|
@ -59,6 +59,7 @@ INT32 centerx, centery;
|
|||
fixed_t centerxfrac, centeryfrac;
|
||||
fixed_t projection;
|
||||
fixed_t projectiony; // aspect ratio
|
||||
fixed_t fovtan; // field of view
|
||||
|
||||
// just for profiling purposes
|
||||
size_t framecount;
|
||||
|
@ -108,10 +109,12 @@ static CV_PossibleValue_t drawdist_precip_cons_t[] = {
|
|||
{1024, "1024"}, {1536, "1536"}, {2048, "2048"},
|
||||
{0, "None"}, {0, NULL}};
|
||||
|
||||
static CV_PossibleValue_t fov_cons_t[] = {{60*FRACUNIT, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card
|
||||
static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}};
|
||||
|
||||
static void Fov_OnChange(void);
|
||||
static void ChaseCam_OnChange(void);
|
||||
static void ChaseCam2_OnChange(void);
|
||||
static void FlipCam_OnChange(void);
|
||||
|
@ -141,6 +144,7 @@ consvar_t cv_drawdist = {"drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL,
|
|||
consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
//consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_fov = {"fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Okay, whoever said homremoval causes a performance hit should be shot.
|
||||
consvar_t cv_homremoval = {"homremoval", "No", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -184,6 +188,14 @@ void SplitScreen_OnChange(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
static void Fov_OnChange(void)
|
||||
{
|
||||
// Shouldn't be needed with render parity?
|
||||
//if ((netgame || multiplayer) && !cv_debug && cv_fov.value != 90*FRACUNIT)
|
||||
// CV_Set(&cv_fov, cv_fov.defaultvalue);
|
||||
|
||||
R_SetViewSize();
|
||||
}
|
||||
|
||||
static void ChaseCam_OnChange(void)
|
||||
{
|
||||
|
@ -448,8 +460,8 @@ static void R_InitTextureMapping(void)
|
|||
//
|
||||
// Calc focallength
|
||||
// so FIELDOFVIEW angles covers SCREENWIDTH.
|
||||
focallength = FixedDiv(centerxfrac,
|
||||
FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2));
|
||||
focallength = FixedDiv(projection,
|
||||
FINETANGENT(FINEANGLES/4+FIELDOFVIEW/2));
|
||||
|
||||
#ifdef ESLOPE
|
||||
focallengthf = FIXED_TO_FLOAT(focallength);
|
||||
|
@ -457,9 +469,9 @@ static void R_InitTextureMapping(void)
|
|||
|
||||
for (i = 0; i < FINEANGLES/2; i++)
|
||||
{
|
||||
if (FINETANGENT(i) > FRACUNIT*2)
|
||||
if (FINETANGENT(i) > fovtan*2)
|
||||
t = -1;
|
||||
else if (FINETANGENT(i) < -FRACUNIT*2)
|
||||
else if (FINETANGENT(i) < -fovtan*2)
|
||||
t = viewwidth+1;
|
||||
else
|
||||
{
|
||||
|
@ -563,6 +575,7 @@ void R_ExecuteSetViewSize(void)
|
|||
INT32 j;
|
||||
INT32 level;
|
||||
INT32 startmapl;
|
||||
angle_t fov;
|
||||
|
||||
setsizeneeded = false;
|
||||
|
||||
|
@ -585,9 +598,12 @@ void R_ExecuteSetViewSize(void)
|
|||
centerxfrac = centerx<<FRACBITS;
|
||||
centeryfrac = centery<<FRACBITS;
|
||||
|
||||
projection = centerxfrac;
|
||||
//projectiony = (((vid.height*centerx*BASEVIDWIDTH)/BASEVIDHEIGHT)/vid.width)<<FRACBITS;
|
||||
projectiony = centerxfrac;
|
||||
fov = FixedAngle(cv_fov.value/2) + ANGLE_90;
|
||||
fovtan = FINETANGENT(fov >> ANGLETOFINESHIFT);
|
||||
if (splitscreen == 1) // Splitscreen FOV should be adjusted to maintain expected vertical view
|
||||
fovtan = 17*fovtan/10;
|
||||
|
||||
projection = projectiony = FixedDiv(centerxfrac, fovtan);
|
||||
|
||||
R_InitViewBuffer(scaledviewwidth, viewheight);
|
||||
|
||||
|
@ -613,7 +629,7 @@ void R_ExecuteSetViewSize(void)
|
|||
for (i = 0; i < j; i++)
|
||||
{
|
||||
dy = ((i - viewheight*8)<<FRACBITS) + FRACUNIT/2;
|
||||
dy = abs(dy);
|
||||
dy = FixedMul(abs(dy), fovtan);
|
||||
yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy);
|
||||
}
|
||||
}
|
||||
|
@ -734,7 +750,7 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
|
|||
static mobj_t *viewmobj;
|
||||
|
||||
// WARNING: a should be unsigned but to add with 2048, it isn't!
|
||||
#define AIMINGTODY(a) ((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS)
|
||||
#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS, fovtan)
|
||||
|
||||
// recalc necessary stuff for mouseaiming
|
||||
// slopes are already calculated for the full possible view (which is 4*viewheight).
|
||||
|
@ -1203,6 +1219,7 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_drawdist);
|
||||
CV_RegisterVar(&cv_drawdist_nights);
|
||||
CV_RegisterVar(&cv_drawdist_precip);
|
||||
CV_RegisterVar(&cv_fov);
|
||||
|
||||
CV_RegisterVar(&cv_chasecam);
|
||||
CV_RegisterVar(&cv_chasecam2);
|
||||
|
|
|
@ -84,6 +84,7 @@ extern conscar_t cv_shadowoffs;
|
|||
#endif //#ifdef GLBADSHADOWS
|
||||
extern consvar_t cv_translucency;
|
||||
extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip;
|
||||
extern consvar_t cv_fov;
|
||||
extern consvar_t cv_skybox;
|
||||
extern consvar_t cv_tailspickup;
|
||||
|
||||
|
|
|
@ -1205,7 +1205,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
|
|||
#define ROTSPRITE_XCENTER (newwidth / 2)
|
||||
#define ROTSPRITE_YCENTER (newheight / 2)
|
||||
|
||||
if (!sprframe->rotsprite.cached[rot])
|
||||
if (!(sprframe->rotsprite.cached & (1<<rot)))
|
||||
{
|
||||
INT32 dx, dy;
|
||||
INT32 px, py;
|
||||
|
@ -1375,7 +1375,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
|
|||
}
|
||||
|
||||
// This rotation is cached now
|
||||
sprframe->rotsprite.cached[rot] = true;
|
||||
sprframe->rotsprite.cached |= (1<<rot);
|
||||
|
||||
// free image data
|
||||
Z_Free(patch);
|
||||
|
@ -1399,9 +1399,9 @@ void R_FreeSingleRotSprite(spritedef_t *spritedef)
|
|||
for (frame = 0; frame < spritedef->numframes; frame++)
|
||||
{
|
||||
spriteframe_t *sprframe = &spritedef->spriteframes[frame];
|
||||
for (rot = 0; rot < 8; rot++)
|
||||
for (rot = 0; rot < 16; rot++)
|
||||
{
|
||||
if (sprframe->rotsprite.cached[rot])
|
||||
if (sprframe->rotsprite.cached & (1<<rot))
|
||||
{
|
||||
for (ang = 0; ang < ROTANGLES; ang++)
|
||||
{
|
||||
|
@ -1432,7 +1432,7 @@ void R_FreeSingleRotSprite(spritedef_t *spritedef)
|
|||
Z_Free(rotsprite);
|
||||
}
|
||||
}
|
||||
sprframe->rotsprite.cached[rot] = false;
|
||||
sprframe->rotsprite.cached &= ~(1<<rot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
272
src/r_things.c
272
src/r_things.c
|
@ -105,24 +105,21 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
|
|||
UINT8 rotation,
|
||||
UINT8 flipped)
|
||||
{
|
||||
char cn = R_Frame2Char(frame); // for debugging
|
||||
char cn = R_Frame2Char(frame), cr = R_Rotation2Char(rotation); // for debugging
|
||||
|
||||
INT32 r, ang;
|
||||
lumpnum_t lumppat = wad;
|
||||
lumppat <<= 16;
|
||||
lumppat += lump;
|
||||
|
||||
if (frame >= 64 || !(R_ValidSpriteAngle(rotation)))
|
||||
I_Error("R_InstallSpriteLump: Bad frame characters in lump %s", W_CheckNameForNum(lumppat));
|
||||
|
||||
if (maxframe ==(size_t)-1 || frame > maxframe)
|
||||
maxframe = frame;
|
||||
|
||||
// rotsprite
|
||||
#ifdef ROTSPRITE
|
||||
for (r = 0; r < 8; r++)
|
||||
sprtemp[frame].rotsprite.cached = 0;
|
||||
for (r = 0; r < 16; r++)
|
||||
{
|
||||
sprtemp[frame].rotsprite.cached[r] = false;
|
||||
for (ang = 0; ang < ROTANGLES; ang++)
|
||||
sprtemp[frame].rotsprite.patch[r][ang] = NULL;
|
||||
}
|
||||
|
@ -133,16 +130,16 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
|
|||
// the lump should be used for all rotations
|
||||
if (sprtemp[frame].rotate == SRF_SINGLE)
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple rot = 0 lump\n", spritename, cn);
|
||||
else if (sprtemp[frame].rotate != SRF_NONE) // Let's bundle 1-8 and L/R rotations into one debug message.
|
||||
else if (sprtemp[frame].rotate != SRF_NONE) // Let's bundle 1-8/16 and L/R rotations into one debug message.
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn);
|
||||
|
||||
sprtemp[frame].rotate = SRF_SINGLE;
|
||||
for (r = 0; r < 8; r++)
|
||||
for (r = 0; r < 16; r++)
|
||||
{
|
||||
sprtemp[frame].lumppat[r] = lumppat;
|
||||
sprtemp[frame].lumpid[r] = lumpid;
|
||||
}
|
||||
sprtemp[frame].flip = flipped ? 0xFF : 0; // 11111111 in binary
|
||||
sprtemp[frame].flip = flipped ? 0xFFFF : 0; // 1111111111111111 in binary
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -151,54 +148,67 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
|
|||
UINT8 rightfactor = ((rotation == ROT_R) ? 4 : 0);
|
||||
|
||||
// the lump should be used for half of all rotations
|
||||
if (sprtemp[frame].rotate == SRF_SINGLE)
|
||||
if (sprtemp[frame].rotate == SRF_NONE)
|
||||
sprtemp[frame].rotate = SRF_SINGLE;
|
||||
else if (sprtemp[frame].rotate == SRF_SINGLE)
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has L/R rotations and a rot = 0 lump\n", spritename, cn);
|
||||
else if (sprtemp[frame].rotate == SRF_3D)
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn);
|
||||
else if (sprtemp[frame].rotate == SRF_3DGE)
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-G rotations\n", spritename, cn);
|
||||
else if ((sprtemp[frame].rotate & SRF_LEFT) && (rotation == ROT_L))
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple L rotations\n", spritename, cn);
|
||||
else if ((sprtemp[frame].rotate & SRF_RIGHT) && (rotation == ROT_R))
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple R rotations\n", spritename, cn);
|
||||
|
||||
if (sprtemp[frame].rotate == SRF_NONE)
|
||||
sprtemp[frame].rotate = SRF_SINGLE;
|
||||
|
||||
sprtemp[frame].rotate |= ((rotation == ROT_R) ? SRF_RIGHT : SRF_LEFT);
|
||||
if (sprtemp[frame].rotate == (SRF_3D|SRF_2D))
|
||||
sprtemp[frame].rotate = SRF_2D; // SRF_3D|SRF_2D being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen.
|
||||
if ((sprtemp[frame].rotate & SRF_2D) == SRF_2D)
|
||||
sprtemp[frame].rotate &= ~SRF_3DMASK; // SRF_3D|SRF_2D being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen.
|
||||
|
||||
for (r = 0; r < 4; r++) // Thanks to R_PrecacheLevel, we can't leave sprtemp[*].lumppat[*] == LUMPERROR... so we load into the front/back angle too.
|
||||
// load into every relevant angle, including the front one
|
||||
for (r = 0; r < 4; r++)
|
||||
{
|
||||
sprtemp[frame].lumppat[r + rightfactor] = lumppat;
|
||||
sprtemp[frame].lumpid[r + rightfactor] = lumpid;
|
||||
sprtemp[frame].lumppat[r + rightfactor + 8] = lumppat;
|
||||
sprtemp[frame].lumpid[r + rightfactor + 8] = lumpid;
|
||||
|
||||
}
|
||||
|
||||
if (flipped)
|
||||
sprtemp[frame].flip |= (0x0F<<rightfactor); // 00001111 or 11110000 in binary, depending on rotation being ROT_L or ROT_R
|
||||
sprtemp[frame].flip |= (0x0F0F<<rightfactor); // 0000111100001111 or 1111000011110000 in binary, depending on rotation being ROT_L or ROT_R
|
||||
else
|
||||
sprtemp[frame].flip &= ~(0x0F<<rightfactor); // ditto
|
||||
sprtemp[frame].flip &= ~(0x0F0F<<rightfactor); // ditto
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// the lump is only used for one rotation
|
||||
if (sprtemp[frame].rotate == SRF_SINGLE)
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has 1-8 rotations and a rot = 0 lump\n", spritename, cn);
|
||||
else if ((sprtemp[frame].rotate != SRF_3D) && (sprtemp[frame].rotate != SRF_NONE))
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn);
|
||||
if (sprtemp[frame].rotate == SRF_NONE)
|
||||
sprtemp[frame].rotate = SRF_SINGLE;
|
||||
else if (sprtemp[frame].rotate == SRF_SINGLE)
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has 1-8/G rotations and a rot = 0 lump\n", spritename, cn);
|
||||
else if (sprtemp[frame].rotate & SRF_2D)
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8/G rotations\n", spritename, cn);
|
||||
|
||||
// make 0 based
|
||||
rotation--;
|
||||
|
||||
if (rotation == 0 || rotation == 4) // Front or back...
|
||||
sprtemp[frame].rotate = SRF_3D; // Prevent L and R changeover
|
||||
else if (rotation > 3) // Right side
|
||||
sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover
|
||||
else // if (rotation <= 3) // Left side
|
||||
sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_RIGHT)); // Continue allowing R frame changeover
|
||||
{
|
||||
// SRF_3D|SRF_3DGE being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen.
|
||||
UINT8 threedrot = (rotation > 7) ? SRF_3DGE : (sprtemp[frame].rotate & SRF_3DMASK);
|
||||
if (!threedrot)
|
||||
threedrot = SRF_3D;
|
||||
|
||||
if (rotation == 0 || rotation == 4) // Front or back...
|
||||
sprtemp[frame].rotate = threedrot; // Prevent L and R changeover
|
||||
else if ((rotation & 7) > 3) // Right side
|
||||
sprtemp[frame].rotate = (threedrot | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover
|
||||
else // if ((rotation & 7) <= 3) // Left side
|
||||
sprtemp[frame].rotate = (threedrot | (sprtemp[frame].rotate & SRF_RIGHT)); // Continue allowing R frame changeover
|
||||
}
|
||||
|
||||
if (sprtemp[frame].lumppat[rotation] != LUMPERROR)
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %c%c has two lumps mapped to it\n", spritename, cn, '1'+rotation);
|
||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %c%c has two lumps mapped to it\n", spritename, cn, cr);
|
||||
|
||||
// lumppat & lumpid are the same for original Doom, but different
|
||||
// when using sprites in pwad : the lumppat points the new graphics
|
||||
|
@ -259,9 +269,9 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
|
|||
if (memcmp(lumpinfo[l].name,sprname,4)==0)
|
||||
{
|
||||
frame = R_Char2Frame(lumpinfo[l].name[4]);
|
||||
rotation = (UINT8)(lumpinfo[l].name[5] - '0');
|
||||
rotation = R_Char2Rotation(lumpinfo[l].name[5]);
|
||||
|
||||
if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) // Give an actual NAME error -_-...
|
||||
if (frame >= 64 || rotation == 255) // Give an actual NAME error -_-...
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l));
|
||||
continue;
|
||||
|
@ -308,7 +318,13 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
|
|||
if (lumpinfo[l].name[6])
|
||||
{
|
||||
frame = R_Char2Frame(lumpinfo[l].name[6]);
|
||||
rotation = (UINT8)(lumpinfo[l].name[7] - '0');
|
||||
rotation = R_Char2Rotation(lumpinfo[l].name[7]);
|
||||
|
||||
if (frame >= 64 || rotation == 255) // Give an actual NAME error -_-...
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l));
|
||||
continue;
|
||||
}
|
||||
R_InstallSpriteLump(wadnum, l, numspritelumps, frame, rotation, 1);
|
||||
}
|
||||
|
||||
|
@ -369,18 +385,19 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
|
|||
case SRF_2D: // both Left and Right rotations
|
||||
// we test to see whether the left and right slots are present
|
||||
if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR))
|
||||
I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations",
|
||||
I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations (L-R mode)",
|
||||
sprname, R_Frame2Char(frame));
|
||||
break;
|
||||
|
||||
default:
|
||||
// must have all 8 frames
|
||||
for (rotation = 0; rotation < 8; rotation++)
|
||||
// must have all 8/16 frames
|
||||
rotation = ((sprtemp[frame].rotate & SRF_3DGE) ? 16 : 8);
|
||||
while (rotation--)
|
||||
// we test the patch lump, or the id lump whatever
|
||||
// if it was not loaded the two are LUMPERROR
|
||||
if (sprtemp[frame].lumppat[rotation] == LUMPERROR)
|
||||
I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations",
|
||||
sprname, R_Frame2Char(frame));
|
||||
I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations (1-%c mode)",
|
||||
sprname, R_Frame2Char(frame), ((sprtemp[frame].rotate & SRF_3DGE) ? 'G' : '8'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -739,9 +756,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
|||
static void R_DrawVisSprite(vissprite_t *vis)
|
||||
{
|
||||
column_t *column;
|
||||
#ifdef RANGECHECK
|
||||
INT32 texturecolumn;
|
||||
#endif
|
||||
fixed_t frac;
|
||||
patch_t *patch = vis->patch;
|
||||
fixed_t this_scale = vis->mobj->scale;
|
||||
|
@ -889,28 +904,51 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
if (vis->x2 >= vid.width)
|
||||
vis->x2 = vid.width-1;
|
||||
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
|
||||
// Split drawing loops for paper and non-paper to reduce conditional checks per sprite
|
||||
if (vis->scalestep)
|
||||
{
|
||||
#ifdef RANGECHECK
|
||||
// Papersprite drawing loop
|
||||
|
||||
texturecolumn = frac>>FRACBITS;
|
||||
|
||||
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
||||
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||
#else
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
|
||||
#endif
|
||||
if (vis->scalestep)
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += vis->scalestep)
|
||||
{
|
||||
angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF;
|
||||
texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale;
|
||||
|
||||
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
||||
continue;
|
||||
|
||||
if (vis->xiscale < 0) // Flipped sprite
|
||||
texturecolumn = SHORT(patch->width) - 1 - texturecolumn;
|
||||
|
||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
||||
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||
|
||||
if (vis->cut & SC_VFLIP)
|
||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||
else
|
||||
R_DrawMaskedColumn(column);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-paper drawing loop
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
|
||||
{
|
||||
#ifdef RANGECHECK
|
||||
texturecolumn = frac>>FRACBITS;
|
||||
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
||||
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||
#else
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
|
||||
#endif
|
||||
if (vis->cut & SC_VFLIP)
|
||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||
else
|
||||
R_DrawMaskedColumn(column);
|
||||
}
|
||||
if (vis->cut & SC_VFLIP)
|
||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||
else
|
||||
R_DrawMaskedColumn(column);
|
||||
spryscale += vis->scalestep;
|
||||
}
|
||||
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
|
@ -1069,8 +1107,6 @@ static void R_SplitSprite(vissprite_t *sprite)
|
|||
}
|
||||
}
|
||||
|
||||
//#define PROPERPAPER // This was reverted less than 7 hours before 2.2's release because of very strange, frequent crashes.
|
||||
|
||||
//
|
||||
// R_ProjectSprite
|
||||
// Generates a vissprite for a thing
|
||||
|
@ -1094,7 +1130,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
size_t lump;
|
||||
|
||||
size_t rot;
|
||||
UINT8 flip;
|
||||
UINT16 flip;
|
||||
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP));
|
||||
|
||||
INT32 lindex;
|
||||
|
@ -1107,7 +1143,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
fixed_t iscale;
|
||||
fixed_t scalestep;
|
||||
fixed_t offset, offset2;
|
||||
|
||||
boolean papersprite = !!(thing->frame & FF_PAPERSPRITE);
|
||||
fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0;
|
||||
|
||||
INT32 dispoffset = thing->info->dispoffset;
|
||||
|
||||
|
@ -1125,10 +1163,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
INT32 rollangle = 0;
|
||||
#endif
|
||||
|
||||
#ifndef PROPERPAPER
|
||||
fixed_t ang_scale = FRACUNIT;
|
||||
#endif
|
||||
|
||||
// transform the origin point
|
||||
tr_x = thing->x - viewx;
|
||||
tr_y = thing->y - viewy;
|
||||
|
@ -1139,7 +1173,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
tz = gxt-gyt;
|
||||
|
||||
// thing is behind view plane?
|
||||
if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later
|
||||
if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later
|
||||
return;
|
||||
|
||||
gxt = -FixedMul(tr_x, viewsin);
|
||||
|
@ -1147,7 +1181,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
tx = -(gyt + gxt);
|
||||
|
||||
// too far off the side?
|
||||
if (abs(tx) > tz<<2)
|
||||
if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later
|
||||
return;
|
||||
|
||||
// aspect ratio stuff
|
||||
|
@ -1211,20 +1245,14 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
#endif
|
||||
|
||||
if (sprframe->rotate != SRF_SINGLE || papersprite)
|
||||
{
|
||||
ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle);
|
||||
#ifndef PROPERPAPER
|
||||
if (papersprite)
|
||||
ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (sprframe->rotate == SRF_SINGLE)
|
||||
{
|
||||
// use single rotation for all views
|
||||
rot = 0; //Fab: for vis->patch below
|
||||
lump = sprframe->lumpid[0]; //Fab: see note above
|
||||
flip = sprframe->flip; // Will only be 0x00 or 0xFF
|
||||
flip = sprframe->flip; // Will only be 0 or 0xFFFF
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1235,6 +1263,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
rot = 6; // F7 slot
|
||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||
rot = 2; // F3 slot
|
||||
else if (sprframe->rotate & SRF_3DGE) // 16-angle mode
|
||||
{
|
||||
rot = (ang+ANGLE_180+ANGLE_11hh)>>28;
|
||||
rot = ((rot & 1)<<3)|(rot>>1);
|
||||
}
|
||||
else // Normal behaviour
|
||||
rot = (ang+ANGLE_202h)>>29;
|
||||
|
||||
|
@ -1257,7 +1290,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (thing->rollangle)
|
||||
{
|
||||
rollangle = R_GetRollAngle(thing->rollangle);
|
||||
if (!sprframe->rotsprite.cached[rot])
|
||||
if (!(sprframe->rotsprite.cached & (1<<rot)))
|
||||
R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip);
|
||||
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
|
||||
if (rotsprite != NULL)
|
||||
|
@ -1278,31 +1311,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
else
|
||||
offset = -spr_offset;
|
||||
offset = FixedMul(offset, this_scale);
|
||||
#ifndef PROPERPAPER
|
||||
tx += FixedMul(offset, ang_scale);
|
||||
x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS;
|
||||
|
||||
// off the right side?
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
#endif
|
||||
offset2 = FixedMul(spr_width, this_scale);
|
||||
#ifndef PROPERPAPER
|
||||
tx += FixedMul(offset2, ang_scale);
|
||||
x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1);
|
||||
|
||||
// off the left side
|
||||
if (x2 < 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (papersprite)
|
||||
{
|
||||
fixed_t
|
||||
#ifdef PROPERPAPER
|
||||
xscale2,
|
||||
#endif
|
||||
yscale2, cosmul, sinmul, tz2;
|
||||
fixed_t xscale2, yscale2, cosmul, sinmul, tx2, tz2;
|
||||
INT32 range;
|
||||
|
||||
if (ang >= ANGLE_180)
|
||||
|
@ -1320,19 +1333,23 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
gyt = -FixedMul(tr_y, viewsin);
|
||||
tz = gxt-gyt;
|
||||
yscale = FixedDiv(projectiony, tz);
|
||||
if (yscale < 64) return; // Fix some funky visuals
|
||||
//if (yscale < 64) return; // Fix some funky visuals
|
||||
|
||||
#ifdef PROPERPAPER
|
||||
gxt = -FixedMul(tr_x, viewsin);
|
||||
gyt = FixedMul(tr_y, viewcos);
|
||||
tx = -(gyt + gxt);
|
||||
xscale = FixedDiv(projection, tz);
|
||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||
|
||||
// off the right side?
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
#endif
|
||||
// Get paperoffset (offset) and paperoffset (distance)
|
||||
paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul);
|
||||
paperdistance = -FixedMul(tr_x, sinmul) + FixedMul(tr_y, cosmul);
|
||||
if (paperdistance < 0)
|
||||
{
|
||||
paperoffset = -paperoffset;
|
||||
paperdistance = -paperdistance;
|
||||
}
|
||||
centerangle = viewangle - thing->angle;
|
||||
|
||||
tr_x += FixedMul(offset2, cosmul);
|
||||
tr_y += FixedMul(offset2, sinmul);
|
||||
|
@ -1340,38 +1357,52 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
gyt = -FixedMul(tr_y, viewsin);
|
||||
tz2 = gxt-gyt;
|
||||
yscale2 = FixedDiv(projectiony, tz2);
|
||||
if (yscale2 < 64) return; // ditto
|
||||
//if (yscale2 < 64) return; // ditto
|
||||
|
||||
#ifdef PROPERPAPER
|
||||
gxt = -FixedMul(tr_x, viewsin);
|
||||
gyt = FixedMul(tr_y, viewcos);
|
||||
tx = -(gyt + gxt);
|
||||
tx2 = -(gyt + gxt);
|
||||
xscale2 = FixedDiv(projection, tz2);
|
||||
x2 = (centerxfrac + FixedMul(tx,xscale2))>>FRACBITS; x2--;
|
||||
x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS);
|
||||
|
||||
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
|
||||
return;
|
||||
|
||||
// Needs partially clipped
|
||||
if (tz < FixedMul(MINZ, this_scale))
|
||||
{
|
||||
fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz);
|
||||
tx += FixedDiv(tx2-tx, div);
|
||||
tz = FixedMul(MINZ, this_scale);
|
||||
yscale = FixedDiv(projectiony, tz);
|
||||
xscale = FixedDiv(projection, tz);
|
||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||
}
|
||||
else if (tz2 < FixedMul(MINZ, this_scale))
|
||||
{
|
||||
fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2);
|
||||
tx2 += FixedDiv(tx-tx2, div);
|
||||
tz2 = FixedMul(MINZ, this_scale);
|
||||
yscale2 = FixedDiv(projectiony, tz2);
|
||||
xscale2 = FixedDiv(projection, tz2);
|
||||
x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS;
|
||||
}
|
||||
|
||||
// off the right side?
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
|
||||
// off the left side
|
||||
if (x2 < 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
|
||||
return;
|
||||
|
||||
if ((range = x2 - x1) <= 0)
|
||||
return;
|
||||
|
||||
#ifdef PROPERPAPER
|
||||
range++; // fencepost problem
|
||||
#endif
|
||||
|
||||
scalestep = (yscale2 - yscale)/range;
|
||||
xscale =
|
||||
#ifdef PROPERPAPER
|
||||
FixedDiv(range<<FRACBITS, abs(offset2))+1
|
||||
#else
|
||||
FixedMul(xscale, ang_scale)
|
||||
#endif
|
||||
;
|
||||
scalestep = ((yscale2 - yscale)/range) ?: 1;
|
||||
xscale = FixedDiv(range<<FRACBITS, abs(offset2));
|
||||
|
||||
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
|
||||
// sortscale = max(yscale, yscale2);
|
||||
|
@ -1381,7 +1412,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
{
|
||||
scalestep = 0;
|
||||
yscale = sortscale;
|
||||
#ifdef PROPERPAPER
|
||||
tx += offset;
|
||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||
|
||||
|
@ -1395,7 +1425,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
// off the left side
|
||||
if (x2 < 0)
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
|
||||
|
@ -1516,6 +1545,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->pzt = vis->pz + vis->thingheight;
|
||||
vis->texturemid = vis->gzt - viewz;
|
||||
vis->scalestep = scalestep;
|
||||
vis->paperoffset = paperoffset;
|
||||
vis->paperdistance = paperdistance;
|
||||
vis->centerangle = centerangle;
|
||||
|
||||
vis->mobj = thing; // Easy access! Tails 06-07-2002
|
||||
|
||||
|
|
|
@ -20,10 +20,6 @@
|
|||
#include "r_portal.h"
|
||||
#include "r_defs.h"
|
||||
|
||||
// "Left" and "Right" character symbols for additional rotation functionality
|
||||
#define ROT_L ('L' - '0')
|
||||
#define ROT_R ('R' - '0')
|
||||
|
||||
// number of sprite lumps for spritewidth,offset,topoffset lookup tables
|
||||
// Fab: this is a hack : should allocate the lookup tables per sprite
|
||||
#define MAXVISSPRITES 2048 // added 2-2-98 was 128
|
||||
|
@ -181,8 +177,11 @@ typedef struct vissprite_s
|
|||
fixed_t startfrac; // horizontal position of x1
|
||||
fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW
|
||||
fixed_t scalestep; // only for paper sprites, 0 otherwise
|
||||
fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle
|
||||
fixed_t xiscale; // negative if flipped
|
||||
|
||||
angle_t centerangle; // for paper sprites
|
||||
|
||||
fixed_t texturemid;
|
||||
patch_t *patch;
|
||||
|
||||
|
@ -270,7 +269,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn)
|
|||
if (cn == '+') return '\\' - 'A'; // PK3 can't use backslash, so use + instead
|
||||
return cn - 'A';
|
||||
#else
|
||||
if (cn >= 'A' && cn <= 'Z') return cn - 'A';
|
||||
if (cn >= 'A' && cn <= 'Z') return (cn - 'A');
|
||||
if (cn >= '0' && cn <= '9') return (cn - '0') + 26;
|
||||
if (cn >= 'a' && cn <= 'z') return (cn - 'a') + 36;
|
||||
if (cn == '!') return 62;
|
||||
|
@ -279,9 +278,26 @@ FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn)
|
|||
#endif
|
||||
}
|
||||
|
||||
FUNCMATH FUNCINLINE static ATTRINLINE boolean R_ValidSpriteAngle(UINT8 rotation)
|
||||
// "Left" and "Right" character symbols for additional rotation functionality
|
||||
#define ROT_L 17
|
||||
#define ROT_R 18
|
||||
|
||||
FUNCMATH FUNCINLINE static ATTRINLINE char R_Rotation2Char(UINT8 rot)
|
||||
{
|
||||
return ((rotation <= 8) || (rotation == ROT_L) || (rotation == ROT_R));
|
||||
if (rot <= 9) return '0' + rot;
|
||||
if (rot <= 16) return 'A' + (rot - 10);
|
||||
if (rot == ROT_L) return 'L';
|
||||
if (rot == ROT_R) return 'R';
|
||||
return '\xFF';
|
||||
}
|
||||
|
||||
FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Rotation(char cn)
|
||||
{
|
||||
if (cn >= '0' && cn <= '9') return (cn - '0');
|
||||
if (cn >= 'A' && cn <= 'G') return (cn - 'A') + 10;
|
||||
if (cn == 'L') return ROT_L;
|
||||
if (cn == 'R') return ROT_R;
|
||||
return 255;
|
||||
}
|
||||
|
||||
#endif //__R_THINGS__
|
||||
|
|
|
@ -2208,7 +2208,7 @@ static void ST_drawTextHUD(void)
|
|||
|
||||
#define textHUDdraw(str) \
|
||||
{\
|
||||
V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, str);\
|
||||
V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOTOP, str);\
|
||||
y += 8;\
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue