Merge branch 'master' of https://git.magicalgirl.moe/STJr/SRB2Internal.git into object_tweaks

# Conflicts:
#	extras/conf/SRB2-22.cfg
This commit is contained in:
toaster 2019-10-25 20:32:15 +01:00
commit f2596ab0bb
22 changed files with 1156 additions and 334 deletions

View file

@ -1527,7 +1527,7 @@ linedeftypes
title = "Bustable Block";
prefix = "(254)";
flags8text = "[3] Slope skew sides";
flags64text = "[6] Only bustable by Knuckles";
flags64text = "[6] Strong characters only";
flags128text = "[7] Only block non-players";
flags512text = "[9] Shattered by pushables";
flags1024text = "[10] Trigger linedef executor";
@ -2175,7 +2175,7 @@ linedeftypes
title = "Award Rings";
prefix = "(460)";
}
461
{
title = "Spawn Object";
@ -4149,6 +4149,34 @@ thingtypes
angletext = "Retraction interval";
parametertext = "Initial delay";
}
1130
{
title = "Small Mace";
sprite = "SMCEA0";
width = 17;
height = 34;
}
1131
{
title = "Big Mace";
sprite = "BMCEA0";
width = 34;
height = 68;
}
1136
{
title = "Small Fireball";
sprite = "SFBRA0";
width = 17;
height = 34;
}
1137
{
title = "Large Fireball";
sprite = "BFBRA0";
width = 34;
height = 68;
}
}
springs
@ -4265,6 +4293,20 @@ thingtypes
width = 16;
height = 32;
}
1134
{
title = "Yellow Spring Ball";
sprite = "YSPBA0";
width = 17;
height = 34;
}
1135
{
title = "Red Spring Ball";
sprite = "RSPBA0";
width = 17;
height = 34;
}
544
{
arrow = 1;
@ -4863,7 +4905,7 @@ thingtypes
}
1104
{
title = "Mace";
title = "Mace Spawnpoint";
sprite = "SMCEA0";
width = 17;
height = 34;
@ -4873,7 +4915,7 @@ thingtypes
}
1105
{
title = "Chain & Maces";
title = "Chain with Maces Spawnpoint";
sprite = "SMCEA0";
width = 17;
height = 34;
@ -4883,7 +4925,7 @@ thingtypes
}
1106
{
title = "Chained Spring";
title = "Chained Spring Spawnpoint";
sprite = "YSPBA0";
width = 17;
height = 34;
@ -4893,7 +4935,7 @@ thingtypes
}
1107
{
title = "Chain";
title = "Chain Spawnpoint";
sprite = "BMCHA0";
width = 17;
height = 34;
@ -4903,7 +4945,7 @@ thingtypes
1108
{
arrow = 1;
title = "Chain (Hidden)";
title = "Hidden Chain Spawnpoint";
sprite = "internal:chain3";
width = 17;
height = 34;
@ -4911,7 +4953,7 @@ thingtypes
}
1109
{
title = "Firebar";
title = "Firebar Spawnpoint";
sprite = "BFBRA0";
width = 17;
height = 34;
@ -4921,7 +4963,7 @@ thingtypes
}
1110
{
title = "Custom Mace";
title = "Custom Mace Spawnpoint";
sprite = "SMCEA0";
width = 17;
height = 34;
@ -5606,30 +5648,16 @@ thingtypes
title = "BSZ Clover";
sprite = "BSZ8B0";
}
1472
{
title = "Palm Tree Trunk (Big)";
width = 16;
height = 160;
sprite = "BSZ8C0";
}
1473
{
title = "Palm Tree Leaves (Big)";
title = "Palm Tree (Big)";
width = 16;
height = 160;
sprite = "BSZ8D0";
}
1474
{
title = "Palm Tree Trunk (Small)";
width = 8;
height = 80;
sprite = "BSZ8E0";
}
1475
{
title = "Palm Tree Leaves (Small)";
title = "Palm Tree (Small)";
width = 16;
height = 80;
sprite = "BSZ8F0";
@ -6451,4 +6479,4 @@ thingsfilters
}
}
}
}

View file

@ -1692,7 +1692,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
// Kick bot from special stages
if (botskin)
{
if (G_IsSpecialStage(mapnum))
if (G_IsSpecialStage(mapnum) || (mapheaderinfo[mapnum-1] && (mapheaderinfo[mapnum-1]->typeoflevel & TOL_NIGHTS)))
{
if (botingame)
{

View file

@ -5992,6 +5992,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_TARGET_RESPAWN",
"S_TARGET_ALLDONE",
// ATZ's green flame
"S_GREENFLAME",
// Stalagmites
"S_STG0",
"S_STG1",
@ -7745,6 +7748,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_TRAPGOYLEDOWN",
"MT_TRAPGOYLELONG",
"MT_TARGET",
"MT_GREENFLAME",
// Stalagmites
"MT_STALAGMITE0",
@ -8955,9 +8959,9 @@ struct {
{"FF_PLATFORM",FF_PLATFORM}, ///< You can jump up through this to the top.
{"FF_REVERSEPLATFORM",FF_REVERSEPLATFORM}, ///< A fall-through floor in normal gravity, a platform in reverse gravity.
{"FF_INTANGABLEFLATS",FF_INTANGABLEFLATS}, ///< Both flats are intangable, but the sides are still solid.
{"FF_SHATTER",FF_SHATTER}, ///< Used with ::FF_BUSTUP. Thinks everyone's Knuckles.
{"FF_SPINBUST",FF_SPINBUST}, ///< Used with ::FF_BUSTUP. Jump or fall onto it while curled in a ball.
{"FF_ONLYKNUX",FF_ONLYKNUX}, ///< Used with ::FF_BUSTUP. Only Knuckles can break this rock.
{"FF_SHATTER",FF_SHATTER}, ///< Used with ::FF_BUSTUP. Bustable on mere touch.
{"FF_SPINBUST",FF_SPINBUST}, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames.
{"FF_STRONGBUST",FF_STRONGBUST }, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee).
{"FF_RIPPLE",FF_RIPPLE}, ///< Ripple the flats
{"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel
{"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.

View file

@ -201,7 +201,7 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_EGGO
&lspr[NOLIGHT], // SPR_SEBH
&lspr[NOLIGHT], // SPR_FAKE
&lspr[NOLIGHT], // SPR_SHCK
&lspr[LBLUESHINE_L],// SPR_SHCK
// Boss 4 (Castle Eggman)
&lspr[NOLIGHT], // SPR_EGGP
@ -406,6 +406,11 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_HHPL
&lspr[NOLIGHT], // SPR_SHRM
&lspr[NOLIGHT], // SPR_HHZM
// Azure Temple Scenery
&lspr[NOLIGHT], // SPR_BGAR
&lspr[NOLIGHT], // SPR_RCRY
&lspr[GREENBALL_L], // SPR_CFLM
// Botanic Serenity Scenery
&lspr[NOLIGHT], // SPR_BSZ1
@ -426,7 +431,6 @@ light_t *t_lspr[NUMSPRITES] =
// Misc Scenery
&lspr[NOLIGHT], // SPR_STLG
&lspr[NOLIGHT], // SPR_DBAL
&lspr[NOLIGHT], // SPR_RCRY
// Powerup Indicators
&lspr[NOLIGHT], // SPR_ARMA

View file

@ -301,6 +301,11 @@ char sprnames[NUMSPRITES + 1][5] =
"SHRM", // Mushroom
"HHZM", // Misc
// Azure Temple Scenery
"BGAR", // ATZ Gargoyles
"RCRY", // ATZ Red Crystal (Target)
"CFLM", // Green torch flame
// Botanic Serenity Scenery
"BSZ1", // Tall flowers
"BSZ2", // Medium flowers
@ -320,7 +325,6 @@ char sprnames[NUMSPRITES + 1][5] =
// Misc Scenery
"STLG", // Stalagmites
"DBAL", // Disco
"RCRY", // ATZ Red Crystal (Target)
// Powerup Indicators
"ARMA", // Armageddon Shield Orb
@ -2572,31 +2576,31 @@ state_t states[NUMSTATES] =
{SPR_WVIN, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_WALLVINE_SHORT
// Trapgoyles
{SPR_GARG, 0, 67, {NULL}, 0, 0, S_TRAPGOYLE_CHECK}, // S_TRAPGOYLE
{SPR_GARG, 0, 3, {NULL}, 0, 0, S_TRAPGOYLE_FIRE1}, // S_TRAPGOYLE_CHECK
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE_FIRE2}, // S_TRAPGOYLE_FIRE1
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE_FIRE3}, // S_TRAPGOYLE_FIRE2
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE}, // S_TRAPGOYLE_FIRE3
{SPR_BGAR, 0, 67, {NULL}, 0, 0, S_TRAPGOYLE_CHECK}, // S_TRAPGOYLE
{SPR_BGAR, 0, 3, {NULL}, 0, 0, S_TRAPGOYLE_FIRE1}, // S_TRAPGOYLE_CHECK
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE_FIRE2}, // S_TRAPGOYLE_FIRE1
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE_FIRE3}, // S_TRAPGOYLE_FIRE2
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLE}, // S_TRAPGOYLE_FIRE3
{SPR_GARG, 0, 67, {NULL}, 0, 0, S_TRAPGOYLEUP_CHECK}, // S_TRAPGOYLEUP
{SPR_GARG, 0, 3, {NULL}, 0, 0, S_TRAPGOYLEUP_FIRE1}, // S_TRAPGOYLEUP_CHECK
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP_FIRE2}, // S_TRAPGOYLEUP_FIRE1
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP_FIRE3}, // S_TRAPGOYLEUP_FIRE2
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP}, // S_TRAPGOYLEUP_FIRE3
{SPR_BGAR, 0, 67, {NULL}, 0, 0, S_TRAPGOYLEUP_CHECK}, // S_TRAPGOYLEUP
{SPR_BGAR, 0, 3, {NULL}, 0, 0, S_TRAPGOYLEUP_FIRE1}, // S_TRAPGOYLEUP_CHECK
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP_FIRE2}, // S_TRAPGOYLEUP_FIRE1
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP_FIRE3}, // S_TRAPGOYLEUP_FIRE2
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+45, S_TRAPGOYLEUP}, // S_TRAPGOYLEUP_FIRE3
{SPR_GARG, 0, 67, {NULL}, 0, 0, S_TRAPGOYLEDOWN_CHECK}, // S_TRAPGOYLEDOWN
{SPR_GARG, 0, 3, {NULL}, 0, 0, S_TRAPGOYLEDOWN_FIRE1}, // S_TRAPGOYLEDOWN_CHECK
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN_FIRE2}, // S_TRAPGOYLEDOWN_FIRE1
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN_FIRE3}, // S_TRAPGOYLEDOWN_FIRE2
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN}, // S_TRAPGOYLEDOWN_FIRE3
{SPR_BGAR, 0, 67, {NULL}, 0, 0, S_TRAPGOYLEDOWN_CHECK}, // S_TRAPGOYLEDOWN
{SPR_BGAR, 0, 3, {NULL}, 0, 0, S_TRAPGOYLEDOWN_FIRE1}, // S_TRAPGOYLEDOWN_CHECK
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN_FIRE2}, // S_TRAPGOYLEDOWN_FIRE1
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN_FIRE3}, // S_TRAPGOYLEDOWN_FIRE2
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16)+315, S_TRAPGOYLEDOWN}, // S_TRAPGOYLEDOWN_FIRE3
{SPR_GARG, 0, 135, {NULL}, 0, 0, S_TRAPGOYLELONG_CHECK}, // S_TRAPGOYLELONG
{SPR_GARG, 0, 3, {NULL}, 0, 0, S_TRAPGOYLELONG_FIRE1}, // S_TRAPGOYLELONG_CHECK
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE2}, // S_TRAPGOYLELONG_FIRE1
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE3}, // S_TRAPGOYLELONG_FIRE2
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE4}, // S_TRAPGOYLELONG_FIRE3
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE5}, // S_TRAPGOYLELONG_FIRE4
{SPR_GARG, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG}, // S_TRAPGOYLELONG_FIRE5
{SPR_BGAR, 0, 135, {NULL}, 0, 0, S_TRAPGOYLELONG_CHECK}, // S_TRAPGOYLELONG
{SPR_BGAR, 0, 3, {NULL}, 0, 0, S_TRAPGOYLELONG_FIRE1}, // S_TRAPGOYLELONG_CHECK
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE2}, // S_TRAPGOYLELONG_FIRE1
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE3}, // S_TRAPGOYLELONG_FIRE2
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE4}, // S_TRAPGOYLELONG_FIRE3
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG_FIRE5}, // S_TRAPGOYLELONG_FIRE4
{SPR_BGAR, 0, 1, {A_TrapShot}, (16<<16)+MT_DEMONFIRE, (30<<16), S_TRAPGOYLELONG}, // S_TRAPGOYLELONG_FIRE5
// Target/Red Crystal
{SPR_RCRY, 0, -1, {NULL}, 0, 0, S_TARGET_IDLE}, // S_TARGET_IDLE
@ -2605,6 +2609,9 @@ state_t states[NUMSTATES] =
{SPR_RCRY, 1, 0, {A_SpawnObjectRelative}, 0, MT_TARGET, S_NULL}, // S_TARGET_RESPAWN
{SPR_RCRY, FF_FULLBRIGHT|1, -1, {A_SetObjectFlags}, MF_PUSHABLE, 1, S_TARGET_ALLDONE}, // S_TARGET_ALLDONE
// Green flame
{SPR_CFLM, FF_FULLBRIGHT|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 3, S_GREENFLAME}, // S_GREENFLAME
// Stalagmites
{SPR_STLG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_STG0
{SPR_STLG, 1, -1, {NULL}, 0, 0, S_NULL}, // S_STG1
@ -4096,7 +4103,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MT_THOK, // damage
sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE, // flags
MT_NULL // raisestate
(statenum_t)MT_NULL// raisestate
},
{ // MT_TAILSOVERLAY
@ -4528,7 +4535,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // damage
sfx_s3kd2l, // activesound
MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
MT_CRUSHCHAIN // raisestate
(statenum_t)MT_CRUSHCHAIN// raisestate
},
{ // MT_CRUSHCHAIN
@ -11303,7 +11310,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
},
{ // MT_SMALLMACE
-1, // doomednum
1130, // doomednum
S_SMALLMACE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
@ -11330,7 +11337,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
},
{ // MT_BIGMACE
-1, // doomednum
1131, // doomednum
S_BIGMACE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
@ -11385,7 +11392,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_BIGGRABCHAIN
-1, // doomednum
S_BIGGRABCHAIN, // spawnstate
S_BIGGRABCHAIN, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -11411,7 +11418,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
},
{ // MT_YELLOWSPRINGBALL
-1, // doomednum
1134, // doomednum
S_YELLOWSPRINGBALL, // spawnstate
1000, // spawnhealth
S_YELLOWSPRINGBALL2, // seestate
@ -11438,7 +11445,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
},
{ // MT_REDSPRINGBALL
-1, // doomednum
1135, // doomednum
S_REDSPRINGBALL, // spawnstate
1000, // spawnhealth
S_REDSPRINGBALL2, // seestate
@ -11465,7 +11472,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
},
{ // MT_SMALLFIREBAR
-1, // doomednum
1136, // doomednum
S_SMALLFIREBAR1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
@ -11492,7 +11499,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
},
{ // MT_BIGFIREBAR
-1, // doomednum
1137, // doomednum
S_BIGFIREBAR1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
@ -12028,7 +12035,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // damage
sfx_None, // activesound
MF_SLIDEME|MF_SOLID|MF_PUSHABLE, // flags
MT_ROCKCRUMBLE3 // raisestate
(statenum_t)MT_ROCKCRUMBLE3// raisestate
},
{ // MT_BRAMBLES
@ -12730,7 +12737,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // damage
sfx_s3k76, // activesound
MF_PUSHABLE, // flags
MT_MINECARTSIDEMARK // raisestate
(statenum_t)MT_MINECARTSIDEMARK// raisestate
},
{ // MT_MINECARTSEG
@ -13678,6 +13685,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_GREENFLAME
1505, // doomednum
S_GREENFLAME, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
MT_NULL, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOGRAVITY|MF_PAIN, // flags
S_NULL // raisestate
},
{ // MT_STALAGMITE0
1900, // doomednum
S_STG0, // spawnstate

View file

@ -556,6 +556,11 @@ typedef enum sprite
SPR_HHPL, // Dr Seuss Trees
SPR_SHRM, // Mushroom
SPR_HHZM, // Misc
// Azure Temple Scenery
SPR_BGAR, // ATZ Gargoyles
SPR_RCRY, // ATZ Red Crystal (Target)
SPR_CFLM, // Green torch flame
// Botanic Serenity Scenery
SPR_BSZ1, // Tall flowers
@ -576,7 +581,6 @@ typedef enum sprite
// Misc Scenery
SPR_STLG, // Stalagmites
SPR_DBAL, // Disco
SPR_RCRY, // ATZ Red Crystal (Target)
// Powerup Indicators
SPR_ARMA, // Armageddon Shield Orb
@ -2720,6 +2724,9 @@ typedef enum state
S_TARGET_RESPAWN,
S_TARGET_ALLDONE,
// ATZ's green flame
S_GREENFLAME,
// Stalagmites
S_STG0,
S_STG1,
@ -4496,6 +4503,7 @@ typedef enum mobj_type
MT_TRAPGOYLEDOWN,
MT_TRAPGOYLELONG,
MT_TARGET, // AKA Red Crystal
MT_GREENFLAME,
// Stalagmites
MT_STALAGMITE0,

View file

@ -1121,7 +1121,7 @@ void LUA_Archive(void)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
if (!playeringame[i] && i > 0) // dedicated servers...
continue;
// all players in game will be archived, even if they just add a 0.
ArchiveExtVars(&players[i], "player");
@ -1157,7 +1157,7 @@ void LUA_UnArchive(void)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
if (!playeringame[i] && i > 0) // dedicated servers...
continue;
UnArchiveExtVars(&players[i]);
}

View file

@ -4546,10 +4546,12 @@ static boolean M_LevelAvailableOnPlatter(INT32 mapnum)
if (!(mapheaderinfo[mapnum]->typeoflevel & TOL_COOP))
return true;
if (mapvisited[mapnum]) // MV_MP
if (mapnum+1 == spstage_start)
return true;
if (mapnum+1 == spstage_start)
#ifndef DEVELOP
if (mapvisited[mapnum]) // MV_MP
#endif
return true;
/* FALLTHRU */
@ -4895,13 +4897,25 @@ static void M_HandleLevelPlatter(INT32 choice)
{
boolean exitmenu = false; // exit to previous menu
INT32 selectval;
UINT8 iter;
switch (choice)
{
case KEY_DOWNARROW:
if (lsrow == levelselect.numrows-1)
{
if (levelselect.numrows < 3)
{
if (!lsoffs[0]) // prevent sound spam
{
lsoffs[0] = -8;
S_StartSound(NULL,sfx_s3kb7);
}
return;
}
lsrow = UINT8_MAX;
}
lsrow++;
if (lsrow == levelselect.numrows)
lsrow = 0;
lsoffs[0] = lsvseperation(lsrow);
@ -4915,17 +4929,29 @@ static void M_HandleLevelPlatter(INT32 choice)
break;
case KEY_UPARROW:
lsoffs[0] = -lsvseperation(lsrow);
iter = lsrow;
if (!lsrow)
{
if (levelselect.numrows < 3)
{
if (!lsoffs[0]) // prevent sound spam
{
lsoffs[0] = 8;
S_StartSound(NULL,sfx_s3kb7);
}
return;
}
lsrow = levelselect.numrows;
}
lsrow--;
if (lsrow == UINT8_MAX)
lsrow = levelselect.numrows-1;
lsoffs[0] = -lsvseperation(iter);
if (levelselect.rows[lsrow].header[0])
lshli = lsrow;
else
{
UINT8 iter = lsrow;
iter = lsrow;
do
iter = ((iter == 0) ? levelselect.numrows-1 : iter-1);
while ((iter != lsrow) && !(levelselect.rows[iter].header[0]));
@ -4958,7 +4984,7 @@ static void M_HandleLevelPlatter(INT32 choice)
M_LevelSelectWarp(0);
Nextmap_OnChange();
}
else if (!lsoffs[0]) // prevent sound spam
else if (!lsoffs[0]) // prevent sound spam
{
lsoffs[0] = -8;
S_StartSound(NULL,sfx_s3kb2);
@ -4988,7 +5014,7 @@ static void M_HandleLevelPlatter(INT32 choice)
ifselectvalnextmap(lscol) else ifselectvalnextmap(0)
}
else if (!lsoffs[1]) // prevent sound spam
else if (!lsoffs[1]) // prevent sound spam
{
lsoffs[1] = 8;
S_StartSound(NULL,sfx_s3kb7);
@ -5017,7 +5043,7 @@ static void M_HandleLevelPlatter(INT32 choice)
ifselectvalnextmap(lscol) else ifselectvalnextmap(0)
}
else if (!lsoffs[1]) // prevent sound spam
else if (!lsoffs[1]) // prevent sound spam
{
lsoffs[1] = -8;
S_StartSound(NULL,sfx_s3kb7);
@ -5188,7 +5214,13 @@ static void M_DrawLevelPlatterMenu(void)
// finds row at top of the screen
while (y > -8)
{
iter = ((iter == 0) ? levelselect.numrows-1 : iter-1);
if (iter == 0)
{
if (levelselect.numrows < 3)
break;
iter = levelselect.numrows;
}
iter--;
y -= lsvseperation(iter);
}
@ -5197,7 +5229,13 @@ static void M_DrawLevelPlatterMenu(void)
{
M_DrawLevelPlatterRow(iter, y);
y += lsvseperation(iter);
iter = ((iter == levelselect.numrows-1) ? 0 : iter+1);
if (iter == levelselect.numrows-1)
{
if (levelselect.numrows < 3)
break;
iter = UINT8_MAX;
}
iter++;
}
// draw cursor box

View file

@ -197,7 +197,7 @@ INT32 M_MapNumber(char first, char second)
// ==========================================================================
// some libcs has no access function, make our own
#if defined (_WIN32_WCE)
#if 0
int access(const char *path, int amode)
{
int accesshandle = -1;

View file

@ -2171,7 +2171,7 @@ void A_CrushclawLaunch(mobj_t *actor)
UINT8 i = 0;
for (i = 0; (i < CSEGS); i++)
{
mobj_t *newchain = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->info->raisestate);
mobj_t *newchain = P_SpawnMobjFromMobj(actor, 0, 0, 0, (mobjtype_t)actor->info->raisestate);
P_SetTarget(&prevchain->target, newchain);
prevchain = newchain;
}

View file

@ -1493,8 +1493,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_SetMobjState(mo2, mo2->info->painstate);
}
}
S_StartSound(toucher, special->info->painsound);
return;
case MT_FAKEMOBILE:
@ -2468,6 +2466,28 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY;
P_SetThingPosition(target);
if (target->player->powers[pw_super])
{
target->player->powers[pw_super] = 0;
if (P_IsLocalPlayer(target->player))
{
music_stack_noposition = true; // HACK: Do not reposition next music
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
}
P_RestoreMusic(target->player);
if (gametype != GT_COOP)
{
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[target->player-players]));
}
}
target->color = target->player->skincolor;
target->colorized = false;
G_GhostAddColor(GHC_NORMAL);
if ((target->player->lives <= 1) && (netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value == 0))
;
else if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap) && (target->player->lives != INFLIVES)

View file

@ -674,7 +674,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
if (delta1 >= delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
@ -687,7 +687,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
highceiling = bottomheight;
}
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
if (delta1 < delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;
@ -720,7 +720,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
if (delta1 >= delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
@ -733,7 +733,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
highceiling = bottomheight;
}
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
if (delta1 < delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;

View file

@ -1990,6 +1990,8 @@ void P_XYMovement(mobj_t *mo)
{
mo->momz = transfermomz;
mo->standingslope = NULL;
if (player->pflags & PF_SPINNING)
player->pflags = (player->pflags & ~PF_SPINNING) | (PF_JUMPED | PF_THOKKED);
}
}
#endif
@ -4716,13 +4718,17 @@ static void P_Boss4MoveSpikeballs(mobj_t *mobj, angle_t angle, fixed_t fz)
}
}
#define CEZ3TILT
// Pull them closer.
static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t dz)
{
INT32 s;
mobj_t *base = mobj, *seg;
fixed_t originx, originy, workx, worky, dx, dy, bz = mobj->watertop+(8<<FRACBITS);
fixed_t workx, worky, dx, dy, bz = mobj->watertop+(8<<FRACBITS);
fixed_t rad = (9*132)<<FRACBITS;
#ifdef CEZ3TILT
fixed_t originx, originy;
if (mobj->spawnpoint)
{
originx = mobj->spawnpoint->x << FRACBITS;
@ -4733,13 +4739,25 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t dz)
originx = mobj->x;
originy = mobj->y;
}
#else
if (mobj->spawnpoint)
{
rad -= R_PointToDist2(mobj->x, mobj->y,
(mobj->spawnpoint->x<<FRACBITS), (mobj->spawnpoint->y<<FRACBITS));
}
#endif
dz /= 9;
while ((base = base->tracer)) // there are 10 per spoke, remember that
{
dx = (originx + P_ReturnThrustX(mobj, angle, (9*132)<<FRACBITS) - mobj->x)/9;
dy = (originy + P_ReturnThrustY(mobj, angle, (9*132)<<FRACBITS) - mobj->y)/9;
#ifdef CEZ3TILT
dx = (originx + P_ReturnThrustX(mobj, angle, rad) - mobj->x)/9;
dy = (originy + P_ReturnThrustY(mobj, angle, rad) - mobj->y)/9;
#else
dx = P_ReturnThrustX(mobj, angle, rad)/9;
dy = P_ReturnThrustY(mobj, angle, rad)/9;
#endif
workx = mobj->x + P_ReturnThrustX(mobj, angle, (112)<<FRACBITS);
worky = mobj->y + P_ReturnThrustY(mobj, angle, (112)<<FRACBITS);
for (seg = base, s = 9; seg; seg = seg->hnext, --s)
@ -4929,6 +4947,7 @@ static void P_Boss4Thinker(mobj_t *mobj)
mobj->movecount += mobj->threshold;
if (mobj->movecount <= 0)
{
mobj->flags2 &= ~MF2_INVERTAIMABLE;
mobj->movecount = 0;
mobj->movedir++; // Initialization complete, next phase!
}
@ -10321,6 +10340,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->movefactor = -512*FRACUNIT;
mobj->flags2 |= MF2_CLASSICPUSH;
break;
case MT_EGGMOBILE4:
mobj->flags2 |= MF2_INVERTAIMABLE;
break;
case MT_FLICKY_08:
mobj->color = (P_RandomChance(FRACUNIT/2) ? SKINCOLOR_RED : SKINCOLOR_AQUA);
break;

View file

@ -2718,6 +2718,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
CONS_Debug(DBG_GAMELOGIC, "Line type 414 Executor: sfx number %d is invalid!\n", sfxnum);
return;
}
if (line->tag != 0) // Do special stuff only if a non-zero linedef tag is set
{
if (line->flags & ML_EFFECT5) // Repeat Midtexture
@ -2758,30 +2759,32 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
return;
}
}
if (line->flags & ML_NOCLIMB)
else
{
// play the sound from nowhere, but only if display player triggered it
if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer]))
if (line->flags & ML_NOCLIMB)
{
// play the sound from nowhere, but only if display player triggered it
if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer]))
S_StartSound(NULL, sfxnum);
}
else if (line->flags & ML_EFFECT4)
{
// play the sound from nowhere
S_StartSound(NULL, sfxnum);
}
else if (line->flags & ML_EFFECT4)
{
// play the sound from nowhere
S_StartSound(NULL, sfxnum);
}
else if (line->flags & ML_BLOCKMONSTERS)
{
// play the sound from calling sector's soundorg
if (callsec)
S_StartSound(&callsec->soundorg, sfxnum);
}
else if (line->flags & ML_BLOCKMONSTERS)
{
// play the sound from calling sector's soundorg
if (callsec)
S_StartSound(&callsec->soundorg, sfxnum);
else if (mo)
S_StartSound(&mo->subsector->sector->soundorg, sfxnum);
}
else if (mo)
S_StartSound(&mo->subsector->sector->soundorg, sfxnum);
}
else if (mo)
{
// play the sound from mobj that triggered it
S_StartSound(mo, sfxnum);
{
// play the sound from mobj that triggered it
S_StartSound(mo, sfxnum);
}
}
}
break;
@ -7089,7 +7092,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
case 254: // Bustable block
ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP;
if (lines[i].flags & ML_NOCLIMB)
ffloorflags |= FF_ONLYKNUX;
ffloorflags |= FF_STRONGBUST;
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
break;

View file

@ -2456,39 +2456,42 @@ static void P_CheckBustableBlocks(player_t *player)
if ((rover->flags & FF_BUSTUP)/* && !rover->master->frontsector->crumblestate*/)
{
// If it's an FF_SPINBUST, you have to either be jumping, or coming down
// onto the top from a spin.
if (rover->flags & FF_SPINBUST && ((!(player->pflags & PF_JUMPED) && !(player->pflags & PF_SPINNING) && !(player->pflags & PF_BOUNCING)) || (player->pflags & PF_STARTDASH)))
// If it's an FF_SHATTER, you can break it just by touching it.
if (rover->flags & FF_SHATTER)
goto bust;
// If it's an FF_SPINBUST, you can break it if you are in your spinning frames
// (either from jumping or spindashing).
if (rover->flags & FF_SPINBUST
&& (((player->pflags & PF_SPINNING) && !(player->pflags & PF_STARTDASH))
|| (player->pflags & PF_JUMPED && !(player->pflags & PF_NOJUMPDAMAGE))))
goto bust;
// You can always break it if you have CA_GLIDEANDCLIMB
// or if you are bouncing on it
// or you are using CA_TWINSPIN/CA2_MELEE.
if (player->charability == CA_GLIDEANDCLIMB
|| (player->pflags & PF_BOUNCING)
|| ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY))
|| (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2))
goto bust;
if (rover->flags & FF_STRONGBUST)
continue;
// if it's not an FF_SHATTER, you must be spinning (and not jumping)
// or be super
// or have CA_GLIDEANDCLIMB
// or be in dashmode with SF_DASHMODE
// or be using CA_TWINSPIN
// or be using CA2_MELEE
// or are drilling in NiGHTS
// or are recording for Metal Sonic
if (!(rover->flags & FF_SHATTER) && !(rover->flags & FF_SPINBUST)
&& !((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED))
// If it's not an FF_STRONGBUST, you can break if you are spinning (and not jumping)
// or you are super
// or you are in dashmode with SF_DASHMODE
// or you are drilling in NiGHTS
// or you are recording for Metal Sonic
if (!((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED))
&& !(player->powers[pw_super])
&& !(player->charability == CA_GLIDEANDCLIMB)
&& !(player->pflags & PF_BOUNCING)
&& !((player->charflags & SF_DASHMODE) && (player->dashmode >= 3*TICRATE))
&& !((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY))
&& !(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
&& !(player->pflags & PF_DRILLING)
&& !metalrecording)
continue;
// Only players with CA_GLIDEANDCLIMB, or CA_TWINSPIN/CA2_MELEE users can break this rock...
if (!(rover->flags & FF_SHATTER) && (rover->flags & FF_ONLYKNUX)
&& !(player->charability == CA_GLIDEANDCLIMB
|| (player->pflags & PF_BOUNCING)
|| ((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY))
|| (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)))
continue;
bust:
topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
@ -4153,8 +4156,11 @@ static void P_DoSuperStuff(player_t *player)
{
player->powers[pw_super] = 0;
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
music_stack_noposition = true; // HACK: Do not reposition next music
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
if (P_IsLocalPlayer(player))
{
music_stack_noposition = true; // HACK: Do not reposition next music
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
}
P_RestoreMusic(player);
P_SpawnShieldOrb(player);
@ -4223,7 +4229,7 @@ static void P_DoSuperStuff(player_t *player)
if (gametype != GT_COOP)
player->powers[pw_flashing] = flashingtics-1;
if ((player->mo->health > 0) && (player->mo->sprite2 & FF_SPR2SUPER))
if (player->mo->sprite2 & FF_SPR2SUPER)
P_SetPlayerMobjState(player->mo, player->mo->state-states);
// Inform the netgame that the champion has fallen in the heat of battle.
@ -4236,8 +4242,11 @@ static void P_DoSuperStuff(player_t *player)
}
// Resume normal music if you're the console player
music_stack_noposition = true; // HACK: Do not reposition next music
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
if (P_IsLocalPlayer(player))
{
music_stack_noposition = true; // HACK: Do not reposition next music
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
}
P_RestoreMusic(player);
// If you had a shield, restore its visual significance.
@ -4345,7 +4354,6 @@ void P_DoJump(player_t *player, boolean soundandstate)
{
player->mo->momz = 9*FRACUNIT;
player->powers[pw_carry] = CR_NONE;
player->mo->tracer->flags |= MF_PUSHABLE;
P_SetTarget(&player->mo->tracer->target, NULL);
P_SetTarget(&player->mo->tracer, NULL);
}
@ -10457,7 +10465,7 @@ static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t target
//Axes must be directly parallel or antiparallel, give or take 5 degrees.
if (angdiff < ANG10)
{
mark = P_SpawnMobj(nx, ny, nz, mobj->info->raisestate);
mark = P_SpawnMobj(nx, ny, nz, (mobjtype_t)mobj->info->raisestate);
return mark;
}
}
@ -10672,7 +10680,11 @@ static void P_MinecartThink(player_t *player)
}
}
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
if (player->mo->state-states != S_PLAY_STND)
{
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
player->mo->tics = -1;
}
// Move player to minecart.
P_TeleportMove(player->mo, minecart->x - minecart->momx, minecart->y - minecart->momy, minecart->z + max(minecart->momz, 0) + 8*FRACUNIT);
@ -12074,7 +12086,7 @@ void P_PlayerAfterThink(player_t *player)
mo->momx = rock->momx;
mo->momy = rock->momy;
mo->momz = 0;
if (player->panim == PA_IDLE && (mo->momx || mo->momy))
{
P_SetPlayerMobjState(player->mo, S_PLAY_WALK);

View file

@ -35,7 +35,7 @@
#endif
// Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog
#ifdef _WIN32_WCE
#if 0
#define AVOID_ERRNO
#else
#include <errno.h>
@ -483,7 +483,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
wadnum = patch->wad;
lumpnum = patch->lump;
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); // can't use W_CachePatchNumPwad because OpenGL
#ifndef NO_PNG_LUMPS
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
@ -557,7 +557,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
texturememory += blocksize;
block = Z_Malloc(blocksize+1, PU_STATIC, &texturecache[texnum]);
memset(block, 0xFF, blocksize+1); // Transparency hack
memset(block, TRANSPARENTPIXEL, blocksize+1); // Transparency hack
// columns lookup table
colofs = (UINT32 *)(void *)block;
@ -2520,7 +2520,11 @@ void R_PrecacheLevel(void)
"spritememory: %s k\n", sizeu1(flatmemory>>10), sizeu2(texturememory>>10), sizeu3(spritememory>>10));
}
// https://github.com/coelckers/prboom-plus/blob/master/prboom2/src/r_patch.c#L350
//
// R_CheckIfPatch
//
// Returns true if the lump is a valid patch.
//
boolean R_CheckIfPatch(lumpnum_t lump)
{
size_t size;
@ -2565,6 +2569,71 @@ boolean R_CheckIfPatch(lumpnum_t lump)
return result;
}
//
// R_TextureToFlat
//
// Convert a texture to a flat.
//
void R_TextureToFlat(size_t tex, UINT8 *flat)
{
texture_t *texture = textures[tex];
fixed_t col, ofs;
column_t *column;
UINT8 *desttop, *dest, *deststop;
UINT8 *source;
// yea
R_CheckTextureCache(tex);
desttop = flat;
deststop = desttop + (texture->width * texture->height);
for (col = 0; col < texture->width; col++, desttop++)
{
// no post_t info
if (!texture->holes)
{
column = (column_t *)(R_GetColumn(tex, col));
source = (UINT8 *)(column);
dest = desttop;
for (ofs = 0; dest < deststop && ofs < texture->height; ofs++)
{
if (source[ofs] != TRANSPARENTPIXEL)
*dest = source[ofs];
dest += texture->width;
}
}
else
{
INT32 topdelta, prevdelta = -1;
column = (column_t *)((UINT8 *)R_GetColumn(tex, col) - 3);
while (column->topdelta != 0xff)
{
topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
dest = desttop + (topdelta * texture->width);
source = (UINT8 *)column + 3;
for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
{
if (source[ofs] != TRANSPARENTPIXEL)
*dest = source[ofs];
dest += texture->width;
}
column = (column_t *)((UINT8 *)column + column->length + 4);
}
}
}
}
//
// R_PatchToFlat
//
// Convert a patch to a flat.
//
void R_PatchToFlat(patch_t *patch, UINT8 *flat)
{
fixed_t col, ofs;
@ -2599,7 +2668,124 @@ void R_PatchToFlat(patch_t *patch, UINT8 *flat)
}
}
//
// R_FlatToPatch
//
// Convert a flat to a patch.
//
static unsigned char imgbuf[1<<26];
patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency)
{
UINT32 x, y;
UINT8 *img;
UINT8 *imgptr = imgbuf;
UINT8 *colpointers, *startofspan;
size_t size = 0;
// Write image size and offset
WRITEINT16(imgptr, width);
WRITEINT16(imgptr, height);
WRITEINT16(imgptr, leftoffset);
WRITEINT16(imgptr, topoffset);
// Leave placeholder to column pointers
colpointers = imgptr;
imgptr += width*4;
// Write columns
for (x = 0; x < width; x++)
{
int lastStartY = 0;
int spanSize = 0;
startofspan = NULL;
// Write column pointer
WRITEINT32(colpointers, imgptr - imgbuf);
// Write pixels
for (y = 0; y < height; y++)
{
UINT8 paletteIndex = raw[((y * width) + x)];
boolean opaque = transparency ? (paletteIndex != TRANSPARENTPIXEL) : true;
// End span if we have a transparent pixel
if (!opaque)
{
if (startofspan)
WRITEUINT8(imgptr, 0);
startofspan = NULL;
continue;
}
// Start new column if we need to
if (!startofspan || spanSize == 255)
{
int writeY = y;
// If we reached the span size limit, finish the previous span
if (startofspan)
WRITEUINT8(imgptr, 0);
if (y > 254)
{
// Make sure we're aligned to 254
if (lastStartY < 254)
{
WRITEUINT8(imgptr, 254);
WRITEUINT8(imgptr, 0);
imgptr += 2;
lastStartY = 254;
}
// Write stopgap empty spans if needed
writeY = y - lastStartY;
while (writeY > 254)
{
WRITEUINT8(imgptr, 254);
WRITEUINT8(imgptr, 0);
imgptr += 2;
writeY -= 254;
}
}
startofspan = imgptr;
WRITEUINT8(imgptr, writeY);
imgptr += 2;
spanSize = 0;
lastStartY = y;
}
// Write the pixel
WRITEUINT8(imgptr, paletteIndex);
spanSize++;
startofspan[1] = spanSize;
}
if (startofspan)
WRITEUINT8(imgptr, 0);
WRITEUINT8(imgptr, 0xFF);
}
size = imgptr-imgbuf;
img = Z_Malloc(size, PU_STATIC, NULL);
memcpy(img, imgbuf, size);
Z_Free(raw);
if (destsize != NULL)
*destsize = size;
return (patch_t *)img;
}
#ifndef NO_PNG_LUMPS
//
// R_IsLumpPNG
//
// Returns true if the lump is a valid PNG.
//
boolean R_IsLumpPNG(const UINT8 *d, size_t s)
{
if (s < 67) // http://garethrees.org/2007/11/14/pngcrush/
@ -2812,125 +2998,31 @@ static UINT8 *PNG_RawConvert(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topo
return flat;
}
//
// R_PNGToFlat
//
// Convert a PNG to a flat.
UINT8 *R_PNGToFlat(levelflat_t *levelflat, UINT8 *png, size_t size)
//
UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size)
{
return PNG_RawConvert(png, &levelflat->width, &levelflat->height, NULL, NULL, size);
return PNG_RawConvert(png, width, height, NULL, NULL, size);
}
//
// R_PNGToPatch
//
// Convert a PNG to a patch.
static unsigned char imgbuf[1<<26];
//
patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency)
{
UINT16 width, height;
INT16 topoffset = 0, leftoffset = 0;
UINT8 *raw = PNG_RawConvert(png, &width, &height, &topoffset, &leftoffset, size);
UINT32 x, y;
UINT8 *img;
UINT8 *imgptr = imgbuf;
UINT8 *colpointers, *startofspan;
if (!raw)
I_Error("R_PNGToPatch: conversion failed");
// Write image size and offset
WRITEINT16(imgptr, width);
WRITEINT16(imgptr, height);
WRITEINT16(imgptr, leftoffset);
WRITEINT16(imgptr, topoffset);
// Leave placeholder to column pointers
colpointers = imgptr;
imgptr += width*4;
// Write columns
for (x = 0; x < width; x++)
{
int lastStartY = 0;
int spanSize = 0;
startofspan = NULL;
//printf("%d ", x);
// Write column pointer (@TODO may be wrong)
WRITEINT32(colpointers, imgptr - imgbuf);
// Write pixels
for (y = 0; y < height; y++)
{
UINT8 paletteIndex = raw[((y * width) + x)];
boolean opaque = transparency ? (paletteIndex != TRANSPARENTPIXEL) : true;
// End span if we have a transparent pixel
if (!opaque)
{
if (startofspan)
WRITEUINT8(imgptr, 0);
startofspan = NULL;
continue;
}
// Start new column if we need to
if (!startofspan || spanSize == 255)
{
int writeY = y;
// If we reached the span size limit, finish the previous span
if (startofspan)
WRITEUINT8(imgptr, 0);
if (y > 254)
{
// Make sure we're aligned to 254
if (lastStartY < 254)
{
WRITEUINT8(imgptr, 254);
WRITEUINT8(imgptr, 0);
imgptr += 2;
lastStartY = 254;
}
// Write stopgap empty spans if needed
writeY = y - lastStartY;
while (writeY > 254)
{
WRITEUINT8(imgptr, 254);
WRITEUINT8(imgptr, 0);
imgptr += 2;
writeY -= 254;
}
}
startofspan = imgptr;
WRITEUINT8(imgptr, writeY);///@TODO calculate starting y pos
imgptr += 2;
spanSize = 0;
lastStartY = y;
}
// Write the pixel
WRITEUINT8(imgptr, paletteIndex);
spanSize++;
startofspan[1] = spanSize;
}
if (startofspan)
WRITEUINT8(imgptr, 0);
WRITEUINT8(imgptr, 0xFF);
}
size = imgptr-imgbuf;
img = Z_Malloc(size, PU_STATIC, NULL);
memcpy(img, imgbuf, size);
Z_Free(raw);
if (destsize != NULL)
*destsize = size;
return (patch_t *)img;
return R_FlatToPatch(raw, width, height, leftoffset, topoffset, destsize, transparency);
}
boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size)
@ -3001,53 +3093,3 @@ boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size)
}
#endif
#endif
void R_TextureToFlat(size_t tex, UINT8 *flat)
{
texture_t *texture = textures[tex];
fixed_t col, ofs;
column_t *column;
UINT8 *desttop, *dest, *deststop;
UINT8 *source;
desttop = flat;
deststop = desttop + (texture->width * texture->height);
for (col = 0; col < texture->width; col++, desttop++)
{
column = (column_t *)R_GetColumn(tex, col);
if (!texture->holes)
{
dest = desttop;
source = (UINT8 *)(column);
for (ofs = 0; dest < deststop && ofs < texture->height; ofs++)
{
if (source[ofs] != TRANSPARENTPIXEL)
*dest = source[ofs];
dest += texture->width;
}
}
else
{
INT32 topdelta, prevdelta = -1;
while (column->topdelta != 0xff)
{
topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
dest = desttop + (topdelta * texture->width);
source = (UINT8 *)(column) + 3;
for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
{
if (source[ofs] != TRANSPARENTPIXEL)
*dest = source[ofs];
dest += texture->width;
}
column = (column_t *)((UINT8 *)column + column->length + 4);
}
}
}
}

View file

@ -159,15 +159,14 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap);
#define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a))
boolean R_CheckIfPatch(lumpnum_t lump);
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
void R_PatchToFlat(patch_t *patch, UINT8 *flat);
void R_TextureToFlat(size_t tex, UINT8 *flat);
void R_PatchToFlat(patch_t *patch, UINT8 *flat);
patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency);
#ifndef NO_PNG_LUMPS
boolean R_IsLumpPNG(const UINT8 *d, size_t s);
UINT8 *R_PNGToFlat(levelflat_t *levelflat, UINT8 *png, size_t size);
UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size);
patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency);
boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size);
#endif

View file

@ -139,9 +139,9 @@ typedef enum
FF_PLATFORM = 0x2000000, ///< You can jump up through this to the top.
FF_REVERSEPLATFORM = 0x4000000, ///< A fall-through floor in normal gravity, a platform in reverse gravity.
FF_INTANGABLEFLATS = 0x6000000, ///< Both flats are intangable, but the sides are still solid.
FF_SHATTER = 0x8000000, ///< Used with ::FF_BUSTUP. Thinks everyone's Knuckles.
FF_SPINBUST = 0x10000000, ///< Used with ::FF_BUSTUP. Jump or fall onto it while curled in a ball.
FF_ONLYKNUX = 0x20000000, ///< Used with ::FF_BUSTUP. Only Knuckles can break this rock.
FF_SHATTER = 0x8000000, ///< Used with ::FF_BUSTUP. Bustable on mere touch.
FF_SPINBUST = 0x10000000, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames.
FF_STRONGBUST = 0x20000000, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee).
FF_RIPPLE = 0x40000000, ///< Ripple the flats
FF_COLORMAPONLY = 0x80000000, ///< Only copy the colormap, not the lightlevel
FF_GOOWATER = FF_SHATTERBOTTOM, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.

View file

@ -44,6 +44,9 @@
// Quincunx antialiasing of flats!
//#define QUINCUNX
// good night sweet prince
#define SHITPLANESPARENCY
//SoM: 3/23/2000: Use Boom visplane hashing.
visplane_t *visplanes[MAXVISPLANES];
@ -650,6 +653,11 @@ static void R_DrawSkyPlane(visplane_t *pl)
}
}
//
// R_CheckPowersOfTwo
//
// Self-explanatory?
//
boolean R_CheckPowersOfTwo(void)
{
boolean wpow2 = (!(ds_flatwidth & (ds_flatwidth - 1)));
@ -667,6 +675,11 @@ boolean R_CheckPowersOfTwo(void)
return ds_powersoftwo;
}
//
// R_CheckFlatLength
//
// Determine the flat's dimensions from the lump length.
//
void R_CheckFlatLength(size_t size)
{
switch (size)
@ -723,7 +736,24 @@ void R_CheckFlatLength(size_t size)
}
}
static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boolean ispng)
//
// R_GenerateFlat
//
// Generate a flat from specified width and height.
//
static UINT8 *R_GenerateFlat(UINT16 width, UINT16 height)
{
UINT8 *flat = Z_Malloc(width * height, PU_LEVEL, NULL);
memset(flat, TRANSPARENTPIXEL, width * height);
return flat;
}
//
// R_GetTextureFlat
//
// Convert a texture or patch to a flat.
//
static UINT8 *R_GetTextureFlat(levelflat_t *levelflat, boolean leveltexture, boolean ispng)
{
UINT8 *flat;
textureflat_t *texflat = &texflats[levelflat->texturenum];
@ -747,14 +777,14 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole
// If the texture changed, or the patch doesn't exist, convert either of them to a flat.
if (levelflat->flatpatch == NULL || texturechanged)
{
// Level texture
if (leveltexture)
{
texture_t *texture = textures[levelflat->texturenum];
texflat->width = ds_flatwidth = texture->width;
texflat->height = ds_flatheight = texture->height;
texflat->flat = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL);
memset(texflat->flat, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight);
texflat->flat = R_GenerateFlat(ds_flatwidth, ds_flatheight);
R_TextureToFlat(levelflat->texturenum, texflat->flat);
flat = texflat->flat;
@ -762,13 +792,14 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole
levelflat->width = ds_flatwidth;
levelflat->height = ds_flatheight;
}
// Patch (never happens yet)
else
{
patch = (patch_t *)ds_source;
#ifndef NO_PNG_LUMPS
if (ispng)
{
levelflat->flatpatch = R_PNGToFlat(levelflat, ds_source, W_LumpLength(levelflat->lumpnum));
levelflat->flatpatch = R_PNGToFlat(&levelflat->width, &levelflat->height, ds_source, W_LumpLength(levelflat->lumpnum));
levelflat->topoffset = levelflat->leftoffset = 0;
ds_flatwidth = levelflat->width;
ds_flatheight = levelflat->height;
@ -782,8 +813,7 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole
levelflat->topoffset = patch->topoffset * FRACUNIT;
levelflat->leftoffset = patch->leftoffset * FRACUNIT;
levelflat->flatpatch = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL);
memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight);
levelflat->flatpatch = R_GenerateFlat(ds_flatwidth, ds_flatheight);
R_PatchToFlat(patch, levelflat->flatpatch);
}
flat = levelflat->flatpatch;
@ -794,11 +824,11 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole
flat = levelflat->flatpatch;
ds_flatwidth = levelflat->width;
ds_flatheight = levelflat->height;
xoffs += levelflat->leftoffset;
yoffs += levelflat->topoffset;
}
xoffs += levelflat->leftoffset;
yoffs += levelflat->topoffset;
levelflat->lasttexturenum = levelflat->texturenum;
return flat;
}
@ -841,7 +871,11 @@ void R_DrawSinglePlane(visplane_t *pl)
else // Opaque, but allow transparent flat pixels
spanfunc = splatfunc;
#ifdef SHITPLANESPARENCY
if ((spanfunc == splatfunc) != (pl->extra_colormap && (pl->extra_colormap->fog & 4)))
#else
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
#endif
light = (pl->lightlevel >> LIGHTSEGSHIFT);
else
light = LIGHTLEVELS-1;
@ -895,7 +929,11 @@ void R_DrawSinglePlane(visplane_t *pl)
else // Opaque, but allow transparent flat pixels
spanfunc = splatfunc;
#ifdef SHITPLANESPARENCY
if ((spanfunc == splatfunc) != (pl->extra_colormap && (pl->extra_colormap->fog & 4)))
#else
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
#endif
light = (pl->lightlevel >> LIGHTSEGSHIFT);
else
light = LIGHTLEVELS-1;
@ -963,15 +1001,15 @@ void R_DrawSinglePlane(visplane_t *pl)
// Check if the flat is actually a wall texture.
if (levelflat->texturenum != 0 && levelflat->texturenum != -1)
flat = R_GetPatchFlat(levelflat, true, false);
flat = R_GetTextureFlat(levelflat, true, false);
#ifndef NO_PNG_LUMPS
// Maybe it's a PNG?!
else if (R_IsLumpPNG(ds_source, size))
flat = R_GetPatchFlat(levelflat, false, true);
flat = R_GetTextureFlat(levelflat, false, true);
#endif
// Maybe it's just a patch, then?
else if (R_CheckIfPatch(levelflat->lumpnum))
flat = R_GetPatchFlat(levelflat, false, false);
flat = R_GetTextureFlat(levelflat, false, false);
// It's a raw flat.
else
{

View file

@ -39,13 +39,8 @@
// we try to re-allocate a minimum of buffers for stability of the memory,
// so all the small-enough tables based on screen size, are allocated once
// and for all at the maximum size.
#if defined (_WIN32_WCE)
#define MAXVIDWIDTH 320
#define MAXVIDHEIGHT 200
#else
#define MAXVIDWIDTH 1920 // don't set this too high because actually
#define MAXVIDHEIGHT 1200 // lots of tables are allocated with the MAX size.
#endif
#define BASEVIDWIDTH 320 // NEVER CHANGE THIS! This is the original
#define BASEVIDHEIGHT 200 // resolution of the graphics.

9
tools/flatb/Makefile Normal file
View file

@ -0,0 +1,9 @@
.PHONY : all clean
all : flatb
flatb.exe : flatb.c
i686-w64-mingw32-gcc $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ $<
clean :
$(RM) flatb flatb.exe

566
tools/flatb/flatb.c Normal file
View file

@ -0,0 +1,566 @@
#define HELP \
"Usage: flatb WAD-file list-file" "\n"\
"Replace flats and textures by name in a DOOM WAD." "\n"\
"\n"\
"list-file may have the following format:" "\n"\
"\n"\
"GFZFLR01 GFZFLR02" "\n"\
"# Comment" "\n"\
"GFZROCK GFZBLOCK" "\n"\
"\n"\
"The first name and second name may be delimited by any whitespace." "\n"\
"\n"\
"Copyright 2019 James R." "\n"\
"All rights reserved." "\n"
/*
Copyright 2019 James R.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#define cchar const char
#define cvoid const void
#define LONG int32_t
#define va_inline( __ap,__last, ... )\
(\
va_start (__ap,__last),\
__VA_ARGS__,\
va_end (__ap)\
)
#define DELIM "\t\n\r "
typedef struct
{
FILE * fp;
cchar * filename;
}
File;
int (*le32)(cvoid *);
void
Pexit (int c, cchar *s, ...)
{
va_list ap;
va_inline (ap, s,
vfprintf(stderr, s, ap)
);
exit(c);
}
void
Prexit (cchar *pr, ...)
{
va_list ap;
va_inline (ap, pr,
vfprintf(stderr, pr, ap)
);
perror("");
exit(-1);
}
void
Fopen (File *f, cchar *filename, const char *mode)
{
FILE *fp;
if (!( fp = fopen(filename, mode) ))
Prexit("%s", filename);
f->filename = filename;
f->fp = fp;
}
void
Ferr (File *f)
{
if (ferror(f->fp))
Prexit("%s", f->filename);
}
char *
Fgets (File *f, int b, char *p)
{
if (!( p = fgets(p, b, f->fp) ))
Ferr(f);
return p;
}
void
Fread (File *f, int b, void *p)
{
if (fread(p, 1, b, f->fp) < b)
Ferr(f);
}
void
Fwrite (File *f, int b, cvoid *s)
{
if (fwrite(s, 1, b, f->fp) < b)
Ferr(f);
}
void
Fseek (File *f, long o)
{
if (fseek(f->fp, o, SEEK_SET) == -1)
Prexit("%s", f->filename);
}
void *
Malloc (int b)
{
void *p;
if (!( p = malloc(b) ))
Prexit("%d", b);
return p;
}
void *
Calloc (int c, int b)
{
void *p;
if (!( p = calloc(c, b) ))
Prexit("(%d)%d", c, b);
return p;
}
void
Reallocp (void *pp, int b)
{
void *p;
if (!( p = realloc((*(void **)pp), b) ))
Prexit("%d", b);
(*(void **)pp) = p;
}
void
strucpy (char *p, cchar *s, int n)
{
int c;
int i;
for (i = 0; i < n && ( c = s[i] ); ++i)
p[i] = toupper(c);
}
int
e32 (cvoid *s)
{
unsigned int c;
c = *(LONG *)s;
return (
( c >> 24 ) |
(( c >> 8 )& 0x00FF00 )|
(( c << 8 )& 0xFF0000 )|
( c << 24 )
);
}
int
n32 (cvoid *s)
{
return *(LONG *)s;
}
void
Ie ()
{
int c;
c = 1;
if (*(char *)&c == 1)
le32 = n32;
else
le32 = e32;
}
File wad_file;
File list_file;
int list_c;
char *** list_v;
char * directory;
char * lump;
int lumpsize;
char * sectors;
int sectors_c;
char * sides;
int sides_c;
int st_floors;
int st_ceilings;
int st_sectors;
int st_sides;
int st_uppers;
int st_mids;
int st_lowers;
/* this is horseshit */
char * old;
char * new;
int did;
void
Itable ()
{
char a[1024];
char ***ttt;
char ***ppp;
char **pp;
int c;
while (Fgets(&list_file, sizeof a, a))
{
c = a[0];
if (!(
c == '\n' ||
c == '#'
))
{
list_c++;
}
}
rewind(list_file.fp);
list_v = Calloc(list_c, sizeof (char **));
for (
ttt = ( ppp = list_v ) + list_c;
ppp < ttt;
++ppp
)
{
(*ppp) = pp = Calloc(2, sizeof (char *));
pp[0] = Malloc(9);
pp[1] = Malloc(9);
}
}
void
Iwad ()
{
char buf[12];
char * t;
char * p;
int map;
char *sector_p;
char * side_p;
int n;
int h;
Fread(&wad_file, 12, buf);
if (
memcmp(buf, "IWAD", 4) != 0 &&
memcmp(buf, "PWAD", 4) != 0
)
{
Pexit(-1,"%s: Not a WAD\n", wad_file.filename);
}
Fseek(&wad_file, (*le32)(&buf[8]));
n = (*le32)(&buf[4]) * 8;
h = n / 9;
n *= 2;
directory = Malloc(n);
/* minimum number of lumps for a map */
sectors = Malloc(h);
sides = Malloc(h);
Fread(&wad_file, n, directory);
sector_p = sectors;
side_p = sides;
map = 3;
for (t = ( p = directory ) + n; p < t; p += 16)
{
/* looking for SECTORS? Hopefully order doesn't matter in real world. */
/* also search for fucking SIDES MY SIDES AAAAAAAAAA */
switch (map)
{
case 0:
case 2:
if (strncmp(&p[8], "SECTORS", 8) == 0)
{
/* copy file offset and size */
memcpy(sector_p, p, 8);
sector_p += 8;
sectors_c++;
map |= 1;
}
case 1:
if (strncmp(&p[8], "SIDEDEFS", 8) == 0)
{
memcpy(side_p, p, 8);
side_p += 8;
sides_c++;
map |= 2;
}
}
if (map == 3)
{
/* MAP marker */
if (p[13] == '\0' && strncmp(&p[8], "MAP", 3) == 0)
map = 0;
}
}
}
void
Fuckyou (char *p, int f, int *st)
{
if (strncmp(p, old, 8) == 0)
{
strncpy(p, new, 8);
(*st)++;
did |= f;
}
}
void
Epic (char *p, char *t)
{
char *top;
char *bot;
int i;
/* oh hi magic number! */
for (; p < t; p += 26)
{
bot = &p [4];
top = &p[12];
did = 0;
for (i = 0; i < list_c; ++i)
{
old = list_v[i][0];
new = list_v[i][1];
switch (did)
{
case 0:
case 2:
Fuckyou(bot, 1, &st_floors);
case 1:
Fuckyou(top, 2, &st_ceilings);
}
if (did == 3)
break;
}
if (did)
st_sectors++;
}
}
void
Epic2 (char *p, char *t)
{
char *top;
char *mid;
char *bot;
int i;
for (; p < t; p += 30)
{
top = &p [4];
bot = &p[12];
mid = &p[20];
did = 0;
for (i = 0; i < list_c; ++i)
{
old = list_v[i][0];
new = list_v[i][1];
switch (did)
{
case 0:
case 2:
case 4:
case 6:
Fuckyou(top, 1, &st_uppers);
case 1:
case 5:
Fuckyou(mid, 2, &st_mids);
case 3:
Fuckyou(bot, 4, &st_lowers);
}
if (did == 7)
break;
}
if (did)
st_sides++;
}
}
void
Fuck (char *p, int c, void (*fn)(char *,char *))
{
char *t;
int offs;
int size;
for (t = p + c * 8; p < t; p += 8)
{
offs = (*le32)(p);
size = (*le32)(p + 4);
if (lumpsize < size)
{
Reallocp(&lump, size);
lumpsize = size;
}
Fseek(&wad_file, offs);
Fread(&wad_file, size, lump);
(*fn)(lump, lump + size);
Fseek(&wad_file, offs);
Fwrite(&wad_file, size, lump);
}
}
void
Awad ()
{
Fuck (sectors, sectors_c, Epic);
Fuck (sides, sides_c, Epic2);
}
void
Readtable ()
{
char a[1024];
int s;
char *old;
char *new;
int c;
s = 0;
while (Fgets(&list_file, sizeof a, a))
{
c = a[0];
if (!(
c == '\n' ||
c == '#'
))
{
if (
( old = strtok(a, DELIM) ) &&
( new = strtok(0, DELIM) )
)
{
strucpy(list_v[s][0], old, 8);
strucpy(list_v[s][1], new, 8);
++s;
}
}
}
}
void
Cleanup ()
{
char ***ttt;
char ***ppp;
char **pp;
free(lump);
free(sides);
free(sectors);
free(directory);
if (list_v)
{
for (
ttt = ( ppp = list_v ) + list_c;
ppp < ttt && ( pp = (*ppp) );
++ppp
)
{
free(pp[0]);
free(pp[1]);
free(pp);
}
free(list_v);
}
}
int
main (int ac, char **av)
{
int n;
if (ac < 3)
Pexit(0,HELP);
Fopen (& wad_file, av[1], "rb+");
Fopen (&list_file, av[2], "r");
if (atexit(Cleanup) != 0)
Pexit(-1,"Failed to register cleanup function.\n");
Itable();
Readtable();
Ie();
Iwad();
Awad();
printf(
"%5d sectors changed.\n"
"%5d floors.\n"
"%5d ceilings.\n"
"\n"
"%5d sides.\n"
"%5d upper textures.\n"
"%5d mid textures.\n"
"%5d lower textures.\n",
st_sectors,
st_floors,
st_ceilings,
st_sides,
st_uppers,
st_mids,
st_lowers);
return 0;
}