This commit is contained in:
Jaime Passos 2019-08-18 14:16:48 -03:00
parent 37dd048f12
commit f68652aa66
23 changed files with 841 additions and 47 deletions

View file

@ -2319,6 +2319,11 @@ static actionpointer_t actionpointers[] =
{{A_SpawnObjectRelative}, "A_SPAWNOBJECTRELATIVE"},
{{A_ChangeAngleRelative}, "A_CHANGEANGLERELATIVE"},
{{A_ChangeAngleAbsolute}, "A_CHANGEANGLEABSOLUTE"},
#ifdef ROTSPRITE
{{A_RollAngle}, "A_ROLLANGLE"},
{{A_ChangeRollAngleRelative},"A_CHANGEROLLANGLERELATIVE"},
{{A_ChangeRollAngleAbsolute},"A_CHANGEROLLANGLEABSOLUTE"},
#endif
{{A_PlaySound}, "A_PLAYSOUND"},
{{A_FindTarget}, "A_FINDTARGET"},
{{A_FindTracer}, "A_FINDTRACER"},

View file

@ -489,6 +489,8 @@ extern INT32 cv_debug;
// Misc stuff for later...
// =======================
#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180)
// Modifier key variables, accessible anywhere
extern UINT8 shiftdown, ctrldown, altdown;
extern boolean capslock;
@ -616,4 +618,9 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// SRB2CB itself ported this from PrBoom+
#define NEWCLIP
/// Sprite rotation
#define ROTSPRITE
#define ROTANGLES 24 // Needs to be a divisor of 360 (45, 60, 90, 120...)
#define ROTANGDIFF (360 / ROTANGLES)
#endif // __DOOMDEF__

View file

@ -933,10 +933,14 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch)
{
if (!grmip->downloaded && !grmip->grInfo.data)
{
patch_t *patch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
patch_t *patch = gpatch->rawpatch;
if (!patch)
patch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
HWR_MakePatch(patch, gpatch, grmip, true);
Z_Free(patch);
// You can't free rawpatch for some reason?
if (!gpatch->rawpatch)
Z_Free(patch);
}
HWD.pfnSetTexture(grmip);
@ -955,12 +959,16 @@ void HWR_GetPatch(GLPatch_t *gpatch)
{
// load the software patch, PU_STATIC or the Z_Malloc for hardware patch will
// flush the software patch before the conversion! oh yeah I suffered
patch_t *ptr = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
patch_t *ptr = gpatch->rawpatch;
if (!ptr)
ptr = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
HWR_MakePatch(ptr, gpatch, &gpatch->mipmap, true);
// this is inefficient.. but the hardware patch in heap is purgeable so it should
// not fragment memory, and besides the REAL cache here is the hardware memory
Z_Free(ptr);
// You can't free rawpatch for some reason?
if (!gpatch->rawpatch)
Z_Free(ptr);
}
HWD.pfnSetTexture(&gpatch->mipmap);
@ -1207,6 +1215,22 @@ GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum)
return HWR_GetCachedGLPatchPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum));
}
#ifdef ROTSPRITE
GLPatch_t *HWR_GetCachedGLRotSprite(aatree_t *hwrcache, UINT16 rollangle, patch_t *rawpatch)
{
GLPatch_t *grpatch;
if (!(grpatch = M_AATreeGet(hwrcache, rollangle)))
{
grpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL);
grpatch->rawpatch = rawpatch;
M_AATreeSet(hwrcache, rollangle, grpatch);
}
return grpatch;
}
#endif
// Need to do this because they aren't powers of 2
static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 pblockheight,
lumpnum_t fademasklumpnum, UINT16 fmwidth, UINT16 fmheight)

View file

@ -83,6 +83,7 @@ struct GLPatch_s
float max_s,max_t;
UINT16 wadnum; // the software patch lump num for when the hardware patch
UINT16 lumpnum; // was flushed, and we need to re-create it
void *rawpatch; // :^)
GLMipmap_t mipmap;
};
typedef struct GLPatch_s GLPatch_t;

View file

@ -103,6 +103,11 @@ typedef struct
FLOAT fovxangle, fovyangle;
INT32 splitscreen;
boolean flip; // screenflip
#ifdef ROTSPRITE
// rotsprite
boolean roll;
FLOAT centerx,centery;
#endif
} FTransform;
// Transformed vector, as passed to HWR API

View file

@ -72,7 +72,8 @@ typedef struct gr_vissprite_s
struct gr_vissprite_s *next;
float x1, x2;
float tz, ty;
lumpnum_t patchlumpnum;
//lumpnum_t patchlumpnum;
GLPatch_t *gpatch;
boolean flip;
UINT8 translucency; //alpha level 0-255
mobj_t *mobj;
@ -109,6 +110,9 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum);
void HWR_SetPalette(RGBA_t *palette);
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump);
GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum);
#ifdef ROTSPRITE
GLPatch_t *HWR_GetCachedGLRotSprite(aatree_t *hwrcache, UINT16 rollangle, patch_t *rawpatch);
#endif
void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
// --------

View file

@ -4332,7 +4332,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
if (hires)
this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)spr->mobj->skin)->highresscale);
gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
// cache the patch in the graphics card memory
//12/12/99: Hurdler: same comment as above (for md2)
@ -4688,7 +4688,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
// sure to do it the right way. So actually, we keep normal sprite
// in memory and we add the md2 model if it exists for that sprite
gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
#ifdef ALAM_LIGHTING
if (!(spr->mobj->flags2 & MF2_DEBRIS) && (spr->mobj->sprite != SPR_PLAY ||
@ -4833,7 +4833,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
return;
// cache sprite graphics
gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
// create the sprite billboard
//
@ -5477,10 +5477,22 @@ static void HWR_ProjectSprite(mobj_t *thing)
angle_t mobjangle = (thing->player ? thing->player->drawangle : thing->angle);
float z1, z2;
fixed_t spr_width, spr_height;
fixed_t spr_offset, spr_topoffset;
#ifdef ROTSPRITE
patch_t *rotsprite = NULL;
angle_t arollangle;
UINT32 rollangle;
#endif
if (!thing)
return;
else
this_scale = FIXED_TO_FLOAT(thing->scale);
#ifdef ROTSPRITE
arollangle = thing->rollangle;
rollangle = AngleFixed(arollangle)>>FRACBITS;
#endif
this_scale = FIXED_TO_FLOAT(thing->scale);
// transform the origin point
tr_x = FIXED_TO_FLOAT(thing->x) - gr_viewx;
@ -5573,6 +5585,30 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale);
spr_width = spritecachedinfo[lumpoff].width;
spr_height = spritecachedinfo[lumpoff].height;
spr_offset = spritecachedinfo[lumpoff].offset;
spr_topoffset = spritecachedinfo[lumpoff].topoffset;
#ifdef ROTSPRITE
if (rollangle > 0)
{
if (!sprframe->rotsprite.cached[rot])
R_CacheRotSprite(sprframe, rot, flip);
rollangle /= ROTANGDIFF;
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
if (rotsprite != NULL)
{
spr_width = rotsprite->width << FRACBITS;
spr_height = rotsprite->height << FRACBITS;
spr_offset = rotsprite->leftoffset << FRACBITS;
spr_topoffset = rotsprite->topoffset << FRACBITS;
// flip -> rotate, not rotate -> flip
flip = 0;
}
}
#endif
if (papersprite)
{
rightsin = FIXED_TO_FLOAT(FINESINE((mobjangle)>>ANGLETOFINESHIFT));
@ -5586,13 +5622,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (flip)
{
x1 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale);
x2 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale);
x1 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_scale);
x2 = (FIXED_TO_FLOAT(spr_offset) * this_scale);
}
else
{
x1 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale);
x2 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale);
x1 = (FIXED_TO_FLOAT(spr_offset) * this_scale);
x2 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_scale);
}
// test if too close
@ -5614,13 +5650,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (vflip)
{
gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale;
gzt = gz + FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height) * this_scale;
gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spr_topoffset) * this_scale;
gzt = gz + FIXED_TO_FLOAT(spr_height) * this_scale;
}
else
{
gzt = FIXED_TO_FLOAT(thing->z) + FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale;
gz = gzt - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height) * this_scale;
gzt = FIXED_TO_FLOAT(thing->z) + FIXED_TO_FLOAT(spr_topoffset) * this_scale;
gz = gzt - FIXED_TO_FLOAT(spr_height) * this_scale;
}
if (thing->subsector->sector->cullheight)
@ -5653,7 +5689,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->x2 = x2;
vis->tz = tz; // Keep tz for the simple sprite sorting that happens
vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
vis->patchlumpnum = sprframe->lumppat[rot];
//vis->patchlumpnum = sprframe->lumppat[rot];
#ifdef ROTSPRITE
if (rotsprite)
vis->gpatch = (GLPatch_t *)rotsprite;
else
#endif
vis->gpatch = (GLPatch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
vis->flip = flip;
vis->mobj = thing;
vis->z1 = z1;
@ -5779,7 +5821,8 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->z2 = z2;
vis->tz = tz;
vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
vis->patchlumpnum = sprframe->lumppat[rot];
//vis->patchlumpnum = sprframe->lumppat[rot];
vis->gpatch = (GLPatch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
vis->flip = flip;
vis->mobj = (mobj_t *)thing;

View file

@ -1401,7 +1401,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
else
{
// Sprite
gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
HWR_GetMappedPatch(gpatch, spr->colormap);
}
@ -1503,7 +1503,22 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
const fixed_t anglef = AngleFixed((R_PointToAngle(spr->mobj->x, spr->mobj->y))-ANGLE_180);
p.angley = FIXED_TO_FLOAT(anglef);
}
p.anglex = 0.0f;
// rotsprite
#ifdef ROTSPRITE
if (spr->mobj->rollangle)
{
// do i have to support ROTANGLES here??????
fixed_t anglef = AngleFixed(spr->mobj->rollangle);
p.anglex = FIXED_TO_FLOAT(anglef);
// pivot
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2);
p.centery = FIXED_TO_FLOAT(spr->mobj->height/2);
p.roll = true;
}
else
#endif
p.anglex = 0.0f;
color[0] = Surf.FlatColor.s.red;
color[1] = Surf.FlatColor.s.green;

View file

@ -1636,7 +1636,18 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
if (flipped)
scaley = -scaley;
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f);
#ifdef ROTSPRITE
// rotsprite
if (pos->roll)
{
pglTranslatef(pos->centerx, pos->centery, 0);
pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f);
pglTranslatef(-pos->centerx, -pos->centery, 0);
}
else
#endif
pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f);
val = *gl_cmd_buffer++;

View file

@ -2408,7 +2408,11 @@ state_t states[NUMSTATES] =
{SPR_BARX, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL5}, // S_TNTBARREL_EXPL4
{SPR_BARX, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL6}, // S_TNTBARREL_EXPL5
{SPR_NULL, 0, 35, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_EXPL6
#ifndef ROTSPRITE
{SPR_BARR, 1|FF_ANIMATE, -1, {NULL}, 7, 2, S_NULL}, // S_TNTBARREL_FLYING
#else
{SPR_BARR, 1, 1, {A_RollAngle}, 14, 0, S_TNTBARREL_FLYING}, // S_TNTBARREL_FLYING
#endif
// TNT proximity shell
{SPR_REMT, 0, 10, {A_Look}, 33554433, 0, S_PROXIMITY_TNT}, // S_PROXIMITY_TNT

View file

@ -153,6 +153,11 @@ void A_SpawnObjectAbsolute();
void A_SpawnObjectRelative();
void A_ChangeAngleRelative();
void A_ChangeAngleAbsolute();
#ifdef ROTSPRITE
void A_RollAngle();
void A_ChangeRollAngleRelative();
void A_ChangeRollAngleAbsolute();
#endif
void A_PlaySound();
void A_FindTarget();
void A_FindTracer();

View file

@ -32,6 +32,9 @@ enum mobj_e {
mobj_snext,
mobj_sprev,
mobj_angle,
#ifdef ROTSPRITE
mobj_rollangle,
#endif
mobj_sprite,
mobj_frame,
mobj_sprite2,
@ -98,6 +101,9 @@ static const char *const mobj_opt[] = {
"snext",
"sprev",
"angle",
#ifdef ROTSPRITE
"rollangle",
#endif
"sprite",
"frame",
"sprite2",
@ -197,6 +203,11 @@ static int mobj_get(lua_State *L)
case mobj_angle:
lua_pushangle(L, mo->angle);
break;
#ifdef ROTSPRITE
case mobj_rollangle:
lua_pushangle(L, mo->rollangle);
break;
#endif
case mobj_sprite:
lua_pushinteger(L, mo->sprite);
break;
@ -447,6 +458,11 @@ static int mobj_set(lua_State *L)
else if (mo->player == &players[secondarydisplayplayer])
localangle2 = mo->angle;
break;
#ifdef ROTSPRITE
case mobj_rollangle:
mo->rollangle = luaL_checkangle(L, 3);
break;
#endif
case mobj_sprite:
mo->sprite = luaL_checkinteger(L, 3);
break;

View file

@ -179,6 +179,11 @@ void A_SpawnObjectAbsolute(mobj_t *actor);
void A_SpawnObjectRelative(mobj_t *actor);
void A_ChangeAngleRelative(mobj_t *actor);
void A_ChangeAngleAbsolute(mobj_t *actor);
#ifdef ROTSPRITE
void A_RollAngle(mobj_t *actor);
void A_ChangeRollAngleRelative(mobj_t *actor);
void A_ChangeRollAngleAbsolute(mobj_t *actor);
#endif // ROTSPRITE
void A_PlaySound(mobj_t *actor);
void A_FindTarget(mobj_t *actor);
void A_FindTracer(mobj_t *actor);
@ -8172,7 +8177,7 @@ void A_ChangeAngleRelative(mobj_t *actor)
#ifdef PARANOIA
if (amin > amax)
I_Error("A_ChangeAngleRelative: var1 is greater then var2");
I_Error("A_ChangeAngleRelative: var1 is greater than var2");
#endif
/*
if (angle < amin)
@ -8206,7 +8211,7 @@ void A_ChangeAngleAbsolute(mobj_t *actor)
#ifdef PARANOIA
if (amin > amax)
I_Error("A_ChangeAngleAbsolute: var1 is greater then var2");
I_Error("A_ChangeAngleAbsolute: var1 is greater than var2");
#endif
/*
if (angle < amin)
@ -8217,6 +8222,105 @@ void A_ChangeAngleAbsolute(mobj_t *actor)
actor->angle = FixedAngle(P_RandomRange(amin, amax));
}
#ifdef ROTSPRITE
// Function: A_RollAngle
//
// Description: Changes the roll angle.
//
// var1 = angle
// var2 = relative? (default)
//
void A_RollAngle(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
const angle_t angle = FixedAngle(locvar1*FRACUNIT);
#ifdef HAVE_BLUA
if (LUA_CallAction("A_RollAngle", actor))
return;
#endif
// relative (default)
if (!locvar2)
actor->rollangle += angle;
// absolute
else
actor->rollangle = angle;
}
// Function: A_ChangeRollAngleRelative
//
// Description: Changes the roll angle to a random relative value between the min and max. Set min and max to the same value to eliminate randomness
//
// var1 = min
// var2 = max
//
void A_ChangeRollAngleRelative(mobj_t *actor)
{
// Oh god, the old code /sucked/. Changed this and the absolute version to get a random range using amin and amax instead of
// getting a random angle from the _entire_ spectrum and then clipping. While we're at it, do the angle conversion to the result
// rather than the ranges, so <0 and >360 work as possible values. -Red
INT32 locvar1 = var1;
INT32 locvar2 = var2;
//angle_t angle = (P_RandomByte()+1)<<24;
const fixed_t amin = locvar1*FRACUNIT;
const fixed_t amax = locvar2*FRACUNIT;
//const angle_t amin = FixedAngle(locvar1*FRACUNIT);
//const angle_t amax = FixedAngle(locvar2*FRACUNIT);
#ifdef HAVE_BLUA
if (LUA_CallAction("A_ChangeRollAngleRelative", actor))
return;
#endif
#ifdef PARANOIA
if (amin > amax)
I_Error("A_ChangeRollAngleRelative: var1 is greater than var2");
#endif
/*
if (angle < amin)
angle = amin;
if (angle > amax)
angle = amax;*/
actor->rollangle += FixedAngle(P_RandomRange(amin, amax));
}
// Function: A_ChangeRollAngleAbsolute
//
// Description: Changes the roll angle to a random absolute value between the min and max. Set min and max to the same value to eliminate randomness
//
// var1 = min
// var2 = max
//
void A_ChangeRollAngleAbsolute(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
//angle_t angle = (P_RandomByte()+1)<<24;
const fixed_t amin = locvar1*FRACUNIT;
const fixed_t amax = locvar2*FRACUNIT;
//const angle_t amin = FixedAngle(locvar1*FRACUNIT);
//const angle_t amax = FixedAngle(locvar2*FRACUNIT);
#ifdef HAVE_BLUA
if (LUA_CallAction("A_ChangeRollAngleAbsolute", actor))
return;
#endif
#ifdef PARANOIA
if (amin > amax)
I_Error("A_ChangeRollAngleAbsolute: var1 is greater than var2");
#endif
/*
if (angle < amin)
angle = amin;
if (angle > amax)
angle = amax;*/
actor->rollangle = FixedAngle(P_RandomRange(amin, amax));
}
#endif // ROTSPRITE
// Function: A_PlaySound
//
// Description: Plays a sound

View file

@ -277,6 +277,9 @@ typedef struct mobj_s
// More drawing info: to determine current sprite.
angle_t angle; // orientation
#ifdef ROTSPRITE
angle_t rollangle;
#endif
spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT8 sprite2; // player sprites
@ -397,6 +400,9 @@ typedef struct precipmobj_s
// More drawing info: to determine current sprite.
angle_t angle; // orientation
#ifdef ROTSPRITE
angle_t rollangle;
#endif
spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT8 sprite2; // player sprites

View file

@ -1267,6 +1267,9 @@ typedef enum
MD2_SLOPE = 1<<11,
#endif
MD2_COLORIZED = 1<<12,
#ifdef ROTSPRITE
MD2_ROLLANGLE = 1<<13,
#endif
} mobj_diff2_t;
typedef enum
@ -1486,6 +1489,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
#endif
if (mobj->colorized)
diff2 |= MD2_COLORIZED;
#ifdef ROTSPRITE
if (mobj->rollangle)
diff2 |= MD2_ROLLANGLE;
#endif
if (diff2 != 0)
diff |= MD_MORE;
@ -1650,6 +1657,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
#endif
if (diff2 & MD2_COLORIZED)
WRITEUINT8(save_p, mobj->colorized);
#ifdef ROTSPRITE
if (diff2 & MD2_ROLLANGLE)
WRITEANGLE(save_p, mobj->rollangle);
#endif
WRITEUINT32(save_p, mobj->mobjnum);
}
@ -2726,6 +2737,12 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
#endif
if (diff2 & MD2_COLORIZED)
mobj->colorized = READUINT8(save_p);
#ifdef ROTSPRITE
if (diff2 & MD2_ROLLANGLE)
mobj->rollangle = READANGLE(save_p);
else
mobj->rollangle = 0;
#endif
if (diff & MD_REDFLAG)
{

View file

@ -540,9 +540,10 @@ levelflat_t *levelflats;
size_t P_PrecacheLevelFlats(void)
{
lumpnum_t lump;
size_t i, flatmemory = 0;
size_t i;
//SoM: 4/18/2000: New flat code to make use of levelflats.
flatmemory = 0;
for (i = 0; i < numlevelflats; i++)
{
lump = levelflats[i].lumpnum;

View file

@ -6706,6 +6706,11 @@ static void P_NiGHTSMovement(player_t *player)
INT32 i;
statenum_t flystate;
UINT16 visangle;
#ifdef ROTSPRITE
angle_t rollangle = 0;
UINT8 turningstate = 0;
UINT8 turndiff = 24;
#endif
player->pflags &= ~PF_DRILLING;
@ -6890,6 +6895,9 @@ static void P_NiGHTSMovement(player_t *player)
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6])
{
player->mo->momx = player->mo->momy = player->mo->momz = 0;
#ifdef ROTSPRITE
player->mo->rollangle = 0;
#endif
return;
}
@ -6904,6 +6912,9 @@ static void P_NiGHTSMovement(player_t *player)
P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_DRILL6);
player->mo->flags |= MF_NOCLIPHEIGHT;
#ifdef ROTSPRITE
player->mo->rollangle = 0;
#endif
return;
}
@ -7176,6 +7187,7 @@ static void P_NiGHTSMovement(player_t *player)
flystate = (P_IsObjectOnGround(player->mo)) ? S_PLAY_NIGHTS_STAND : S_PLAY_NIGHTS_FLOAT;
else
{
#ifndef ROTSPRITE
visangle = ((player->anotherflyangle + 7) % 360)/15;
if (visangle > 18) // Over 270 degrees.
visangle = 30 - visangle;
@ -7192,15 +7204,55 @@ static void P_NiGHTSMovement(player_t *player)
visangle += 6; // shift to S_PLAY_NIGHTS_FLY7-C
}
flystate = S_PLAY_NIGHTS_FLY0 + (visangle*2); // S_PLAY_FLY0-C - the *2 is to skip over drill states
flystate = S_PLAY_NIGHTS_FLY0 + (visangle*2); // S_PLAY_NIGHTS_FLY0-C - the *2 is to skip over drill states
if (player->pflags & PF_DRILLING)
flystate++; // shift to S_PLAY_NIGHTS_DRILL0-C
#else
angle_t a = R_PointToAngle(player->mo->x, player->mo->y) - player->mo->angle;
visangle = (player->flyangle % 360);
flystate = S_PLAY_NIGHTS_FLY0;
if (player->pflags & PF_DRILLING)
flystate++; // shift to S_PLAY_NIGHTS_DRILL0-C
else
{
if ((visangle >= (90-turndiff) && visangle <= (90+turndiff))
|| (visangle >= (270-turndiff) && visangle <= (270+turndiff)))
{
turningstate = 3;
flystate = S_PLAY_NIGHTS_DRILL0;
}
}
if (player->flyangle >= 90 && player->flyangle <= 270)
{
if (player->flyangle == 270 && (a < ANGLE_180))
;
else if (player->flyangle == 90 && (a < ANGLE_180))
;
else
visangle += 180;
}
rollangle = FixedAngle(visangle*FRACUNIT);
#endif // ROTSPRITE
}
if (player->mo->state != &states[flystate])
P_SetPlayerMobjState(player->mo, flystate);
#ifdef ROTSPRITE
player->mo->rollangle = rollangle;
if (turningstate)
{
player->mo->frame = turningstate;
player->mo->tics = -1;
}
else if (player->mo->tics == -1)
player->mo->tics = states[flystate].tics;
#endif // ROTSPRITE
if (player == &players[consoleplayer])
localangle = player->mo->angle;
else if (player == &players[secondarydisplayplayer])

View file

@ -114,7 +114,7 @@ sprcache_t *spritecachedinfo;
lighttable_t *colormaps;
// for debugging/info purposes
static size_t flatmemory, spritememory, texturememory;
size_t flatmemory, spritememory, texturememory;
// highcolor stuff
INT16 color8to16[256]; // remap color index to highcolor rgb value
@ -2306,3 +2306,211 @@ void R_PrecacheLevel(void)
"texturememory: %s k\n"
"spritememory: %s k\n", sizeu1(flatmemory>>10), sizeu2(texturememory>>10), sizeu3(spritememory>>10));
}
#ifdef ROTSPRITE
// https://github.com/coelckers/prboom-plus/blob/master/prboom2/src/r_patch.c#L350
boolean R_CheckIfPatch(lumpnum_t lump)
{
size_t size;
INT16 width, height;
patch_t *patch;
boolean result;
size = W_LumpLength(lump);
// minimum length of a valid Doom patch
if (size < 13)
return false;
patch = (patch_t *)W_CacheLumpNum(lump, PU_STATIC);
width = SHORT(patch->width);
height = SHORT(patch->height);
result = (height > 0 && height <= 16384 && width > 0 && width <= 16384 && width < (INT16)(size / 4));
if (result)
{
// The dimensions seem like they might be valid for a patch, so
// check the column directory for extra security. All columns
// must begin after the column directory, and none of them must
// point past the end of the patch.
INT16 x;
for (x = 0; x < width; x++)
{
UINT32 ofs = LONG(patch->columnofs[x]);
// Need one byte for an empty column (but there's patches that don't know that!)
if (ofs < (UINT32)width * 4 + 8 || ofs >= (UINT32)size)
{
result = false;
break;
}
}
}
return result;
}
// https://github.com/Jimita/SRB2/blob/flats-png/src/r_data.c#L2157
void R_PatchToFlat(patch_t *patch, UINT16 *raw, boolean flip)
{
fixed_t col, ofs;
column_t *column;
UINT16 *desttop, *dest, *deststop;
UINT8 *source;
desttop = raw;
deststop = desttop + (SHORT(patch->width) * SHORT(patch->height));
#define DEAR_GOD_FORGIVE_ME_FOR_MY_MACROS \
{ \
INT32 topdelta, prevdelta = -1; \
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[col])); \
while (column->topdelta != 0xff) \
{ \
topdelta = column->topdelta; \
if (topdelta <= prevdelta) \
topdelta += prevdelta; \
prevdelta = topdelta; \
dest = desttop + (topdelta * SHORT(patch->width)); \
source = (UINT8 *)(column) + 3; \
for (ofs = 0; dest < deststop && ofs < column->length; ofs++) \
{ \
*dest = source[ofs]; \
dest += SHORT(patch->width); \
} \
column = (column_t *)((UINT8 *)column + column->length + 4); \
} \
}
if (!flip)
{
for (col = 0; col < SHORT(patch->width); col++, desttop++)
DEAR_GOD_FORGIVE_ME_FOR_MY_MACROS
}
else
{
// flipped
for (col = SHORT(patch->width)-1; col >= 0; col--, desttop++)
DEAR_GOD_FORGIVE_ME_FOR_MY_MACROS
}
}
// https://github.com/Jimita/SRB2/blob/flats-png/src/r_data.c#L1970
static UINT8 imgbuf[1<<26];
patch_t *R_FlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, size_t *size)
{
UINT32 x, y;
UINT8 *img;
UINT8 *imgptr = imgbuf;
UINT8 *colpointers, *startofspan;
#define WRITE8(buf, a) ({*buf = (a); buf++;})
#define WRITE16(buf, a) ({*buf = (a)&255; buf++; *buf = (a)>>8; buf++;})
#define WRITE32(buf, a) ({WRITE16(buf, (a)&65535); WRITE16(buf, (a)>>16);})
if (!raw)
return NULL;
// Write image size and offset
WRITE16(imgptr, width);
WRITE16(imgptr, height);
// no offsets
WRITE16(imgptr, 0);
WRITE16(imgptr, 0);
// Leave placeholder to column pointers
colpointers = imgptr;
imgptr += width*4;
// Write columns
for (x = 0; x < width; x++)
{
int lastStartY = 0;
int spanSize = 0;
startofspan = NULL;
//printf("%d ", x);
// Write column pointer (@TODO may be wrong)
WRITE32(colpointers, imgptr - imgbuf);
// Write pixels
for (y = 0; y < height; y++)
{
UINT16 pixel = raw[((y * width) + x)];
UINT8 paletteIndex = (pixel & 0xFF);
UINT8 opaque = (pixel != 0xFF00); // If 1, we have a pixel
// End span if we have a transparent pixel
if (!opaque)
{
if (startofspan)
WRITE8(imgptr, 0);
startofspan = NULL;
continue;
}
// Start new column if we need to
if (!startofspan || spanSize == 255)
{
int writeY = y;
// If we reached the span size limit, finish the previous span
if (startofspan)
WRITE8(imgptr, 0);
if (y > 254)
{
// Make sure we're aligned to 254
if (lastStartY < 254)
{
WRITE8(imgptr, 254);
WRITE8(imgptr, 0);
imgptr += 2;
lastStartY = 254;
}
// Write stopgap empty spans if needed
writeY = y - lastStartY;
while (writeY > 254)
{
WRITE8(imgptr, 254);
WRITE8(imgptr, 0);
imgptr += 2;
writeY -= 254;
}
}
startofspan = imgptr;
WRITE8(imgptr, writeY);///@TODO calculate starting y pos
imgptr += 2;
spanSize = 0;
lastStartY = y;
}
// Write the pixel
WRITE8(imgptr, paletteIndex);
spanSize++;
startofspan[1] = spanSize;
}
if (startofspan)
WRITE8(imgptr, 0);
WRITE8(imgptr, 0xFF);
}
#undef WRITE8
#undef WRITE16
#undef WRITE32
*size = imgptr-imgbuf;
img = malloc(*size);
memcpy(img, imgbuf, *size);
return (patch_t *)img;
}
#endif

View file

@ -77,13 +77,20 @@ void R_CheckTextureCache(INT32 tex);
// Retrieve column data for span blitting.
UINT8 *R_GetColumn(fixed_t tex, INT32 col);
UINT8 *R_GetFlat(lumpnum_t flatnum);
#ifdef ROTSPRITE
boolean R_CheckIfPatch(lumpnum_t lump);
void R_PatchToFlat(patch_t *patch, UINT16 *raw, boolean flip);
patch_t *R_FlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, size_t *size);
#endif
// I/O, setting up the stuff.
void R_InitData(void);
void R_PrecacheLevel(void);
extern size_t flatmemory, spritememory, texturememory;
// Retrieval.
// Floor/ceiling opaque texture tiles,
// lookup by name. For animation?

View file

@ -24,6 +24,10 @@
#include "screen.h" // MAXVIDWIDTH, MAXVIDHEIGHT
#ifdef HWRENDER
#include "m_aatree.h"
#endif
#define POLYOBJECTS
//
@ -723,6 +727,18 @@ typedef struct
#pragma pack()
#endif
// Rotated sprite 0-360
#ifdef ROTSPRITE
typedef struct
{
patch_t *patch[8][ROTANGLES];
boolean cached[8];
#ifdef HWRENDER
aatree_t *hardware_patch[8];
#endif
} rotsprite_t;
#endif
typedef enum
{
SRF_SINGLE = 0, // 0-angle for all rotations
@ -760,6 +776,10 @@ typedef struct
// Flip bits (1 = flip) to use for view angles 0-7.
UINT8 flip;
#ifdef ROTSPRITE
rotsprite_t rotsprite;
#endif
} spriteframe_t;
//

View file

@ -1007,8 +1007,6 @@ void R_DrawSinglePlane(visplane_t *pl)
temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy);
zeroheight = FIXED_TO_FLOAT(temp);
#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180)
// p is the texture origin in view space
// Don't add in the offsets at this stage, because doing so can result in
// errors if the flat is rotated.

View file

@ -22,6 +22,7 @@
#include "m_misc.h"
#include "info.h" // spr2names
#include "i_video.h" // rendermode
#include "i_system.h"
#include "r_things.h"
#include "r_plane.h"
#include "r_portal.h"
@ -35,6 +36,9 @@
#include "fastcmp.h"
#ifdef HWRENDER
#include "hardware/hw_md2.h"
#include "hardware/hw_glob.h"
#include "hardware/hw_light.h"
#include "hardware/hw_drv.h"
#endif
#ifdef PC_DOS
@ -68,6 +72,11 @@ static lighttable_t **spritelights;
INT16 negonearray[MAXVIDWIDTH];
INT16 screenheightarray[MAXVIDWIDTH];
#ifdef ROTSPRITE
static fixed_t cosang2rad[ROTANGLES];
static fixed_t sinang2rad[ROTANGLES];
#endif
//
// INITIALIZATION FUNCTIONS
//
@ -100,7 +109,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
{
char cn = R_Frame2Char(frame); // for debugging
INT32 r;
INT32 r, ang;
lumpnum_t lumppat = wad;
lumppat <<= 16;
lumppat += lump;
@ -111,6 +120,20 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
if (maxframe ==(size_t)-1 || frame > maxframe)
maxframe = frame;
// rotsprite
#ifdef ROTSPRITE
for (r = 0; r < 8; r++)
{
sprtemp[frame].rotsprite.cached[r] = false;
for (ang = 0; ang < ROTANGLES; ang++)
sprtemp[frame].rotsprite.patch[r][ang] = NULL;
#ifdef HWRENDER
if (rendermode == render_opengl)
sprtemp[frame].rotsprite.hardware_patch[r] = M_AATreeAlloc(AATREE_ZUSER);
#endif // HWRENDER
}
#endif
if (rotation == 0)
{
// the lump should be used for all rotations
@ -193,6 +216,157 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
sprtemp[frame].flip &= ~(1<<rotation);
}
#ifdef ROTSPRITE
void R_CacheRotSprite(spriteframe_t *sprframe, INT32 rot, UINT8 flip)
{
UINT32 i;
INT32 angle;
patch_t *patch;
patch_t *newpatch;
UINT16 *rawsrc, *rawdst;
size_t size, size2;
const char *lumpname;
if (!sprframe->rotsprite.cached[rot])
{
INT32 sx,sy;
INT32 dx,dy;
INT32 ox,oy;
INT32 nox,noy;
INT32 width,height;
fixed_t ca, sa;
lumpnum_t lump = sprframe->lumppat[rot];
if (lump == LUMPERROR)
return;
// Because there's something wrong with SPR_DFLM, I guess
if (!R_CheckIfPatch(lump))
return;
patch = (patch_t *)W_CacheLumpNum(lump, PU_CACHE);
lumpname = W_CheckNameForNum(lump);
CONS_Debug(DBG_RENDER, "R_CacheRotSprite: %s\n", lumpname);
//CONS_Printf("%d\n", angle * ROTANGDIFF);
width = patch->width;
height = patch->height;
// patch origin
ox = (width / 2);
oy = (height / 2);
// Draw the sprite to a temporary buffer.
size = (width*height);
rawsrc = Z_Malloc(size * sizeof(UINT16), PU_STATIC, NULL);
// can't memset here
for (i = 0; i < size; i++)
rawsrc[i] = 0xFF00;
R_PatchToFlat(patch, rawsrc, (flip != 0x00));
// Don't cache angle = 0, that would be stoopid
for (angle = 1; angle < ROTANGLES; angle++)
{
INT32 minx = 32767, maxx = -32767;
INT32 miny = 32767, maxy = -32767;
INT32 newwidth, newheight;
ca = cosang2rad[angle];
sa = sinang2rad[angle];
// Find the dimensions of the rotated patch.
// This is BROKEN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
for (sy = 0; sy < height; sy++)
{
for (sx = 0; sx < width; sx++)
{
dx = FixedMul((sx-ox) << FRACBITS, ca) + FixedMul((sy-oy) << FRACBITS, sa) + (ox << FRACBITS);
dy = -FixedMul((sx-oy) << FRACBITS, sa) + FixedMul((sy-oy) << FRACBITS, ca) + (oy << FRACBITS);
dx >>= FRACBITS;
dy >>= FRACBITS;
if (dx < minx) minx = dx;
if (dx > maxx) maxx = dx;
if (dy < miny) miny = dy;
if (dy > maxy) maxy = dy;
}
}
newwidth = (maxx - minx) * 1.5f;
newheight = (maxy - miny) * 1.5f;
nox = (newwidth / 2);
noy = (newheight / 2);
size2 = (newwidth * newheight);
if (!size2)
size2 = size;
rawdst = Z_Malloc(size2 * sizeof(UINT16), PU_STATIC, NULL);
// can't memset here
for (i = 0; i < size2; i++)
rawdst[i] = 0xFF00;
// Draw the rotated sprite to a temporary buffer.
for (dy = 0; dy < newheight; dy++)
{
for (dx = 0; dx < newwidth; dx++)
{
sx = FixedMul((dx-nox) << FRACBITS, ca) + FixedMul((dy-noy) << FRACBITS, sa) + (ox << FRACBITS);
sy = -FixedMul((dx-nox) << FRACBITS, sa) + FixedMul((dy-noy) << FRACBITS, ca) + (oy << FRACBITS);
sx >>= FRACBITS;
sy >>= FRACBITS;
if (sx >= 0 && sy >= 0 && sx < width && sy < height)
rawdst[(dy*newwidth)+dx] = rawsrc[(sy*width)+sx];
}
}
// make patch
newpatch = R_FlatToPatch(rawdst, newwidth, newheight, &size);
// This is BROKEN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
newpatch->leftoffset = (newpatch->width / 2) - ((ox - patch->leftoffset) * ((flip != 0x00) ? -1 : 1));
newpatch->topoffset = (newpatch->height / 2) - (oy - patch->topoffset);
//BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer
if (rendermode != render_none) // not for psprite
newpatch->topoffset += 4;
// P_PrecacheLevel
if (devparm) spritememory += size;
#ifdef HWRENDER
if (rendermode == render_opengl)
{
GLPatch_t *grPatch = HWR_GetCachedGLRotSprite(sprframe->rotsprite.hardware_patch[rot], angle, newpatch);
HWR_MakePatch(newpatch, grPatch, &grPatch->mipmap, false);
sprframe->rotsprite.patch[rot][angle] = (patch_t *)grPatch;
}
else
#endif // HWRENDER
sprframe->rotsprite.patch[rot][angle] = newpatch;
// free rotated image data
Z_Free(rawdst);
}
// This rotation is cached now
sprframe->rotsprite.cached[rot] = true;
// free image data
Z_Free(rawsrc);
#ifdef HWRENDER
if (rendermode == render_soft)
#endif
W_UnlockCachedPatch(patch);
// Can remove if needed
I_OsPolling();
I_UpdateNoBlit();
}
}
#endif
// Install a single sprite, given its identifying name (4 chars)
//
// (originally part of R_AddSpriteDefs)
@ -214,6 +388,9 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
lumpinfo_t *lumpinfo;
patch_t patch;
UINT8 numadded = 0;
#ifdef ROTSPRITE
INT32 rot, ang;
#endif
memset(sprtemp,0xFF, sizeof (sprtemp));
maxframe = (size_t)-1;
@ -356,6 +533,16 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
if (spritedef->numframes && // has been allocated
spritedef->numframes < maxframe) // more frames are defined ?
{
#ifdef ROTSPRITE
for (frame = 0; frame < spritedef->numframes; frame++)
{
spriteframe_t *sprframe = &spritedef->spriteframes[frame];
for (rot = 0; rot < 8; rot++)
if (sprframe->rotsprite.cached[rot])
for (ang = 0; ang < ROTANGLES; ang++)
Z_Free(sprframe->rotsprite.patch[rot][ang]);
}
#endif // ROTSPRITE
Z_Free(spritedef->spriteframes);
spritedef->spriteframes = NULL;
}
@ -449,7 +636,6 @@ UINT32 visspritecount;
static UINT32 clippedvissprites;
static vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL};
//
// R_InitSprites
// Called at program start.
@ -457,11 +643,23 @@ static vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL
void R_InitSprites(void)
{
size_t i;
#ifdef ROTSPRITE
INT32 angle, realangle = 0;
float fa;
#endif
for (i = 0; i < MAXVIDWIDTH; i++)
{
negonearray[i] = -1;
#ifdef ROTSPRITE
for (angle = 0; angle < ROTANGLES; angle++)
{
fa = ANG2RAD(FixedAngle(realangle<<FRACBITS));
cosang2rad[angle] = FLOAT_TO_FIXED(cos(-fa));
sinang2rad[angle] = FLOAT_TO_FIXED(sin(-fa));
realangle += ROTANGDIFF;
}
#endif
//
// count the number of sprite names, and allocate sprites table
@ -701,7 +899,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
INT32 texturecolumn;
#endif
fixed_t frac;
patch_t *patch = W_CacheLumpNum(vis->patch, PU_CACHE);
patch_t *patch = vis->patch;
fixed_t this_scale = vis->mobj->scale;
INT32 x1, x2;
INT64 overflow_test;
@ -870,7 +1068,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
INT64 overflow_test;
//Fab : R_InitSprites now sets a wad lump number
patch = W_CacheLumpNum(vis->patch, PU_CACHE);
patch = vis->patch;
if (!patch)
return;
@ -1050,6 +1248,15 @@ static void R_ProjectSprite(mobj_t *thing)
INT32 light = 0;
fixed_t this_scale = thing->scale;
// rotsprite
fixed_t spr_width, spr_height;
fixed_t spr_offset, spr_topoffset;
#ifdef ROTSPRITE
patch_t *rotsprite = NULL;
angle_t arollangle = thing->rollangle;
UINT32 rollangle = AngleFixed(arollangle)>>FRACBITS;
#endif
fixed_t ang_scale = FRACUNIT;
// transform the origin point
@ -1158,11 +1365,35 @@ static void R_ProjectSprite(mobj_t *thing)
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
this_scale = FixedMul(this_scale, ((skin_t *)thing->skin)->highresscale);
spr_width = spritecachedinfo[lump].width;
spr_height = spritecachedinfo[lump].height;
spr_offset = spritecachedinfo[lump].offset;
spr_topoffset = spritecachedinfo[lump].topoffset;
#ifdef ROTSPRITE
if (rollangle > 0)
{
if (!sprframe->rotsprite.cached[rot])
R_CacheRotSprite(sprframe, rot, flip);
rollangle /= ROTANGDIFF;
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
if (rotsprite != NULL)
{
spr_width = rotsprite->width << FRACBITS;
spr_height = rotsprite->height << FRACBITS;
spr_offset = rotsprite->leftoffset << FRACBITS;
spr_topoffset = rotsprite->topoffset << FRACBITS;
// flip -> rotate, not rotate -> flip
flip = 0;
}
}
#endif
// calculate edges of the shape
if (flip)
offset = spritecachedinfo[lump].offset - spritecachedinfo[lump].width;
offset = spr_offset - spr_width;
else
offset = -spritecachedinfo[lump].offset;
offset = -spr_offset;
offset = FixedMul(offset, this_scale);
tx += FixedMul(offset, ang_scale);
x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS;
@ -1171,7 +1402,7 @@ static void R_ProjectSprite(mobj_t *thing)
if (x1 > viewwidth)
return;
offset2 = FixedMul(spritecachedinfo[lump].width, this_scale);
offset2 = FixedMul(spr_width, this_scale);
tx += FixedMul(offset2, ang_scale);
x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1);
@ -1273,13 +1504,13 @@ static void R_ProjectSprite(mobj_t *thing)
// When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned.
// sprite height - sprite topoffset is the proper inverse of the vertical offset, of course.
// remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes!
gz = oldthing->z + oldthing->height - FixedMul(spritecachedinfo[lump].topoffset, this_scale);
gzt = gz + FixedMul(spritecachedinfo[lump].height, this_scale);
gz = oldthing->z + oldthing->height - FixedMul(spr_topoffset, this_scale);
gzt = gz + FixedMul(spr_height, this_scale);
}
else
{
gzt = oldthing->z + FixedMul(spritecachedinfo[lump].topoffset, this_scale);
gz = gzt - FixedMul(spritecachedinfo[lump].height, this_scale);
gzt = oldthing->z + FixedMul(spr_topoffset, this_scale);
gz = gzt - FixedMul(spr_height, this_scale);
}
if (thing->subsector->sector->cullheight)
@ -1378,7 +1609,7 @@ static void R_ProjectSprite(mobj_t *thing)
if (flip)
{
vis->startfrac = spritecachedinfo[lump].width-1;
vis->startfrac = spr_width-1;
vis->xiscale = -iscale;
}
else
@ -1395,7 +1626,12 @@ static void R_ProjectSprite(mobj_t *thing)
//Fab: lumppat is the lump number of the patch to use, this is different
// than lumpid for sprites-in-pwad : the graphics are patched
vis->patch = sprframe->lumppat[rot];
#ifdef ROTSPRITE
if (rotsprite != NULL)
vis->patch = rotsprite;
else
#endif
vis->patch = W_CacheLumpNum(sprframe->lumppat[rot], PU_CACHE);
//
// determine the colormap (lightlevel & special effects)
@ -1587,7 +1823,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
//Fab: lumppat is the lump number of the patch to use, this is different
// than lumpid for sprites-in-pwad : the graphics are patched
vis->patch = sprframe->lumppat[0];
vis->patch = W_CacheLumpNum(sprframe->lumppat[0], PU_CACHE);
// specific translucency
if (thing->frame & FF_TRANSMASK)

View file

@ -17,6 +17,7 @@
#include "sounds.h"
#include "r_plane.h"
#include "r_portal.h"
#include "r_defs.h"
// "Left" and "Right" character symbols for additional rotation functionality
#define ROT_L ('L' - '0')
@ -51,6 +52,10 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight);
// (only sprites from namelist are added or replaced)
void R_AddSpriteDefs(UINT16 wadnum);
#ifdef ROTSPRITE
void R_CacheRotSprite(spriteframe_t *sprframe, INT32 rot, UINT8 flip);
#endif
//SoM: 6/5/2000: Light sprites correctly!
void R_AddSprites(sector_t *sec, INT32 lightlevel);
void R_InitSprites(void);
@ -176,7 +181,7 @@ typedef struct vissprite_s
fixed_t xiscale; // negative if flipped
fixed_t texturemid;
lumpnum_t patch;
patch_t *patch;
lighttable_t *colormap; // for color translation and shadow draw
// maxbright frames as well