mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-14 08:50:53 +00:00
Merge remote-tracking branch 'origin/next' into pitch-roll
This commit is contained in:
commit
f126ceb878
23 changed files with 477 additions and 217 deletions
|
@ -91,6 +91,8 @@ actionpointer_t actionpointers[] =
|
|||
{{A_FaceTracer}, "A_FACETRACER"},
|
||||
{{A_Scream}, "A_SCREAM"},
|
||||
{{A_BossDeath}, "A_BOSSDEATH"},
|
||||
{{A_SetShadowScale}, "A_SETSHADOWSCALE"},
|
||||
{{A_ShadowScream}, "A_SHADOWSCREAM"},
|
||||
{{A_CustomPower}, "A_CUSTOMPOWER"},
|
||||
{{A_GiveWeapon}, "A_GIVEWEAPON"},
|
||||
{{A_RingBox}, "A_RINGBOX"},
|
||||
|
|
|
@ -530,6 +530,22 @@ extern boolean capslock;
|
|||
// i_system.c, replace getchar() once the keyboard has been appropriated
|
||||
INT32 I_GetKey(void);
|
||||
|
||||
/* http://www.cse.yorku.ca/~oz/hash.html */
|
||||
static inline
|
||||
UINT32 quickncasehash (const char *p, size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
UINT32 x = 5381;
|
||||
|
||||
while (i < n && p[i])
|
||||
{
|
||||
x = (x * 33) ^ tolower(p[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
#ifndef min // Double-Check with WATTCP-32's cdefs.h
|
||||
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
|
|
@ -3632,6 +3632,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
FBITFIELD blendmode = PF_Translucent|PF_Modulated;
|
||||
INT32 shader = SHADER_DEFAULT;
|
||||
UINT8 i;
|
||||
INT32 heightsec, phs;
|
||||
SINT8 flip = P_MobjFlip(thing);
|
||||
|
||||
INT32 light;
|
||||
|
@ -3644,7 +3645,23 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
|
||||
groundz = R_GetShadowZ(thing, &groundslope);
|
||||
|
||||
//if (abs(groundz - gl_viewz) / tz > 4) return; // Prevent stretchy shadows and possible crashes
|
||||
heightsec = thing->subsector->sector->heightsec;
|
||||
if (viewplayer->mo && viewplayer->mo->subsector)
|
||||
phs = viewplayer->mo->subsector->sector->heightsec;
|
||||
else
|
||||
phs = -1;
|
||||
|
||||
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
|
||||
{
|
||||
if (gl_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ?
|
||||
thing->z >= sectors[heightsec].floorheight :
|
||||
thing->z < sectors[heightsec].floorheight)
|
||||
return;
|
||||
if (gl_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ?
|
||||
thing->z < sectors[heightsec].ceilingheight && gl_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
|
||||
thing->z >= sectors[heightsec].ceilingheight)
|
||||
return;
|
||||
}
|
||||
|
||||
floordiff = abs((flip < 0 ? thing->height : 0) + thing->z - groundz);
|
||||
|
||||
|
@ -5179,8 +5196,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
#ifdef ROTSPRITE
|
||||
if (papersprite)
|
||||
rollangle = thing->pitch // pitch should flip the sprite rotation on one side of the papersprite (OpenGL does this by default)
|
||||
+ (ang >= ANGLE_180 ? -1 : 1) * thing->rollangle; // rollangle should use the same rotation for both sides of a papersprite (Software behavior parity)
|
||||
rollangle = thing->rollangle;
|
||||
else
|
||||
{
|
||||
rollangle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), thing->roll)
|
||||
|
@ -5310,13 +5326,19 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
|
||||
{
|
||||
float top = gzt;
|
||||
float bottom = FIXED_TO_FLOAT(thing->z);
|
||||
|
||||
if (R_ThingIsFloorSprite(thing))
|
||||
top = bottom;
|
||||
|
||||
if (gl_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ?
|
||||
FIXED_TO_FLOAT(thing->z) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
|
||||
gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight))
|
||||
bottom >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
|
||||
top < FIXED_TO_FLOAT(sectors[heightsec].floorheight))
|
||||
return;
|
||||
if (gl_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ?
|
||||
gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gl_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
|
||||
FIXED_TO_FLOAT(thing->z) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
|
||||
top < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gl_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
|
||||
bottom >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
30
src/info.c
30
src/info.c
|
@ -2992,10 +2992,10 @@ state_t states[NUMSTATES] =
|
|||
{SPR_NULL, 0, 15*2, {NULL}, 0, 0, S_ZAPSB2 }, // S_ZAPSB11
|
||||
|
||||
// Thunder spark
|
||||
{SPR_SSPK, FF_ANIMATE, -1, {NULL}, 1, 2, S_NULL}, // S_THUNDERCOIN_SPARK
|
||||
{SPR_SSPK, FF_ANIMATE|FF_FULLBRIGHT, -1, {NULL}, 1, 2, S_NULL}, // S_THUNDERCOIN_SPARK
|
||||
|
||||
// Invincibility Sparkles
|
||||
{SPR_IVSP, FF_ANIMATE, 32, {NULL}, 31, 1, S_NULL}, // S_IVSP
|
||||
{SPR_IVSP, FF_ANIMATE|FF_FULLBRIGHT, 32, {NULL}, 31, 1, S_NULL}, // S_IVSP
|
||||
|
||||
// Super Sonic Spark
|
||||
{SPR_SSPK, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK2}, // S_SSPK1
|
||||
|
@ -3936,23 +3936,23 @@ state_t states[NUMSTATES] =
|
|||
{SPR_SPRK, FF_TRANS20|FF_ANIMATE|9, 18, {NULL}, 8, 2, S_NULL}, // S_SPRK3
|
||||
|
||||
// Robot Explosion
|
||||
{SPR_BOM1, 0, 0, {A_FlickySpawn}, 0, 0, S_XPLD1}, // S_XPLD_FLICKY
|
||||
{SPR_BOM1, 0, 2, {A_Scream}, 0, 0, S_XPLD2}, // S_XPLD1
|
||||
{SPR_BOM1, 1, 2, {NULL}, 0, 0, S_XPLD3}, // S_XPLD2
|
||||
{SPR_BOM1, 2, 3, {NULL}, 0, 0, S_XPLD4}, // S_XPLD3
|
||||
{SPR_BOM1, 3, 3, {NULL}, 0, 0, S_XPLD5}, // S_XPLD4
|
||||
{SPR_BOM1, 4, 4, {NULL}, 0, 0, S_XPLD6}, // S_XPLD5
|
||||
{SPR_BOM1, 5, 4, {NULL}, 0, 0, S_NULL}, // S_XPLD6
|
||||
{SPR_BOM1, 0, 0, {A_FlickySpawn}, 0, 0, S_XPLD1}, // S_XPLD_FLICKY
|
||||
{SPR_BOM1, 0, 2, {A_ShadowScream}, 0, 0, S_XPLD2}, // S_XPLD1
|
||||
{SPR_BOM1, 1, 2, {NULL}, 0, 0, S_XPLD3}, // S_XPLD2
|
||||
{SPR_BOM1, 2, 3, {NULL}, 0, 0, S_XPLD4}, // S_XPLD3
|
||||
{SPR_BOM1, 3, 3, {NULL}, 0, 0, S_XPLD5}, // S_XPLD4
|
||||
{SPR_BOM1, 4, 4, {NULL}, 0, 0, S_XPLD6}, // S_XPLD5
|
||||
{SPR_BOM1, 5, 4, {NULL}, 0, 0, S_NULL}, // S_XPLD6
|
||||
|
||||
{SPR_BOM1, FF_ANIMATE, 21, {NULL}, 5, 4, S_INVISIBLE}, // S_XPLD_EGGTRAP
|
||||
|
||||
// Underwater Explosion
|
||||
{SPR_BOM4, 0, 3, {A_Scream}, 0, 0, S_WPLD2}, // S_WPLD1
|
||||
{SPR_BOM4, 1, 3, {NULL}, 0, 0, S_WPLD3}, // S_WPLD2
|
||||
{SPR_BOM4, 2, 3, {NULL}, 0, 0, S_WPLD4}, // S_WPLD3
|
||||
{SPR_BOM4, 3, 3, {NULL}, 0, 0, S_WPLD5}, // S_WPLD4
|
||||
{SPR_BOM4, 4, 3, {NULL}, 0, 0, S_WPLD6}, // S_WPLD5
|
||||
{SPR_BOM4, 5, 3, {NULL}, 0, 0, S_NULL}, // S_WPLD6
|
||||
{SPR_BOM4, 0, 3, {A_ShadowScream}, 0, 0, S_WPLD2}, // S_WPLD1
|
||||
{SPR_BOM4, 1, 3, {NULL}, 0, 0, S_WPLD3}, // S_WPLD2
|
||||
{SPR_BOM4, 2, 3, {NULL}, 0, 0, S_WPLD4}, // S_WPLD3
|
||||
{SPR_BOM4, 3, 3, {NULL}, 0, 0, S_WPLD5}, // S_WPLD4
|
||||
{SPR_BOM4, 4, 3, {NULL}, 0, 0, S_WPLD6}, // S_WPLD5
|
||||
{SPR_BOM4, 5, 3, {NULL}, 0, 0, S_NULL}, // S_WPLD6
|
||||
|
||||
{SPR_DUST, FF_TRANS40, 4, {NULL}, 0, 0, S_DUST2}, // S_DUST1
|
||||
{SPR_DUST, 1|FF_TRANS50, 5, {NULL}, 0, 0, S_DUST3}, // S_DUST2
|
||||
|
|
|
@ -44,6 +44,8 @@ enum actionnum
|
|||
A_FACETRACER,
|
||||
A_SCREAM,
|
||||
A_BOSSDEATH,
|
||||
A_SETSHADOWSCALE,
|
||||
A_SHADOWSCREAM,
|
||||
A_CUSTOMPOWER,
|
||||
A_GIVEWEAPON,
|
||||
A_RINGBOX,
|
||||
|
@ -312,6 +314,8 @@ void A_FaceTarget();
|
|||
void A_FaceTracer();
|
||||
void A_Scream();
|
||||
void A_BossDeath();
|
||||
void A_SetShadowScale();
|
||||
void A_ShadowScream(); // MARIA!!!!!!
|
||||
void A_CustomPower(); // Use this for a custom power
|
||||
void A_GiveWeapon(); // Gives the player weapon(s)
|
||||
void A_RingBox(); // Obtained Ring Box Tails
|
||||
|
|
|
@ -88,6 +88,7 @@ enum line_e {
|
|||
line_v2,
|
||||
line_dx,
|
||||
line_dy,
|
||||
line_angle,
|
||||
line_flags,
|
||||
line_special,
|
||||
line_tag,
|
||||
|
@ -113,6 +114,7 @@ static const char *const line_opt[] = {
|
|||
"v2",
|
||||
"dx",
|
||||
"dy",
|
||||
"angle",
|
||||
"flags",
|
||||
"special",
|
||||
"tag",
|
||||
|
@ -823,6 +825,9 @@ static int line_get(lua_State *L)
|
|||
case line_dy:
|
||||
lua_pushfixed(L, line->dy);
|
||||
return 1;
|
||||
case line_angle:
|
||||
lua_pushangle(L, line->angle);
|
||||
return 1;
|
||||
case line_flags:
|
||||
lua_pushinteger(L, line->flags);
|
||||
return 1;
|
||||
|
|
22
src/m_menu.c
22
src/m_menu.c
|
@ -4751,7 +4751,7 @@ static void M_DrawPauseMenu(void)
|
|||
emblemslot = 2;
|
||||
break;
|
||||
case ET_NGRADE:
|
||||
snprintf(targettext, 9, "%u", P_GetScoreForGrade(gamemap, 0, emblem->var));
|
||||
snprintf(targettext, 9, "%u", P_GetScoreForGradeOverall(gamemap, emblem->var));
|
||||
snprintf(currenttext, 9, "%u", G_GetBestNightsScore(gamemap, 0));
|
||||
|
||||
targettext[8] = 0;
|
||||
|
@ -5408,11 +5408,13 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
|
|||
|
||||
if (actnum)
|
||||
sprintf(mapname, "%s %d", mapheaderinfo[headingIterate]->lvlttl, actnum);
|
||||
else if (V_ThinStringWidth(mapheaderinfo[headingIterate]->lvlttl, 0) <= 80)
|
||||
strlcpy(mapname, mapheaderinfo[headingIterate]->lvlttl, 22);
|
||||
else
|
||||
strcpy(mapname, mapheaderinfo[headingIterate]->lvlttl);
|
||||
|
||||
if (strlen(mapname) >= 17)
|
||||
strcpy(mapname+17-3, "...");
|
||||
{
|
||||
strlcpy(mapname, mapheaderinfo[headingIterate]->lvlttl, 15);
|
||||
strcat(mapname, "...");
|
||||
}
|
||||
|
||||
strcpy(levelselect.rows[row].mapnames[col], (const char *)mapname);
|
||||
}
|
||||
|
@ -5747,7 +5749,7 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea
|
|||
? 159 : 63));
|
||||
|
||||
if (strlen(levelselect.rows[row].mapnames[col]) > 6) // "AERIAL GARDEN" vs "ACT 18" - "THE ACT" intentionally compressed
|
||||
V_DrawThinString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]);
|
||||
V_DrawThinString(x, y+50+1, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]);
|
||||
else
|
||||
V_DrawString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]);
|
||||
}
|
||||
|
@ -8748,12 +8750,12 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
|||
|
||||
if(!mapheaderinfo[(fake-1) & 8191])
|
||||
savegameinfo[slot].levelname[0] = '\0';
|
||||
else if (V_ThinStringWidth(mapheaderinfo[(fake-1) & 8191]->lvlttl, 0) <= 78)
|
||||
strlcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl, 22);
|
||||
else
|
||||
{
|
||||
strlcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl, 17+1);
|
||||
|
||||
if (strlen(mapheaderinfo[(fake-1) & 8191]->lvlttl) >= 17)
|
||||
strcpy(savegameinfo[slot].levelname+17-3, "...");
|
||||
strlcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl, 15);
|
||||
strcat(savegameinfo[slot].levelname, "...");
|
||||
}
|
||||
|
||||
savegameinfo[slot].gamemap = fake;
|
||||
|
|
|
@ -389,9 +389,9 @@ typedef struct
|
|||
// level select platter
|
||||
typedef struct
|
||||
{
|
||||
char header[22+5]; // mapheader_t lvltttl max length + " ZONE"
|
||||
char header[22+5]; // mapheader_t lvlttl max length + " ZONE"
|
||||
INT32 maplist[3];
|
||||
char mapnames[3][17+1];
|
||||
char mapnames[3][22]; // lvlttl max length
|
||||
boolean mapavailable[4]; // mapavailable[3] == wide or not
|
||||
} levelselectrow_t;
|
||||
|
||||
|
|
|
@ -107,6 +107,8 @@ void A_GoldMonitorRestore(mobj_t *actor);
|
|||
void A_GoldMonitorSparkle(mobj_t *actor);
|
||||
void A_Explode(mobj_t *actor);
|
||||
void A_BossDeath(mobj_t *actor);
|
||||
void A_SetShadowScale(mobj_t *actor);
|
||||
void A_ShadowScream(mobj_t *actor);
|
||||
void A_CustomPower(mobj_t *actor);
|
||||
void A_GiveWeapon(mobj_t *actor);
|
||||
void A_RingBox(mobj_t *actor);
|
||||
|
@ -4169,6 +4171,41 @@ bossjustdie:
|
|||
}
|
||||
}
|
||||
|
||||
// Function: A_SetShadowScale
|
||||
//
|
||||
// Description: Sets the target's shadowscale.
|
||||
//
|
||||
// var1 = new fixed_t shadowscale (default = FRACUNIT)
|
||||
// var2 = unused
|
||||
//
|
||||
void A_SetShadowScale(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
|
||||
if (LUA_CallAction(A_SETSHADOWSCALE, actor))
|
||||
return;
|
||||
|
||||
actor->shadowscale = locvar1;
|
||||
}
|
||||
|
||||
|
||||
// Function: A_ShadowScream
|
||||
//
|
||||
// Description: Sets the target's shadowscale and starts the death sound of the object.
|
||||
//
|
||||
// var1 = new fixed_t shadowscale (default = FRACUNIT)
|
||||
// var2 = unused
|
||||
//
|
||||
void A_ShadowScream(mobj_t *actor)
|
||||
{
|
||||
if (LUA_CallAction(A_SHADOWSCREAM, actor))
|
||||
return;
|
||||
|
||||
A_SetShadowScale(actor);
|
||||
A_Scream(actor);
|
||||
}
|
||||
|
||||
|
||||
// Function: A_CustomPower
|
||||
//
|
||||
// Description: Provides a custom powerup. Target (must be a player) is awarded the powerup. Reactiontime of the object is used as an index to the powers array.
|
||||
|
|
|
@ -3101,7 +3101,7 @@ static void P_HitCameraSlideLine(line_t *ld, camera_t *thiscam)
|
|||
}
|
||||
|
||||
side = P_PointOnLineSide(thiscam->x, thiscam->y, ld);
|
||||
lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
|
||||
lineangle = ld->angle;
|
||||
|
||||
if (side == 1)
|
||||
lineangle += ANGLE_180;
|
||||
|
@ -3147,7 +3147,7 @@ static void P_HitSlideLine(line_t *ld)
|
|||
|
||||
side = P_PointOnLineSide(slidemo->x, slidemo->y, ld);
|
||||
|
||||
lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
|
||||
lineangle = ld->angle;
|
||||
|
||||
if (side == 1)
|
||||
lineangle += ANGLE_180;
|
||||
|
@ -3190,7 +3190,7 @@ static void P_HitBounceLine(line_t *ld)
|
|||
return;
|
||||
}
|
||||
|
||||
lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
|
||||
lineangle = ld->angle;
|
||||
|
||||
if (lineangle >= ANGLE_180)
|
||||
lineangle -= ANGLE_180;
|
||||
|
|
32
src/p_mobj.c
32
src/p_mobj.c
|
@ -7864,7 +7864,8 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
case MT_WOODDEBRIS:
|
||||
case MT_BRICKDEBRIS:
|
||||
case MT_BROKENROBOT:
|
||||
if (mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height)
|
||||
if (((!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height))
|
||||
|| (mobj->eflags & MFE_VERTICALFLIP && mobj->z + mobj->height >= P_CeilingzAtPos(mobj->x, mobj->y, mobj->z, mobj->height)))
|
||||
&& mobj->state != &states[mobj->info->deathstate])
|
||||
{
|
||||
P_SetMobjState(mobj, mobj->info->deathstate);
|
||||
|
@ -8433,7 +8434,10 @@ static boolean P_HangsterThink(mobj_t *mobj)
|
|||
}
|
||||
//after swooping back up, check for ceiling
|
||||
else if ((st == S_HANGSTER_RETURN1 || st == S_HANGSTER_RETURN2) && mobj->momz == 0 && mobj->ceilingz == (mobj->z + mobj->height))
|
||||
{
|
||||
P_SetMobjState(mobj, (st = S_HANGSTER_RETURN3));
|
||||
mobj->momx = mobj->momy = 0;
|
||||
}
|
||||
|
||||
//should you roost on a ceiling with F_SKY1 as its flat, disappear forever
|
||||
if (st == S_HANGSTER_RETURN3 && mobj->momz == 0 && mobj->ceilingz == (mobj->z + mobj->height)
|
||||
|
@ -9723,7 +9727,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
if (P_IsObjectOnGround(mobj))
|
||||
mobj->rollangle = 0;
|
||||
else
|
||||
mobj->rollangle = R_PointToAngle2(0, 0, mobj->momz, (mobj->scale << 1) - min(abs(mobj->momz), mobj->scale << 1));
|
||||
mobj->rollangle = R_PointToAngle2(0, 0, P_MobjFlip(mobj)*mobj->momz, (mobj->scale << 1) - min(abs(mobj->momz), mobj->scale << 1));
|
||||
break;
|
||||
case MT_SPINFIRE:
|
||||
if (mobj->flags & MF_NOGRAVITY)
|
||||
|
@ -10412,6 +10416,7 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing)
|
|||
switch (thing->type)
|
||||
{
|
||||
case MT_PLAYER:
|
||||
case MT_METALSONIC_RACE:
|
||||
case MT_ROLLOUTROCK:
|
||||
|
||||
case MT_EGGMOBILE4_MACE:
|
||||
|
@ -10456,6 +10461,27 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing)
|
|||
|
||||
return 2*FRACUNIT/3;
|
||||
|
||||
case MT_FLICKY_01:
|
||||
case MT_FLICKY_02:
|
||||
case MT_FLICKY_03:
|
||||
case MT_FLICKY_04:
|
||||
case MT_FLICKY_05:
|
||||
case MT_FLICKY_06:
|
||||
case MT_FLICKY_07:
|
||||
case MT_FLICKY_08:
|
||||
case MT_FLICKY_09:
|
||||
case MT_FLICKY_10:
|
||||
case MT_FLICKY_11:
|
||||
case MT_FLICKY_12:
|
||||
case MT_FLICKY_13:
|
||||
case MT_FLICKY_14:
|
||||
case MT_FLICKY_15:
|
||||
case MT_FLICKY_16:
|
||||
case MT_SECRETFLICKY_01:
|
||||
case MT_SECRETFLICKY_02:
|
||||
|
||||
return FRACUNIT;
|
||||
|
||||
default:
|
||||
|
||||
if (thing->flags & (MF_ENEMY|MF_BOSS))
|
||||
|
@ -10477,7 +10503,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
|
||||
if (type == MT_NULL)
|
||||
{
|
||||
#if 0
|
||||
#if 0
|
||||
#ifdef PARANOIA
|
||||
I_Error("Tried to spawn MT_NULL\n");
|
||||
#endif
|
||||
|
|
|
@ -785,7 +785,7 @@ static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo)
|
|||
vertex_t closest;
|
||||
|
||||
// calculate angle of line and subtract 90 degrees to get normal
|
||||
lineangle = R_PointToAngle2(0, 0, line->dx, line->dy) - ANGLE_90;
|
||||
lineangle = line->angle - ANGLE_90;
|
||||
lineangle >>= ANGLETOFINESHIFT;
|
||||
momx = FixedMul(po->thrust, FINECOSINE(lineangle));
|
||||
momy = FixedMul(po->thrust, FINESINE(lineangle));
|
||||
|
@ -1060,6 +1060,8 @@ static void Polyobj_rotateLine(line_t *ld)
|
|||
ld->dx = v2->x - v1->x;
|
||||
ld->dy = v2->y - v1->y;
|
||||
|
||||
ld->angle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
|
||||
|
||||
// determine slopetype
|
||||
ld->slopetype = !ld->dx ? ST_VERTICAL : !ld->dy ? ST_HORIZONTAL :
|
||||
((ld->dy > 0) == (ld->dx > 0)) ? ST_POSITIVE : ST_NEGATIVE;
|
||||
|
|
|
@ -508,6 +508,17 @@ UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade)
|
|||
return mapheaderinfo[map-1]->grades[mare].grade[grade-1];
|
||||
}
|
||||
|
||||
UINT32 P_GetScoreForGradeOverall(INT16 map, UINT8 grade)
|
||||
{
|
||||
UINT8 mares;
|
||||
INT32 i;
|
||||
UINT32 score = 0;
|
||||
mares = mapheaderinfo[map-1]->numGradedMares;
|
||||
for (i = 0; i < mares; ++i)
|
||||
score += P_GetScoreForGrade(map, i, grade);
|
||||
return score;
|
||||
}
|
||||
|
||||
//
|
||||
// levelflats
|
||||
//
|
||||
|
@ -1058,6 +1069,8 @@ static void P_InitializeLinedef(line_t *ld)
|
|||
ld->dx = v2->x - v1->x;
|
||||
ld->dy = v2->y - v1->y;
|
||||
|
||||
ld->angle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
|
||||
|
||||
ld->bbox[BOXLEFT] = min(v1->x, v2->x);
|
||||
ld->bbox[BOXRIGHT] = max(v1->x, v2->x);
|
||||
ld->bbox[BOXBOTTOM] = min(v1->y, v2->y);
|
||||
|
@ -4725,7 +4738,7 @@ static boolean P_LoadAddon(UINT16 wadnum, UINT16 numlumps)
|
|||
// Reload it all anyway, just in case they
|
||||
// added some textures but didn't insert a
|
||||
// TEXTURES/etc. list.
|
||||
R_LoadTextures(); // numtexture changes
|
||||
R_LoadTexturesPwad(wadnum); // numtexture changes
|
||||
|
||||
// Reload ANIMDEFS
|
||||
P_InitPicAnims();
|
||||
|
|
|
@ -122,5 +122,6 @@ void P_AddGradesForMare(INT16 i, UINT8 mare, char *gtext);
|
|||
UINT8 P_GetGrade(UINT32 pscore, INT16 map, UINT8 mare);
|
||||
UINT8 P_HasGrades(INT16 map, UINT8 mare);
|
||||
UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade);
|
||||
UINT32 P_GetScoreForGradeOverall(INT16 map, UINT8 grade);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1241,7 +1241,7 @@ static boolean PolyFlag(line_t *line)
|
|||
|
||||
pfd.polyObjNum = Tag_FGet(&line->tags);
|
||||
pfd.speed = P_AproxDistance(line->dx, line->dy) >> FRACBITS;
|
||||
pfd.angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y) >> ANGLETOFINESHIFT;
|
||||
pfd.angle = line->angle >> ANGLETOFINESHIFT;
|
||||
pfd.momx = sides[line->sidenum[0]].textureoffset >> FRACBITS;
|
||||
|
||||
return EV_DoPolyObjFlag(&pfd);
|
||||
|
|
32
src/p_user.c
32
src/p_user.c
|
@ -2054,12 +2054,22 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
|||
|
||||
ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle);
|
||||
ghost->rollangle = mobj->rollangle;
|
||||
|
||||
ghost->sprite = mobj->sprite;
|
||||
ghost->sprite2 = mobj->sprite2;
|
||||
ghost->frame = mobj->frame;
|
||||
ghost->tics = -1;
|
||||
ghost->frame &= ~FF_TRANSMASK;
|
||||
ghost->frame |= tr_trans50<<FF_TRANSSHIFT;
|
||||
|
||||
ghost->renderflags = mobj->renderflags;
|
||||
ghost->blendmode = mobj->blendmode;
|
||||
|
||||
ghost->spritexscale = mobj->spritexscale;
|
||||
ghost->spriteyscale = mobj->spriteyscale;
|
||||
ghost->spritexoffset = mobj->spritexoffset;
|
||||
ghost->spriteyoffset = mobj->spriteyoffset;
|
||||
|
||||
ghost->fuse = ghost->info->damage;
|
||||
ghost->skin = mobj->skin;
|
||||
|
||||
|
@ -6695,7 +6705,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad
|
|||
//
|
||||
static void P_DoNiGHTSCapsule(player_t *player)
|
||||
{
|
||||
INT32 i, spherecount, totalduration, popduration, deductinterval, deductquantity, sphereresult, firstpoptic, startingspheres;
|
||||
INT32 i, spherecount, totalduration, popduration, deductinterval, deductquantity, sphereresult, firstpoptic;
|
||||
INT32 tictimer = ++player->capsule->extravalue2;
|
||||
|
||||
if (abs(player->mo->x-player->capsule->x) <= 3*FRACUNIT)
|
||||
|
@ -6818,15 +6828,20 @@ static void P_DoNiGHTSCapsule(player_t *player)
|
|||
|
||||
if (player->capsule->health > sphereresult && player->spheres > 0)
|
||||
{
|
||||
// If spherecount isn't a multiple of deductquantity, the final deduction might steal too many spheres from the player
|
||||
// E.g. with 80 capsule health, deductquantity is 3, 3*26 is 78, 78+3=81, and then it'll have stolen more than the 80 that it was meant to!
|
||||
// So let's adjust deductquantity accordingly for the final deduction
|
||||
deductquantity = min(deductquantity, player->capsule->health - sphereresult);
|
||||
|
||||
player->spheres -= deductquantity;
|
||||
player->capsule->health -= deductquantity;
|
||||
|
||||
if (player->spheres < 0) // This can't happen... without Lua, setrings, et cetera
|
||||
player->spheres = 0;
|
||||
|
||||
//if (player->capsule->health < sphereresult) // This can't happen
|
||||
//player->capsule->health = sphereresult;
|
||||
}
|
||||
|
||||
if (player->spheres < 0)
|
||||
player->spheres = 0;
|
||||
|
||||
if (player->capsule->health < sphereresult)
|
||||
player->capsule->health = sphereresult;
|
||||
}
|
||||
|
||||
// Spawn a 'pop' for every 2 tics
|
||||
|
@ -6847,9 +6862,8 @@ static void P_DoNiGHTSCapsule(player_t *player)
|
|||
}
|
||||
else
|
||||
{
|
||||
startingspheres = player->spheres - player->capsule->health;
|
||||
player->spheres -= player->capsule->health;
|
||||
player->capsule->health = 0;
|
||||
player->spheres = startingspheres;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -387,6 +387,7 @@ typedef struct line_s
|
|||
vertex_t *v2;
|
||||
|
||||
fixed_t dx, dy; // Precalculated v2 - v1 for side checking.
|
||||
angle_t angle; // Precalculated angle between dx and dy
|
||||
|
||||
// Animation related.
|
||||
INT16 flags;
|
||||
|
|
|
@ -105,6 +105,7 @@ typedef struct
|
|||
} spriteinfo_t;
|
||||
|
||||
// Portable Network Graphics
|
||||
#define PNG_HEADER_SIZE (8)
|
||||
boolean Picture_IsLumpPNG(const UINT8 *d, size_t s);
|
||||
#define Picture_ThrowPNGError(lumpname, wadfilename) I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .png - please convert to either Doom or Flat (raw) image format.", lumpname, wadfilename); // Fears Of LJ Sonic
|
||||
|
||||
|
|
283
src/r_textures.c
283
src/r_textures.c
|
@ -59,6 +59,7 @@ INT32 *texturetranslation;
|
|||
// Painfully simple texture id cacheing to make maps load faster. :3
|
||||
static struct {
|
||||
char name[9];
|
||||
UINT32 hash;
|
||||
INT32 id;
|
||||
} *tidcache = NULL;
|
||||
static INT32 tidcachelen = 0;
|
||||
|
@ -725,6 +726,7 @@ Rloadflats (INT32 i, INT32 w)
|
|||
UINT16 texstart, texend;
|
||||
texture_t *texture;
|
||||
texpatch_t *patch;
|
||||
UINT8 header[PNG_HEADER_SIZE];
|
||||
|
||||
// Yes
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
|
@ -743,7 +745,6 @@ Rloadflats (INT32 i, INT32 w)
|
|||
// Work through each lump between the markers in the WAD.
|
||||
for (j = 0; j < (texend - texstart); j++)
|
||||
{
|
||||
UINT8 *flatlump;
|
||||
UINT16 wadnum = (UINT16)w;
|
||||
lumpnum_t lumpnum = texstart + j;
|
||||
size_t lumplength;
|
||||
|
@ -755,7 +756,7 @@ Rloadflats (INT32 i, INT32 w)
|
|||
continue; // If it is then SKIP IT
|
||||
}
|
||||
|
||||
flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
W_ReadLumpHeaderPwad(wadnum, lumpnum, header, sizeof header, 0);
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
|
||||
switch (lumplength)
|
||||
|
@ -788,14 +789,17 @@ Rloadflats (INT32 i, INT32 w)
|
|||
|
||||
// Set texture properties.
|
||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
texture->hash = quickncasehash(texture->name, 8);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)flatlump, lumplength))
|
||||
if (Picture_IsLumpPNG(header, lumplength))
|
||||
{
|
||||
UINT8 *flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
INT32 width, height;
|
||||
Picture_PNGDimensions((UINT8 *)flatlump, &width, &height, NULL, NULL, lumplength);
|
||||
texture->width = (INT16)width;
|
||||
texture->height = (INT16)height;
|
||||
Z_Free(flatlump);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -814,8 +818,6 @@ Rloadflats (INT32 i, INT32 w)
|
|||
patch->lump = texstart + j;
|
||||
patch->flip = 0;
|
||||
|
||||
Z_Unlock(flatlump);
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
|
@ -835,8 +837,8 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
UINT16 j;
|
||||
UINT16 texstart, texend, texturesLumpPos;
|
||||
texture_t *texture;
|
||||
softwarepatch_t *patchlump;
|
||||
texpatch_t *patch;
|
||||
softwarepatch_t patchlump;
|
||||
|
||||
// Get the lump numbers for the markers in the WAD, if they exist.
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
|
@ -876,7 +878,7 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
continue; // If it is then SKIP IT
|
||||
}
|
||||
|
||||
patchlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
W_ReadLumpHeaderPwad(wadnum, lumpnum, &patchlump, PNG_HEADER_SIZE, 0);
|
||||
#ifndef NO_PNG_LUMPS
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
#endif
|
||||
|
@ -886,20 +888,23 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
|
||||
// Set texture properties.
|
||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
texture->hash = quickncasehash(texture->name, 8);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)patchlump, lumplength))
|
||||
if (Picture_IsLumpPNG((UINT8 *)&patchlump, lumplength))
|
||||
{
|
||||
UINT8 *png = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
INT32 width, height;
|
||||
Picture_PNGDimensions((UINT8 *)patchlump, &width, &height, NULL, NULL, lumplength);
|
||||
Picture_PNGDimensions(png, &width, &height, NULL, NULL, lumplength);
|
||||
texture->width = (INT16)width;
|
||||
texture->height = (INT16)height;
|
||||
Z_Free(png);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
texture->width = SHORT(patchlump->width);
|
||||
texture->height = SHORT(patchlump->height);
|
||||
texture->width = SHORT(patchlump.width);
|
||||
texture->height = SHORT(patchlump.height);
|
||||
}
|
||||
|
||||
texture->type = TEXTURETYPE_SINGLEPATCH;
|
||||
|
@ -915,8 +920,6 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
patch->lump = texstart + j;
|
||||
patch->flip = 0;
|
||||
|
||||
Z_Unlock(patchlump);
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
|
@ -926,27 +929,53 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
return i;
|
||||
}
|
||||
|
||||
//
|
||||
// R_LoadTextures
|
||||
// Initializes the texture list with the textures from the world map.
|
||||
//
|
||||
void R_LoadTextures(void)
|
||||
static INT32
|
||||
count_range
|
||||
( const char * marker_start,
|
||||
const char * marker_end,
|
||||
const char * folder,
|
||||
UINT16 wadnum)
|
||||
{
|
||||
INT32 i, w;
|
||||
UINT16 j;
|
||||
UINT16 texstart, texend, texturesLumpPos;
|
||||
UINT16 texstart, texend;
|
||||
INT32 count = 0;
|
||||
|
||||
// Free previous memory before numtextures change.
|
||||
if (numtextures)
|
||||
// Count flats
|
||||
if (W_FileHasFolders(wadfiles[wadnum]))
|
||||
{
|
||||
for (i = 0; i < numtextures; i++)
|
||||
{
|
||||
Z_Free(textures[i]);
|
||||
Z_Free(texturecache[i]);
|
||||
}
|
||||
Z_Free(texturetranslation);
|
||||
Z_Free(textures);
|
||||
texstart = W_CheckNumForFolderStartPK3(folder, wadnum, 0);
|
||||
texend = W_CheckNumForFolderEndPK3(folder, wadnum, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForMarkerStartPwad(marker_start, wadnum, 0);
|
||||
texend = W_CheckNumForNamePwad(marker_end, wadnum, texstart);
|
||||
}
|
||||
|
||||
if (texstart != INT16_MAX && texend != INT16_MAX)
|
||||
{
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (W_FileHasFolders(wadfiles[wadnum]))
|
||||
{
|
||||
for (j = texstart; j < texend; j++)
|
||||
{
|
||||
if (!W_IsLumpFolder(wadnum, j)) // Check if lump is a folder; if not, then count it
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else // Add all the textures between markers
|
||||
{
|
||||
count += (texend - texstart);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static INT32 R_CountTextures(UINT16 wadnum)
|
||||
{
|
||||
UINT16 texturesLumpPos;
|
||||
INT32 count = 0;
|
||||
|
||||
// Load patches and textures.
|
||||
|
||||
|
@ -955,113 +984,132 @@ void R_LoadTextures(void)
|
|||
// the markers.
|
||||
// This system will allocate memory for all duplicate/patched textures even if it never uses them,
|
||||
// but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures.
|
||||
for (w = 0, numtextures = 0; w < numwadfiles; w++)
|
||||
{
|
||||
|
||||
#ifdef WALLFLATS
|
||||
// Count flats
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForMarkerStartPwad("F_START", (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
|
||||
}
|
||||
count += count_range("F_START", "F_END", "flats/", wadnum);
|
||||
#endif
|
||||
|
||||
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
|
||||
{
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
for (j = texstart; j < texend; j++)
|
||||
{
|
||||
if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
|
||||
numtextures++;
|
||||
}
|
||||
}
|
||||
else // Add all the textures between F_START and F_END
|
||||
{
|
||||
numtextures += (UINT32)(texend - texstart);
|
||||
}
|
||||
}
|
||||
#endif/*WALLFLATS*/
|
||||
// Count the textures from TEXTURES lumps
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, 0);
|
||||
|
||||
// Count the textures from TEXTURES lumps
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||
}
|
||||
|
||||
// Count single-patch textures
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
continue;
|
||||
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
for (j = texstart; j < texend; j++)
|
||||
{
|
||||
if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
|
||||
numtextures++;
|
||||
}
|
||||
}
|
||||
else // Add all the textures between TX_START and TX_END
|
||||
{
|
||||
numtextures += (UINT32)(texend - texstart);
|
||||
}
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
count += R_CountTexturesInTEXTURESLump(wadnum, texturesLumpPos);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, texturesLumpPos + 1);
|
||||
}
|
||||
|
||||
// If no textures found by this point, bomb out
|
||||
if (!numtextures)
|
||||
I_Error("No textures detected in any WADs!\n");
|
||||
// Count single-patch textures
|
||||
count += count_range(TX_START, TX_END, "textures/", wadnum);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
recallocuser
|
||||
( void * user,
|
||||
size_t old,
|
||||
size_t new)
|
||||
{
|
||||
char *p = Z_Realloc(*(void**)user,
|
||||
new, PU_STATIC, user);
|
||||
|
||||
if (new > old)
|
||||
memset(&p[old], 0, (new - old));
|
||||
}
|
||||
|
||||
static void R_AllocateTextures(INT32 add)
|
||||
{
|
||||
const INT32 newtextures = (numtextures + add);
|
||||
const size_t newsize = newtextures * sizeof (void*);
|
||||
const size_t oldsize = numtextures * sizeof (void*);
|
||||
|
||||
INT32 i;
|
||||
|
||||
// Allocate memory and initialize to 0 for all the textures we are initialising.
|
||||
// There are actually 5 buffers allocated in one for convenience.
|
||||
textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL);
|
||||
recallocuser(&textures, oldsize, newsize);
|
||||
|
||||
// Allocate texture column offset table.
|
||||
texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *)));
|
||||
recallocuser(&texturecolumnofs, oldsize, newsize);
|
||||
// Allocate texture referencing cache.
|
||||
texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2));
|
||||
recallocuser(&texturecache, oldsize, newsize);
|
||||
// Allocate texture width table.
|
||||
texturewidth = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3));
|
||||
recallocuser(&texturewidth, oldsize, newsize);
|
||||
// Allocate texture height table.
|
||||
textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4));
|
||||
recallocuser(&textureheight, oldsize, newsize);
|
||||
// Create translation table for global animation.
|
||||
texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL);
|
||||
Z_Realloc(texturetranslation, (newtextures + 1) * sizeof(*texturetranslation), PU_STATIC, &texturetranslation);
|
||||
|
||||
for (i = 0; i < numtextures; i++)
|
||||
texturetranslation[i] = i;
|
||||
|
||||
for (i = 0, w = 0; w < numwadfiles; w++)
|
||||
for (i = 0; i < numtextures; ++i)
|
||||
{
|
||||
#ifdef WALLFLATS
|
||||
i = Rloadflats(i, w);
|
||||
#endif
|
||||
i = Rloadtextures(i, w);
|
||||
// R_FlushTextureCache relies on the user for
|
||||
// Z_Free, texturecache has been reallocated so the
|
||||
// user is now garbage memory.
|
||||
Z_SetUser(texturecache[i],
|
||||
(void**)&texturecache[i]);
|
||||
}
|
||||
|
||||
while (i < newtextures)
|
||||
{
|
||||
texturetranslation[i] = i;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static INT32 R_DefineTextures(INT32 i, UINT16 w)
|
||||
{
|
||||
#ifdef WALLFLATS
|
||||
i = Rloadflats(i, w);
|
||||
#endif
|
||||
return Rloadtextures(i, w);
|
||||
}
|
||||
|
||||
static void R_FinishLoadingTextures(INT32 add)
|
||||
{
|
||||
numtextures += add;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
HWR_LoadMapTextures(numtextures);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// R_LoadTextures
|
||||
// Initializes the texture list with the textures from the world map.
|
||||
//
|
||||
void R_LoadTextures(void)
|
||||
{
|
||||
INT32 i, w;
|
||||
INT32 newtextures = 0;
|
||||
|
||||
for (w = 0; w < numwadfiles; w++)
|
||||
{
|
||||
newtextures += R_CountTextures((UINT16)w);
|
||||
}
|
||||
|
||||
// If no textures found by this point, bomb out
|
||||
if (!newtextures)
|
||||
I_Error("No textures detected in any WADs!\n");
|
||||
|
||||
R_AllocateTextures(newtextures);
|
||||
|
||||
for (i = 0, w = 0; w < numwadfiles; w++)
|
||||
{
|
||||
i = R_DefineTextures(i, w);
|
||||
}
|
||||
|
||||
R_FinishLoadingTextures(newtextures);
|
||||
}
|
||||
|
||||
void R_LoadTexturesPwad(UINT16 wadnum)
|
||||
{
|
||||
INT32 newtextures = R_CountTextures(wadnum);
|
||||
|
||||
R_AllocateTextures(newtextures);
|
||||
R_DefineTextures(numtextures, wadnum);
|
||||
R_FinishLoadingTextures(newtextures);
|
||||
}
|
||||
|
||||
static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)
|
||||
{
|
||||
char *texturesToken;
|
||||
|
@ -1368,6 +1416,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture)
|
|||
// Allocate memory for a zero-patch texture. Obviously, we'll be adding patches momentarily.
|
||||
resultTexture = (texture_t *)Z_Calloc(sizeof(texture_t),PU_STATIC,NULL);
|
||||
M_Memcpy(resultTexture->name, newTextureName, 8);
|
||||
resultTexture->hash = quickncasehash(newTextureName, 8);
|
||||
resultTexture->width = newTextureWidth;
|
||||
resultTexture->height = newTextureHeight;
|
||||
resultTexture->type = TEXTURETYPE_COMPOSITE;
|
||||
|
@ -1594,19 +1643,22 @@ void R_ClearTextureNumCache(boolean btell)
|
|||
INT32 R_CheckTextureNumForName(const char *name)
|
||||
{
|
||||
INT32 i;
|
||||
UINT32 hash;
|
||||
|
||||
// "NoTexture" marker.
|
||||
if (name[0] == '-')
|
||||
return 0;
|
||||
|
||||
hash = quickncasehash(name, 8);
|
||||
|
||||
for (i = 0; i < tidcachelen; i++)
|
||||
if (!strncasecmp(tidcache[i].name, name, 8))
|
||||
if (tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8))
|
||||
return tidcache[i].id;
|
||||
|
||||
// Need to parse the list backwards, so textures loaded more recently are used in lieu of ones loaded earlier
|
||||
//for (i = 0; i < numtextures; i++) <- old
|
||||
for (i = (numtextures - 1); i >= 0; i--) // <- new
|
||||
if (!strncasecmp(textures[i]->name, name, 8))
|
||||
if (textures[i]->hash == hash && !strncasecmp(textures[i]->name, name, 8))
|
||||
{
|
||||
tidcachelen++;
|
||||
Z_Realloc(tidcache, tidcachelen * sizeof(*tidcache), PU_STATIC, &tidcache);
|
||||
|
@ -1615,6 +1667,7 @@ INT32 R_CheckTextureNumForName(const char *name)
|
|||
#ifndef ZDEBUG
|
||||
CONS_Debug(DBG_SETUP, "texture #%s: %s\n", sizeu1(tidcachelen), tidcache[tidcachelen-1].name);
|
||||
#endif
|
||||
tidcache[tidcachelen-1].hash = hash;
|
||||
tidcache[tidcachelen-1].id = i;
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ typedef struct
|
|||
{
|
||||
// Keep name for switch changing, etc.
|
||||
char name[8];
|
||||
UINT32 hash;
|
||||
UINT8 type; // TEXTURETYPE_
|
||||
INT16 width, height;
|
||||
boolean holes;
|
||||
|
@ -76,6 +77,7 @@ extern UINT8 **texturecache; // graphics data for each generated full-size textu
|
|||
|
||||
// Load TEXTURES definitions, create lookup tables
|
||||
void R_LoadTextures(void);
|
||||
void R_LoadTexturesPwad(UINT16 wadnum);
|
||||
void R_FlushTextureCache(void);
|
||||
|
||||
// Texture generation
|
||||
|
|
139
src/r_things.c
139
src/r_things.c
|
@ -1275,6 +1275,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
vissprite_t *shadow;
|
||||
patch_t *patch;
|
||||
fixed_t xscale, yscale, shadowxscale, shadowyscale, shadowskew, x1, x2;
|
||||
INT32 heightsec, phs;
|
||||
INT32 light = 0;
|
||||
fixed_t scalemul; UINT8 trans;
|
||||
fixed_t floordiff;
|
||||
|
@ -1286,6 +1287,24 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
|
||||
if (abs(groundz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes
|
||||
|
||||
heightsec = thing->subsector->sector->heightsec;
|
||||
if (viewplayer->mo && viewplayer->mo->subsector)
|
||||
phs = viewplayer->mo->subsector->sector->heightsec;
|
||||
else
|
||||
phs = -1;
|
||||
|
||||
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
|
||||
{
|
||||
if (viewz < sectors[phs].floorheight ?
|
||||
groundz >= sectors[heightsec].floorheight :
|
||||
groundz < sectors[heightsec].floorheight)
|
||||
return;
|
||||
if (viewz > sectors[phs].ceilingheight ?
|
||||
groundz < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight :
|
||||
groundz >= sectors[heightsec].ceilingheight)
|
||||
return;
|
||||
}
|
||||
|
||||
floordiff = abs((isflipped ? thing->height : 0) + thing->z - groundz);
|
||||
|
||||
trans = floordiff / (100*FRACUNIT) + 3;
|
||||
|
@ -1591,8 +1610,17 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
#ifdef ROTSPRITE
|
||||
if (papersprite)
|
||||
rollangle = (ang >= ANGLE_180 ? -1 : 1) * thing->pitch // pitch should flip the sprite rotation on one side of the papersprite
|
||||
+ thing->rollangle; // rollangle should use the same rotation for both sides of a papersprite
|
||||
{
|
||||
if (ang >= ANGLE_180)
|
||||
{
|
||||
// Makes Software act much more sane like OpenGL
|
||||
rollangle = InvAngle(thing->rollangle);
|
||||
}
|
||||
else
|
||||
{
|
||||
rollangle = thing->rollangle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rollangle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), thing->roll)
|
||||
|
@ -1952,13 +1980,19 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
|
||||
{
|
||||
fixed_t top = gzt;
|
||||
fixed_t bottom = thing->z;
|
||||
|
||||
if (splat)
|
||||
top = bottom;
|
||||
|
||||
if (viewz < sectors[phs].floorheight ?
|
||||
thing->z >= sectors[heightsec].floorheight :
|
||||
gzt < sectors[heightsec].floorheight)
|
||||
bottom >= sectors[heightsec].floorheight :
|
||||
top < sectors[heightsec].floorheight)
|
||||
return;
|
||||
if (viewz > sectors[phs].ceilingheight ?
|
||||
gzt < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight :
|
||||
thing->z >= sectors[heightsec].ceilingheight)
|
||||
top < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight :
|
||||
bottom >= sectors[heightsec].ceilingheight)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2832,6 +2866,57 @@ static void R_DrawPrecipitationSprite(vissprite_t *spr)
|
|||
R_DrawPrecipitationVisSprite(spr);
|
||||
}
|
||||
|
||||
//SoM: 3/17/2000: Clip sprites in water.
|
||||
static void R_HeightSecClip(vissprite_t *spr, INT32 x1, INT32 x2)
|
||||
{
|
||||
fixed_t mh, h;
|
||||
INT32 x, phs;
|
||||
|
||||
if (spr->heightsec == -1)
|
||||
return;
|
||||
|
||||
if (spr->cut & (SC_SPLAT | SC_SHADOW) || spr->renderflags & RF_SHADOWDRAW)
|
||||
return;
|
||||
|
||||
phs = viewplayer->mo->subsector->sector->heightsec;
|
||||
|
||||
if ((mh = sectors[spr->heightsec].floorheight) > spr->gz &&
|
||||
(h = centeryfrac - FixedMul(mh -= viewz, spr->sortscale)) >= 0 &&
|
||||
(h >>= FRACBITS) < viewheight)
|
||||
{
|
||||
if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight))
|
||||
{ // clip bottom
|
||||
for (x = x1; x <= x2; x++)
|
||||
if (spr->clipbot[x] == -2 || h < spr->clipbot[x])
|
||||
spr->clipbot[x] = (INT16)h;
|
||||
}
|
||||
else // clip top
|
||||
{
|
||||
for (x = x1; x <= x2; x++)
|
||||
if (spr->cliptop[x] == -2 || h > spr->cliptop[x])
|
||||
spr->cliptop[x] = (INT16)h;
|
||||
}
|
||||
}
|
||||
|
||||
if ((mh = sectors[spr->heightsec].ceilingheight) < spr->gzt &&
|
||||
(h = centeryfrac - FixedMul(mh-viewz, spr->sortscale)) >= 0 &&
|
||||
(h >>= FRACBITS) < viewheight)
|
||||
{
|
||||
if (phs != -1 && viewz >= sectors[phs].ceilingheight)
|
||||
{ // clip bottom
|
||||
for (x = x1; x <= x2; x++)
|
||||
if (spr->clipbot[x] == -2 || h < spr->clipbot[x])
|
||||
spr->clipbot[x] = (INT16)h;
|
||||
}
|
||||
else // clip top
|
||||
{
|
||||
for (x = x1; x <= x2; x++)
|
||||
if (spr->cliptop[x] == -2 || h > spr->cliptop[x])
|
||||
spr->cliptop[x] = (INT16)h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// R_ClipVisSprite
|
||||
// Clips vissprites without drawing, so that portals can work. -Red
|
||||
void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal)
|
||||
|
@ -2933,47 +3018,9 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p
|
|||
}
|
||||
}
|
||||
}
|
||||
//SoM: 3/17/2000: Clip sprites in water.
|
||||
if (spr->heightsec != -1) // only things in specially marked sectors
|
||||
{
|
||||
fixed_t mh, h;
|
||||
INT32 phs = viewplayer->mo->subsector->sector->heightsec;
|
||||
if ((mh = sectors[spr->heightsec].floorheight) > spr->gz &&
|
||||
(h = centeryfrac - FixedMul(mh -= viewz, spr->sortscale)) >= 0 &&
|
||||
(h >>= FRACBITS) < viewheight)
|
||||
{
|
||||
if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight))
|
||||
{ // clip bottom
|
||||
for (x = x1; x <= x2; x++)
|
||||
if (spr->clipbot[x] == -2 || h < spr->clipbot[x])
|
||||
spr->clipbot[x] = (INT16)h;
|
||||
}
|
||||
else // clip top
|
||||
{
|
||||
for (x = x1; x <= x2; x++)
|
||||
if (spr->cliptop[x] == -2 || h > spr->cliptop[x])
|
||||
spr->cliptop[x] = (INT16)h;
|
||||
}
|
||||
}
|
||||
|
||||
if ((mh = sectors[spr->heightsec].ceilingheight) < spr->gzt &&
|
||||
(h = centeryfrac - FixedMul(mh-viewz, spr->sortscale)) >= 0 &&
|
||||
(h >>= FRACBITS) < viewheight)
|
||||
{
|
||||
if (phs != -1 && viewz >= sectors[phs].ceilingheight)
|
||||
{ // clip bottom
|
||||
for (x = x1; x <= x2; x++)
|
||||
if (spr->clipbot[x] == -2 || h < spr->clipbot[x])
|
||||
spr->clipbot[x] = (INT16)h;
|
||||
}
|
||||
else // clip top
|
||||
{
|
||||
for (x = x1; x <= x2; x++)
|
||||
if (spr->cliptop[x] == -2 || h > spr->cliptop[x])
|
||||
spr->cliptop[x] = (INT16)h;
|
||||
}
|
||||
}
|
||||
}
|
||||
R_HeightSecClip(spr, x1, x2);
|
||||
|
||||
if (spr->cut & SC_TOP && spr->cut & SC_BOTTOM)
|
||||
{
|
||||
for (x = x1; x <= x2; x++)
|
||||
|
|
19
src/w_wad.c
19
src/w_wad.c
|
@ -361,6 +361,7 @@ static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const
|
|||
lumpinfo->size = ftell(handle);
|
||||
fseek(handle, 0, SEEK_SET);
|
||||
strcpy(lumpinfo->name, lumpname);
|
||||
lumpinfo->hash = quickncasehash(lumpname, 8);
|
||||
|
||||
// Allocate the lump's long name.
|
||||
lumpinfo->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
|
@ -459,6 +460,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
|
|||
lump_p->compression = CM_NOCOMPRESSION;
|
||||
memset(lump_p->name, 0x00, 9);
|
||||
strncpy(lump_p->name, fileinfo->name, 8);
|
||||
lump_p->hash = quickncasehash(lump_p->name, 8);
|
||||
|
||||
// Allocate the lump's long name.
|
||||
lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
|
@ -634,6 +636,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
|
|||
|
||||
memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
|
||||
strncpy(lump_p->name, trimname, min(8, dotpos - trimname));
|
||||
lump_p->hash = quickncasehash(lump_p->name, 8);
|
||||
|
||||
lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL);
|
||||
strlcpy(lump_p->longname, trimname, dotpos - trimname + 1);
|
||||
|
@ -1225,12 +1228,14 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
|||
{
|
||||
UINT16 i;
|
||||
static char uname[8 + 1];
|
||||
UINT32 hash;
|
||||
|
||||
if (!TestValidLump(wad,0))
|
||||
return INT16_MAX;
|
||||
|
||||
strlcpy(uname, name, sizeof uname);
|
||||
strupr(uname);
|
||||
hash = quickncasehash(uname, 8);
|
||||
|
||||
//
|
||||
// scan forward
|
||||
|
@ -1241,7 +1246,7 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
|||
{
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
if (!strncmp(lump_p->name, uname, sizeof(uname) - 1))
|
||||
if (lump_p->hash == hash && !strncmp(lump_p->name, uname, sizeof(uname) - 1))
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -1444,15 +1449,20 @@ lumpnum_t W_CheckNumForLongName(const char *name)
|
|||
// TODO: Make it search through cache first, maybe...?
|
||||
lumpnum_t W_CheckNumForMap(const char *name)
|
||||
{
|
||||
UINT32 hash = quickncasehash(name, 8);
|
||||
UINT16 lumpNum, end;
|
||||
UINT32 i;
|
||||
lumpinfo_t *p;
|
||||
for (i = numwadfiles - 1; i < numwadfiles; i--)
|
||||
{
|
||||
if (wadfiles[i]->type == RET_WAD)
|
||||
{
|
||||
for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++)
|
||||
if (!strncmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8))
|
||||
{
|
||||
p = wadfiles[i]->lumpinfo + lumpNum;
|
||||
if (p->hash == hash && !strncmp(name, p->name, 8))
|
||||
return (i<<16) + lumpNum;
|
||||
}
|
||||
}
|
||||
else if (W_FileHasFolders(wadfiles[i]))
|
||||
{
|
||||
|
@ -1464,9 +1474,10 @@ lumpnum_t W_CheckNumForMap(const char *name)
|
|||
// Now look for the specified map.
|
||||
for (; lumpNum < end; lumpNum++)
|
||||
{
|
||||
if (!strnicmp(name, wadfiles[i]->lumpinfo[lumpNum].name, 8))
|
||||
p = wadfiles[i]->lumpinfo + lumpNum;
|
||||
if (p->hash == hash && !strnicmp(name, p->name, 8))
|
||||
{
|
||||
const char *extension = strrchr(wadfiles[i]->lumpinfo[lumpNum].fullname, '.');
|
||||
const char *extension = strrchr(p->fullname, '.');
|
||||
if (!(extension && stricmp(extension, ".wad")))
|
||||
return (i<<16) + lumpNum;
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ typedef struct
|
|||
unsigned long position; // filelump_t filepos
|
||||
unsigned long disksize; // filelump_t size
|
||||
char name[9]; // filelump_t name[] e.g. "LongEntr"
|
||||
UINT32 hash;
|
||||
char *longname; // e.g. "LongEntryName"
|
||||
char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension"
|
||||
char *diskpath; // path to the file e.g. "/usr/games/srb2/Addon/Folder/Subfolder/LongEntryName.extension"
|
||||
|
|
Loading…
Reference in a new issue