mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 17:22:12 +00:00
Merge branch 'public_hexang' into 'next'
Hexafaceted sprite angle support. See merge request STJr/SRB2!652
This commit is contained in:
commit
57a31077e7
7 changed files with 135 additions and 88 deletions
|
@ -5493,7 +5493,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
spriteinfo_t *sprinfo;
|
spriteinfo_t *sprinfo;
|
||||||
size_t lumpoff;
|
size_t lumpoff;
|
||||||
unsigned rot;
|
unsigned rot;
|
||||||
UINT8 flip;
|
UINT16 flip;
|
||||||
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP));
|
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP));
|
||||||
|
|
||||||
angle_t ang;
|
angle_t ang;
|
||||||
|
@ -5579,12 +5579,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
flip = sprframe->flip; // Will only be 0x00 or 0xFF
|
flip = sprframe->flip; // Will only be 0x00 or 0xFF
|
||||||
|
|
||||||
if (papersprite && ang < ANGLE_180)
|
if (papersprite && ang < ANGLE_180)
|
||||||
{
|
flip ^= 0xFFFF;
|
||||||
if (flip)
|
|
||||||
flip = 0;
|
|
||||||
else
|
|
||||||
flip = 255;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5593,6 +5588,11 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
rot = 6; // F7 slot
|
rot = 6; // F7 slot
|
||||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||||
rot = 2; // F3 slot
|
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
|
else // Normal behaviour
|
||||||
rot = (ang+ANGLE_202h)>>29;
|
rot = (ang+ANGLE_202h)>>29;
|
||||||
|
|
||||||
|
@ -5601,12 +5601,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
flip = sprframe->flip & (1<<rot);
|
flip = sprframe->flip & (1<<rot);
|
||||||
|
|
||||||
if (papersprite && ang < ANGLE_180)
|
if (papersprite && ang < ANGLE_180)
|
||||||
{
|
flip ^= (1<<rot);
|
||||||
if (flip)
|
|
||||||
flip = 0;
|
|
||||||
else
|
|
||||||
flip = 1<<rot;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
|
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
|
||||||
|
@ -5621,7 +5616,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
if (thing->rollangle)
|
if (thing->rollangle)
|
||||||
{
|
{
|
||||||
rollangle = R_GetRollAngle(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);
|
R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip);
|
||||||
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
|
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
|
||||||
if (rotsprite != NULL)
|
if (rotsprite != NULL)
|
||||||
|
|
|
@ -468,11 +468,11 @@ static int libd_getSpritePatch(lua_State *L)
|
||||||
|
|
||||||
// convert WAD editor angle numbers (1-8) to internal angle numbers (0-7)
|
// 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)
|
// 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)
|
if (angle != 0)
|
||||||
angle--;
|
angle--;
|
||||||
|
|
||||||
if (angle >= 8) // out of range?
|
if (angle >= ((sprframe->rotate & SRF_3DGE) ? 16 : 8)) // out of range?
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// push both the patch and it's "flip" value
|
// 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)
|
// 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)
|
// 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)
|
if (angle != 0)
|
||||||
angle--;
|
angle--;
|
||||||
|
|
||||||
if (angle >= 8) // out of range?
|
if (angle >= ((sprframe->rotate & SRF_3DGE) ? 16 : 8)) // out of range?
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// push both the patch and it's "flip" value
|
// push both the patch and it's "flip" value
|
||||||
|
|
29
src/r_data.c
29
src/r_data.c
|
@ -2710,14 +2710,29 @@ void R_PrecacheLevel(void)
|
||||||
for (j = 0; j < sprites[i].numframes; j++)
|
for (j = 0; j < sprites[i].numframes; j++)
|
||||||
{
|
{
|
||||||
sf = &sprites[i].spriteframes[j];
|
sf = &sprites[i].spriteframes[j];
|
||||||
for (k = 0; k < 8; k++)
|
#define cacheang(a) {\
|
||||||
{
|
lump = sf->lumppat[a];\
|
||||||
// see R_InitSprites for more about lumppat,lumpid
|
if (devparm)\
|
||||||
lump = sf->lumppat[k];
|
spritememory += W_LumpLength(lump);\
|
||||||
if (devparm)
|
W_CachePatchNum(lump, PU_PATCH);\
|
||||||
spritememory += W_LumpLength(lump);
|
|
||||||
W_CachePatchNum(lump, PU_PATCH);
|
|
||||||
}
|
}
|
||||||
|
// see R_InitSprites for more about lumppat,lumpid
|
||||||
|
switch (sf->rotate)
|
||||||
|
{
|
||||||
|
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);
|
free(spritepresent);
|
||||||
|
|
24
src/r_defs.h
24
src/r_defs.h
|
@ -727,8 +727,8 @@ typedef struct
|
||||||
#ifdef ROTSPRITE
|
#ifdef ROTSPRITE
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
patch_t *patch[8][ROTANGLES];
|
patch_t *patch[16][ROTANGLES];
|
||||||
boolean cached[8];
|
UINT16 cached;
|
||||||
} rotsprite_t;
|
} rotsprite_t;
|
||||||
#endif/*ROTSPRITE*/
|
#endif/*ROTSPRITE*/
|
||||||
|
|
||||||
|
@ -736,9 +736,11 @@ typedef enum
|
||||||
{
|
{
|
||||||
SRF_SINGLE = 0, // 0-angle for all rotations
|
SRF_SINGLE = 0, // 0-angle for all rotations
|
||||||
SRF_3D = 1, // Angles 1-8
|
SRF_3D = 1, // Angles 1-8
|
||||||
SRF_LEFT = 2, // Left side uses single patch
|
SRF_3DGE = 2, // 3DGE, ZDoom and Doom Legacy all have 16-angle support. Why not us?
|
||||||
SRF_RIGHT = 4, // Right side uses single patch
|
SRF_3DMASK = SRF_3D|SRF_3DGE, // 3
|
||||||
SRF_2D = SRF_LEFT|SRF_RIGHT, // 6
|
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
|
SRF_NONE = 0xff // Initial value
|
||||||
} spriterotateflags_t; // SRF's up!
|
} spriterotateflags_t; // SRF's up!
|
||||||
|
|
||||||
|
@ -764,7 +766,7 @@ typedef struct patchinfo_s patchinfo_t;
|
||||||
// Sprites are patches with a special naming convention so they can be
|
// Sprites are patches with a special naming convention so they can be
|
||||||
// recognized by R_InitSprites.
|
// recognized by R_InitSprites.
|
||||||
// The base name is NNNNFx or NNNNFxFx, with x indicating the rotation,
|
// 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.
|
// 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
|
// A sprite is a patch_t that is assumed to represent a three dimensional
|
||||||
// object and may have multiple rotations predrawn.
|
// object and may have multiple rotations predrawn.
|
||||||
|
@ -781,12 +783,12 @@ typedef struct
|
||||||
// name eight times.
|
// name eight times.
|
||||||
UINT8 rotate; // see spriterotateflags_t above
|
UINT8 rotate; // see spriterotateflags_t above
|
||||||
|
|
||||||
// Lump to use for view angles 0-7.
|
// Lump to use for view angles 0-7/15.
|
||||||
lumpnum_t lumppat[8]; // lump number 16 : 16 wad : lump
|
lumpnum_t lumppat[16]; // lump number 16 : 16 wad : lump
|
||||||
size_t lumpid[8]; // id in the spriteoffset, spritewidth, etc. tables
|
size_t lumpid[16]; // id in the spriteoffset, spritewidth, etc. tables
|
||||||
|
|
||||||
// Flip bits (1 = flip) to use for view angles 0-7.
|
// Flip bits (1 = flip) to use for view angles 0-7/15.
|
||||||
UINT8 flip;
|
UINT16 flip;
|
||||||
|
|
||||||
#ifdef ROTSPRITE
|
#ifdef ROTSPRITE
|
||||||
rotsprite_t rotsprite;
|
rotsprite_t rotsprite;
|
||||||
|
|
|
@ -1205,7 +1205,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
|
||||||
#define ROTSPRITE_XCENTER (newwidth / 2)
|
#define ROTSPRITE_XCENTER (newwidth / 2)
|
||||||
#define ROTSPRITE_YCENTER (newheight / 2)
|
#define ROTSPRITE_YCENTER (newheight / 2)
|
||||||
|
|
||||||
if (!sprframe->rotsprite.cached[rot])
|
if (!(sprframe->rotsprite.cached & (1<<rot)))
|
||||||
{
|
{
|
||||||
INT32 dx, dy;
|
INT32 dx, dy;
|
||||||
INT32 px, py;
|
INT32 px, py;
|
||||||
|
@ -1375,7 +1375,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
|
||||||
}
|
}
|
||||||
|
|
||||||
// This rotation is cached now
|
// This rotation is cached now
|
||||||
sprframe->rotsprite.cached[rot] = true;
|
sprframe->rotsprite.cached |= (1<<rot);
|
||||||
|
|
||||||
// free image data
|
// free image data
|
||||||
Z_Free(patch);
|
Z_Free(patch);
|
||||||
|
@ -1399,9 +1399,9 @@ void R_FreeSingleRotSprite(spritedef_t *spritedef)
|
||||||
for (frame = 0; frame < spritedef->numframes; frame++)
|
for (frame = 0; frame < spritedef->numframes; frame++)
|
||||||
{
|
{
|
||||||
spriteframe_t *sprframe = &spritedef->spriteframes[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++)
|
for (ang = 0; ang < ROTANGLES; ang++)
|
||||||
{
|
{
|
||||||
|
@ -1432,7 +1432,7 @@ void R_FreeSingleRotSprite(spritedef_t *spritedef)
|
||||||
Z_Free(rotsprite);
|
Z_Free(rotsprite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sprframe->rotsprite.cached[rot] = false;
|
sprframe->rotsprite.cached &= ~(1<<rot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
102
src/r_things.c
102
src/r_things.c
|
@ -105,24 +105,21 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
|
||||||
UINT8 rotation,
|
UINT8 rotation,
|
||||||
UINT8 flipped)
|
UINT8 flipped)
|
||||||
{
|
{
|
||||||
char cn = R_Frame2Char(frame); // for debugging
|
char cn = R_Frame2Char(frame), cr = R_Rotation2Char(rotation); // for debugging
|
||||||
|
|
||||||
INT32 r, ang;
|
INT32 r, ang;
|
||||||
lumpnum_t lumppat = wad;
|
lumpnum_t lumppat = wad;
|
||||||
lumppat <<= 16;
|
lumppat <<= 16;
|
||||||
lumppat += lump;
|
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)
|
if (maxframe ==(size_t)-1 || frame > maxframe)
|
||||||
maxframe = frame;
|
maxframe = frame;
|
||||||
|
|
||||||
// rotsprite
|
// rotsprite
|
||||||
#ifdef 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++)
|
for (ang = 0; ang < ROTANGLES; ang++)
|
||||||
sprtemp[frame].rotsprite.patch[r][ang] = NULL;
|
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
|
// the lump should be used for all rotations
|
||||||
if (sprtemp[frame].rotate == SRF_SINGLE)
|
if (sprtemp[frame].rotate == SRF_SINGLE)
|
||||||
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple rot = 0 lump\n", spritename, cn);
|
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);
|
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;
|
sprtemp[frame].rotate = SRF_SINGLE;
|
||||||
for (r = 0; r < 8; r++)
|
for (r = 0; r < 16; r++)
|
||||||
{
|
{
|
||||||
sprtemp[frame].lumppat[r] = lumppat;
|
sprtemp[frame].lumppat[r] = lumppat;
|
||||||
sprtemp[frame].lumpid[r] = lumpid;
|
sprtemp[frame].lumpid[r] = lumpid;
|
||||||
}
|
}
|
||||||
sprtemp[frame].flip = flipped ? 0xFF : 0; // 11111111 in binary
|
sprtemp[frame].flip = flipped ? 0xFFFF : 0; // 1111111111111111 in binary
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,54 +148,67 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
|
||||||
UINT8 rightfactor = ((rotation == ROT_R) ? 4 : 0);
|
UINT8 rightfactor = ((rotation == ROT_R) ? 4 : 0);
|
||||||
|
|
||||||
// the lump should be used for half of all rotations
|
// 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);
|
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)
|
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);
|
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))
|
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);
|
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))
|
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);
|
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);
|
sprtemp[frame].rotate |= ((rotation == ROT_R) ? SRF_RIGHT : SRF_LEFT);
|
||||||
if (sprtemp[frame].rotate == (SRF_3D|SRF_2D))
|
if ((sprtemp[frame].rotate & SRF_2D) == 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.
|
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].lumppat[r + rightfactor] = lumppat;
|
||||||
sprtemp[frame].lumpid[r + rightfactor] = lumpid;
|
sprtemp[frame].lumpid[r + rightfactor] = lumpid;
|
||||||
|
sprtemp[frame].lumppat[r + rightfactor + 8] = lumppat;
|
||||||
|
sprtemp[frame].lumpid[r + rightfactor + 8] = lumpid;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flipped)
|
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
|
else
|
||||||
sprtemp[frame].flip &= ~(0x0F<<rightfactor); // ditto
|
sprtemp[frame].flip &= ~(0x0F0F<<rightfactor); // ditto
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the lump is only used for one rotation
|
if (sprtemp[frame].rotate == SRF_NONE)
|
||||||
if (sprtemp[frame].rotate == SRF_SINGLE)
|
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_SINGLE)
|
||||||
else if ((sprtemp[frame].rotate != SRF_3D) && (sprtemp[frame].rotate != SRF_NONE))
|
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has 1-8/G rotations and a rot = 0 lump\n", spritename, cn);
|
||||||
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_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
|
// make 0 based
|
||||||
rotation--;
|
rotation--;
|
||||||
|
|
||||||
|
{
|
||||||
|
// 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...
|
if (rotation == 0 || rotation == 4) // Front or back...
|
||||||
sprtemp[frame].rotate = SRF_3D; // Prevent L and R changeover
|
sprtemp[frame].rotate = threedrot; // Prevent L and R changeover
|
||||||
else if (rotation > 3) // Right side
|
else if ((rotation & 7) > 3) // Right side
|
||||||
sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover
|
sprtemp[frame].rotate = (threedrot | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover
|
||||||
else // if (rotation <= 3) // Left side
|
else // if ((rotation & 7) <= 3) // Left side
|
||||||
sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_RIGHT)); // Continue allowing R frame changeover
|
sprtemp[frame].rotate = (threedrot | (sprtemp[frame].rotate & SRF_RIGHT)); // Continue allowing R frame changeover
|
||||||
|
}
|
||||||
|
|
||||||
if (sprtemp[frame].lumppat[rotation] != LUMPERROR)
|
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
|
// lumppat & lumpid are the same for original Doom, but different
|
||||||
// when using sprites in pwad : the lumppat points the new graphics
|
// 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)
|
if (memcmp(lumpinfo[l].name,sprname,4)==0)
|
||||||
{
|
{
|
||||||
frame = R_Char2Frame(lumpinfo[l].name[4]);
|
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));
|
CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l));
|
||||||
continue;
|
continue;
|
||||||
|
@ -308,7 +318,13 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
|
||||||
if (lumpinfo[l].name[6])
|
if (lumpinfo[l].name[6])
|
||||||
{
|
{
|
||||||
frame = R_Char2Frame(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);
|
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
|
case SRF_2D: // both Left and Right rotations
|
||||||
// we test to see whether the left and right slots are present
|
// we test to see whether the left and right slots are present
|
||||||
if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR))
|
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));
|
sprname, R_Frame2Char(frame));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// must have all 8 frames
|
// must have all 8/16 frames
|
||||||
for (rotation = 0; rotation < 8; rotation++)
|
rotation = ((sprtemp[frame].rotate & SRF_3DGE) ? 16 : 8);
|
||||||
|
while (rotation--)
|
||||||
// we test the patch lump, or the id lump whatever
|
// we test the patch lump, or the id lump whatever
|
||||||
// if it was not loaded the two are LUMPERROR
|
// if it was not loaded the two are LUMPERROR
|
||||||
if (sprtemp[frame].lumppat[rotation] == LUMPERROR)
|
if (sprtemp[frame].lumppat[rotation] == LUMPERROR)
|
||||||
I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations",
|
I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations (1-%c mode)",
|
||||||
sprname, R_Frame2Char(frame));
|
sprname, R_Frame2Char(frame), ((sprtemp[frame].rotate & SRF_3DGE) ? 'G' : '8'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1094,7 +1111,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
size_t lump;
|
size_t lump;
|
||||||
|
|
||||||
size_t rot;
|
size_t rot;
|
||||||
UINT8 flip;
|
UINT16 flip;
|
||||||
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP));
|
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP));
|
||||||
|
|
||||||
INT32 lindex;
|
INT32 lindex;
|
||||||
|
@ -1224,7 +1241,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
// use single rotation for all views
|
// use single rotation for all views
|
||||||
rot = 0; //Fab: for vis->patch below
|
rot = 0; //Fab: for vis->patch below
|
||||||
lump = sprframe->lumpid[0]; //Fab: see note above
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -1235,6 +1252,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
rot = 6; // F7 slot
|
rot = 6; // F7 slot
|
||||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||||
rot = 2; // F3 slot
|
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
|
else // Normal behaviour
|
||||||
rot = (ang+ANGLE_202h)>>29;
|
rot = (ang+ANGLE_202h)>>29;
|
||||||
|
|
||||||
|
@ -1257,7 +1279,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
if (thing->rollangle)
|
if (thing->rollangle)
|
||||||
{
|
{
|
||||||
rollangle = R_GetRollAngle(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);
|
R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip);
|
||||||
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
|
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
|
||||||
if (rotsprite != NULL)
|
if (rotsprite != NULL)
|
||||||
|
|
|
@ -20,10 +20,6 @@
|
||||||
#include "r_portal.h"
|
#include "r_portal.h"
|
||||||
#include "r_defs.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
|
// number of sprite lumps for spritewidth,offset,topoffset lookup tables
|
||||||
// Fab: this is a hack : should allocate the lookup tables per sprite
|
// Fab: this is a hack : should allocate the lookup tables per sprite
|
||||||
#define MAXVISSPRITES 2048 // added 2-2-98 was 128
|
#define MAXVISSPRITES 2048 // added 2-2-98 was 128
|
||||||
|
@ -270,7 +266,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn)
|
||||||
if (cn == '+') return '\\' - 'A'; // PK3 can't use backslash, so use + instead
|
if (cn == '+') return '\\' - 'A'; // PK3 can't use backslash, so use + instead
|
||||||
return cn - 'A';
|
return cn - 'A';
|
||||||
#else
|
#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 >= '0' && cn <= '9') return (cn - '0') + 26;
|
||||||
if (cn >= 'a' && cn <= 'z') return (cn - 'a') + 36;
|
if (cn >= 'a' && cn <= 'z') return (cn - 'a') + 36;
|
||||||
if (cn == '!') return 62;
|
if (cn == '!') return 62;
|
||||||
|
@ -279,9 +275,26 @@ FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn)
|
||||||
#endif
|
#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__
|
#endif //__R_THINGS__
|
||||||
|
|
Loading…
Reference in a new issue