mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 01:01:33 +00:00
Merge branch 'next' into udmf-fofs-mkii
This commit is contained in:
commit
0b4bbacec0
24 changed files with 483 additions and 216 deletions
|
@ -91,6 +91,8 @@ actionpointer_t actionpointers[] =
|
||||||
{{A_FaceTracer}, "A_FACETRACER"},
|
{{A_FaceTracer}, "A_FACETRACER"},
|
||||||
{{A_Scream}, "A_SCREAM"},
|
{{A_Scream}, "A_SCREAM"},
|
||||||
{{A_BossDeath}, "A_BOSSDEATH"},
|
{{A_BossDeath}, "A_BOSSDEATH"},
|
||||||
|
{{A_SetShadowScale}, "A_SETSHADOWSCALE"},
|
||||||
|
{{A_ShadowScream}, "A_SHADOWSCREAM"},
|
||||||
{{A_CustomPower}, "A_CUSTOMPOWER"},
|
{{A_CustomPower}, "A_CUSTOMPOWER"},
|
||||||
{{A_GiveWeapon}, "A_GIVEWEAPON"},
|
{{A_GiveWeapon}, "A_GIVEWEAPON"},
|
||||||
{{A_RingBox}, "A_RINGBOX"},
|
{{A_RingBox}, "A_RINGBOX"},
|
||||||
|
|
|
@ -530,6 +530,22 @@ extern boolean capslock;
|
||||||
// i_system.c, replace getchar() once the keyboard has been appropriated
|
// i_system.c, replace getchar() once the keyboard has been appropriated
|
||||||
INT32 I_GetKey(void);
|
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
|
#ifndef min // Double-Check with WATTCP-32's cdefs.h
|
||||||
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3605,6 +3605,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
||||||
FBITFIELD blendmode = PF_Translucent|PF_Modulated;
|
FBITFIELD blendmode = PF_Translucent|PF_Modulated;
|
||||||
INT32 shader = SHADER_DEFAULT;
|
INT32 shader = SHADER_DEFAULT;
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
INT32 heightsec, phs;
|
||||||
SINT8 flip = P_MobjFlip(thing);
|
SINT8 flip = P_MobjFlip(thing);
|
||||||
|
|
||||||
INT32 light;
|
INT32 light;
|
||||||
|
@ -3617,7 +3618,23 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
||||||
|
|
||||||
groundz = R_GetShadowZ(thing, &groundslope);
|
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);
|
floordiff = abs((flip < 0 ? thing->height : 0) + thing->z - groundz);
|
||||||
|
|
||||||
|
@ -5274,13 +5291,19 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
|
|
||||||
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
|
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) ?
|
if (gl_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ?
|
||||||
FIXED_TO_FLOAT(thing->z) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
|
bottom >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
|
||||||
gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight))
|
top < FIXED_TO_FLOAT(sectors[heightsec].floorheight))
|
||||||
return;
|
return;
|
||||||
if (gl_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ?
|
if (gl_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ?
|
||||||
gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gl_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
|
top < 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))
|
bottom >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1346,12 +1346,18 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
||||||
//if (tics > durs)
|
//if (tics > durs)
|
||||||
//durs = tics;
|
//durs = tics;
|
||||||
|
|
||||||
|
INT32 blendmode;
|
||||||
|
if (spr->mobj->frame & FF_BLENDMASK)
|
||||||
|
blendmode = ((spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
|
||||||
|
else
|
||||||
|
blendmode = spr->mobj->blendmode;
|
||||||
|
|
||||||
if (spr->mobj->frame & FF_TRANSMASK)
|
if (spr->mobj->frame & FF_TRANSMASK)
|
||||||
Surf.PolyFlags = HWR_SurfaceBlend(spr->mobj->blendmode, (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
Surf.PolyFlags = HWR_SurfaceBlend(blendmode, (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Surf.PolyColor.s.alpha = (spr->mobj->flags2 & MF2_SHADOW) ? 0x40 : 0xff;
|
Surf.PolyColor.s.alpha = (spr->mobj->flags2 & MF2_SHADOW) ? 0x40 : 0xff;
|
||||||
Surf.PolyFlags = HWR_GetBlendModeFlag(spr->mobj->blendmode);
|
Surf.PolyFlags = HWR_GetBlendModeFlag(blendmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't forget to enable the depth test because we can't do this
|
// don't forget to enable the depth test because we can't do this
|
||||||
|
|
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
|
{SPR_NULL, 0, 15*2, {NULL}, 0, 0, S_ZAPSB2 }, // S_ZAPSB11
|
||||||
|
|
||||||
// Thunder spark
|
// 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
|
// 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
|
// Super Sonic Spark
|
||||||
{SPR_SSPK, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK2}, // S_SSPK1
|
{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
|
{SPR_SPRK, FF_TRANS20|FF_ANIMATE|9, 18, {NULL}, 8, 2, S_NULL}, // S_SPRK3
|
||||||
|
|
||||||
// Robot Explosion
|
// Robot Explosion
|
||||||
{SPR_BOM1, 0, 0, {A_FlickySpawn}, 0, 0, S_XPLD1}, // S_XPLD_FLICKY
|
{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, 0, 2, {A_ShadowScream}, 0, 0, S_XPLD2}, // S_XPLD1
|
||||||
{SPR_BOM1, 1, 2, {NULL}, 0, 0, S_XPLD3}, // S_XPLD2
|
{SPR_BOM1, 1, 2, {NULL}, 0, 0, S_XPLD3}, // S_XPLD2
|
||||||
{SPR_BOM1, 2, 3, {NULL}, 0, 0, S_XPLD4}, // S_XPLD3
|
{SPR_BOM1, 2, 3, {NULL}, 0, 0, S_XPLD4}, // S_XPLD3
|
||||||
{SPR_BOM1, 3, 3, {NULL}, 0, 0, S_XPLD5}, // S_XPLD4
|
{SPR_BOM1, 3, 3, {NULL}, 0, 0, S_XPLD5}, // S_XPLD4
|
||||||
{SPR_BOM1, 4, 4, {NULL}, 0, 0, S_XPLD6}, // S_XPLD5
|
{SPR_BOM1, 4, 4, {NULL}, 0, 0, S_XPLD6}, // S_XPLD5
|
||||||
{SPR_BOM1, 5, 4, {NULL}, 0, 0, S_NULL}, // S_XPLD6
|
{SPR_BOM1, 5, 4, {NULL}, 0, 0, S_NULL}, // S_XPLD6
|
||||||
|
|
||||||
{SPR_BOM1, FF_ANIMATE, 21, {NULL}, 5, 4, S_INVISIBLE}, // S_XPLD_EGGTRAP
|
{SPR_BOM1, FF_ANIMATE, 21, {NULL}, 5, 4, S_INVISIBLE}, // S_XPLD_EGGTRAP
|
||||||
|
|
||||||
// Underwater Explosion
|
// Underwater Explosion
|
||||||
{SPR_BOM4, 0, 3, {A_Scream}, 0, 0, S_WPLD2}, // S_WPLD1
|
{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, 1, 3, {NULL}, 0, 0, S_WPLD3}, // S_WPLD2
|
||||||
{SPR_BOM4, 2, 3, {NULL}, 0, 0, S_WPLD4}, // S_WPLD3
|
{SPR_BOM4, 2, 3, {NULL}, 0, 0, S_WPLD4}, // S_WPLD3
|
||||||
{SPR_BOM4, 3, 3, {NULL}, 0, 0, S_WPLD5}, // S_WPLD4
|
{SPR_BOM4, 3, 3, {NULL}, 0, 0, S_WPLD5}, // S_WPLD4
|
||||||
{SPR_BOM4, 4, 3, {NULL}, 0, 0, S_WPLD6}, // S_WPLD5
|
{SPR_BOM4, 4, 3, {NULL}, 0, 0, S_WPLD6}, // S_WPLD5
|
||||||
{SPR_BOM4, 5, 3, {NULL}, 0, 0, S_NULL}, // S_WPLD6
|
{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, FF_TRANS40, 4, {NULL}, 0, 0, S_DUST2}, // S_DUST1
|
||||||
{SPR_DUST, 1|FF_TRANS50, 5, {NULL}, 0, 0, S_DUST3}, // S_DUST2
|
{SPR_DUST, 1|FF_TRANS50, 5, {NULL}, 0, 0, S_DUST3}, // S_DUST2
|
||||||
|
|
|
@ -44,6 +44,8 @@ enum actionnum
|
||||||
A_FACETRACER,
|
A_FACETRACER,
|
||||||
A_SCREAM,
|
A_SCREAM,
|
||||||
A_BOSSDEATH,
|
A_BOSSDEATH,
|
||||||
|
A_SETSHADOWSCALE,
|
||||||
|
A_SHADOWSCREAM,
|
||||||
A_CUSTOMPOWER,
|
A_CUSTOMPOWER,
|
||||||
A_GIVEWEAPON,
|
A_GIVEWEAPON,
|
||||||
A_RINGBOX,
|
A_RINGBOX,
|
||||||
|
@ -312,6 +314,8 @@ void A_FaceTarget();
|
||||||
void A_FaceTracer();
|
void A_FaceTracer();
|
||||||
void A_Scream();
|
void A_Scream();
|
||||||
void A_BossDeath();
|
void A_BossDeath();
|
||||||
|
void A_SetShadowScale();
|
||||||
|
void A_ShadowScream(); // MARIA!!!!!!
|
||||||
void A_CustomPower(); // Use this for a custom power
|
void A_CustomPower(); // Use this for a custom power
|
||||||
void A_GiveWeapon(); // Gives the player weapon(s)
|
void A_GiveWeapon(); // Gives the player weapon(s)
|
||||||
void A_RingBox(); // Obtained Ring Box Tails
|
void A_RingBox(); // Obtained Ring Box Tails
|
||||||
|
|
|
@ -88,6 +88,7 @@ enum line_e {
|
||||||
line_v2,
|
line_v2,
|
||||||
line_dx,
|
line_dx,
|
||||||
line_dy,
|
line_dy,
|
||||||
|
line_angle,
|
||||||
line_flags,
|
line_flags,
|
||||||
line_special,
|
line_special,
|
||||||
line_tag,
|
line_tag,
|
||||||
|
@ -113,6 +114,7 @@ static const char *const line_opt[] = {
|
||||||
"v2",
|
"v2",
|
||||||
"dx",
|
"dx",
|
||||||
"dy",
|
"dy",
|
||||||
|
"angle",
|
||||||
"flags",
|
"flags",
|
||||||
"special",
|
"special",
|
||||||
"tag",
|
"tag",
|
||||||
|
@ -835,6 +837,9 @@ static int line_get(lua_State *L)
|
||||||
case line_dy:
|
case line_dy:
|
||||||
lua_pushfixed(L, line->dy);
|
lua_pushfixed(L, line->dy);
|
||||||
return 1;
|
return 1;
|
||||||
|
case line_angle:
|
||||||
|
lua_pushangle(L, line->angle);
|
||||||
|
return 1;
|
||||||
case line_flags:
|
case line_flags:
|
||||||
lua_pushinteger(L, line->flags);
|
lua_pushinteger(L, line->flags);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
22
src/m_menu.c
22
src/m_menu.c
|
@ -4751,7 +4751,7 @@ static void M_DrawPauseMenu(void)
|
||||||
emblemslot = 2;
|
emblemslot = 2;
|
||||||
break;
|
break;
|
||||||
case ET_NGRADE:
|
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));
|
snprintf(currenttext, 9, "%u", G_GetBestNightsScore(gamemap, 0));
|
||||||
|
|
||||||
targettext[8] = 0;
|
targettext[8] = 0;
|
||||||
|
@ -5408,11 +5408,13 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
|
||||||
|
|
||||||
if (actnum)
|
if (actnum)
|
||||||
sprintf(mapname, "%s %d", mapheaderinfo[headingIterate]->lvlttl, 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
|
else
|
||||||
strcpy(mapname, mapheaderinfo[headingIterate]->lvlttl);
|
{
|
||||||
|
strlcpy(mapname, mapheaderinfo[headingIterate]->lvlttl, 15);
|
||||||
if (strlen(mapname) >= 17)
|
strcat(mapname, "...");
|
||||||
strcpy(mapname+17-3, "...");
|
}
|
||||||
|
|
||||||
strcpy(levelselect.rows[row].mapnames[col], (const char *)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));
|
? 159 : 63));
|
||||||
|
|
||||||
if (strlen(levelselect.rows[row].mapnames[col]) > 6) // "AERIAL GARDEN" vs "ACT 18" - "THE ACT" intentionally compressed
|
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
|
else
|
||||||
V_DrawString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]);
|
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])
|
if(!mapheaderinfo[(fake-1) & 8191])
|
||||||
savegameinfo[slot].levelname[0] = '\0';
|
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
|
else
|
||||||
{
|
{
|
||||||
strlcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl, 17+1);
|
strlcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl, 15);
|
||||||
|
strcat(savegameinfo[slot].levelname, "...");
|
||||||
if (strlen(mapheaderinfo[(fake-1) & 8191]->lvlttl) >= 17)
|
|
||||||
strcpy(savegameinfo[slot].levelname+17-3, "...");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
savegameinfo[slot].gamemap = fake;
|
savegameinfo[slot].gamemap = fake;
|
||||||
|
|
|
@ -389,9 +389,9 @@ typedef struct
|
||||||
// level select platter
|
// level select platter
|
||||||
typedef struct
|
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];
|
INT32 maplist[3];
|
||||||
char mapnames[3][17+1];
|
char mapnames[3][22]; // lvlttl max length
|
||||||
boolean mapavailable[4]; // mapavailable[3] == wide or not
|
boolean mapavailable[4]; // mapavailable[3] == wide or not
|
||||||
} levelselectrow_t;
|
} levelselectrow_t;
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,8 @@ void A_GoldMonitorRestore(mobj_t *actor);
|
||||||
void A_GoldMonitorSparkle(mobj_t *actor);
|
void A_GoldMonitorSparkle(mobj_t *actor);
|
||||||
void A_Explode(mobj_t *actor);
|
void A_Explode(mobj_t *actor);
|
||||||
void A_BossDeath(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_CustomPower(mobj_t *actor);
|
||||||
void A_GiveWeapon(mobj_t *actor);
|
void A_GiveWeapon(mobj_t *actor);
|
||||||
void A_RingBox(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
|
// 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.
|
// 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);
|
side = P_PointOnLineSide(thiscam->x, thiscam->y, ld);
|
||||||
lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
|
lineangle = ld->angle;
|
||||||
|
|
||||||
if (side == 1)
|
if (side == 1)
|
||||||
lineangle += ANGLE_180;
|
lineangle += ANGLE_180;
|
||||||
|
@ -3147,7 +3147,7 @@ static void P_HitSlideLine(line_t *ld)
|
||||||
|
|
||||||
side = P_PointOnLineSide(slidemo->x, slidemo->y, ld);
|
side = P_PointOnLineSide(slidemo->x, slidemo->y, ld);
|
||||||
|
|
||||||
lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
|
lineangle = ld->angle;
|
||||||
|
|
||||||
if (side == 1)
|
if (side == 1)
|
||||||
lineangle += ANGLE_180;
|
lineangle += ANGLE_180;
|
||||||
|
@ -3190,7 +3190,7 @@ static void P_HitBounceLine(line_t *ld)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
|
lineangle = ld->angle;
|
||||||
|
|
||||||
if (lineangle >= ANGLE_180)
|
if (lineangle >= ANGLE_180)
|
||||||
lineangle -= ANGLE_180;
|
lineangle -= ANGLE_180;
|
||||||
|
|
32
src/p_mobj.c
32
src/p_mobj.c
|
@ -7869,7 +7869,8 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
||||||
case MT_WOODDEBRIS:
|
case MT_WOODDEBRIS:
|
||||||
case MT_BRICKDEBRIS:
|
case MT_BRICKDEBRIS:
|
||||||
case MT_BROKENROBOT:
|
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])
|
&& mobj->state != &states[mobj->info->deathstate])
|
||||||
{
|
{
|
||||||
P_SetMobjState(mobj, mobj->info->deathstate);
|
P_SetMobjState(mobj, mobj->info->deathstate);
|
||||||
|
@ -8438,7 +8439,10 @@ static boolean P_HangsterThink(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
//after swooping back up, check for ceiling
|
//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))
|
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));
|
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
|
//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)
|
if (st == S_HANGSTER_RETURN3 && mobj->momz == 0 && mobj->ceilingz == (mobj->z + mobj->height)
|
||||||
|
@ -9728,7 +9732,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
if (P_IsObjectOnGround(mobj))
|
if (P_IsObjectOnGround(mobj))
|
||||||
mobj->rollangle = 0;
|
mobj->rollangle = 0;
|
||||||
else
|
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;
|
break;
|
||||||
case MT_SPINFIRE:
|
case MT_SPINFIRE:
|
||||||
if (mobj->flags & MF_NOGRAVITY)
|
if (mobj->flags & MF_NOGRAVITY)
|
||||||
|
@ -10417,6 +10421,7 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing)
|
||||||
switch (thing->type)
|
switch (thing->type)
|
||||||
{
|
{
|
||||||
case MT_PLAYER:
|
case MT_PLAYER:
|
||||||
|
case MT_METALSONIC_RACE:
|
||||||
case MT_ROLLOUTROCK:
|
case MT_ROLLOUTROCK:
|
||||||
|
|
||||||
case MT_EGGMOBILE4_MACE:
|
case MT_EGGMOBILE4_MACE:
|
||||||
|
@ -10461,6 +10466,27 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing)
|
||||||
|
|
||||||
return 2*FRACUNIT/3;
|
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:
|
default:
|
||||||
|
|
||||||
if (thing->flags & (MF_ENEMY|MF_BOSS))
|
if (thing->flags & (MF_ENEMY|MF_BOSS))
|
||||||
|
@ -10482,7 +10508,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||||
|
|
||||||
if (type == MT_NULL)
|
if (type == MT_NULL)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
I_Error("Tried to spawn MT_NULL\n");
|
I_Error("Tried to spawn MT_NULL\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -785,7 +785,7 @@ static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo)
|
||||||
vertex_t closest;
|
vertex_t closest;
|
||||||
|
|
||||||
// calculate angle of line and subtract 90 degrees to get normal
|
// 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;
|
lineangle >>= ANGLETOFINESHIFT;
|
||||||
momx = FixedMul(po->thrust, FINECOSINE(lineangle));
|
momx = FixedMul(po->thrust, FINECOSINE(lineangle));
|
||||||
momy = FixedMul(po->thrust, FINESINE(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->dx = v2->x - v1->x;
|
||||||
ld->dy = v2->y - v1->y;
|
ld->dy = v2->y - v1->y;
|
||||||
|
|
||||||
|
ld->angle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
|
||||||
|
|
||||||
// determine slopetype
|
// determine slopetype
|
||||||
ld->slopetype = !ld->dx ? ST_VERTICAL : !ld->dy ? ST_HORIZONTAL :
|
ld->slopetype = !ld->dx ? ST_VERTICAL : !ld->dy ? ST_HORIZONTAL :
|
||||||
((ld->dy > 0) == (ld->dx > 0)) ? ST_POSITIVE : ST_NEGATIVE;
|
((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];
|
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
|
// levelflats
|
||||||
//
|
//
|
||||||
|
@ -1058,6 +1069,8 @@ static void P_InitializeLinedef(line_t *ld)
|
||||||
ld->dx = v2->x - v1->x;
|
ld->dx = v2->x - v1->x;
|
||||||
ld->dy = v2->y - v1->y;
|
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[BOXLEFT] = min(v1->x, v2->x);
|
||||||
ld->bbox[BOXRIGHT] = max(v1->x, v2->x);
|
ld->bbox[BOXRIGHT] = max(v1->x, v2->x);
|
||||||
ld->bbox[BOXBOTTOM] = min(v1->y, v2->y);
|
ld->bbox[BOXBOTTOM] = min(v1->y, v2->y);
|
||||||
|
@ -5146,7 +5159,7 @@ static boolean P_LoadAddon(UINT16 wadnum, UINT16 numlumps)
|
||||||
// Reload it all anyway, just in case they
|
// Reload it all anyway, just in case they
|
||||||
// added some textures but didn't insert a
|
// added some textures but didn't insert a
|
||||||
// TEXTURES/etc. list.
|
// TEXTURES/etc. list.
|
||||||
R_LoadTextures(); // numtexture changes
|
R_LoadTexturesPwad(wadnum); // numtexture changes
|
||||||
|
|
||||||
// Reload ANIMDEFS
|
// Reload ANIMDEFS
|
||||||
P_InitPicAnims();
|
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_GetGrade(UINT32 pscore, INT16 map, UINT8 mare);
|
||||||
UINT8 P_HasGrades(INT16 map, UINT8 mare);
|
UINT8 P_HasGrades(INT16 map, UINT8 mare);
|
||||||
UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade);
|
UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade);
|
||||||
|
UINT32 P_GetScoreForGradeOverall(INT16 map, UINT8 grade);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1242,7 +1242,7 @@ static boolean PolyFlag(line_t *line)
|
||||||
|
|
||||||
pfd.polyObjNum = Tag_FGet(&line->tags);
|
pfd.polyObjNum = Tag_FGet(&line->tags);
|
||||||
pfd.speed = P_AproxDistance(line->dx, line->dy) >> FRACBITS;
|
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;
|
pfd.momx = sides[line->sidenum[0]].textureoffset >> FRACBITS;
|
||||||
|
|
||||||
return EV_DoPolyObjFlag(&pfd);
|
return EV_DoPolyObjFlag(&pfd);
|
||||||
|
|
32
src/p_user.c
32
src/p_user.c
|
@ -2051,12 +2051,22 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
||||||
|
|
||||||
ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle);
|
ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle);
|
||||||
ghost->rollangle = mobj->rollangle;
|
ghost->rollangle = mobj->rollangle;
|
||||||
|
|
||||||
ghost->sprite = mobj->sprite;
|
ghost->sprite = mobj->sprite;
|
||||||
ghost->sprite2 = mobj->sprite2;
|
ghost->sprite2 = mobj->sprite2;
|
||||||
ghost->frame = mobj->frame;
|
ghost->frame = mobj->frame;
|
||||||
ghost->tics = -1;
|
ghost->tics = -1;
|
||||||
ghost->frame &= ~FF_TRANSMASK;
|
ghost->frame &= ~FF_TRANSMASK;
|
||||||
ghost->frame |= tr_trans50<<FF_TRANSSHIFT;
|
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->fuse = ghost->info->damage;
|
||||||
ghost->skin = mobj->skin;
|
ghost->skin = mobj->skin;
|
||||||
|
|
||||||
|
@ -6699,7 +6709,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad
|
||||||
//
|
//
|
||||||
static void P_DoNiGHTSCapsule(player_t *player)
|
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;
|
INT32 tictimer = ++player->capsule->extravalue2;
|
||||||
|
|
||||||
if (abs(player->mo->x-player->capsule->x) <= 3*FRACUNIT)
|
if (abs(player->mo->x-player->capsule->x) <= 3*FRACUNIT)
|
||||||
|
@ -6822,15 +6832,20 @@ static void P_DoNiGHTSCapsule(player_t *player)
|
||||||
|
|
||||||
if (player->capsule->health > sphereresult && player->spheres > 0)
|
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->spheres -= deductquantity;
|
||||||
player->capsule->health -= 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
|
// Spawn a 'pop' for every 2 tics
|
||||||
|
@ -6851,9 +6866,8 @@ static void P_DoNiGHTSCapsule(player_t *player)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
startingspheres = player->spheres - player->capsule->health;
|
player->spheres -= player->capsule->health;
|
||||||
player->capsule->health = 0;
|
player->capsule->health = 0;
|
||||||
player->spheres = startingspheres;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -412,6 +412,7 @@ typedef struct line_s
|
||||||
vertex_t *v2;
|
vertex_t *v2;
|
||||||
|
|
||||||
fixed_t dx, dy; // Precalculated v2 - v1 for side checking.
|
fixed_t dx, dy; // Precalculated v2 - v1 for side checking.
|
||||||
|
angle_t angle; // Precalculated angle between dx and dy
|
||||||
|
|
||||||
// Animation related.
|
// Animation related.
|
||||||
INT16 flags;
|
INT16 flags;
|
||||||
|
|
|
@ -105,6 +105,7 @@ typedef struct
|
||||||
} spriteinfo_t;
|
} spriteinfo_t;
|
||||||
|
|
||||||
// Portable Network Graphics
|
// Portable Network Graphics
|
||||||
|
#define PNG_HEADER_SIZE (8)
|
||||||
boolean Picture_IsLumpPNG(const UINT8 *d, size_t s);
|
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
|
#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
|
// Painfully simple texture id cacheing to make maps load faster. :3
|
||||||
static struct {
|
static struct {
|
||||||
char name[9];
|
char name[9];
|
||||||
|
UINT32 hash;
|
||||||
INT32 id;
|
INT32 id;
|
||||||
} *tidcache = NULL;
|
} *tidcache = NULL;
|
||||||
static INT32 tidcachelen = 0;
|
static INT32 tidcachelen = 0;
|
||||||
|
@ -725,6 +726,7 @@ Rloadflats (INT32 i, INT32 w)
|
||||||
UINT16 texstart, texend;
|
UINT16 texstart, texend;
|
||||||
texture_t *texture;
|
texture_t *texture;
|
||||||
texpatch_t *patch;
|
texpatch_t *patch;
|
||||||
|
UINT8 header[PNG_HEADER_SIZE];
|
||||||
|
|
||||||
// Yes
|
// Yes
|
||||||
if (W_FileHasFolders(wadfiles[w]))
|
if (W_FileHasFolders(wadfiles[w]))
|
||||||
|
@ -743,7 +745,6 @@ Rloadflats (INT32 i, INT32 w)
|
||||||
// Work through each lump between the markers in the WAD.
|
// Work through each lump between the markers in the WAD.
|
||||||
for (j = 0; j < (texend - texstart); j++)
|
for (j = 0; j < (texend - texstart); j++)
|
||||||
{
|
{
|
||||||
UINT8 *flatlump;
|
|
||||||
UINT16 wadnum = (UINT16)w;
|
UINT16 wadnum = (UINT16)w;
|
||||||
lumpnum_t lumpnum = texstart + j;
|
lumpnum_t lumpnum = texstart + j;
|
||||||
size_t lumplength;
|
size_t lumplength;
|
||||||
|
@ -755,7 +756,7 @@ Rloadflats (INT32 i, INT32 w)
|
||||||
continue; // If it is then SKIP IT
|
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);
|
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||||
|
|
||||||
switch (lumplength)
|
switch (lumplength)
|
||||||
|
@ -788,14 +789,17 @@ Rloadflats (INT32 i, INT32 w)
|
||||||
|
|
||||||
// Set texture properties.
|
// Set texture properties.
|
||||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||||
|
texture->hash = quickncasehash(texture->name, 8);
|
||||||
|
|
||||||
#ifndef NO_PNG_LUMPS
|
#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;
|
INT32 width, height;
|
||||||
Picture_PNGDimensions((UINT8 *)flatlump, &width, &height, NULL, NULL, lumplength);
|
Picture_PNGDimensions((UINT8 *)flatlump, &width, &height, NULL, NULL, lumplength);
|
||||||
texture->width = (INT16)width;
|
texture->width = (INT16)width;
|
||||||
texture->height = (INT16)height;
|
texture->height = (INT16)height;
|
||||||
|
Z_Free(flatlump);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -814,8 +818,6 @@ Rloadflats (INT32 i, INT32 w)
|
||||||
patch->lump = texstart + j;
|
patch->lump = texstart + j;
|
||||||
patch->flip = 0;
|
patch->flip = 0;
|
||||||
|
|
||||||
Z_Unlock(flatlump);
|
|
||||||
|
|
||||||
texturewidth[i] = texture->width;
|
texturewidth[i] = texture->width;
|
||||||
textureheight[i] = texture->height << FRACBITS;
|
textureheight[i] = texture->height << FRACBITS;
|
||||||
i++;
|
i++;
|
||||||
|
@ -835,8 +837,8 @@ Rloadtextures (INT32 i, INT32 w)
|
||||||
UINT16 j;
|
UINT16 j;
|
||||||
UINT16 texstart, texend, texturesLumpPos;
|
UINT16 texstart, texend, texturesLumpPos;
|
||||||
texture_t *texture;
|
texture_t *texture;
|
||||||
softwarepatch_t *patchlump;
|
|
||||||
texpatch_t *patch;
|
texpatch_t *patch;
|
||||||
|
softwarepatch_t patchlump;
|
||||||
|
|
||||||
// Get the lump numbers for the markers in the WAD, if they exist.
|
// Get the lump numbers for the markers in the WAD, if they exist.
|
||||||
if (W_FileHasFolders(wadfiles[w]))
|
if (W_FileHasFolders(wadfiles[w]))
|
||||||
|
@ -876,7 +878,7 @@ Rloadtextures (INT32 i, INT32 w)
|
||||||
continue; // If it is then SKIP IT
|
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
|
#ifndef NO_PNG_LUMPS
|
||||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||||
#endif
|
#endif
|
||||||
|
@ -886,20 +888,23 @@ Rloadtextures (INT32 i, INT32 w)
|
||||||
|
|
||||||
// Set texture properties.
|
// Set texture properties.
|
||||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||||
|
texture->hash = quickncasehash(texture->name, 8);
|
||||||
|
|
||||||
#ifndef NO_PNG_LUMPS
|
#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;
|
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->width = (INT16)width;
|
||||||
texture->height = (INT16)height;
|
texture->height = (INT16)height;
|
||||||
|
Z_Free(png);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
texture->width = SHORT(patchlump->width);
|
texture->width = SHORT(patchlump.width);
|
||||||
texture->height = SHORT(patchlump->height);
|
texture->height = SHORT(patchlump.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
texture->type = TEXTURETYPE_SINGLEPATCH;
|
texture->type = TEXTURETYPE_SINGLEPATCH;
|
||||||
|
@ -915,8 +920,6 @@ Rloadtextures (INT32 i, INT32 w)
|
||||||
patch->lump = texstart + j;
|
patch->lump = texstart + j;
|
||||||
patch->flip = 0;
|
patch->flip = 0;
|
||||||
|
|
||||||
Z_Unlock(patchlump);
|
|
||||||
|
|
||||||
texturewidth[i] = texture->width;
|
texturewidth[i] = texture->width;
|
||||||
textureheight[i] = texture->height << FRACBITS;
|
textureheight[i] = texture->height << FRACBITS;
|
||||||
i++;
|
i++;
|
||||||
|
@ -926,27 +929,53 @@ Rloadtextures (INT32 i, INT32 w)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
static INT32
|
||||||
// R_LoadTextures
|
count_range
|
||||||
// Initializes the texture list with the textures from the world map.
|
( const char * marker_start,
|
||||||
//
|
const char * marker_end,
|
||||||
void R_LoadTextures(void)
|
const char * folder,
|
||||||
|
UINT16 wadnum)
|
||||||
{
|
{
|
||||||
INT32 i, w;
|
|
||||||
UINT16 j;
|
UINT16 j;
|
||||||
UINT16 texstart, texend, texturesLumpPos;
|
UINT16 texstart, texend;
|
||||||
|
INT32 count = 0;
|
||||||
|
|
||||||
// Free previous memory before numtextures change.
|
// Count flats
|
||||||
if (numtextures)
|
if (W_FileHasFolders(wadfiles[wadnum]))
|
||||||
{
|
{
|
||||||
for (i = 0; i < numtextures; i++)
|
texstart = W_CheckNumForFolderStartPK3(folder, wadnum, 0);
|
||||||
{
|
texend = W_CheckNumForFolderEndPK3(folder, wadnum, texstart);
|
||||||
Z_Free(textures[i]);
|
|
||||||
Z_Free(texturecache[i]);
|
|
||||||
}
|
|
||||||
Z_Free(texturetranslation);
|
|
||||||
Z_Free(textures);
|
|
||||||
}
|
}
|
||||||
|
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.
|
// Load patches and textures.
|
||||||
|
|
||||||
|
@ -955,113 +984,132 @@ void R_LoadTextures(void)
|
||||||
// the markers.
|
// the markers.
|
||||||
// This system will allocate memory for all duplicate/patched textures even if it never uses them,
|
// 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.
|
// 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
|
#ifdef WALLFLATS
|
||||||
// Count flats
|
count += count_range("F_START", "F_END", "flats/", wadnum);
|
||||||
if (W_FileHasFolders(wadfiles[w]))
|
#endif
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
|
// Count the textures from TEXTURES lumps
|
||||||
{
|
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, 0);
|
||||||
// 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
|
while (texturesLumpPos != INT16_MAX)
|
||||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
{
|
||||||
while (texturesLumpPos != INT16_MAX)
|
count += R_CountTexturesInTEXTURESLump(wadnum, texturesLumpPos);
|
||||||
{
|
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, texturesLumpPos + 1);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no textures found by this point, bomb out
|
// Count single-patch textures
|
||||||
if (!numtextures)
|
count += count_range(TX_START, TX_END, "textures/", wadnum);
|
||||||
I_Error("No textures detected in any WADs!\n");
|
|
||||||
|
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.
|
// Allocate memory and initialize to 0 for all the textures we are initialising.
|
||||||
// There are actually 5 buffers allocated in one for convenience.
|
recallocuser(&textures, oldsize, newsize);
|
||||||
textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL);
|
|
||||||
|
|
||||||
// Allocate texture column offset table.
|
// Allocate texture column offset table.
|
||||||
texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *)));
|
recallocuser(&texturecolumnofs, oldsize, newsize);
|
||||||
// Allocate texture referencing cache.
|
// Allocate texture referencing cache.
|
||||||
texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2));
|
recallocuser(&texturecache, oldsize, newsize);
|
||||||
// Allocate texture width table.
|
// Allocate texture width table.
|
||||||
texturewidth = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3));
|
recallocuser(&texturewidth, oldsize, newsize);
|
||||||
// Allocate texture height table.
|
// Allocate texture height table.
|
||||||
textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4));
|
recallocuser(&textureheight, oldsize, newsize);
|
||||||
// Create translation table for global animation.
|
// 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++)
|
for (i = 0; i < numtextures; ++i)
|
||||||
texturetranslation[i] = i;
|
|
||||||
|
|
||||||
for (i = 0, w = 0; w < numwadfiles; w++)
|
|
||||||
{
|
{
|
||||||
#ifdef WALLFLATS
|
// R_FlushTextureCache relies on the user for
|
||||||
i = Rloadflats(i, w);
|
// Z_Free, texturecache has been reallocated so the
|
||||||
#endif
|
// user is now garbage memory.
|
||||||
i = Rloadtextures(i, w);
|
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
|
#ifdef HWRENDER
|
||||||
if (rendermode == render_opengl)
|
if (rendermode == render_opengl)
|
||||||
HWR_LoadMapTextures(numtextures);
|
HWR_LoadMapTextures(numtextures);
|
||||||
#endif
|
#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)
|
static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)
|
||||||
{
|
{
|
||||||
char *texturesToken;
|
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.
|
// 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);
|
resultTexture = (texture_t *)Z_Calloc(sizeof(texture_t),PU_STATIC,NULL);
|
||||||
M_Memcpy(resultTexture->name, newTextureName, 8);
|
M_Memcpy(resultTexture->name, newTextureName, 8);
|
||||||
|
resultTexture->hash = quickncasehash(newTextureName, 8);
|
||||||
resultTexture->width = newTextureWidth;
|
resultTexture->width = newTextureWidth;
|
||||||
resultTexture->height = newTextureHeight;
|
resultTexture->height = newTextureHeight;
|
||||||
resultTexture->type = TEXTURETYPE_COMPOSITE;
|
resultTexture->type = TEXTURETYPE_COMPOSITE;
|
||||||
|
@ -1594,19 +1643,22 @@ void R_ClearTextureNumCache(boolean btell)
|
||||||
INT32 R_CheckTextureNumForName(const char *name)
|
INT32 R_CheckTextureNumForName(const char *name)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
UINT32 hash;
|
||||||
|
|
||||||
// "NoTexture" marker.
|
// "NoTexture" marker.
|
||||||
if (name[0] == '-')
|
if (name[0] == '-')
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
hash = quickncasehash(name, 8);
|
||||||
|
|
||||||
for (i = 0; i < tidcachelen; i++)
|
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;
|
return tidcache[i].id;
|
||||||
|
|
||||||
// Need to parse the list backwards, so textures loaded more recently are used in lieu of ones loaded earlier
|
// 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 = 0; i < numtextures; i++) <- old
|
||||||
for (i = (numtextures - 1); i >= 0; i--) // <- new
|
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++;
|
tidcachelen++;
|
||||||
Z_Realloc(tidcache, tidcachelen * sizeof(*tidcache), PU_STATIC, &tidcache);
|
Z_Realloc(tidcache, tidcachelen * sizeof(*tidcache), PU_STATIC, &tidcache);
|
||||||
|
@ -1615,6 +1667,7 @@ INT32 R_CheckTextureNumForName(const char *name)
|
||||||
#ifndef ZDEBUG
|
#ifndef ZDEBUG
|
||||||
CONS_Debug(DBG_SETUP, "texture #%s: %s\n", sizeu1(tidcachelen), tidcache[tidcachelen-1].name);
|
CONS_Debug(DBG_SETUP, "texture #%s: %s\n", sizeu1(tidcachelen), tidcache[tidcachelen-1].name);
|
||||||
#endif
|
#endif
|
||||||
|
tidcache[tidcachelen-1].hash = hash;
|
||||||
tidcache[tidcachelen-1].id = i;
|
tidcache[tidcachelen-1].id = i;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
// Keep name for switch changing, etc.
|
// Keep name for switch changing, etc.
|
||||||
char name[8];
|
char name[8];
|
||||||
|
UINT32 hash;
|
||||||
UINT8 type; // TEXTURETYPE_
|
UINT8 type; // TEXTURETYPE_
|
||||||
INT16 width, height;
|
INT16 width, height;
|
||||||
boolean holes;
|
boolean holes;
|
||||||
|
@ -76,6 +77,7 @@ extern UINT8 **texturecache; // graphics data for each generated full-size textu
|
||||||
|
|
||||||
// Load TEXTURES definitions, create lookup tables
|
// Load TEXTURES definitions, create lookup tables
|
||||||
void R_LoadTextures(void);
|
void R_LoadTextures(void);
|
||||||
|
void R_LoadTexturesPwad(UINT16 wadnum);
|
||||||
void R_FlushTextureCache(void);
|
void R_FlushTextureCache(void);
|
||||||
|
|
||||||
// Texture generation
|
// Texture generation
|
||||||
|
|
137
src/r_things.c
137
src/r_things.c
|
@ -1275,6 +1275,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
||||||
vissprite_t *shadow;
|
vissprite_t *shadow;
|
||||||
patch_t *patch;
|
patch_t *patch;
|
||||||
fixed_t xscale, yscale, shadowxscale, shadowyscale, shadowskew, x1, x2;
|
fixed_t xscale, yscale, shadowxscale, shadowyscale, shadowskew, x1, x2;
|
||||||
|
INT32 heightsec, phs;
|
||||||
INT32 light = 0;
|
INT32 light = 0;
|
||||||
fixed_t scalemul; UINT8 trans;
|
fixed_t scalemul; UINT8 trans;
|
||||||
fixed_t floordiff;
|
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
|
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);
|
floordiff = abs((isflipped ? thing->height : 0) + thing->z - groundz);
|
||||||
|
|
||||||
trans = floordiff / (100*FRACUNIT) + 3;
|
trans = floordiff / (100*FRACUNIT) + 3;
|
||||||
|
@ -1592,7 +1611,16 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
if (thing->rollangle
|
if (thing->rollangle
|
||||||
&& !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE)))
|
&& !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE)))
|
||||||
{
|
{
|
||||||
rollangle = R_GetRollAngle(thing->rollangle);
|
if (papersprite && ang >= ANGLE_180)
|
||||||
|
{
|
||||||
|
// Makes Software act much more sane like OpenGL
|
||||||
|
rollangle = R_GetRollAngle(InvAngle(thing->rollangle));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rollangle = R_GetRollAngle(thing->rollangle);
|
||||||
|
}
|
||||||
|
|
||||||
rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);
|
rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);
|
||||||
|
|
||||||
if (rotsprite != NULL)
|
if (rotsprite != NULL)
|
||||||
|
@ -1942,13 +1970,19 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
|
|
||||||
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
|
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 ?
|
if (viewz < sectors[phs].floorheight ?
|
||||||
thing->z >= sectors[heightsec].floorheight :
|
bottom >= sectors[heightsec].floorheight :
|
||||||
gzt < sectors[heightsec].floorheight)
|
top < sectors[heightsec].floorheight)
|
||||||
return;
|
return;
|
||||||
if (viewz > sectors[phs].ceilingheight ?
|
if (viewz > sectors[phs].ceilingheight ?
|
||||||
gzt < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight :
|
top < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight :
|
||||||
thing->z >= sectors[heightsec].ceilingheight)
|
bottom >= sectors[heightsec].ceilingheight)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2822,6 +2856,57 @@ static void R_DrawPrecipitationSprite(vissprite_t *spr)
|
||||||
R_DrawPrecipitationVisSprite(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
|
// R_ClipVisSprite
|
||||||
// Clips vissprites without drawing, so that portals can work. -Red
|
// 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)
|
void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal)
|
||||||
|
@ -2923,47 +3008,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 &&
|
R_HeightSecClip(spr, x1, x2);
|
||||||
(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (spr->cut & SC_TOP && spr->cut & SC_BOTTOM)
|
if (spr->cut & SC_TOP && spr->cut & SC_BOTTOM)
|
||||||
{
|
{
|
||||||
for (x = x1; x <= x2; x++)
|
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);
|
lumpinfo->size = ftell(handle);
|
||||||
fseek(handle, 0, SEEK_SET);
|
fseek(handle, 0, SEEK_SET);
|
||||||
strcpy(lumpinfo->name, lumpname);
|
strcpy(lumpinfo->name, lumpname);
|
||||||
|
lumpinfo->hash = quickncasehash(lumpname, 8);
|
||||||
|
|
||||||
// Allocate the lump's long name.
|
// Allocate the lump's long name.
|
||||||
lumpinfo->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
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;
|
lump_p->compression = CM_NOCOMPRESSION;
|
||||||
memset(lump_p->name, 0x00, 9);
|
memset(lump_p->name, 0x00, 9);
|
||||||
strncpy(lump_p->name, fileinfo->name, 8);
|
strncpy(lump_p->name, fileinfo->name, 8);
|
||||||
|
lump_p->hash = quickncasehash(lump_p->name, 8);
|
||||||
|
|
||||||
// Allocate the lump's long name.
|
// Allocate the lump's long name.
|
||||||
lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
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?
|
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));
|
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);
|
lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL);
|
||||||
strlcpy(lump_p->longname, trimname, dotpos - trimname + 1);
|
strlcpy(lump_p->longname, trimname, dotpos - trimname + 1);
|
||||||
|
@ -1225,12 +1228,14 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
||||||
{
|
{
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
static char uname[8 + 1];
|
static char uname[8 + 1];
|
||||||
|
UINT32 hash;
|
||||||
|
|
||||||
if (!TestValidLump(wad,0))
|
if (!TestValidLump(wad,0))
|
||||||
return INT16_MAX;
|
return INT16_MAX;
|
||||||
|
|
||||||
strlcpy(uname, name, sizeof uname);
|
strlcpy(uname, name, sizeof uname);
|
||||||
strupr(uname);
|
strupr(uname);
|
||||||
|
hash = quickncasehash(uname, 8);
|
||||||
|
|
||||||
//
|
//
|
||||||
// scan forward
|
// scan forward
|
||||||
|
@ -1241,7 +1246,7 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
||||||
{
|
{
|
||||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
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;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1444,15 +1449,20 @@ lumpnum_t W_CheckNumForLongName(const char *name)
|
||||||
// TODO: Make it search through cache first, maybe...?
|
// TODO: Make it search through cache first, maybe...?
|
||||||
lumpnum_t W_CheckNumForMap(const char *name)
|
lumpnum_t W_CheckNumForMap(const char *name)
|
||||||
{
|
{
|
||||||
|
UINT32 hash = quickncasehash(name, 8);
|
||||||
UINT16 lumpNum, end;
|
UINT16 lumpNum, end;
|
||||||
UINT32 i;
|
UINT32 i;
|
||||||
|
lumpinfo_t *p;
|
||||||
for (i = numwadfiles - 1; i < numwadfiles; i--)
|
for (i = numwadfiles - 1; i < numwadfiles; i--)
|
||||||
{
|
{
|
||||||
if (wadfiles[i]->type == RET_WAD)
|
if (wadfiles[i]->type == RET_WAD)
|
||||||
{
|
{
|
||||||
for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++)
|
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;
|
return (i<<16) + lumpNum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (W_FileHasFolders(wadfiles[i]))
|
else if (W_FileHasFolders(wadfiles[i]))
|
||||||
{
|
{
|
||||||
|
@ -1464,9 +1474,10 @@ lumpnum_t W_CheckNumForMap(const char *name)
|
||||||
// Now look for the specified map.
|
// Now look for the specified map.
|
||||||
for (; lumpNum < end; lumpNum++)
|
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")))
|
if (!(extension && stricmp(extension, ".wad")))
|
||||||
return (i<<16) + lumpNum;
|
return (i<<16) + lumpNum;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ typedef struct
|
||||||
unsigned long position; // filelump_t filepos
|
unsigned long position; // filelump_t filepos
|
||||||
unsigned long disksize; // filelump_t size
|
unsigned long disksize; // filelump_t size
|
||||||
char name[9]; // filelump_t name[] e.g. "LongEntr"
|
char name[9]; // filelump_t name[] e.g. "LongEntr"
|
||||||
|
UINT32 hash;
|
||||||
char *longname; // e.g. "LongEntryName"
|
char *longname; // e.g. "LongEntryName"
|
||||||
char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension"
|
char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension"
|
||||||
char *diskpath; // path to the file e.g. "/usr/games/srb2/Addon/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