Merge branch 'master' into internal-hotplug-stableid

This commit is contained in:
Steel Titanium 2019-09-23 00:44:34 -04:00
commit dfee7efd33
No known key found for this signature in database
GPG key ID: 924BA411F18DFDBE
83 changed files with 5622 additions and 2259 deletions

9
.gitattributes vendored
View file

@ -1,3 +1,12 @@
#Source code
/src/*.c text=auto
/src/*.h text=auto
/src/*.s text=auto
/src/*.m text=auto
/src/*.xpm text=auto
/src/Makefile text=auto
/src/Make*.cfg text=auto
/src/CMakeLists.txt text=auto
# Windows EOL
*.cs -crlf -whitespace
*.mk -crlf -whitespace

View file

@ -62,7 +62,6 @@
#define PNG_NO_READ_iTXt
#define PNG_NO_READ_APNG
#define PNG_NO_READ_UNKNOWN_CHUNKS
#define PNG_NO_READ_USER_TRANSFORM
#define PNG_READ_BGR_SUPPORTED
#define PNG_NO_READ_SWAP_ALPHA

Binary file not shown.

Binary file not shown.

BIN
srb2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -152,7 +152,7 @@ ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
static textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE] = {NULL};
static consvar_t cv_showjoinaddress = {"showjoinaddress", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showjoinaddress = {"showjoinaddress", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t playbackspeed_cons_t[] = {{1, "MIN"}, {10, "MAX"}, {0, NULL}};
consvar_t cv_playbackspeed = {"playbackspeed", "1", 0, playbackspeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -579,6 +579,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->starpostnum = LONG(players[i].starpostnum);
rsp->starposttime = (tic_t)LONG(players[i].starposttime);
rsp->starpostangle = (angle_t)LONG(players[i].starpostangle);
rsp->starpostscale = (fixed_t)LONG(players[i].starpostscale);
rsp->maxlink = LONG(players[i].maxlink);
rsp->dashspeed = (fixed_t)LONG(players[i].dashspeed);
@ -714,6 +715,7 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].starpostnum = LONG(rsp->starpostnum);
players[i].starposttime = (tic_t)LONG(rsp->starposttime);
players[i].starpostangle = (angle_t)LONG(rsp->starpostangle);
players[i].starpostscale = (fixed_t)LONG(rsp->starpostscale);
players[i].maxlink = LONG(rsp->maxlink);
players[i].dashspeed = (fixed_t)LONG(rsp->dashspeed);
@ -2415,7 +2417,7 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
// the remaining players.
if (G_IsSpecialStage(gamemap))
{
INT32 i, count, increment, spheres;
INT32 i, count, sincrement, spheres, rincrement, rings;
for (i = 0, count = 0; i < MAXPLAYERS; i++)
{
@ -2425,18 +2427,35 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
count--;
spheres = players[playernum].spheres;
increment = spheres/count;
rings = players[playernum].rings;
sincrement = spheres/count;
rincrement = rings/count;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && i != playernum)
{
if (spheres < increment)
if (spheres < 2*sincrement)
{
P_GivePlayerSpheres(&players[i], spheres);
spheres = 0;
}
else
P_GivePlayerSpheres(&players[i], increment);
{
P_GivePlayerSpheres(&players[i], sincrement);
spheres -= sincrement;
}
spheres -= increment;
if (rings < 2*rincrement)
{
P_GivePlayerRings(&players[i], rings);
rings = 0;
}
else
{
P_GivePlayerRings(&players[i], rincrement);
rings -= rincrement;
}
}
}
}
@ -2946,13 +2965,13 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
CL_RemovePlayer(pnum, kickreason);
}
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t resynchattempts_cons_t[] = {{0, "MIN"}, {20, "MAX"}, {0, NULL}};
consvar_t cv_resynchattempts = {"resynchattempts", "10", 0, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
consvar_t cv_blamecfail = {"blamecfail", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
consvar_t cv_resynchattempts = {"resynchattempts", "10", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
consvar_t cv_blamecfail = {"blamecfail", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
// max file size to send to a player (in kilobytes)
static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {51200, "MAX"}, {0, NULL}};
@ -2993,11 +3012,6 @@ void D_ClientServerInit(void)
RegisterNetXCmd(XD_KICK, Got_KickCmd);
RegisterNetXCmd(XD_ADDPLAYER, Got_AddPlayer);
#ifndef NONET
CV_RegisterVar(&cv_allownewplayer);
CV_RegisterVar(&cv_joinnextround);
CV_RegisterVar(&cv_showjoinaddress);
CV_RegisterVar(&cv_resynchattempts);
CV_RegisterVar(&cv_blamecfail);
#ifdef DUMPCONSISTENCY
CV_RegisterVar(&cv_dumpconsistency);
#endif

View file

@ -228,6 +228,7 @@ typedef struct
INT32 starpostnum;
tic_t starposttime;
angle_t starpostangle;
fixed_t starpostscale;
INT32 maxlink;
fixed_t dashspeed;
@ -444,6 +445,7 @@ extern INT32 mapchangepending;
// Points inside doomcom
extern doomdata_t *netbuffer;
extern consvar_t cv_showjoinaddress;
extern consvar_t cv_playbackspeed;
#define BASEPACKETSIZE offsetof(doomdata_t, u)

View file

@ -129,6 +129,7 @@ char srb2home[256] = ".";
char srb2path[256] = ".";
boolean usehome = true;
const char *pandf = "%s" PATHSEP "%s";
static char addonsdir[MAX_WADPATH];
//
// EVENT HANDLING
@ -287,7 +288,7 @@ static void D_Display(void)
F_TitleScreenDrawer();
break;
}
// Intentional fall-through
/* FALLTHRU */
case GS_LEVEL:
if (!gametic)
break;
@ -716,6 +717,7 @@ void D_StartTitle(void)
botskin = 0;
cv_debug = 0;
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
lastmaploaded = 0;
// In case someone exits out at the same time they start a time attack run,
@ -1038,7 +1040,6 @@ void D_SRB2Main(void)
// can't use sprintf since there is %u in savegamename
strcatbf(savegamename, srb2home, PATHSEP);
I_mkdir(srb2home, 0700);
#else
snprintf(srb2home, sizeof srb2home, "%s", userhome);
snprintf(downloaddir, sizeof downloaddir, "%s", userhome);
@ -1055,6 +1056,10 @@ void D_SRB2Main(void)
configfile[sizeof configfile - 1] = '\0';
}
// Create addons dir
snprintf(addonsdir, sizeof addonsdir, "%s%s%s", srb2home, PATHSEP, "addons");
I_mkdir(addonsdir, 0755);
// rand() needs seeded regardless of password
srand((unsigned int)time(NULL));

View file

@ -556,9 +556,16 @@ void D_RegisterServerCommands(void)
// d_clisrv
CV_RegisterVar(&cv_maxplayers);
CV_RegisterVar(&cv_resynchattempts);
CV_RegisterVar(&cv_maxsend);
CV_RegisterVar(&cv_noticedownload);
CV_RegisterVar(&cv_downloadspeed);
#ifndef NONET
CV_RegisterVar(&cv_allownewplayer);
CV_RegisterVar(&cv_joinnextround);
CV_RegisterVar(&cv_showjoinaddress);
CV_RegisterVar(&cv_blamecfail);
#endif
COM_AddCommand("ping", Command_Ping_f);
CV_RegisterVar(&cv_nettimeout);
@ -630,6 +637,8 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_screenshot_folder);
CV_RegisterVar(&cv_screenshot_colorprofile);
CV_RegisterVar(&cv_moviemode);
CV_RegisterVar(&cv_movie_option);
CV_RegisterVar(&cv_movie_folder);
// PNG variables
CV_RegisterVar(&cv_zlib_level);
CV_RegisterVar(&cv_zlib_memory);
@ -1909,7 +1918,10 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
precache = false;
if (resetplayer && !FLS)
{
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
}
if (modeattacking)
{
@ -2707,14 +2719,6 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
}
}
// Clear player score and rings if a spectator.
if (players[playernum].spectator)
{
players[playernum].score = players[playernum].rings = 0;
if (players[playernum].mo)
players[playernum].mo->health = 1;
}
// In tag, check to see if you still have a game.
if (G_TagGametype())
P_CheckSurvivors();
@ -3601,7 +3605,7 @@ static void CoopLives_OnChange(void)
{
case 0:
CONS_Printf(M_GetText("Players can now respawn indefinitely.\n"));
return;
break;
case 1:
CONS_Printf(M_GetText("Lives are now per-player.\n"));
return;
@ -4104,6 +4108,7 @@ void Command_ExitGame_f(void)
botskin = 0;
cv_debug = 0;
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
if (dirmenu)
closefilemenu(true);

View file

@ -441,6 +441,7 @@ typedef struct player_s
INT32 starpostnum; // The number of the last starpost you hit
tic_t starposttime; // Your time when you hit the starpost
angle_t starpostangle; // Angle that the starpost is facing - you respawn facing this way
fixed_t starpostscale; // Scale of the player; if negative, player is gravflipped
/////////////////
// NiGHTS Stuff//

View file

@ -1181,6 +1181,20 @@ static void readlevelheader(MYFILE *f, INT32 num)
mapheaderinfo[num-1]->muspostbosspos = (UINT32)get_number(word2);
else if (fastcmp(word, "MUSICPOSTBOSSFADEIN"))
mapheaderinfo[num-1]->muspostbossfadein = (UINT32)get_number(word2);
else if (fastcmp(word, "FORCERESETMUSIC"))
{
// This is a weird one because "FALSE"/"NO" could either apply to "leave to default preference" (cv_resetmusic)
// or "force off". Let's assume it means "force off", and let an unspecified value mean "default preference"
if (fastcmp(word2, "OFF") || word2[0] == 'F' || word2[0] == 'N') i = 0;
else if (fastcmp(word2, "ON") || word2[0] == 'T' || word2[0] == 'Y') i = 1;
else i = -1; // (fastcmp(word2, "DEFAULT"))
if (i >= -1 && i <= 1) // -1 to force off, 1 to force on, 0 to honor default.
// This behavior can be disabled with cv_resetmusicbyheader
mapheaderinfo[num-1]->musforcereset = (SINT8)i;
else
deh_warning("Level header %d: invalid forceresetmusic option %d", num, i);
}
else if (fastcmp(word, "FORCECHARACTER"))
{
strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1);
@ -2957,6 +2971,17 @@ static void readunlockable(MYFILE *f, INT32 num)
Z_Free(s);
}
static const char NIGHTSGRADE_LIST[] = {
'F', // GRADE_F
'E', // GRADE_E
'D', // GRADE_D
'C', // GRADE_C
'B', // GRADE_B
'A', // GRADE_A
'S', // GRADE_S
'\0'
};
#define PARAMCHECK(n) do { if (!params[n]) { deh_warning("Too few parameters, need %d", n); return; }} while (0)
static void readcondition(UINT8 set, UINT32 id, char *word2)
{
@ -3058,7 +3083,21 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
PARAMCHECK(2); // one optional one
ty = UC_NIGHTSSCORE + offset;
re = atoi(params[2 + !!(params[3])]);
i = (params[3] ? 3 : 2);
if (fastncmp("GRADE_",params[i],6))
{
char *p = params[i]+6;
for (re = 0; NIGHTSGRADE_LIST[re]; re++)
if (*p == NIGHTSGRADE_LIST[re])
break;
if (!NIGHTSGRADE_LIST[re])
{
deh_warning("Invalid NiGHTS grade %s\n", params[i]);
return;
}
}
else
re = atoi(params[i]);
// Convert to map number if it appears to be one
if (params[1][0] >= 'A' && params[1][0] <= 'Z')
@ -4589,10 +4628,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_SONIC3KBOSSEXPLOSION6",
"S_JETFUME1",
"S_JETFUME2",
// Boss 1
"S_EGGMOBILE_STND",
"S_EGGMOBILE_ROFL",
"S_EGGMOBILE_LATK1",
"S_EGGMOBILE_LATK2",
"S_EGGMOBILE_LATK3",
@ -4602,7 +4641,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_EGGMOBILE_LATK7",
"S_EGGMOBILE_LATK8",
"S_EGGMOBILE_LATK9",
"S_EGGMOBILE_LATK10",
"S_EGGMOBILE_RATK1",
"S_EGGMOBILE_RATK2",
"S_EGGMOBILE_RATK3",
@ -4612,7 +4650,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_EGGMOBILE_RATK7",
"S_EGGMOBILE_RATK8",
"S_EGGMOBILE_RATK9",
"S_EGGMOBILE_RATK10",
"S_EGGMOBILE_PANIC1",
"S_EGGMOBILE_PANIC2",
"S_EGGMOBILE_PANIC3",
@ -4620,6 +4657,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_EGGMOBILE_PANIC5",
"S_EGGMOBILE_PANIC6",
"S_EGGMOBILE_PANIC7",
"S_EGGMOBILE_PANIC8",
"S_EGGMOBILE_PANIC9",
"S_EGGMOBILE_PANIC10",
"S_EGGMOBILE_PANIC11",
"S_EGGMOBILE_PANIC12",
"S_EGGMOBILE_PANIC13",
"S_EGGMOBILE_PANIC14",
"S_EGGMOBILE_PANIC15",
"S_EGGMOBILE_PAIN",
"S_EGGMOBILE_PAIN2",
"S_EGGMOBILE_DIE1",
@ -4630,6 +4675,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_EGGMOBILE_FLEE2",
"S_EGGMOBILE_BALL",
"S_EGGMOBILE_TARGET",
"S_BOSSEGLZ1",
"S_BOSSEGLZ2",
// Boss 2
"S_EGGMOBILE2_STND",
@ -4661,11 +4708,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Boss 3
"S_EGGMOBILE3_STND",
"S_EGGMOBILE3_LAUGH1",
"S_EGGMOBILE3_LAUGH2",
"S_EGGMOBILE3_LAUGH3",
"S_EGGMOBILE3_LAUGH4",
"S_EGGMOBILE3_LAUGH5",
"S_EGGMOBILE3_SHOCK",
"S_EGGMOBILE3_ATK1",
"S_EGGMOBILE3_ATK2",
"S_EGGMOBILE3_ATK3A",
@ -4674,21 +4717,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_EGGMOBILE3_ATK3D",
"S_EGGMOBILE3_ATK4",
"S_EGGMOBILE3_ATK5",
"S_EGGMOBILE3_LAUGH6",
"S_EGGMOBILE3_LAUGH7",
"S_EGGMOBILE3_LAUGH8",
"S_EGGMOBILE3_LAUGH9",
"S_EGGMOBILE3_LAUGH10",
"S_EGGMOBILE3_LAUGH11",
"S_EGGMOBILE3_LAUGH12",
"S_EGGMOBILE3_LAUGH13",
"S_EGGMOBILE3_LAUGH14",
"S_EGGMOBILE3_LAUGH15",
"S_EGGMOBILE3_LAUGH16",
"S_EGGMOBILE3_LAUGH17",
"S_EGGMOBILE3_LAUGH18",
"S_EGGMOBILE3_LAUGH19",
"S_EGGMOBILE3_LAUGH20",
"S_EGGMOBILE3_ROFL",
"S_EGGMOBILE3_PAIN",
"S_EGGMOBILE3_PAIN2",
"S_EGGMOBILE3_DIE1",
@ -4698,15 +4727,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_EGGMOBILE3_FLEE1",
"S_EGGMOBILE3_FLEE2",
// Boss 3 Propeller
"S_PROPELLER1",
"S_PROPELLER2",
"S_PROPELLER3",
"S_PROPELLER4",
"S_PROPELLER5",
"S_PROPELLER6",
"S_PROPELLER7",
// Boss 3 pinch
"S_FAKEMOBILE_INIT",
"S_FAKEMOBILE",
@ -4719,6 +4739,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FAKEMOBILE_DIE1",
"S_FAKEMOBILE_DIE2",
"S_BOSSSEBH1",
"S_BOSSSEBH2",
// Boss 4
"S_EGGMOBILE4_STND",
"S_EGGMOBILE4_LATK1",
@ -5122,16 +5145,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_MSSHIELD_F1",
"S_MSSHIELD_F2",
"S_MSSHIELD_F3",
"S_MSSHIELD_F4",
"S_MSSHIELD_F5",
"S_MSSHIELD_F6",
"S_MSSHIELD_F7",
"S_MSSHIELD_F8",
"S_MSSHIELD_F9",
"S_MSSHIELD_F10",
"S_MSSHIELD_F11",
"S_MSSHIELD_F12",
// Ring
"S_RING",
@ -5565,14 +5578,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_DRIPC1",
"S_DRIPC2",
// Coral 1
// Coral
"S_CORAL1",
// Coral 2
"S_CORAL2",
// Coral 3
"S_CORAL3",
"S_CORAL4",
"S_CORAL5",
// Blue Crystal
"S_BLUECRYSTAL1",
@ -5580,6 +5591,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Kelp,
"S_KELP",
// Animated algae
"S_ANIMALGAETOP1",
"S_ANIMALGAETOP2",
"S_ANIMALGAESEG",
// DSZ Stalagmites
"S_DSZSTALAGMITE",
"S_DSZ2STALAGMITE",
@ -5724,6 +5740,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_CACTI7",
"S_CACTI8",
"S_CACTI9",
"S_CACTI10",
"S_CACTI11",
"S_CACTITINYSEG",
"S_CACTISMALLSEG",
// Warning signs sprites
"S_ARIDSIGN_CAUTION",
@ -7215,6 +7235,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_EGGTRAP",
"MT_BOSS3WAYPOINT",
"MT_BOSS9GATHERPOINT",
"MT_BOSSJUNK",
// Boss 1
"MT_EGGMOBILE",
@ -7226,15 +7247,11 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
// Boss 2
"MT_EGGMOBILE2",
"MT_EGGMOBILE2_POGO",
"MT_BOSSTANK1",
"MT_BOSSTANK2",
"MT_BOSSSPIGOT",
"MT_GOOP",
"MT_GOOPTRAIL",
// Boss 3
"MT_EGGMOBILE3",
"MT_PROPELLER",
"MT_FAKEMOBILE",
"MT_SHOCK",
@ -7445,11 +7462,15 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_SEAWEED", // DSZ Seaweed
"MT_WATERDRIP", // Dripping Water source
"MT_WATERDROP", // Water drop from dripping water
"MT_CORAL1", // Coral 1
"MT_CORAL2", // Coral 2
"MT_CORAL3", // Coral 3
"MT_CORAL1", // Coral
"MT_CORAL2",
"MT_CORAL3",
"MT_CORAL4",
"MT_CORAL5",
"MT_BLUECRYSTAL", // Blue Crystal
"MT_KELP", // Kelp
"MT_ANIMALGAETOP", // Animated algae top
"MT_ANIMALGAESEG", // Animated algae segment
"MT_DSZSTALAGMITE", // Deep Sea 1 Stalagmite
"MT_DSZ2STALAGMITE", // Deep Sea 2 Stalagmite
"MT_LIGHTBEAM", // DSZ Light beam
@ -7509,6 +7530,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_CACTI7",
"MT_CACTI8",
"MT_CACTI9",
"MT_CACTI10",
"MT_CACTI11",
"MT_CACTITINYSEG",
"MT_CACTISMALLSEG",
"MT_ARIDSIGN_CAUTION",
"MT_ARIDSIGN_CACTI",
"MT_ARIDSIGN_SHARPTURN",
@ -8474,15 +8499,6 @@ struct {
{"LF2_NOVISITNEEDED",LF2_NOVISITNEEDED},
{"LF2_WIDEICON",LF2_WIDEICON},
// NiGHTS grades
{"GRADE_F",GRADE_F},
{"GRADE_E",GRADE_E},
{"GRADE_D",GRADE_D},
{"GRADE_C",GRADE_C},
{"GRADE_B",GRADE_B},
{"GRADE_A",GRADE_A},
{"GRADE_S",GRADE_S},
// Emeralds
{"EMERALD1",EMERALD1},
{"EMERALD2",EMERALD2},
@ -9304,6 +9320,19 @@ static fixed_t find_const(const char **rword)
free(word);
return 0;
}
else if (fastncmp("GRADE_",word,6))
{
char *p = word+6;
for (i = 0; NIGHTSGRADE_LIST[i]; i++)
if (*p == NIGHTSGRADE_LIST[i])
{
free(word);
return i;
}
const_warning("NiGHTS grade",word);
free(word);
return 0;
}
for (i = 0; INT_CONST[i].n; i++)
if (fastcmp(word,INT_CONST[i].n)) {
free(word);
@ -9752,6 +9781,18 @@ static inline int lib_getenum(lua_State *L)
if (mathlib) return luaL_error(L, "skincolor '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("GRADE_",word,6))
{
p = word+6;
for (i = 0; NIGHTSGRADE_LIST[i]; i++)
if (*p == NIGHTSGRADE_LIST[i])
{
lua_pushinteger(L, i);
return 1;
}
if (mathlib) return luaL_error(L, "NiGHTS grade '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("MN_",word,3)) {
p = word+3;
for (i = 0; i < NUMMENUTYPES; i++)

View file

@ -616,4 +616,8 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// SRB2CB itself ported this from PrBoom+
#define NEWCLIP
#ifndef HAVE_PNG
#define NO_PNG_LUMPS
#endif
#endif // __DOOMDEF__

View file

@ -333,6 +333,8 @@ typedef struct
UINT32 muspostbosspos; ///< Post-bossdeath position
UINT32 muspostbossfadein; ///< Post-bossdeath fade-in milliseconds.
SINT8 musforcereset; ///< Force resetmusic (-1 for default; 0 for force off; 1 for force on)
// Lua stuff.
// (This is not ifdeffed so the map header structure can stay identical, just in case.)
UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
@ -418,6 +420,10 @@ extern UINT16 emeralds;
#define EMERALD7 64
#define ALL7EMERALDS(v) ((v & (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7)) == (EMERALD1|EMERALD2|EMERALD3|EMERALD4|EMERALD5|EMERALD6|EMERALD7))
// yes, even in non HAVE_BLUA
#define NUM_LUABANKS 16 // please only make this number go up between versions, never down. you'll break saves otherwise. also, must fit in UINT8
extern INT32 luabanks[NUM_LUABANKS];
extern INT32 nummaprings; //keep track of spawned rings/coins
/** Time attack information, currently a very small structure.

View file

@ -1584,22 +1584,22 @@ void F_StartEnding(void)
UINT8 skinnum = players[consoleplayer].skin;
spritedef_t *sprdef;
spriteframe_t *sprframe;
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= 5)
if (skins[skinnum].sprites[SPR2_XTRA].numframes >= 7)
{
sprdef = &skins[skinnum].sprites[SPR2_XTRA];
// character head, skin specific
sprframe = &sprdef->spriteframes[2];
endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
sprframe = &sprdef->spriteframes[3];
endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
sprframe = &sprdef->spriteframes[4];
endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
sprframe = &sprdef->spriteframes[5];
endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
sprframe = &sprdef->spriteframes[6];
endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
}
else // eh, yknow what? too lazy to put MISSINGs here. eggman wins if you don't give your character an ending firework display.
else // Show a star if your character doesn't have an ending firework display. (Basically the MISSINGs for this)
{
endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_LEVEL);
endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_LEVEL);
endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_LEVEL);
endfwrk[0] = W_CachePatchName("ENDFWRK3", PU_LEVEL);
endfwrk[1] = W_CachePatchName("ENDFWRK4", PU_LEVEL);
endfwrk[2] = W_CachePatchName("ENDFWRK5", PU_LEVEL);
}
endbrdr[0] = W_CachePatchName("ENDBRDR2", PU_LEVEL);
@ -2465,6 +2465,11 @@ void F_TitleDemoTicker(void)
// ==========
// CONTINUE
// ==========
static skin_t *contskins[2];
static UINT8 cont_spr2[2][6];
static UINT8 *contcolormaps[2];
void F_StartContinue(void)
{
I_Assert(!netgame && !multiplayer);
@ -2488,7 +2493,44 @@ void F_StartContinue(void)
S_ChangeMusicInternal("_conti", false);
S_StopSounds();
timetonext = TICRATE*11;
contskins[0] = &skins[players[consoleplayer].skin];
cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT1, NULL);
cont_spr2[0][2] = contskins[0]->contangle & 7;
contcolormaps[0] = R_GetTranslationColormap(players[consoleplayer].skin, players[consoleplayer].skincolor, GTC_CACHE);
cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
cont_spr2[0][5] = max(1, contskins[0]->contspeed);
if (botskin)
{
INT32 secondplaya;
if (secondarydisplayplayer != consoleplayer)
secondplaya = secondarydisplayplayer;
else // HACK
secondplaya = 1;
contskins[1] = &skins[players[secondplaya].skin];
cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT4, NULL);
cont_spr2[1][2] = (contskins[1]->contangle >> 3) & 7;
contcolormaps[1] = R_GetTranslationColormap(players[secondplaya].skin, players[secondplaya].skincolor, GTC_CACHE);
cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
if (cont_spr2[1][0] == SPR2_CNT4)
cont_spr2[1][5] = 4; // sorry, this one is hardcoded
else
cont_spr2[1][5] = max(1, contskins[1]->contspeed);
}
else
{
contskins[1] = NULL;
contcolormaps[1] = NULL;
cont_spr2[1][0] = cont_spr2[1][2] = cont_spr2[1][4] = cont_spr2[1][5] = 0;
}
cont_spr2[0][1] = cont_spr2[0][3] =\
cont_spr2[1][1] = cont_spr2[1][3] = 0;
timetonext = (11*TICRATE)+11;
continuetime = 0;
}
//
@ -2497,47 +2539,198 @@ void F_StartContinue(void)
//
void F_ContinueDrawer(void)
{
patch_t *contsonic;
INT32 i, x = (BASEVIDWIDTH/2) + 4, ncontinues = players[consoleplayer].continues;
if (ncontinues > 20)
ncontinues = 20;
spritedef_t *sprdef;
spriteframe_t *sprframe;
patch_t *patch;
INT32 i, x = (BASEVIDWIDTH>>1), ncontinues = players[consoleplayer].continues;
char numbuf[9] = "CONTNUM*";
tic_t timeleft = (timetonext/TICRATE);
INT32 offsx = 0, offsy = 0, lift[2] = {0, 0};
if (imcontinuing)
contsonic = W_CachePatchName("CONT2", PU_CACHE);
else
contsonic = W_CachePatchName("CONT1", PU_CACHE);
if (continuetime >= 3*TICRATE)
{
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0);
return;
}
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
V_DrawCenteredString(BASEVIDWIDTH/2, 100, 0, "CONTINUE?");
// Draw a Sonic!
V_DrawScaledPatch((BASEVIDWIDTH - SHORT(contsonic->width))/2, 32, 0, contsonic);
if (timetonext >= (11*TICRATE)+10)
return;
// Draw the continue markers! Show continues minus one.
x -= ncontinues * 6;
V_DrawLevelTitle(x - (V_LevelNameWidth("CONTINUE")>>1), 16, 0, "CONTINUE");
// Two stars...
patch = W_CachePatchName("CONTSTAR", PU_CACHE);
V_DrawScaledPatch(x-32, 160, 0, patch);
V_DrawScaledPatch(x+32, 160, 0, patch);
// Time left!
if (timeleft > 9)
{
numbuf[7] = '1';
V_DrawScaledPatch(x - 10, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
numbuf[7] = '0';
V_DrawScaledPatch(x + 10, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
}
else
{
numbuf[7] = '0'+timeleft;
V_DrawScaledPatch(x, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
}
// Draw the continue markers! Show continues.
if (ncontinues > 10)
{
if (!(continuetime & 1) || continuetime > 17)
V_DrawContinueIcon(x, 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
V_DrawScaledPatch(x+12, 68-2, 0, stlivex);
V_DrawRightAlignedString(x+36, 69-5, 0,
va("%d",(imcontinuing ? ncontinues-1 : ncontinues)));
}
else
{
x += (ncontinues/2) * 30;
if (!(ncontinues & 1))
x -= 15;
for (i = 0; i < ncontinues; ++i)
V_DrawContinueIcon(x + (i*12), 140, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
{
if (i == (ncontinues/2) && ((continuetime & 1) || continuetime > 17))
continue;
V_DrawContinueIcon(x - (i*30), 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
}
x = BASEVIDWIDTH>>1;
}
V_DrawCenteredString(BASEVIDWIDTH/2, 168, 0, va("\x82*\x80" " %02d " "\x82*\x80", timetonext/TICRATE));
// Spotlight
V_DrawScaledPatch(x, 140, 0, W_CachePatchName("CONTSPOT", PU_CACHE));
// warping laser
if (continuetime)
{
INT32 w = min(continuetime, 28), brightness = (continuetime>>1) & 7;
if (brightness > 3)
brightness = 8-brightness;
V_DrawFadeFill(x-w, 0, w<<1, 140, 0, 0, (3+brightness));
}
if (contskins[1])
{
if (continuetime > 15)
{
angle_t work = FixedAngle((10*(continuetime-15))<<FRACBITS)>>ANGLETOFINESHIFT;
offsy = FINESINE(work)<<1;
offsx = (27*FINECOSINE(work))>>1;
}
else
offsx = 27<<(FRACBITS-1);
lift[1] = continuetime-10;
if (lift[1] < 0)
lift[1] = 0;
else if (lift[1] > TICRATE+5)
lift[1] = TICRATE+5;
}
lift[0] = continuetime-5;
if (lift[0] < 0)
lift[0] = 0;
else if (lift[0] > TICRATE+5)
lift[0] = TICRATE+5;
#define drawchar(dx, dy, n) {\
sprdef = &contskins[n]->sprites[cont_spr2[n][0]];\
sprframe = &sprdef->spriteframes[cont_spr2[n][1]];\
patch = W_CachePatchNum(sprframe->lumppat[cont_spr2[n][2]], PU_CACHE);\
V_DrawFixedPatch((dx), (dy), FRACUNIT, (sprframe->flip & (1<<cont_spr2[n][2])) ? V_FLIP : 0, patch, contcolormaps[n]);\
}
if (offsy < 0)
drawchar((BASEVIDWIDTH<<(FRACBITS-1))-offsx, ((140-lift[0])<<FRACBITS)-offsy, 0);
if (contskins[1])
drawchar((BASEVIDWIDTH<<(FRACBITS-1))+offsx, ((140-lift[1])<<FRACBITS)+offsy, 1);
if (offsy >= 0)
drawchar((BASEVIDWIDTH<<(FRACBITS-1))-offsx, ((140-lift[0])<<FRACBITS)-offsy, 0);
#undef drawchar
if (timetonext > (11*TICRATE))
V_DrawFadeScreen(31, timetonext-(11*TICRATE));
if (continuetime > ((3*TICRATE) - 10))
V_DrawFadeScreen(0, (continuetime - ((3*TICRATE) - 10)));
}
void F_ContinueTicker(void)
{
if (!imcontinuing)
{
// note the setup to prevent 2x reloading
if (timetonext >= 0)
timetonext--;
if (timetonext == 0)
if (timetonext > 0)
{
if (!(--timetonext))
{
Command_ExitGame_f();
return;
}
}
}
else
{
// note the setup to prevent 2x reloading
if (continuetime >= 0)
continuetime--;
if (continuetime == 0)
if (++continuetime == 3*TICRATE)
{
G_Continue();
return;
}
if (continuetime > 5 && ((continuetime & 1) || continuetime > TICRATE) && (++cont_spr2[0][2]) >= 8)
cont_spr2[0][2] = 0;
if (continuetime > 10 && (!(continuetime & 1) || continuetime > TICRATE+5) && (++cont_spr2[1][2]) >= 8)
cont_spr2[1][2] = 0;
if (continuetime == (3*TICRATE)-10)
S_StartSound(NULL, sfx_cdfm56); // or 31
else if (continuetime == 5)
{
cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT2, NULL);
cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
cont_spr2[0][1] = cont_spr2[0][3] = 0;
cont_spr2[0][5] = 2;
}
else if (continuetime == TICRATE)
{
cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT3, NULL);
cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
cont_spr2[0][1] = cont_spr2[0][3] = 0;
}
else if (contskins[1])
{
if (continuetime == 10)
{
cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT2, NULL);
cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
cont_spr2[1][1] = cont_spr2[1][3] = 0;
cont_spr2[1][5] = 2;
}
else if (continuetime == TICRATE+5)
{
cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT3, NULL);
cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
cont_spr2[1][1] = cont_spr2[1][3] = 0;
}
}
}
if ((++cont_spr2[0][3]) >= cont_spr2[0][5])
{
cont_spr2[0][3] = 0;
if (++cont_spr2[0][1] >= cont_spr2[0][4])
cont_spr2[0][1] = 0;
}
if (contskins[1] && (++cont_spr2[1][3]) >= cont_spr2[1][5])
{
cont_spr2[1][3] = 0;
if (++cont_spr2[1][1] >= cont_spr2[1][4])
cont_spr2[1][1] = 0;
}
}
@ -2568,8 +2761,9 @@ boolean F_ContinueResponder(event_t *event)
keypressed = true;
imcontinuing = true;
continuetime = TICRATE;
S_StartSound(NULL, sfx_itemup);
S_StartSound(NULL, sfx_kc6b);
I_FadeSong(0, MUSICRATE, &S_StopMusic);
return true;
}

View file

@ -751,7 +751,7 @@ boolean preparefilemenu(boolean samedepth)
}
else if (ext == EXT_TXT)
{
if (!strcmp(dent->d_name, "log.txt") || !strcmp(dent->d_name, "errorlog.txt"))
if (!strncmp(dent->d_name, "log-", 4) || !strcmp(dent->d_name, "errorlog.txt"))
ext |= EXT_LOADED;
}

View file

@ -172,6 +172,7 @@ static boolean retrying = false;
UINT8 stagefailed; // Used for GEMS BONUS? Also to see if you beat the stage.
UINT16 emeralds;
INT32 luabanks[NUM_LUABANKS]; // yes, even in non HAVE_BLUA
UINT32 token; // Number of tokens collected in a level
UINT32 tokenlist; // List of tokens collected
boolean gottoken; // Did you get a token? Used for end of act
@ -215,7 +216,7 @@ UINT16 spacetimetics = 11*TICRATE + (TICRATE/2);
UINT16 extralifetics = 4*TICRATE;
UINT16 nightslinktics = 2*TICRATE;
INT32 gameovertics = 15*TICRATE;
INT32 gameovertics = 11*TICRATE;
UINT8 ammoremovaltics = 2*TICRATE;
@ -2083,6 +2084,7 @@ static inline void G_PlayerFinishLevel(INT32 player)
p->mo->flags2 &= ~MF2_SHADOW; // cancel invisibility
P_FlashPal(p, 0, 0); // Resets
p->starpostscale = 0;
p->starpostangle = 0;
p->starposttime = 0;
p->starpostx = 0;
@ -2098,7 +2100,7 @@ static inline void G_PlayerFinishLevel(INT32 player)
// G_PlayerReborn
// Called after a player dies. Almost everything is cleared and initialized.
//
void G_PlayerReborn(INT32 player)
void G_PlayerReborn(INT32 player, boolean betweenmaps)
{
player_t *p;
INT32 score;
@ -2129,6 +2131,7 @@ void G_PlayerReborn(INT32 player)
INT16 starpostz;
INT32 starpostnum;
INT32 starpostangle;
fixed_t starpostscale;
fixed_t jumpfactor;
fixed_t height;
fixed_t spinheight;
@ -2145,6 +2148,8 @@ void G_PlayerReborn(INT32 player)
boolean outofcoop;
INT16 bot;
SINT8 pity;
INT16 rings;
INT16 spheres;
score = players[player].score;
lives = players[player].lives;
@ -2184,6 +2189,7 @@ void G_PlayerReborn(INT32 player)
starpostz = players[player].starpostz;
starpostnum = players[player].starpostnum;
starpostangle = players[player].starpostangle;
starpostscale = players[player].starpostscale;
jumpfactor = players[player].jumpfactor;
height = players[player].height;
spinheight = players[player].spinheight;
@ -2199,6 +2205,17 @@ void G_PlayerReborn(INT32 player)
bot = players[player].bot;
pity = players[player].pity;
if (betweenmaps || !G_IsSpecialStage(gamemap))
{
rings = (ultimatemode ? 0 : mapheaderinfo[gamemap-1]->startrings);
spheres = 0;
}
else
{
rings = players[player].rings;
spheres = players[player].spheres;
}
p = &players[player];
memset(p, 0, sizeof (*p));
@ -2239,6 +2256,7 @@ void G_PlayerReborn(INT32 player)
p->starpostz = starpostz;
p->starpostnum = starpostnum;
p->starpostangle = starpostangle;
p->starpostscale = starpostscale;
p->jumpfactor = jumpfactor;
p->height = height;
p->spinheight = spinheight;
@ -2252,6 +2270,8 @@ void G_PlayerReborn(INT32 player)
if (bot)
p->bot = 1; // reset to AI-controlled
p->pity = pity;
p->rings = rings;
p->spheres = spheres;
// Don't do anything immediately
p->pflags |= PF_USEDOWN;
@ -2259,44 +2279,11 @@ void G_PlayerReborn(INT32 player)
p->pflags |= PF_JUMPDOWN;
p->playerstate = PST_LIVE;
p->rings = p->spheres = 0; // 0 rings
p->panim = PA_IDLE; // standing animation
//if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there
//p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
if (p-players == consoleplayer)
{
if (mapmusflags & MUSIC_RELOADRESET)
{
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
mapmusname[6] = 0;
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
}
// This is in S_Start, but this was not here previously.
// if (cv_resetmusic.value)
// S_StopMusic();
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
}
if (gametype == GT_COOP)
P_FindEmerald(); // scan for emeralds to hunt for
// Reset Nights score and max link to 0 on death
p->marescore = p->maxlink = 0;
// If NiGHTS, find lowest mare to start with.
p->mare = P_FindLowestMare();
CONS_Debug(DBG_NIGHTS, M_GetText("Current mare is %d\n"), p->mare);
if (p->mare == 255)
p->mare = 0;
p->marelap = p->marebonuslap = 0;
// Check to make sure their color didn't change somehow...
if (G_GametypeHasTeams())
{
@ -2315,6 +2302,36 @@ void G_PlayerReborn(INT32 player)
CV_SetValue(&cv_playercolor2, skincolor_blueteam);
}
}
if (betweenmaps)
return;
if (p-players == consoleplayer)
{
if (mapmusflags & MUSIC_RELOADRESET)
{
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
mapmusname[6] = 0;
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
}
// This is in S_Start, but this was not here previously.
// if (RESETMUSIC)
// S_StopMusic();
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
}
if (gametype == GT_COOP)
P_FindEmerald(); // scan for emeralds to hunt for
// If NiGHTS, find lowest mare to start with.
p->mare = P_FindLowestMare();
CONS_Debug(DBG_NIGHTS, M_GetText("Current mare is %d\n"), p->mare);
if (p->mare == 255)
p->mare = 0;
}
//
@ -2370,8 +2387,6 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
P_SpawnPlayer(playernum);
players[playernum].rings = mapheaderinfo[gamemap-1]->startrings;
if (starpost) //Don't even bother with looking for a place to spawn.
{
P_MovePlayerToStarpost(playernum);
@ -2594,7 +2609,7 @@ void G_DoReborn(INT32 playernum)
if (countdowntimeup || (!(netgame || multiplayer) && gametype == GT_COOP))
resetlevel = true;
else if (gametype == GT_COOP && (netgame || multiplayer))
else if (gametype == GT_COOP && (netgame || multiplayer) && !G_IsSpecialStage(gamemap))
{
boolean notgameover = true;
@ -2657,6 +2672,7 @@ void G_DoReborn(INT32 playernum)
{
if (!playeringame[i])
continue;
players[i].starpostscale = 0;
players[i].starpostangle = 0;
players[i].starposttime = 0;
players[i].starpostx = 0;
@ -2779,6 +2795,7 @@ void G_AddPlayer(INT32 playernum)
if (!(cv_coopstarposts.value && (gametype == GT_COOP) && (p->starpostnum < players[i].starpostnum)))
continue;
p->starpostscale = players[i].starpostscale;
p->starposttime = players[i].starposttime;
p->starpostx = players[i].starpostx;
p->starposty = players[i].starposty;
@ -3782,7 +3799,29 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
// File end marker check
CHECKPOS
if (READUINT8(save_p) != 0x1d) BADSAVE;
switch (READUINT8(save_p))
{
case 0xb7:
{
UINT8 i, banksinuse;
CHECKPOS
banksinuse = READUINT8(save_p);
CHECKPOS
if (banksinuse > NUM_LUABANKS)
BADSAVE
for (i = 0; i < banksinuse; i++)
{
(void)READINT32(save_p);
CHECKPOS
}
if (READUINT8(save_p) != 0x1d)
BADSAVE
}
case 0x1d:
break;
default:
BADSAVE
}
// done
saved = FIL_WriteFile(backup, savebuffer, length);
@ -3866,7 +3905,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
for (i = 0; i < MAXPLAYERS; i++)
{
players[i].playerstate = PST_REBORN;
players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0;
players[i].starpostscale = players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0;
players[i].starpostx = players[i].starposty = players[i].starpostz = 0;
if (netgame || multiplayer)
@ -4577,7 +4616,7 @@ void G_GhostTicker(void)
default:
case GHC_RETURNSKIN:
g->mo->skin = g->oldmo.skin;
// fallthru
/* FALLTHRU */
case GHC_NORMAL: // Go back to skin color
g->mo->color = g->oldmo.color;
break;

View file

@ -100,7 +100,7 @@ extern INT32 localaiming, localaiming2; // should be an angle_t but signed
//
void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo);
void G_DoReborn(INT32 playernum);
void G_PlayerReborn(INT32 player);
void G_PlayerReborn(INT32 player, boolean betweenmaps);
void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer,
boolean skipprecutscene, boolean FLS);
char *G_BuildMapTitle(INT32 mapnum);

View file

@ -30,6 +30,7 @@
#include "../z_zone.h"
#include "../v_video.h"
#include "../r_draw.h"
#include "../p_setup.h"
//Hurdler: 25/04/2000: used for new colormap code in hardware mode
//static UINT8 *gr_colormap = NULL; // by default it must be NULL ! (because colormap tables are not initialized)
@ -60,7 +61,6 @@ static const INT32 format2bpp[16] =
2, //14 GR_TEXFMT_AP_88
};
// This code was originally placed directly in HWR_DrawPatchInCache.
// It is now split from it for my sanity! (and the sanity of others)
// -- Monster Iestyn (13/02/19)
@ -138,18 +138,37 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
// Alam: SRB2 uses Mingw, HUGS
switch (bpp)
{
case 2 : texelu16 = (UINT16)((alpha<<8) | texel);
case 2 : // uhhhhhhhh..........
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16));
break;
case 3 : colortemp = V_GetColor(texel);
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
case 4 : colortemp = V_GetColor(texel);
colortemp.s.alpha = alpha;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
// default is 1
default: *dest = texel;
default:
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
*dest = ASTBlendPixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha);
else
*dest = texel;
break;
}
@ -233,18 +252,37 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
// Alam: SRB2 uses Mingw, HUGS
switch (bpp)
{
case 2 : texelu16 = (UINT16)((alpha<<8) | texel);
case 2 : // uhhhhhhhh..........
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16));
break;
case 3 : colortemp = V_GetColor(texel);
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
case 4 : colortemp = V_GetColor(texel);
colortemp.s.alpha = alpha;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
// default is 1
default: *dest = texel;
default:
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
*dest = ASTBlendPixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha);
else
*dest = texel;
break;
}
@ -331,16 +369,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
if (texture->width <= 0 || texture->height <= 0)
return;
/*if ((patch->style == AST_TRANSLUCENT) && (patch->alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency?
{
if (patch->alpha < 255/11) // Is the patch way too translucent? Don't render then.
continue;
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawTransFlippedColumnInCache : HWR_DrawTransColumnInCache;
}
else*/
{
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache;
}
x1 = patch->originx;
width = SHORT(realpatch->width);
@ -420,6 +449,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight,
GrTexInfo *grInfo)
{
#ifdef GLIDE_API_COMPATIBILITY
// Build the full textures from patches.
static const GrLOD_t gr_lods[9] =
{
@ -456,6 +486,9 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight,
INT32 j,k;
INT32 max,min;
#else
(void)grInfo;
#endif
// find a power of 2 width/height
if (cv_grrounddown.value)
@ -511,6 +544,7 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight,
}
else
{
#ifdef GLIDE_API_COMPATIBILITY
//size up to nearest power of 2
blockwidth = 1;
while (blockwidth < originalwidth)
@ -528,9 +562,14 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight,
if (blockheight > 2048)
blockheight = 2048;
//I_Error("3D GenerateTexture : too big");
#else
blockwidth = originalwidth;
blockheight = originalheight;
#endif
}
// do the boring LOD stuff.. blech!
#ifdef GLIDE_API_COMPATIBILITY
if (blockwidth >= blockheight)
{
max = blockwidth;
@ -562,6 +601,7 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight,
if (blockwidth < blockheight)
j += 4;
grInfo->aspectRatioLog2 = gr_aspects[j].aspect;
#endif
blocksize = blockwidth * blockheight;
@ -650,7 +690,12 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
// Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{
size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump);
realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
#ifndef NO_PNG_LUMPS
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false);
#endif
HWR_DrawTexturePatchInCache(&grtex->mipmap,
blockwidth, blockheight,
texture, patch,
@ -679,6 +724,13 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
{
INT32 newwidth, newheight;
#ifndef NO_PNG_LUMPS
// lump is a png so convert it
size_t len = W_LumpLengthPwad(grPatch->wadnum, grPatch->lumpnum);
if ((patch != NULL) && R_IsLumpPNG((const UINT8 *)patch, len))
patch = R_PNGToPatch((const UINT8 *)patch, len, NULL, true);
#endif
// don't do it twice (like a cache)
if (grMipmap->width == 0)
{
@ -756,11 +808,13 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
static size_t gr_numtextures;
static GLTexture_t *gr_textures; // for ALL Doom textures
static GLTexture_t *gr_textures2;
void HWR_InitTextureCache(void)
{
gr_numtextures = 0;
gr_textures = NULL;
gr_textures2 = NULL;
}
@ -799,7 +853,10 @@ void HWR_FreeTextureCache(void)
// texturecache info, we can free it
if (gr_textures)
free(gr_textures);
if (gr_textures2)
free(gr_textures2);
gr_textures = NULL;
gr_textures2 = NULL;
gr_numtextures = 0;
}
@ -817,6 +874,9 @@ void HWR_PrepLevelCache(size_t pnumtextures)
gr_textures = calloc(pnumtextures, sizeof (*gr_textures));
if (gr_textures == NULL)
I_Error("3D can't alloc gr_textures");
gr_textures2 = calloc(pnumtextures, sizeof (*gr_textures2));
if (gr_textures2 == NULL)
I_Error("3D can't alloc gr_textures2");
}
void HWR_SetPalette(RGBA_t *palette)
@ -862,15 +922,39 @@ GLTexture_t *HWR_GetTexture(INT32 tex)
return grtex;
}
// HWR_RenderPlane and HWR_RenderPolyObjectPlane need this to get the flat dimensions from a patch.
lumpnum_t gr_patchflat;
static void HWR_LoadPatchFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
{
UINT8 *flat;
patch_t *patch = (patch_t *)W_CacheLumpNum(flatlumpnum, PU_STATIC);
size_t lumplength = W_LumpLength(flatlumpnum);
#ifndef NO_PNG_LUMPS
if (R_IsLumpPNG((UINT8 *)patch, lumplength))
patch = R_PNGToPatch((UINT8 *)patch, lumplength, NULL, false);
#endif
grMipmap->width = (UINT16)SHORT(patch->width);
grMipmap->height = (UINT16)SHORT(patch->height);
flat = Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data);
memset(flat, TRANSPARENTPIXEL, grMipmap->width * grMipmap->height);
R_PatchToFlat(patch, flat);
}
static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
{
size_t size, pflatsize;
// setup the texture info
#ifdef GLIDE_API_COMPATIBILITY
grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64;
grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64;
grMipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
#endif
grMipmap->grInfo.format = GR_TEXFMT_P_8;
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
@ -900,6 +984,11 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
pflatsize = 64;
break;
}
if (R_CheckIfPatch(flatlumpnum))
HWR_LoadPatchFlat(grMipmap, flatlumpnum);
else
{
grMipmap->width = (UINT16)pflatsize;
grMipmap->height = (UINT16)pflatsize;
@ -907,7 +996,7 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum),
PU_HWRCACHE, &grMipmap->grInfo.data));
}
}
// Download a Doom 'flat' to the hardware cache and make it ready for use
void HWR_GetFlat(lumpnum_t flatlumpnum)
@ -923,6 +1012,52 @@ void HWR_GetFlat(lumpnum_t flatlumpnum)
// The system-memory data can be purged now.
Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED);
gr_patchflat = 0;
if (R_CheckIfPatch(flatlumpnum))
gr_patchflat = flatlumpnum;
}
static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum)
{
UINT8 *flat;
// setup the texture info
#ifdef GLIDE_API_COMPATIBILITY
grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64;
grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64;
grMipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
#endif
grMipmap->grInfo.format = GR_TEXFMT_P_8;
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
grMipmap->width = (UINT16)textures[texturenum]->width;
grMipmap->height = (UINT16)textures[texturenum]->height;
flat = Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data);
memset(flat, TRANSPARENTPIXEL, grMipmap->width * grMipmap->height);
R_TextureToFlat(texturenum, flat);
}
void HWR_GetTextureFlat(INT32 texturenum)
{
GLTexture_t *grtex;
#ifdef PARANOIA
if ((unsigned)texturenum >= gr_numtextures)
I_Error("HWR_GetTextureFlat: texturenum >= numtextures\n");
#endif
if (texturenum == 0 || texturenum == -1)
return;
grtex = &gr_textures2[texturenum];
if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded)
HWR_LoadTextureFlat(&grtex->mipmap, texturenum);
HWD.pfnSetTexture(&grtex->mipmap);
// The system-memory data can be purged now.
Z_ChangeTag(grtex->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED);
}
//

View file

@ -59,9 +59,11 @@ typedef FxI32 GrTextureFormat_t;
typedef struct
{
#ifdef GLIDE_API_COMPATIBILITY
GrLOD_t smallLodLog2;
GrLOD_t largeLodLog2;
GrAspectRatio_t aspectRatioLog2;
#endif
GrTextureFormat_t format;
void *data;
} GrTexInfo;

View file

@ -101,6 +101,7 @@ void HWR_FreeTextureCache(void);
void HWR_FreeExtraSubsectors(void);
void HWR_GetFlat(lumpnum_t flatlumpnum);
void HWR_GetTextureFlat(INT32 texturenum);
GLTexture_t *HWR_GetTexture(INT32 tex);
void HWR_GetPatch(GLPatch_t *gpatch);
void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap);
@ -114,6 +115,8 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
// --------
// hw_draw.c
// --------
extern lumpnum_t gr_patchflat;
extern float gr_patch_scalex;
extern float gr_patch_scaley;

View file

@ -186,17 +186,16 @@ light_t *t_lspr[NUMSPRITES] =
// Boss 1, (Greenflower)
&lspr[NOLIGHT], // SPR_EGGM
&lspr[NOLIGHT], // SPR_EGLZ
// Boss 2, (Techno Hill)
&lspr[NOLIGHT], // SPR_EGGN
&lspr[NOLIGHT], // SPR_TNKA
&lspr[NOLIGHT], // SPR_TNKB
&lspr[NOLIGHT], // SPR_SPNK
&lspr[NOLIGHT], // SPR_TANK
&lspr[NOLIGHT], // SPR_GOOP
// Boss 3 (Deep Sea)
&lspr[NOLIGHT], // SPR_EGGO
&lspr[NOLIGHT], // SPR_PRPL
&lspr[NOLIGHT], // SPR_SEBH
&lspr[NOLIGHT], // SPR_FAKE
// Boss 4 (Castle Eggman)
@ -1226,9 +1225,11 @@ static void HWR_SetLight(void)
lightmappatch.height = 128;
lightmappatch.mipmap.width = 128;
lightmappatch.mipmap.height = 128;
#ifdef GLIDE_API_COMPATIBILITY
lightmappatch.mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_128;
lightmappatch.mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_128;
lightmappatch.mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
#endif
lightmappatch.mipmap.flags = 0; //TF_WRAPXY; // DEBUG: view the overdraw !
}
HWD.pfnSetTexture(&lightmappatch.mipmap);

View file

@ -70,9 +70,9 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
#endif
#ifdef SORTING
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight,
void HWR_AddTransparentFloor(lumpnum_t lumpnum, INT32 texturenum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight,
INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, INT32 texturenum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
#else
static void HWR_Add3DWater(lumpnum_t lumpnum, extrasubsector_t *xsub, fixed_t fixedheight,
@ -522,7 +522,7 @@ static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this c
// HWR_RenderPlane : Render a floor or ceiling convex polygon
// -----------------+
static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight,
FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap)
FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, INT32 texturenum, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap)
{
polyvertex_t * pv;
float height; //constant y for all points on the convex flat polygon
@ -530,8 +530,9 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
INT32 nrPlaneVerts; //verts original define of convex flat polygon
INT32 i;
float flatxref,flatyref;
float fflatsize;
float fflatwidth, fflatheight;
INT32 flatflag;
boolean texflat = true;
size_t len;
float scrollx = 0.0f, scrolly = 0.0f;
angle_t angle = 0;
@ -540,6 +541,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
#ifdef ESLOPE
pslope_t *slope = NULL;
#endif
patch_t *patch;
static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0;
@ -580,9 +582,10 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
if (nrPlaneVerts < 3) //not even a triangle ?
return;
if (nrPlaneVerts > (INT32)UINT16_MAX) // FIXME: exceeds plVerts size
// This check is so inconsistent between functions, it hurts.
if (nrPlaneVerts > INT16_MAX) // FIXME: exceeds plVerts size
{
CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, UINT16_MAX);
CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, INT16_MAX);
return;
}
@ -599,38 +602,47 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
switch (len)
{
case 4194304: // 2048x2048 lump
fflatsize = 2048.0f;
flatflag = 2047;
fflatwidth = fflatheight = 2048.0f;
break;
case 1048576: // 1024x1024 lump
fflatsize = 1024.0f;
flatflag = 1023;
fflatwidth = fflatheight = 1024.0f;
break;
case 262144:// 512x512 lump
fflatsize = 512.0f;
flatflag = 511;
fflatwidth = fflatheight = 512.0f;
break;
case 65536: // 256x256 lump
fflatsize = 256.0f;
flatflag = 255;
fflatwidth = fflatheight = 256.0f;
break;
case 16384: // 128x128 lump
fflatsize = 128.0f;
flatflag = 127;
fflatwidth = fflatheight = 128.0f;
break;
case 1024: // 32x32 lump
fflatsize = 32.0f;
flatflag = 31;
fflatwidth = fflatheight = 32.0f;
break;
default: // 64x64 lump
fflatsize = 64.0f;
flatflag = 63;
fflatwidth = fflatheight = 64.0f;
break;
}
flatflag = ((INT32)fflatwidth)-1;
if (texturenum != 0 && texturenum != -1)
{
fflatwidth = textures[texturenum]->width;
fflatheight = textures[texturenum]->height;
}
else if (gr_patchflat && R_CheckIfPatch(gr_patchflat)) // Just in case?
{
patch = (patch_t *)W_CacheLumpNum(gr_patchflat, PU_STATIC);
fflatwidth = SHORT(patch->width);
fflatheight = SHORT(patch->height);
}
else
texflat = false;
// reference point for flat texture coord for each vertex around the polygon
flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatsize);
flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatsize);
flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatwidth);
flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatheight);
// transform
v3d = planeVerts;
@ -639,14 +651,14 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
{
if (!isceiling) // it's a floor
{
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize;
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatwidth;
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatheight;
angle = FOFsector->floorpic_angle;
}
else // it's a ceiling
{
scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatsize;
scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatwidth;
scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatheight;
angle = FOFsector->ceilingpic_angle;
}
}
@ -654,14 +666,14 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
{
if (!isceiling) // it's a floor
{
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize;
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatwidth;
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatheight;
angle = gr_frontsector->floorpic_angle;
}
else // it's a ceiling
{
scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize;
scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatwidth;
scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatheight;
angle = gr_frontsector->ceilingpic_angle;
}
}
@ -680,17 +692,24 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++)
{
// Hurdler: add scrolling texture on floor/ceiling
v3d->sow = (float)((pv->x / fflatsize) - flatxref + scrollx);
v3d->tow = (float)(-(pv->y / fflatsize) + flatyref + scrolly);
//v3d->sow = (float)(pv->x / fflatsize);
//v3d->tow = (float)(pv->y / fflatsize);
if (texflat)
{
v3d->sow = (float)(pv->x / fflatwidth) + scrollx;
v3d->tow = -(float)(pv->y / fflatheight) + scrolly;
}
else
{
v3d->sow = (float)((pv->x / fflatwidth) - flatxref + scrollx);
v3d->tow = (float)(flatyref - (pv->y / fflatheight) + scrolly);
}
// Need to rotate before translate
if (angle) // Only needs to be done if there's an altered angle
{
tempxsow = FLOAT_TO_FIXED(v3d->sow);
tempytow = FLOAT_TO_FIXED(v3d->tow);
if (texflat)
tempytow = -tempytow;
v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
v3d->tow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));
}
@ -3164,21 +3183,23 @@ static inline void HWR_AddPolyObjectSegs(void)
#ifdef POLYOBJECTS_PLANES
static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector,
FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, INT32 texturenum, sector_t *FOFsector,
UINT8 alpha, extracolormap_t *planecolormap)
{
float height; //constant y for all points on the convex flat polygon
FOutVector *v3d;
INT32 i;
float flatxref,flatyref;
float fflatsize;
float fflatwidth, fflatheight;
INT32 flatflag;
boolean texflat = true;
size_t len;
float scrollx = 0.0f, scrolly = 0.0f;
angle_t angle = 0;
FSurfaceInfo Surf;
fixed_t tempxsow, tempytow;
size_t nrPlaneVerts;
patch_t *patch;
static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0;
@ -3209,38 +3230,47 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
switch (len)
{
case 4194304: // 2048x2048 lump
fflatsize = 2048.0f;
flatflag = 2047;
fflatwidth = fflatheight = 2048.0f;
break;
case 1048576: // 1024x1024 lump
fflatsize = 1024.0f;
flatflag = 1023;
fflatwidth = fflatheight = 1024.0f;
break;
case 262144:// 512x512 lump
fflatsize = 512.0f;
flatflag = 511;
fflatwidth = fflatheight = 512.0f;
break;
case 65536: // 256x256 lump
fflatsize = 256.0f;
flatflag = 255;
fflatwidth = fflatheight = 256.0f;
break;
case 16384: // 128x128 lump
fflatsize = 128.0f;
flatflag = 127;
fflatwidth = fflatheight = 128.0f;
break;
case 1024: // 32x32 lump
fflatsize = 32.0f;
flatflag = 31;
fflatwidth = fflatheight = 32.0f;
break;
default: // 64x64 lump
fflatsize = 64.0f;
flatflag = 63;
fflatwidth = fflatheight = 64.0f;
break;
}
flatflag = ((INT32)fflatwidth)-1;
if (texturenum != 0 && texturenum != -1)
{
fflatwidth = textures[texturenum]->width;
fflatheight = textures[texturenum]->height;
}
else if (gr_patchflat && R_CheckIfPatch(gr_patchflat)) // Just in case?
{
patch = (patch_t *)W_CacheLumpNum(gr_patchflat, PU_STATIC);
fflatwidth = SHORT(patch->width);
fflatheight = SHORT(patch->height);
}
else
texflat = false;
// reference point for flat texture coord for each vertex around the polygon
flatxref = (float)(((fixed_t)FIXED_TO_FLOAT(polysector->origVerts[0].x) & (~flatflag)) / fflatsize);
flatyref = (float)(((fixed_t)FIXED_TO_FLOAT(polysector->origVerts[0].y) & (~flatflag)) / fflatsize);
flatxref = (float)((polysector->origVerts[0].x & (~flatflag)) / fflatwidth);
flatyref = (float)((polysector->origVerts[0].y & (~flatflag)) / fflatheight);
// transform
v3d = planeVerts;
@ -3249,14 +3279,14 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
{
if (!isceiling) // it's a floor
{
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize;
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatwidth;
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatheight;
angle = FOFsector->floorpic_angle>>ANGLETOFINESHIFT;
}
else // it's a ceiling
{
scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatsize;
scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatwidth;
scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatheight;
angle = FOFsector->ceilingpic_angle>>ANGLETOFINESHIFT;
}
}
@ -3264,14 +3294,14 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
{
if (!isceiling) // it's a floor
{
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize;
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatwidth;
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatheight;
angle = gr_frontsector->floorpic_angle>>ANGLETOFINESHIFT;
}
else // it's a ceiling
{
scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize;
scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatwidth;
scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatheight;
angle = gr_frontsector->ceilingpic_angle>>ANGLETOFINESHIFT;
}
}
@ -3294,15 +3324,26 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
for (i = 0; i < (INT32)nrPlaneVerts; i++,v3d++)
{
// Hurdler: add scrolling texture on floor/ceiling
v3d->sow = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatsize) - flatxref + scrollx); // Go from the polysector's original vertex locations
v3d->tow = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatsize) + scrolly); // Means the flat is offset based on the original vertex locations
// Go from the polysector's original vertex locations
// Means the flat is offset based on the original vertex locations
if (texflat)
{
v3d->sow = (float)(FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) + scrollx;
v3d->tow = -(float)(FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly;
}
else
{
v3d->sow = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) - flatxref + scrollx);
v3d->tow = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly);
}
// Need to rotate before translate
if (angle) // Only needs to be done if there's an altered angle
{
tempxsow = FLOAT_TO_FIXED(v3d->sow);
tempytow = FLOAT_TO_FIXED(v3d->tow);
if (texflat)
tempytow = -tempytow;
v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
v3d->tow = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle))));
}
@ -3333,6 +3374,7 @@ static void HWR_AddPolyObjectPlanes(void)
{
size_t i;
sector_t *polyobjsector;
INT32 light = 0;
// Polyobject Planes need their own function for drawing because they don't have extrasubsectors by themselves
// It should be okay because polyobjects should always be convex anyway
@ -3351,19 +3393,23 @@ static void HWR_AddPolyObjectPlanes(void)
&& polyobjsector->floorheight >= gr_frontsector->floorheight
&& (viewz < polyobjsector->floorheight))
{
light = R_GetPlaneLight(gr_frontsector, polyobjsector->floorheight, true);
if (po_ptrs[i]->translucency > 0)
{
FSurfaceInfo Surf;
FBITFIELD blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, po_ptrs[i], false, polyobjsector->floorheight,
polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL);
FBITFIELD blendmode;
memset(&Surf, 0x00, sizeof(Surf));
blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum, po_ptrs[i], false, polyobjsector->floorheight,
(light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.FlatColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap));
}
else
{
HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum);
HWR_GetTextureFlat(levelflats[polyobjsector->floorpic].texturenum);
HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude,
polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum,
polyobjsector, 255, NULL);
(light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum,
polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap));
}
}
@ -3371,21 +3417,23 @@ static void HWR_AddPolyObjectPlanes(void)
&& polyobjsector->ceilingheight <= gr_frontsector->ceilingheight
&& (viewz > polyobjsector->ceilingheight))
{
light = R_GetPlaneLight(gr_frontsector, polyobjsector->ceilingheight, true);
if (po_ptrs[i]->translucency > 0)
{
FSurfaceInfo Surf;
FBITFIELD blendmode;
memset(&Surf, 0x00, sizeof(Surf));
blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, po_ptrs[i], true, polyobjsector->ceilingheight,
polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL);
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum, po_ptrs[i], true, polyobjsector->ceilingheight,
(light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.FlatColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap));
}
else
{
HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum);
HWR_GetTextureFlat(levelflats[polyobjsector->ceilingpic].texturenum);
HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude,
polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum,
polyobjsector, 255, NULL);
(light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum,
polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap));
}
}
}
@ -3536,11 +3584,12 @@ static void HWR_Subsector(size_t num)
if (sub->validcount != validcount)
{
HWR_GetFlat(levelflats[gr_frontsector->floorpic].lumpnum);
HWR_GetTextureFlat(levelflats[gr_frontsector->floorpic].texturenum);
HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], false,
// Hack to make things continue to work around slopes.
locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight,
// We now return you to your regularly scheduled rendering.
PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, false, floorcolormap);
PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, levelflats[gr_frontsector->floorpic].texturenum, NULL, 255, false, floorcolormap);
}
}
else
@ -3558,11 +3607,12 @@ static void HWR_Subsector(size_t num)
if (sub->validcount != validcount)
{
HWR_GetFlat(levelflats[gr_frontsector->ceilingpic].lumpnum);
HWR_GetTextureFlat(levelflats[gr_frontsector->ceilingpic].texturenum);
HWR_RenderPlane(NULL, &extrasubsectors[num], true,
// Hack to make things continue to work around slopes.
locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight,
// We now return you to your regularly scheduled rendering.
PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum,NULL, 255, false, ceilingcolormap);
PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum, levelflats[gr_frontsector->ceilingpic].texturenum, NULL, 255, false, ceilingcolormap);
}
}
else
@ -3621,7 +3671,7 @@ static void HWR_Subsector(size_t num)
else
alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG);
HWR_AddTransparentFloor(0,
HWR_AddTransparentFloor(0, 0,
&extrasubsectors[num],
false,
*rover->bottomheight,
@ -3640,6 +3690,7 @@ static void HWR_Subsector(size_t num)
rover->alpha-1, rover->master->frontsector);
#else
HWR_AddTransparentFloor(levelflats[*rover->bottompic].lumpnum,
levelflats[*rover->bottompic].texturenum,
&extrasubsectors[num],
false,
*rover->bottomheight,
@ -3651,8 +3702,9 @@ static void HWR_Subsector(size_t num)
else
{
HWR_GetFlat(levelflats[*rover->bottompic].lumpnum);
HWR_GetTextureFlat(levelflats[*rover->bottompic].texturenum);
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum,
HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, levelflats[*rover->bottompic].texturenum,
rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap);
}
}
@ -3684,7 +3736,7 @@ static void HWR_Subsector(size_t num)
else
alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG);
HWR_AddTransparentFloor(0,
HWR_AddTransparentFloor(0, 0,
&extrasubsectors[num],
true,
*rover->topheight,
@ -3703,6 +3755,7 @@ static void HWR_Subsector(size_t num)
rover->alpha-1, rover->master->frontsector);
#else
HWR_AddTransparentFloor(levelflats[*rover->toppic].lumpnum,
levelflats[*rover->bottompic].texturenum,
&extrasubsectors[num],
true,
*rover->topheight,
@ -3715,8 +3768,9 @@ static void HWR_Subsector(size_t num)
else
{
HWR_GetFlat(levelflats[*rover->toppic].lumpnum);
HWR_GetTextureFlat(levelflats[*rover->toppic].texturenum);
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum,
HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, levelflats[*rover->toppic].texturenum,
rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap);
}
}
@ -5045,6 +5099,7 @@ typedef struct
fixed_t fixedheight;
INT32 lightlevel;
lumpnum_t lumpnum;
INT32 texturenum;
INT32 alpha;
sector_t *FOFSector;
FBITFIELD blend;
@ -5063,6 +5118,7 @@ typedef struct
fixed_t fixedheight;
INT32 lightlevel;
lumpnum_t lumpnum;
INT32 texturenum;
INT32 alpha;
sector_t *FOFSector;
FBITFIELD blend;
@ -5093,7 +5149,7 @@ static INT32 drawcount = 0;
#define MAX_TRANSPARENTFLOOR 512
// This will likely turn into a copy of HWR_Add3DWater and replace it.
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling,
void HWR_AddTransparentFloor(lumpnum_t lumpnum, INT32 texturenum, extrasubsector_t *xsub, boolean isceiling,
fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap)
{
static size_t allocedplanes = 0;
@ -5112,6 +5168,7 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean
planeinfo[numplanes].fixedheight = fixedheight;
planeinfo[numplanes].lightlevel = lightlevel;
planeinfo[numplanes].lumpnum = lumpnum;
planeinfo[numplanes].texturenum = texturenum;
planeinfo[numplanes].xsub = xsub;
planeinfo[numplanes].alpha = alpha;
planeinfo[numplanes].FOFSector = FOFSector;
@ -5125,7 +5182,7 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean
// Adding this for now until I can create extrasubsector info for polyobjects
// When that happens it'll just be done through HWR_AddTransparentFloor and HWR_RenderPlane
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling,
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, INT32 texturenum, polyobj_t *polysector, boolean isceiling,
fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap)
{
static size_t allocedpolyplanes = 0;
@ -5144,6 +5201,7 @@ void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector,
polyplaneinfo[numpolyplanes].fixedheight = fixedheight;
polyplaneinfo[numpolyplanes].lightlevel = lightlevel;
polyplaneinfo[numpolyplanes].lumpnum = lumpnum;
polyplaneinfo[numpolyplanes].texturenum = texturenum;
polyplaneinfo[numpolyplanes].polysector = polysector;
polyplaneinfo[numpolyplanes].alpha = alpha;
polyplaneinfo[numpolyplanes].FOFSector = FOFSector;
@ -5305,9 +5363,12 @@ static void HWR_CreateDrawNodes(void)
gr_frontsector = NULL;
if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture))
{
HWR_GetFlat(sortnode[sortindex[i]].plane->lumpnum);
HWR_GetTextureFlat(sortnode[sortindex[i]].plane->texturenum);
}
HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel,
sortnode[sortindex[i]].plane->lumpnum, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap);
sortnode[sortindex[i]].plane->lumpnum, sortnode[sortindex[i]].plane->texturenum, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap);
}
else if (sortnode[sortindex[i]].polyplane)
{
@ -5315,9 +5376,12 @@ static void HWR_CreateDrawNodes(void)
gr_frontsector = NULL;
if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture))
{
HWR_GetFlat(sortnode[sortindex[i]].polyplane->lumpnum);
HWR_GetTextureFlat(sortnode[sortindex[i]].polyplane->texturenum);
}
HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel,
sortnode[sortindex[i]].polyplane->lumpnum, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap);
sortnode[sortindex[i]].polyplane->lumpnum, sortnode[sortindex[i]].polyplane->texturenum, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap);
}
else if (sortnode[sortindex[i]].wall)
{

View file

@ -26,6 +26,7 @@
#include <string.h>
#include <math.h>
#include "../d_main.h"
#include "../doomdef.h"
#include "../doomstat.h"
#include "../fastcmp.h"
@ -70,6 +71,10 @@
#endif
#endif
#ifndef errno
#include "errno.h"
#endif
#define NUMVERTEXNORMALS 162
float avertexnormals[NUMVERTEXNORMALS][3] = {
{-0.525731f, 0.000000f, 0.850651f},
@ -294,7 +299,8 @@ static md2_model_t *md2_readModel(const char *filename)
if (model == NULL)
return 0;
file = fopen(filename, "rb");
//Filename checking fixed ~Monster Iestyn and Golden
file = fopen(va("%s"PATHSEP"%s", srb2home, filename), "rb");
if (!file)
{
free(model);
@ -523,7 +529,8 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
#endif
#endif
png_FILE_p png_FILE;
char *pngfilename = va("md2/%s", filename);
//Filename checking fixed ~Monster Iestyn and Golden
char *pngfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2home, filename);
FIL_ForceExtension(pngfilename, ".png");
png_FILE = fopen(pngfilename, "rb");
@ -651,7 +658,8 @@ static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
size_t pw, ph, size, ptr = 0;
INT32 ch, rep;
FILE *file;
char *pcxfilename = va("md2/%s", filename);
//Filename checking fixed ~Monster Iestyn and Golden
char *pcxfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2home, filename);
FIL_ForceExtension(pcxfilename, ".pcx");
file = fopen(pcxfilename, "rb");
@ -747,10 +755,12 @@ static void md2_loadTexture(md2_t *model)
grpatch->mipmap.width = (UINT16)w;
grpatch->mipmap.height = (UINT16)h;
#ifdef GLIDE_API_COMPATIBILITY
// not correct!
grpatch->mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
#endif
}
HWD.pfnSetTexture(&grpatch->mipmap);
HWR_UnlockCachedPatch(grpatch);
@ -798,10 +808,12 @@ static void md2_loadBlendTexture(md2_t *model)
grpatch->mipmap.width = (UINT16)w;
grpatch->mipmap.height = (UINT16)h;
#ifdef GLIDE_API_COMPATIBILITY
// not correct!
grpatch->mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
#endif
}
HWD.pfnSetTexture(&grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary
HWR_UnlockCachedPatch(grpatch);
@ -841,11 +853,12 @@ void HWR_InitMD2(void)
}
// read the md2.dat file
f = fopen("md2.dat", "rt");
//Filename checking fixed ~Monster Iestyn and Golden
f = fopen(va("%s"PATHSEP"%s", srb2home, "md2.dat"), "rt");
if (!f)
{
CONS_Printf("%s", M_GetText("Error while loading md2.dat\n"));
CONS_Printf("%s %s\n", M_GetText("Error while loading md2.dat:"), strerror(errno));
nomd2s = true;
return;
}
@ -907,7 +920,8 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup
CONS_Printf("AddPlayerMD2()...\n");
// read the md2.dat file
f = fopen("md2.dat", "rt");
//Filename checking fixed ~Monster Iestyn and Golden
f = fopen(va("%s"PATHSEP"%s", srb2home, "md2.dat"), "rt");
if (!f)
{
@ -952,7 +966,8 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu
return;
// Read the md2.dat file
f = fopen("md2.dat", "rt");
//Filename checking fixed ~Monster Iestyn and Golden
f = fopen(va("%s"PATHSEP"%s", srb2home, "md2.dat"), "rt");
if (!f)
{
@ -1198,7 +1213,7 @@ static UINT8 P_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *p
if (!md2 || !skin)
return 0;
if ((unsigned)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
return 0;
while (!(md2->model->spr2frames[spr2*2 + 1])

View file

@ -73,18 +73,17 @@ char sprnames[NUMSPRITES + 1][5] =
"JETF", // Boss jet fumes
// Boss 1 (Greenflower)
"EGGM",
"EGGM", // Boss 1
"EGLZ", // Boss 1 Junk
// Boss 2 (Techno Hill)
"EGGN", // Boss 2
"TNKA", // Boss 2 Tank 1
"TNKB", // Boss 2 Tank 2
"SPNK", // Boss 2 Spigot
"TANK", // Boss 2 Junk
"GOOP", // Boss 2 Goop
// Boss 3 (Deep Sea)
"EGGO", // Boss 3
"PRPL", // Boss 3 Propeller
"SEBH", // Boss 3 Junk
"FAKE", // Boss 3 Fakemobile
// Boss 4 (Castle Eggman)
@ -213,11 +212,11 @@ char sprnames[NUMSPRITES + 1][5] =
"GARG", // Deep Sea Gargoyle
"SEWE", // Deep Sea Seaweed
"DRIP", // Dripping water
"CRL1", // Coral 1
"CRL2", // Coral 2
"CRL3", // Coral 3
"CORL", // Coral
"BCRY", // Blue Crystal
"KELP", // Kelp
"ALGA", // Animated algae top
"ALGB", // Animated algae segment
"DSTG", // DSZ Stalagmites
"LIBE", // DSZ Light beam
@ -247,7 +246,7 @@ char sprnames[NUMSPRITES + 1][5] =
// Arid Canyon Scenery
"BTBL", // Big tumbleweed
"STBL", // Small tumbleweed
"CACT", // Cacti sprites
"CACT", // Cacti
"WWSG", // Caution Sign
"WWS2", // Cacti Sign
"WWS3", // Sharp Turn Sign
@ -577,8 +576,14 @@ char spr2names[NUMPLAYERSPRITES][5] =
"TALA",
"TALB",
"CNT1",
"CNT2",
"CNT3",
"CNT4",
"SIGN",
"LIFE",
"XTRA",
};
playersprite_t free_spr2 = SPR2_FIRSTFREESLOT;
@ -674,8 +679,14 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
SPR2_TAL9, // SPR2_TALA,
SPR2_TAL0, // SPR2_TALB,
SPR2_WAIT, // SPR2_CNT1,
SPR2_FALL, // SPR2_CNT2,
SPR2_SPNG, // SPR2_CNT3,
SPR2_CNT1, // SPR2_CNT4,
0, // SPR2_SIGN,
0, // SPR2_LIFE,
0, // SPR2_XTRA (should never be referenced)
};
@ -728,7 +739,7 @@ state_t states[NUMSTATES] =
// CA_FLY/CA_SWIM
{SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY
{SPR_PLAY, SPR2_SWIM, 2, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM
{SPR_PLAY, SPR2_SWIM, 4, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM
{SPR_PLAY, SPR2_TIRE, 12, {NULL}, 0, 0, S_PLAY_FLY_TIRED}, // S_PLAY_FLY_TIRED
// CA_GLIDEANDCLIMB
@ -1179,49 +1190,58 @@ state_t states[NUMSTATES] =
{SPR_BOM3, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_SONIC3KBOSSEXPLOSION6}, // S_SONIC3KBOSSEXPLOSION5
{SPR_BOM3, FF_FULLBRIGHT|5, 4, {NULL}, 0, 0, S_NULL}, // S_SONIC3KBOSSEXPLOSION6
{SPR_JETF, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_JETFUME2}, // S_JETFUME1
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_JETFUME1}, // S_JETFUME2
{SPR_JETF, FF_ANIMATE|FF_FULLBRIGHT, -1, {NULL}, 2, 1, S_NULL}, // S_JETFUME1
// Boss 1
{SPR_EGGM, 0, 1, {A_Boss1Chase}, 0, 0, S_EGGMOBILE_STND}, // S_EGGMOBILE_STND
{SPR_EGGM, FF_ANIMATE|17, 35, {A_FaceTarget}, 1, 2, S_EGGMOBILE_STND}, // S_EGGMOBILE_ROFL
{SPR_EGGM, 1, 3, {A_FaceTarget}, 0, 0, S_EGGMOBILE_LATK2}, // S_EGGMOBILE_LATK1
{SPR_EGGM, 2, 15, {NULL}, 0, 0, S_EGGMOBILE_LATK3}, // S_EGGMOBILE_LATK2
{SPR_EGGM, 3, 2, {A_FaceTarget}, 0, 0, S_EGGMOBILE_LATK4}, // S_EGGMOBILE_LATK3
{SPR_EGGM, 4, 1, {NULL}, 0, 0, S_EGGMOBILE_LATK5}, // S_EGGMOBILE_LATK4
{SPR_EGGM, 5, 1, {NULL}, 0, 0, S_EGGMOBILE_LATK6}, // S_EGGMOBILE_LATK5
{SPR_EGGM, 6, 1, {NULL}, 0, 0, S_EGGMOBILE_LATK7}, // S_EGGMOBILE_LATK6
{SPR_EGGM, 7, 1, {NULL}, 0, 0, S_EGGMOBILE_LATK8}, // S_EGGMOBILE_LATK7
{SPR_EGGM, 8, 45, {A_Boss1Laser}, MT_LASER, 0, S_EGGMOBILE_LATK9}, // S_EGGMOBILE_LATK8
{SPR_EGGM, 9, 10, {NULL}, 0, 0, S_EGGMOBILE_LATK10}, // S_EGGMOBILE_LATK9
{SPR_EGGM, 10, 2, {NULL}, 0, 0, S_EGGMOBILE_STND}, // S_EGGMOBILE_LATK10
{SPR_EGGM, 11, 3, {A_FaceTarget}, 0, 0, S_EGGMOBILE_RATK2}, // S_EGGMOBILE_RATK1
{SPR_EGGM, 12, 15, {NULL}, 0, 0, S_EGGMOBILE_RATK3}, // S_EGGMOBILE_RATK2
{SPR_EGGM, 13, 2, {A_FaceTarget}, 0, 0, S_EGGMOBILE_RATK4}, // S_EGGMOBILE_RATK3
{SPR_EGGM, 14, 1, {NULL}, 0, 0, S_EGGMOBILE_RATK5}, // S_EGGMOBILE_RATK4
{SPR_EGGM, 15, 1, {NULL}, 0, 0, S_EGGMOBILE_RATK6}, // S_EGGMOBILE_RATK5
{SPR_EGGM, 16, 1, {NULL}, 0, 0, S_EGGMOBILE_RATK7}, // S_EGGMOBILE_RATK6
{SPR_EGGM, 17, 1, {NULL}, 0, 0, S_EGGMOBILE_RATK8}, // S_EGGMOBILE_RATK7
{SPR_EGGM, 18, 45, {A_Boss1Laser}, MT_LASER, 1, S_EGGMOBILE_RATK9}, // S_EGGMOBILE_RATK8
{SPR_EGGM, 19, 10, {NULL}, 0, 0, S_EGGMOBILE_RATK10}, // S_EGGMOBILE_RATK9
{SPR_EGGM, 20, 2, {NULL}, 0, 0, S_EGGMOBILE_STND}, // S_EGGMOBILE_RATK10
{SPR_EGGM, 3, 12, {NULL}, 0, 0, S_EGGMOBILE_PANIC2}, // S_EGGMOBILE_PANIC1
{SPR_EGGM, 4, 45, {A_Boss1Laser}, MT_LASER, 2, S_EGGMOBILE_PANIC3}, // S_EGGMOBILE_PANIC2
{SPR_EGGM, 3, 8, {NULL}, 0, 0, S_EGGMOBILE_PANIC4}, // S_EGGMOBILE_PANIC3
{SPR_EGGM, 4, 45, {A_Boss1Laser}, MT_LASER, 2, S_EGGMOBILE_PANIC5 }, // S_EGGMOBILE_PANIC4
{SPR_EGGM, 3, 8, {NULL}, 0, 0, S_EGGMOBILE_PANIC6}, // S_EGGMOBILE_PANIC5
{SPR_EGGM, 4, 45, {A_Boss1Laser}, MT_LASER, 2, S_EGGMOBILE_PANIC7 }, // S_EGGMOBILE_PANIC6
{SPR_EGGM, 0, 35, {NULL}, 0, 0, S_EGGMOBILE_STND }, // S_EGGMOBILE_PANIC7
{SPR_EGGM, 21, 24, {A_Pain}, 0, 0, S_EGGMOBILE_PAIN2}, // S_EGGMOBILE_PAIN
{SPR_EGGM, 21, 16, {A_SkullAttack}, 1, 1, S_EGGMOBILE_STND}, // S_EGGMOBILE_PAIN2
{SPR_EGGM, 22, 2, {A_Fall}, 0, 0, S_EGGMOBILE_DIE2}, // S_EGGMOBILE_DIE1
{SPR_EGGM, 22, 2, {A_BossScream}, 0, 0, S_EGGMOBILE_DIE3}, // S_EGGMOBILE_DIE2
{SPR_EGGM, 22, 0, {A_Repeat}, 17, S_EGGMOBILE_DIE2, S_EGGMOBILE_DIE4}, // S_EGGMOBILE_DIE3
{SPR_EGGM, 22, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_EGGMOBILE_DIE4
{SPR_EGGM, 23, 2, {A_BossScream}, 0, 0, S_EGGMOBILE_FLEE2}, // S_EGGMOBILE_FLEE1
{SPR_EGGM, 24, 2, {A_BossScream}, 0, 0, S_EGGMOBILE_FLEE1}, // S_EGGMOBILE_FLEE2
{SPR_EGGM, 3, 2, {NULL}, 0, 0, S_EGGMOBILE_LATK4}, // S_EGGMOBILE_LATK3
{SPR_EGGM, 4, 2, {A_FaceTarget}, 0, 0, S_EGGMOBILE_LATK5}, // S_EGGMOBILE_LATK4
{SPR_EGGM, 6, 0, {A_PrepareRepeat}, 45, 0, S_EGGMOBILE_LATK6}, // S_EGGMOBILE_LATK5
{SPR_EGGM, 5, 1, {A_Boss1Laser}, MT_LASER, 0, S_EGGMOBILE_LATK7}, // S_EGGMOBILE_LATK6
{SPR_EGGM, 6, 1, {A_Boss1Laser}, MT_LASER, (1<<16), S_EGGMOBILE_LATK8}, // S_EGGMOBILE_LATK7
{SPR_EGGM, 5, 0, {A_Repeat}, 45, S_EGGMOBILE_LATK6, S_EGGMOBILE_LATK9}, // S_EGGMOBILE_LATK8
{SPR_EGGM, 8, 2, {NULL}, 0, 0, S_EGGMOBILE_ROFL}, // S_EGGMOBILE_LATK9
{SPR_EGGM, 9, 3, {A_FaceTarget}, 0, 0, S_EGGMOBILE_RATK2}, // S_EGGMOBILE_RATK1
{SPR_EGGM, 10, 15, {NULL}, 0, 0, S_EGGMOBILE_RATK3}, // S_EGGMOBILE_RATK2
{SPR_EGGM, 11, 2, {NULL}, 0, 0, S_EGGMOBILE_RATK4}, // S_EGGMOBILE_RATK3
{SPR_EGGM, 12, 2, {A_FaceTarget}, 0, 0, S_EGGMOBILE_RATK5}, // S_EGGMOBILE_RATK4
{SPR_EGGM, 14, 0, {A_PrepareRepeat}, 45, 0, S_EGGMOBILE_RATK6}, // S_EGGMOBILE_RATK5
{SPR_EGGM, 13, 1, {A_Boss1Laser}, MT_LASER, 1, S_EGGMOBILE_RATK7}, // S_EGGMOBILE_RATK6
{SPR_EGGM, 14, 1, {A_Boss1Laser}, MT_LASER, 1|(1<<16), S_EGGMOBILE_RATK8}, // S_EGGMOBILE_RATK7
{SPR_EGGM, 13, 0, {A_Repeat}, 45, S_EGGMOBILE_RATK6, S_EGGMOBILE_RATK9}, // S_EGGMOBILE_RATK8
{SPR_EGGM, 16, 2, {NULL}, 0, 0, S_EGGMOBILE_ROFL}, // S_EGGMOBILE_RATK9
{SPR_EGGM, 0, 0, {A_PrepareRepeat}, 45, 0, S_EGGMOBILE_PANIC2}, // S_EGGMOBILE_PANIC1
{SPR_EGGM, FF_ANIMATE|1, 16, {A_FaceTarget}, 3, 4, S_EGGMOBILE_PANIC3}, // S_EGGMOBILE_PANIC2
{SPR_EGGM, 7, 1, {A_Boss1Laser}, MT_LASER, 2, S_EGGMOBILE_PANIC4}, // S_EGGMOBILE_PANIC3
{SPR_EGGM, 6, 1, {A_Boss1Laser}, MT_LASER, 2|(1<<16), S_EGGMOBILE_PANIC5}, // S_EGGMOBILE_PANIC4
{SPR_EGGM, 6, 0, {A_Repeat}, 45, S_EGGMOBILE_PANIC3, S_EGGMOBILE_PANIC6}, // S_EGGMOBILE_PANIC5
{SPR_EGGM, 0, 0, {A_PrepareRepeat}, 45, 0, S_EGGMOBILE_PANIC7}, // S_EGGMOBILE_PANIC6
{SPR_EGGM, FF_ANIMATE|9, 16, {A_FaceTarget}, 3, 4, S_EGGMOBILE_PANIC8}, // S_EGGMOBILE_PANIC7
{SPR_EGGM, 15, 1, {A_Boss1Laser}, MT_LASER, 2, S_EGGMOBILE_PANIC9}, // S_EGGMOBILE_PANIC8
{SPR_EGGM, 14, 1, {A_Boss1Laser}, MT_LASER, 2|(1<<16), S_EGGMOBILE_PANIC10}, // S_EGGMOBILE_PANIC9
{SPR_EGGM, 14, 0, {A_Repeat}, 45, S_EGGMOBILE_PANIC8, S_EGGMOBILE_PANIC11}, // S_EGGMOBILE_PANIC10
{SPR_EGGM, 0, 0, {A_PrepareRepeat}, 45, 0, S_EGGMOBILE_PANIC12}, // S_EGGMOBILE_PANIC11
{SPR_EGGM, FF_ANIMATE|1, 16, {A_FaceTarget}, 3, 4, S_EGGMOBILE_PANIC13}, // S_EGGMOBILE_PANIC12
{SPR_EGGM, 7, 1, {A_Boss1Laser}, MT_LASER, 2, S_EGGMOBILE_PANIC14}, // S_EGGMOBILE_PANIC13
{SPR_EGGM, 6, 1, {A_Boss1Laser}, MT_LASER, 2|(1<<16), S_EGGMOBILE_PANIC15}, // S_EGGMOBILE_PANIC14
{SPR_EGGM, 6, 0, {A_Repeat}, 45, S_EGGMOBILE_PANIC13, S_EGGMOBILE_ROFL}, // S_EGGMOBILE_PANIC15
{SPR_EGGM, 19, 24, {A_Pain}, 0, 0, S_EGGMOBILE_PAIN2}, // S_EGGMOBILE_PAIN
{SPR_EGGM, 19, 16, {A_SkullAttack}, 3, 1, S_EGGMOBILE_STND}, // S_EGGMOBILE_PAIN2
{SPR_EGGM, 20, 2, {A_Fall}, 17, 0, S_EGGMOBILE_DIE2}, // S_EGGMOBILE_DIE1
{SPR_EGGM, 20, 2, {A_BossScream}, 0, 0, S_EGGMOBILE_DIE3}, // S_EGGMOBILE_DIE2
{SPR_EGGM, 20, 0, {A_Repeat}, 17, S_EGGMOBILE_DIE2, S_EGGMOBILE_DIE4}, // S_EGGMOBILE_DIE3
{SPR_EGGM, 20, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_EGGMOBILE_DIE4
{SPR_EGGM, 21, 2, {A_BossScream}, 0, 0, S_EGGMOBILE_FLEE2}, // S_EGGMOBILE_FLEE1
{SPR_EGGM, 22, 2, {A_BossScream}, 0, 0, S_EGGMOBILE_FLEE1}, // S_EGGMOBILE_FLEE2
{SPR_UNID, 1, 1, {A_UnidusBall}, 2, 0, S_EGGMOBILE_BALL}, // S_EGGMOBILE_BALL
{SPR_NULL, 0, 1, {A_FocusTarget}, 0, 0, S_EGGMOBILE_TARGET}, // S_EGGMOBILE_TARGET
{SPR_EGLZ, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSEGLZ1
{SPR_EGLZ, 1, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSEGLZ2
// Boss 2
{SPR_EGGN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGMOBILE2_STND
{SPR_EGGN, 1, 4, {NULL}, 0, 0, S_EGGMOBILE2_POGO2}, // S_EGGMOBILE2_POGO1
@ -1240,9 +1260,9 @@ state_t states[NUMSTATES] =
{SPR_EGGN, 6, 2, {A_BossScream}, 0, 0, S_EGGMOBILE2_FLEE2}, // S_EGGMOBILE2_FLEE1
{SPR_EGGN, 7, 2, {A_BossScream}, 0, 0, S_EGGMOBILE2_FLEE1}, // S_EGGMOBILE2_FLEE2
{SPR_TNKA, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSTANK1
{SPR_TNKB, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSTANK2
{SPR_SPNK, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSPIGOT
{SPR_TANK, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSTANK1
{SPR_TANK, 1, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSTANK2
{SPR_TANK, 2, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSPIGOT
// Boss 2 Goop
{SPR_GOOP, 0, 2, {A_SpawnObjectRelative}, 0, MT_GOOPTRAIL, S_GOOP2}, // S_GOOP1
@ -1252,34 +1272,16 @@ state_t states[NUMSTATES] =
// Boss 3
{SPR_EGGO, 0, 1, {NULL}, 0, 0, S_EGGMOBILE3_STND}, // S_EGGMOBILE3_STND
{SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH2}, // S_EGGMOBILE3_LAUGH1
{SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH3}, // S_EGGMOBILE3_LAUGH2
{SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH4}, // S_EGGMOBILE3_LAUGH3
{SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH5}, // S_EGGMOBILE3_LAUGH4
{SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_ATK1}, // S_EGGMOBILE3_LAUGH5
{SPR_EGGO, 1, 2, {NULL}, 0, 0, S_EGGMOBILE3_ATK2}, // S_EGGMOBILE3_ATK1
{SPR_EGGO, FF_ANIMATE, 24, {NULL}, 1, 2, S_EGGMOBILE3_ATK2}, // S_EGGMOBILE3_SHOCK
{SPR_EGGO, 6|FF_ANIMATE, 24, {NULL}, 1, 2, S_EGGMOBILE3_ATK2}, // S_EGGMOBILE3_ATK1
{SPR_EGGO, 2, 2, {NULL}, 0, 0, S_EGGMOBILE3_ATK3A}, // S_EGGMOBILE3_ATK2
{SPR_EGGO, 3, 2, {A_BossFireShot}, MT_TORPEDO, 2, S_EGGMOBILE3_ATK3B}, // S_EGGMOBILE3_ATK3A
{SPR_EGGO, 3, 2, {A_BossFireShot}, MT_TORPEDO, 4, S_EGGMOBILE3_ATK3C}, // S_EGGMOBILE3_ATK3B
{SPR_EGGO, 3, 2, {A_BossFireShot}, MT_TORPEDO, 3, S_EGGMOBILE3_ATK3D}, // S_EGGMOBILE3_ATK3C
{SPR_EGGO, 3, 2, {A_BossFireShot}, MT_TORPEDO, 5, S_EGGMOBILE3_ATK4}, // S_EGGMOBILE3_ATK3D
{SPR_EGGO, 4, 2, {NULL}, 0, 0, S_EGGMOBILE3_ATK5}, // S_EGGMOBILE3_ATK4
{SPR_EGGO, 5, 2, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH6}, // S_EGGMOBILE3_ATK5
{SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH7}, // S_EGGMOBILE3_LAUGH6
{SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH8}, // S_EGGMOBILE3_LAUGH7
{SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH9}, // S_EGGMOBILE3_LAUGH8
{SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH10}, // S_EGGMOBILE3_LAUGH9
{SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH11}, // S_EGGMOBILE3_LAUGH10
{SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH12}, // S_EGGMOBILE3_LAUGH11
{SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH13}, // S_EGGMOBILE3_LAUGH12
{SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH14}, // S_EGGMOBILE3_LAUGH13
{SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH15}, // S_EGGMOBILE3_LAUGH14
{SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH16}, // S_EGGMOBILE3_LAUGH15
{SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH17}, // S_EGGMOBILE3_LAUGH16
{SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH18}, // S_EGGMOBILE3_LAUGH17
{SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH19}, // S_EGGMOBILE3_LAUGH18
{SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH20}, // S_EGGMOBILE3_LAUGH19
{SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_STND}, // S_EGGMOBILE3_LAUGH20
{SPR_EGGO, 5, 2, {NULL}, 0, 0, S_EGGMOBILE3_ROFL}, // S_EGGMOBILE3_ATK5
{SPR_EGGO, 6|FF_ANIMATE, 60, {NULL}, 1, 2, S_EGGMOBILE3_STND}, // S_EGGMOBILE3_ROFL
{SPR_EGGO, 8, 1, {A_Boss3TakeDamage}, 0, 0, S_EGGMOBILE3_PAIN2}, // S_EGGMOBILE3_PAIN
{SPR_EGGO, 8, 23, {A_Pain}, 0, 0, S_EGGMOBILE3_STND}, // S_EGGMOBILE3_PAIN2
{SPR_EGGO, 9, 2, {A_Fall}, 0, 0, S_EGGMOBILE3_DIE2}, // S_EGGMOBILE3_DIE1
@ -1289,17 +1291,8 @@ state_t states[NUMSTATES] =
{SPR_EGGO, 10, 2, {A_BossScream}, 0, 0, S_EGGMOBILE3_FLEE2}, // S_EGGMOBILE3_FLEE1
{SPR_EGGO, 11, 2, {A_BossScream}, 0, 0, S_EGGMOBILE3_FLEE1}, // S_EGGMOBILE3_FLEE2
// Boss 3 Propeller
{SPR_PRPL, 0, 1, {NULL}, 0, 0, S_PROPELLER2}, // S_PROPELLER1
{SPR_PRPL, 1, 1, {NULL}, 0, 0, S_PROPELLER3}, // S_PROPELLER2
{SPR_PRPL, 2, 1, {NULL}, 0, 0, S_PROPELLER4}, // S_PROPELLER3
{SPR_PRPL, 3, 1, {NULL}, 0, 0, S_PROPELLER5}, // S_PROPELLER4
{SPR_PRPL, 4, 1, {NULL}, 0, 0, S_PROPELLER6}, // S_PROPELLER5
{SPR_PRPL, 5, 1, {NULL}, 0, 0, S_PROPELLER7}, // S_PROPELLER6
{SPR_PRPL, 6, 1, {NULL}, 0, 0, S_PROPELLER1}, // S_PROPELLER7
// Boss 3 Pinch
{SPR_FAKE, 0, 1, {A_BossJetFume}, 1, 0, S_FAKEMOBILE}, // S_FAKEMOBILE_INIT
{SPR_FAKE, 0, 1, {NULL}, 0, 0, S_FAKEMOBILE}, // S_FAKEMOBILE_INIT
{SPR_FAKE, 0, 1, {A_Boss3Path}, 0, 0, S_FAKEMOBILE}, // S_FAKEMOBILE
{SPR_FAKE, 0, 22, {NULL}, 0, 0, S_FAKEMOBILE_ATK2}, // S_FAKEMOBILE_ATK1
{SPR_FAKE, 0, 2, {NULL}, 0, 0, S_FAKEMOBILE_ATK3A}, // S_FAKEMOBILE_ATK2
@ -1307,33 +1300,36 @@ state_t states[NUMSTATES] =
{SPR_FAKE, 0, 2, {A_BossFireShot}, MT_TORPEDO2, 4, S_FAKEMOBILE_ATK3C}, // S_FAKEMOBILE_ATK3B
{SPR_FAKE, 0, 2, {A_BossFireShot}, MT_TORPEDO2, 3, S_FAKEMOBILE_ATK3D}, // S_FAKEMOBILE_ATK3C
{SPR_FAKE, 0, 2, {A_BossFireShot}, MT_TORPEDO2, 5, S_FAKEMOBILE}, // S_FAKEMOBILE_ATK3D
{SPR_FAKE, 0, 1, {NULL}, 0, 0, S_FAKEMOBILE_DIE2}, // S_FAKEMOBILE_DIE1
{SPR_FAKE, 1, 1, {NULL}, 0, 0, S_FAKEMOBILE_DIE2}, // S_FAKEMOBILE_DIE1
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_FAKEMOBILE_DIE1}, // S_FAKEMOBILE_DIE2
{SPR_SEBH, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSEBH1
{SPR_SEBH, 1, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSEBH2
// Boss 4
{SPR_EGGP, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGMOBILE4_STND
{SPR_EGGP, 1, 3, {NULL}, 0, 0, S_EGGMOBILE4_LATK2}, // S_EGGMOBILE4_LATK1
{SPR_EGGP, 2, 15, {NULL}, 0, 0, S_EGGMOBILE4_LATK3}, // S_EGGMOBILE4_LATK2
{SPR_EGGP, 3, 2, {NULL}, 0, 0, S_EGGMOBILE4_LATK4}, // S_EGGMOBILE4_LATK3
{SPR_EGGP, 4, 4, {NULL}, 0, 0, S_EGGMOBILE4_LATK5}, // S_EGGMOBILE4_LATK4
{SPR_EGGP, 4, 50, {A_Boss4Reverse}, sfx_mswing, 0, S_EGGMOBILE4_LATK6}, // S_EGGMOBILE4_LATK5
{SPR_EGGP, 5, 2, {NULL}, 0, 0, S_EGGMOBILE4_STND}, // S_EGGMOBILE4_LATK6
{SPR_EGGP, 6, 3, {NULL}, 0, 0, S_EGGMOBILE4_RATK2}, // S_EGGMOBILE4_RATK1
{SPR_EGGP, 7, 15, {NULL}, 0, 0, S_EGGMOBILE4_RATK3}, // S_EGGMOBILE4_RATK2
{SPR_EGGP, 8, 2, {NULL}, 0, 0, S_EGGMOBILE4_RATK4}, // S_EGGMOBILE4_RATK3
{SPR_EGGP, 9, 4, {NULL}, 0, 0, S_EGGMOBILE4_RATK5}, // S_EGGMOBILE4_RATK4
{SPR_EGGP, 9,150, {A_Boss4SpeedUp}, sfx_mswing, 0, S_EGGMOBILE4_RATK6}, // S_EGGMOBILE4_RATK5
{SPR_EGGP,10, 2, {NULL}, 0, 0, S_EGGMOBILE4_STND}, // S_EGGMOBILE4_RATK6
{SPR_EGGP, 0, 20, {A_Boss4Raise}, sfx_doord1, 0, S_EGGMOBILE4_RAISE2}, // S_EGGMOBILE4_RAISE1
{SPR_EGGP,13|FF_ANIMATE, -1, {NULL}, 1, 10, S_NULL}, // S_EGGMOBILE4_RAISE2
{SPR_EGGP,11, 0, {A_Boss4Reverse}, sfx_alarm, sfx_s3k60, S_EGGMOBILE4_PAIN2}, // S_EGGMOBILE4_PAIN1
{SPR_EGGP,11, 24, {A_Pain}, 0, 0, S_EGGMOBILE4_STND}, // S_EGGMOBILE4_PAIN2
{SPR_EGGP,12, 2, {A_Fall}, 0, 0, S_EGGMOBILE4_DIE2}, // S_EGGMOBILE4_DIE1
{SPR_EGGP,12, 2, {A_BossScream}, 0, 0, S_EGGMOBILE4_DIE3}, // S_EGGMOBILE4_DIE2
{SPR_EGGP,12, 0, {A_Repeat}, 17, S_EGGMOBILE4_DIE2, S_EGGMOBILE4_DIE4}, // S_EGGMOBILE4_DIE3
{SPR_EGGP,12, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_EGGMOBILE4_DIE4
{SPR_EGGP,13, 2, {A_BossScream}, 0, 0, S_EGGMOBILE4_FLEE2}, // S_EGGMOBILE4_FLEE1
{SPR_EGGP,14, 2, {A_BossScream}, 0, 0, S_EGGMOBILE4_FLEE1}, // S_EGGMOBILE4_FLEE2
{SPR_EGGP, 4, 2, {NULL}, 0, 0, S_EGGMOBILE4_LATK5}, // S_EGGMOBILE4_LATK4
{SPR_EGGP, 5, 50, {A_Boss4Reverse}, sfx_mswing, 0, S_EGGMOBILE4_LATK6}, // S_EGGMOBILE4_LATK5
{SPR_EGGP, 6, 2, {NULL}, 0, 0, S_EGGMOBILE4_STND}, // S_EGGMOBILE4_LATK6
{SPR_EGGP, 7, 3, {NULL}, 0, 0, S_EGGMOBILE4_RATK2}, // S_EGGMOBILE4_RATK1
{SPR_EGGP, 8, 15, {NULL}, 0, 0, S_EGGMOBILE4_RATK3}, // S_EGGMOBILE4_RATK2
{SPR_EGGP, 9, 2, {NULL}, 0, 0, S_EGGMOBILE4_RATK4}, // S_EGGMOBILE4_RATK3
{SPR_EGGP,10, 2, {NULL}, 0, 0, S_EGGMOBILE4_RATK5}, // S_EGGMOBILE4_RATK4
{SPR_EGGP,11,150, {A_Boss4SpeedUp}, sfx_mswing, 0, S_EGGMOBILE4_RATK6}, // S_EGGMOBILE4_RATK5
{SPR_EGGP,12, 2, {NULL}, 0, 0, S_EGGMOBILE4_STND}, // S_EGGMOBILE4_RATK6
{SPR_EGGP,13, 20, {A_Boss4Raise}, sfx_doord1, 0, S_EGGMOBILE4_RAISE2}, // S_EGGMOBILE4_RAISE1
{SPR_EGGP,15|FF_ANIMATE, -1, {NULL}, 1, 10, S_NULL}, // S_EGGMOBILE4_RAISE2
{SPR_EGGP,13, 0, {A_Boss4Reverse}, sfx_alarm, sfx_s3k60, S_EGGMOBILE4_PAIN2}, // S_EGGMOBILE4_PAIN1
{SPR_EGGP,13, 24, {A_Pain}, 0, 0, S_EGGMOBILE4_STND}, // S_EGGMOBILE4_PAIN2
{SPR_EGGP,14, 2, {A_Fall}, 0, 0, S_EGGMOBILE4_DIE2}, // S_EGGMOBILE4_DIE1
{SPR_EGGP,14, 2, {A_BossScream}, 0, 0, S_EGGMOBILE4_DIE3}, // S_EGGMOBILE4_DIE2
{SPR_EGGP,14, 0, {A_Repeat}, 17, S_EGGMOBILE4_DIE2, S_EGGMOBILE4_DIE4}, // S_EGGMOBILE4_DIE3
{SPR_EGGP,14, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_EGGMOBILE4_DIE4
{SPR_EGGP,15, 2, {A_BossScream}, 0, 0, S_EGGMOBILE4_FLEE2}, // S_EGGMOBILE4_FLEE1
{SPR_EGGP,16, 2, {A_BossScream}, 0, 0, S_EGGMOBILE4_FLEE1}, // S_EGGMOBILE4_FLEE2
{SPR_BMCE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGMOBILE4_MACE
{SPR_BMCE, 0, 2, {A_BossScream}, 1, 0, S_EGGMOBILE4_MACE_DIE2}, // S_EGGMOBILE4_MACE_DIE1
{SPR_NULL, 0, 2, {A_BossScream}, 1, 0, S_EGGMOBILE4_MACE_DIE3}, // S_EGGMOBILE4_MACE_DIE2
@ -1732,18 +1728,8 @@ state_t states[NUMSTATES] =
{SPR_METL, 11, 1, {A_BossScream}, 0, 0, S_METALSONIC_FLEE2}, // S_METALSONIC_FLEE1
{SPR_METL, 11, 7, {NULL}, 0, 0, S_METALSONIC_FLEE1}, // S_METALSONIC_FLEE2
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 0, 1, {NULL}, 0, 0, S_MSSHIELD_F2}, // S_MSSHIELD_F1
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 1, 1, {NULL}, 0, 0, S_MSSHIELD_F3}, // S_MSSHIELD_F2
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 2, 1, {NULL}, 0, 0, S_MSSHIELD_F4}, // S_MSSHIELD_F3
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 3, 1, {NULL}, 0, 0, S_MSSHIELD_F5}, // S_MSSHIELD_F4
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 4, 1, {NULL}, 0, 0, S_MSSHIELD_F6}, // S_MSSHIELD_F5
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 5, 1, {NULL}, 0, 0, S_MSSHIELD_F7}, // S_MSSHIELD_F6
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 6, 1, {NULL}, 0, 0, S_MSSHIELD_F8}, // S_MSSHIELD_F7
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 7, 1, {NULL}, 0, 0, S_MSSHIELD_F9}, // S_MSSHIELD_F8
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 8, 1, {NULL}, 0, 0, S_MSSHIELD_F10}, // S_MSSHIELD_F9
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 9, 1, {NULL}, 0, 0, S_MSSHIELD_F11}, // S_MSSHIELD_F10
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30|10, 1, {NULL}, 0, 0, S_MSSHIELD_F12}, // S_MSSHIELD_F11
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30|11, 1, {NULL}, 0, 0, S_MSSHIELD_F1}, // S_MSSHIELD_F12
{SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30|FF_ANIMATE, -1, {NULL}, 11, 1, S_NULL}, // S_MSSHIELD_F1
{SPR_MSCF, FF_FULLBRIGHT|FF_ANIMATE|12, -1, {NULL}, 8, 2, S_NULL}, // S_MSSHIELD_F2
// Ring
{SPR_RING, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_RING}, // S_RING
@ -2178,14 +2164,12 @@ state_t states[NUMSTATES] =
{SPR_DRIP, FF_TRANS30|4, 1, {NULL}, 0, 0, S_DRIPC2}, // S_DRIPC1
{SPR_DRIP, FF_TRANS30|5, 1, {NULL}, 0, 0, S_NULL}, // S_DRIPC2
// Coral 1
{SPR_CRL1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CORAL1
// Coral 2
{SPR_CRL2, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CORAL2
// Coral 3
{SPR_CRL3, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CORAL3
// Coral
{SPR_CORL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CORAL1
{SPR_CORL, 1, -1, {NULL}, 0, 0, S_NULL}, // S_CORAL2
{SPR_CORL, 2, -1, {NULL}, 0, 0, S_NULL}, // S_CORAL3
{SPR_CORL, 3, -1, {NULL}, 0, 0, S_NULL}, // S_CORAL4
{SPR_CORL, 4, -1, {NULL}, 0, 0, S_NULL}, // S_CORAL5
// Blue Crystal
{SPR_BCRY, FF_TRANS30, -1, {NULL}, 0, 0, S_NULL}, // S_BLUECRYSTAL1
@ -2193,6 +2177,11 @@ state_t states[NUMSTATES] =
// Kelp
{SPR_KELP, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KELP
// Animated algae
{SPR_ALGA, 0, 1, {A_ConnectToGround}, MT_ANIMALGAESEG, 0, S_ANIMALGAETOP2}, // S_ANIMALGAETOP1
{SPR_ALGA, 0|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 11, 4, S_NULL}, // S_ANIMALGAETOP2
{SPR_ALGB, 0|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 11, 4, S_NULL}, // S_ANIMALGAESEG
// DSZ Stalagmites
{SPR_DSTG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_DSZSTALAGMITE
{SPR_DSTG, 1, -1, {NULL}, 0, 0, S_NULL}, // S_DSZ2STALAGMITE
@ -2337,16 +2326,20 @@ state_t states[NUMSTATES] =
{SPR_STBL, 6, 5, {NULL}, 0, 0, S_LITTLETUMBLEWEED_ROLL8}, // S_LITTLETUMBLEWEED_ROLL7
{SPR_STBL, 7, 5, {NULL}, 0, 0, S_LITTLETUMBLEWEED_ROLL1}, // S_LITTLETUMBLEWEED_ROLL8
// Cacti Sprites
{SPR_CACT, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI1
{SPR_CACT, 1, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI2
{SPR_CACT, 2, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI3
{SPR_CACT, 3, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI4
// Cacti
{SPR_CACT, 0, -1, {A_ConnectToGround}, MT_CACTITINYSEG, 0, S_NULL}, // S_CACTI1
{SPR_CACT, 1, -1, {A_ConnectToGround}, MT_CACTISMALLSEG, 0, S_NULL}, // S_CACTI2
{SPR_CACT, 2, -1, {A_ConnectToGround}, MT_CACTITINYSEG, 0, S_NULL}, // S_CACTI3
{SPR_CACT, 3, -1, {A_ConnectToGround}, MT_CACTISMALLSEG, 0, S_NULL}, // S_CACTI4
{SPR_CACT, 4, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI5
{SPR_CACT, 5, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI6
{SPR_CACT, 6, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI7
{SPR_CACT, 7, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI8
{SPR_CACT, 8, -1, {NULL}, 0, 0, S_NULL}, // S_CACTI9
{SPR_CACT, 9, -1, {A_ConnectToGround}, MT_CACTITINYSEG, 0, S_NULL}, // S_CACTI10
{SPR_CACT, 10, -1, {A_ConnectToGround}, MT_CACTISMALLSEG, 0, S_NULL}, // S_CACTI11
{SPR_CACT, 11, -1, {NULL}, 0, 0, S_NULL}, // S_CACTITINYSEG
{SPR_CACT, 12, -1, {NULL}, 0, 0, S_NULL}, // S_CACTISMALLSEG
// Warning Signs
{SPR_WWSG, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_ARIDSIGN_CAUTION
@ -5144,6 +5137,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_BOSSJUNK
-1, // doomednum
S_BOSSEGLZ1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
64*FRACUNIT, // height
2, // display offset
100, // mass
1, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
},
{ // MT_EGGMOBILE
200, // doomednum
S_EGGMOBILE_STND, // spawnstate
@ -5333,87 +5353,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_EGGMOBILE2_POGO5 // raisestate
},
{ // MT_BOSSTANK1
-1, // doomednum
S_BOSSTANK1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
64*FRACUNIT, // height
0, // display offset
100, // mass
1, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
},
{ // MT_BOSSTANK2
-1, // doomednum
S_BOSSTANK2, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
64*FRACUNIT, // height
0, // display offset
100, // mass
1, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
},
{ // MT_BOSSSPIGOT
-1, // doomednum
S_BOSSSPIGOT, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
24*FRACUNIT, // height
0, // display offset
100, // mass
1, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
},
{ // MT_GOOP
-1, // doomednum
S_GOOP1, // spawnstate
@ -5477,10 +5416,10 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // reactiontime
sfx_None, // attacksound
S_EGGMOBILE3_PAIN, // painstate
MT_PROPELLER, // painchance
MT_NULL, // painchance
sfx_dmpain, // painsound
S_NULL, // meleestate
S_EGGMOBILE3_LAUGH1,// missilestate
S_EGGMOBILE3_SHOCK, // missilestate
S_EGGMOBILE3_DIE1, // deathstate
S_EGGMOBILE3_FLEE1, // xdeathstate
sfx_s3kb4, // deathsound
@ -5492,34 +5431,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
3, // damage
sfx_telept, // activesound
MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY|MF_BOSS|MF_NOCLIPHEIGHT, // flags
S_EGGMOBILE3_LAUGH20 // raisestate
},
{ // MT_PROPELLER
-1, // doomednum
S_PROPELLER1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
1, // speed
4*FRACUNIT, // radius
4*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
S_EGGMOBILE3_ROFL // raisestate
},
{ // MT_FAKEMOBILE
@ -5531,7 +5443,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
MT_PROPELLER, // painchance
MT_NULL, // painchance
sfx_s3k7b, // painsound
S_NULL, // meleestate
S_FAKEMOBILE_ATK1, // missilestate
@ -6592,8 +6504,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
16*FRACUNIT, // height
16*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
100, // mass
1, // damage
@ -6673,8 +6585,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_ncitem, // deathsound
1, // speed
8*FRACUNIT, // radius
16*FRACUNIT, // height
16*FRACUNIT, // radius
30*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
@ -9211,7 +9123,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // mass
20, // damage
sfx_None, // activesound
MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags
S_NULL // raisestate
},
@ -10177,8 +10089,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
16*FRACUNIT, // height
29*FRACUNIT, // radius
40*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
@ -10204,8 +10116,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
16*FRACUNIT, // height
30*FRACUNIT, // radius
53*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
@ -10231,8 +10143,62 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
16*FRACUNIT, // height
28*FRACUNIT, // radius
41*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_CORAL4
1014, // doomednum
S_CORAL4, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
56*FRACUNIT, // radius
112*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_CORAL5
1015, // doomednum
S_CORAL5, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
56*FRACUNIT, // radius
112*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
@ -10295,6 +10261,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_ANIMALGAETOP
1013, // doomednum
S_ANIMALGAETOP1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
48*FRACUNIT, // radius
120*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
sfx_None, // activesound
MF_NOCLIP|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags
S_NULL // raisestate
},
{ // MT_ANIMALGAESEG
-1, // doomednum
S_ANIMALGAESEG, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
48*FRACUNIT, // radius
120*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
sfx_None, // activesound
MF_NOCLIP|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_DSZSTALAGMITE
1008, // doomednum
S_DSZSTALAGMITE,// spawnstate
@ -11554,13 +11574,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
13*FRACUNIT, // radius
24*FRACUNIT, // height
0, // display offset
100, // mass
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
MF_SCENERY|MF_PAIN|MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags
S_NULL // raisestate
},
@ -11581,13 +11601,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
64*FRACUNIT, // height
15*FRACUNIT, // radius
52*FRACUNIT, // height
0, // display offset
100, // mass
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
MF_SCENERY|MF_PAIN|MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags
S_NULL // raisestate
},
@ -11608,13 +11628,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
13*FRACUNIT, // radius
24*FRACUNIT, // height
0, // display offset
100, // mass
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
MF_SCENERY|MF_PAIN|MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags
S_NULL // raisestate
},
@ -11635,13 +11655,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
80*FRACUNIT, // height
15*FRACUNIT, // radius
52*FRACUNIT, // height
0, // display offset
100, // mass
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
MF_SCENERY|MF_PAIN|MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags
S_NULL // raisestate
},
@ -11665,7 +11685,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
32*FRACUNIT, // radius
96*FRACUNIT, // height
0, // display offset
100, // mass
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SCENERY|MF_PAIN, // flags
@ -11692,7 +11712,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
20*FRACUNIT, // radius
128*FRACUNIT, // height
0, // display offset
100, // mass
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SCENERY|MF_PAIN, // flags
@ -11719,7 +11739,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
24*FRACUNIT, // radius
224*FRACUNIT, // height
0, // display offset
100, // mass
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SCENERY|MF_PAIN, // flags
@ -11746,7 +11766,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
24*FRACUNIT, // radius
256*FRACUNIT, // height
0, // display offset
100, // mass
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SCENERY|MF_PAIN, // flags
@ -11773,13 +11793,121 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
48*FRACUNIT, // radius
96*FRACUNIT, // height
0, // display offset
100, // mass
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SCENERY|MF_PAIN, // flags
S_NULL // raisestate
},
{ // MT_CACTI10
1230, // doomednum
S_CACTI10, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
13*FRACUNIT, // radius
28*FRACUNIT, // height
0, // display offset
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_PAIN|MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags
S_NULL // raisestate
},
{ // MT_CACTI11
1231, // doomednum
S_CACTI11, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
15*FRACUNIT, // radius
60*FRACUNIT, // height
0, // display offset
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_PAIN|MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags
S_NULL // raisestate
},
{ // MT_CACTITINYSEG
-1, // doomednum
S_CACTITINYSEG, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
13*FRACUNIT, // radius
28*FRACUNIT, // height
0, // display offset
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_SCENERY|MF_PAIN|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_CACTISMALLSEG
-1, // doomednum
S_CACTISMALLSEG, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
15*FRACUNIT, // radius
60*FRACUNIT, // height
0, // display offset
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_SCENERY|MF_PAIN|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_ARIDSIGN_CAUTION
1212, // doomednum
S_ARIDSIGN_CAUTION, // spawnstate

View file

@ -319,18 +319,17 @@ typedef enum sprite
SPR_JETF, // Boss jet fumes
// Boss 1 (Greenflower)
SPR_EGGM,
SPR_EGGM, // Boss 1
SPR_EGLZ, // Boss 1 Junk
// Boss 2 (Techno Hill)
SPR_EGGN, // Boss 2
SPR_TNKA, // Boss 2 Tank 1
SPR_TNKB, // Boss 2 Tank 2
SPR_SPNK, // Boss 2 Spigot
SPR_TANK, // Boss 2 Junk
SPR_GOOP, // Boss 2 Goop
// Boss 3 (Deep Sea)
SPR_EGGO, // Boss 3
SPR_PRPL, // Boss 3 Propeller
SPR_SEBH, // Boss 3 Junk
SPR_FAKE, // Boss 3 Fakemobile
// Boss 4 (Castle Eggman)
@ -459,11 +458,11 @@ typedef enum sprite
SPR_GARG, // Deep Sea Gargoyle
SPR_SEWE, // Deep Sea Seaweed
SPR_DRIP, // Dripping water
SPR_CRL1, // Coral 1
SPR_CRL2, // Coral 2
SPR_CRL3, // Coral 3
SPR_CORL, // Coral
SPR_BCRY, // Blue Crystal
SPR_KELP, // Kelp
SPR_ALGA, // Animated algae top
SPR_ALGB, // Animated algae segment
SPR_DSTG, // DSZ Stalagmites
SPR_LIBE, // DSZ Light beam
@ -493,7 +492,7 @@ typedef enum sprite
// Arid Canyon Scenery
SPR_BTBL, // Big tumbleweed
SPR_STBL, // Small tumbleweed
SPR_CACT, // Cacti sprites
SPR_CACT, // Cacti
SPR_WWSG, // Caution Sign
SPR_WWS2, // Cacti Sign
SPR_WWS3, // Sharp Turn Sign
@ -833,9 +832,15 @@ typedef enum playersprite
SPR2_TALA,
SPR2_TALB,
SPR2_CNT1, // continue disappointment
SPR2_CNT2, // continue lift
SPR2_CNT3, // continue spin
SPR2_CNT4, // continue "soooooooniiic!" tugging
SPR2_SIGN, // end sign head
SPR2_LIFE, // life monitor icon
SPR2_XTRA, // stuff that isn't in-game - keep this last in the list
SPR2_XTRA, // stuff that isn't in-map - "would this ever need an md2 or variable length animation?"
SPR2_FIRSTFREESLOT,
SPR2_LASTFREESLOT = 0x7f,
@ -1333,10 +1338,10 @@ typedef enum state
S_SONIC3KBOSSEXPLOSION6,
S_JETFUME1,
S_JETFUME2,
// Boss 1
S_EGGMOBILE_STND,
S_EGGMOBILE_ROFL,
S_EGGMOBILE_LATK1,
S_EGGMOBILE_LATK2,
S_EGGMOBILE_LATK3,
@ -1346,7 +1351,6 @@ typedef enum state
S_EGGMOBILE_LATK7,
S_EGGMOBILE_LATK8,
S_EGGMOBILE_LATK9,
S_EGGMOBILE_LATK10,
S_EGGMOBILE_RATK1,
S_EGGMOBILE_RATK2,
S_EGGMOBILE_RATK3,
@ -1356,7 +1360,6 @@ typedef enum state
S_EGGMOBILE_RATK7,
S_EGGMOBILE_RATK8,
S_EGGMOBILE_RATK9,
S_EGGMOBILE_RATK10,
S_EGGMOBILE_PANIC1,
S_EGGMOBILE_PANIC2,
S_EGGMOBILE_PANIC3,
@ -1364,6 +1367,14 @@ typedef enum state
S_EGGMOBILE_PANIC5,
S_EGGMOBILE_PANIC6,
S_EGGMOBILE_PANIC7,
S_EGGMOBILE_PANIC8,
S_EGGMOBILE_PANIC9,
S_EGGMOBILE_PANIC10,
S_EGGMOBILE_PANIC11,
S_EGGMOBILE_PANIC12,
S_EGGMOBILE_PANIC13,
S_EGGMOBILE_PANIC14,
S_EGGMOBILE_PANIC15,
S_EGGMOBILE_PAIN,
S_EGGMOBILE_PAIN2,
S_EGGMOBILE_DIE1,
@ -1375,6 +1386,9 @@ typedef enum state
S_EGGMOBILE_BALL,
S_EGGMOBILE_TARGET,
S_BOSSEGLZ1,
S_BOSSEGLZ2,
// Boss 2
S_EGGMOBILE2_STND,
S_EGGMOBILE2_POGO1,
@ -1405,11 +1419,7 @@ typedef enum state
// Boss 3
S_EGGMOBILE3_STND,
S_EGGMOBILE3_LAUGH1,
S_EGGMOBILE3_LAUGH2,
S_EGGMOBILE3_LAUGH3,
S_EGGMOBILE3_LAUGH4,
S_EGGMOBILE3_LAUGH5,
S_EGGMOBILE3_SHOCK,
S_EGGMOBILE3_ATK1,
S_EGGMOBILE3_ATK2,
S_EGGMOBILE3_ATK3A,
@ -1418,21 +1428,7 @@ typedef enum state
S_EGGMOBILE3_ATK3D,
S_EGGMOBILE3_ATK4,
S_EGGMOBILE3_ATK5,
S_EGGMOBILE3_LAUGH6,
S_EGGMOBILE3_LAUGH7,
S_EGGMOBILE3_LAUGH8,
S_EGGMOBILE3_LAUGH9,
S_EGGMOBILE3_LAUGH10,
S_EGGMOBILE3_LAUGH11,
S_EGGMOBILE3_LAUGH12,
S_EGGMOBILE3_LAUGH13,
S_EGGMOBILE3_LAUGH14,
S_EGGMOBILE3_LAUGH15,
S_EGGMOBILE3_LAUGH16,
S_EGGMOBILE3_LAUGH17,
S_EGGMOBILE3_LAUGH18,
S_EGGMOBILE3_LAUGH19,
S_EGGMOBILE3_LAUGH20,
S_EGGMOBILE3_ROFL,
S_EGGMOBILE3_PAIN,
S_EGGMOBILE3_PAIN2,
S_EGGMOBILE3_DIE1,
@ -1442,15 +1438,6 @@ typedef enum state
S_EGGMOBILE3_FLEE1,
S_EGGMOBILE3_FLEE2,
// Boss 3 Propeller
S_PROPELLER1,
S_PROPELLER2,
S_PROPELLER3,
S_PROPELLER4,
S_PROPELLER5,
S_PROPELLER6,
S_PROPELLER7,
// Boss 3 Pinch
S_FAKEMOBILE_INIT,
S_FAKEMOBILE,
@ -1463,6 +1450,9 @@ typedef enum state
S_FAKEMOBILE_DIE1,
S_FAKEMOBILE_DIE2,
S_BOSSSEBH1,
S_BOSSSEBH2,
// Boss 4
S_EGGMOBILE4_STND,
S_EGGMOBILE4_LATK1,
@ -1866,16 +1856,6 @@ typedef enum state
S_MSSHIELD_F1,
S_MSSHIELD_F2,
S_MSSHIELD_F3,
S_MSSHIELD_F4,
S_MSSHIELD_F5,
S_MSSHIELD_F6,
S_MSSHIELD_F7,
S_MSSHIELD_F8,
S_MSSHIELD_F9,
S_MSSHIELD_F10,
S_MSSHIELD_F11,
S_MSSHIELD_F12,
// Ring
S_RING,
@ -2309,14 +2289,12 @@ typedef enum state
S_DRIPC1,
S_DRIPC2,
// Coral 1
// Coral
S_CORAL1,
// Coral 2
S_CORAL2,
// Coral 3
S_CORAL3,
S_CORAL4,
S_CORAL5,
// Blue Crystal
S_BLUECRYSTAL1,
@ -2324,6 +2302,11 @@ typedef enum state
// Kelp,
S_KELP,
// Animated algae
S_ANIMALGAETOP1,
S_ANIMALGAETOP2,
S_ANIMALGAESEG,
// DSZ Stalagmites
S_DSZSTALAGMITE,
S_DSZ2STALAGMITE,
@ -2458,7 +2441,7 @@ typedef enum state
S_LITTLETUMBLEWEED_ROLL7,
S_LITTLETUMBLEWEED_ROLL8,
// Cacti Sprites
// Cacti
S_CACTI1,
S_CACTI2,
S_CACTI3,
@ -2468,8 +2451,12 @@ typedef enum state
S_CACTI7,
S_CACTI8,
S_CACTI9,
S_CACTI10,
S_CACTI11,
S_CACTITINYSEG,
S_CACTISMALLSEG,
// Warning signs sprites
// Warning signs
S_ARIDSIGN_CAUTION,
S_ARIDSIGN_CACTI,
S_ARIDSIGN_SHARPTURN,
@ -3981,6 +3968,7 @@ typedef enum mobj_type
MT_EGGTRAP,
MT_BOSS3WAYPOINT,
MT_BOSS9GATHERPOINT,
MT_BOSSJUNK,
// Boss 1
MT_EGGMOBILE,
@ -3992,15 +3980,11 @@ typedef enum mobj_type
// Boss 2
MT_EGGMOBILE2,
MT_EGGMOBILE2_POGO,
MT_BOSSTANK1,
MT_BOSSTANK2,
MT_BOSSSPIGOT,
MT_GOOP,
MT_GOOPTRAIL,
// Boss 3
MT_EGGMOBILE3,
MT_PROPELLER,
MT_FAKEMOBILE,
MT_SHOCK,
@ -4211,11 +4195,15 @@ typedef enum mobj_type
MT_SEAWEED, // DSZ Seaweed
MT_WATERDRIP, // Dripping Water source
MT_WATERDROP, // Water drop from dripping water
MT_CORAL1, // Coral 1
MT_CORAL2, // Coral 2
MT_CORAL3, // Coral 3
MT_CORAL1, // Coral
MT_CORAL2,
MT_CORAL3,
MT_CORAL4,
MT_CORAL5,
MT_BLUECRYSTAL, // Blue Crystal
MT_KELP, // Kelp
MT_ANIMALGAETOP, // Animated algae top
MT_ANIMALGAESEG, // Animated algae segment
MT_DSZSTALAGMITE, // Deep Sea 1 Stalagmite
MT_DSZ2STALAGMITE, // Deep Sea 2 Stalagmite
MT_LIGHTBEAM, // DSZ Light beam
@ -4266,15 +4254,19 @@ typedef enum mobj_type
// Arid Canyon Scenery
MT_BIGTUMBLEWEED,
MT_LITTLETUMBLEWEED,
MT_CACTI1,
MT_CACTI2,
MT_CACTI3,
MT_CACTI4,
MT_CACTI5, // Harmful Cactus 1
MT_CACTI6, // Harmful Cactus 2
MT_CACTI7, // Harmful Cactus 3
MT_CACTI8, // Harmful Cactus 4
MT_CACTI9, // Harmful Cactus 5
MT_CACTI1, // Tiny Red Flower Cactus
MT_CACTI2, // Small Red Flower Cactus
MT_CACTI3, // Tiny Blue Flower Cactus
MT_CACTI4, // Small Blue Flower Cactus
MT_CACTI5, // Prickly Pear
MT_CACTI6, // Barrel Cactus
MT_CACTI7, // Tall Barrel Cactus
MT_CACTI8, // Armed Cactus
MT_CACTI9, // Ball Cactus
MT_CACTI10, // Tiny Cactus
MT_CACTI11, // Small Cactus
MT_CACTITINYSEG, // Tiny Cactus Segment
MT_CACTISMALLSEG, // Small Cactus Segment
MT_ARIDSIGN_CAUTION, // Caution Sign
MT_ARIDSIGN_CACTI, // Cacti Sign
MT_ARIDSIGN_SHARPTURN, // Sharp Turn Sign

View file

@ -182,6 +182,8 @@ static const struct {
{META_CAMERA, "camera_t"},
{META_ACTION, "action"},
{META_LUABANKS, "luabanks[]"},
{NULL, NULL}
};
@ -228,6 +230,18 @@ static int lib_isPlayerAdmin(lua_State *L)
return 1;
}
static int lib_reserveLuabanks(lua_State *L)
{
static boolean reserved = false;
if (!lua_lumploading)
return luaL_error(L, "luabanks[] cannot be reserved from within a hook or coroutine!");
if (reserved)
return luaL_error(L, "luabanks[] has already been reserved! Only one savedata-enabled mod at a time may use this feature.");
reserved = true;
LUA_PushUserdata(L, &luabanks, META_LUABANKS);
return 1;
}
// M_RANDOM
//////////////
@ -2736,6 +2750,7 @@ static luaL_Reg lib[] = {
{"chatprintf", lib_chatprintf},
{"userdataType", lib_userdataType},
{"IsPlayerAdmin", lib_isPlayerAdmin},
{"reserveLuabanks", lib_reserveLuabanks},
// m_random
{"P_RandomFixed",lib_pRandomFixed},

View file

@ -18,6 +18,7 @@
#include "p_mobj.h"
#include "p_local.h"
#include "z_zone.h"
#include "doomstat.h" // luabanks[]
#include "lua_script.h"
#include "lua_libs.h"
@ -146,7 +147,7 @@ static int lib_getSpr2default(lua_State *L)
return luaL_error(L, "spr2defaults[] invalid index");
if (i >= free_spr2)
return 0;
return luaL_error(L, "spr2defaults[] index %d out of range (%d - %d)", i, 0, free_spr2-1);
lua_pushinteger(L, spr2defaults[i]);
return 1;
@ -1026,6 +1027,61 @@ static int sfxinfo_num(lua_State *L)
return 1;
}
//////////////
// LUABANKS //
//////////////
static int lib_getluabanks(lua_State *L)
{
UINT8 i;
lua_remove(L, 1); // don't care about luabanks[] dummy userdata.
if (lua_isnumber(L, 1))
i = lua_tonumber(L, 1);
else
return luaL_error(L, "luabanks[] invalid index");
if (i >= NUM_LUABANKS)
luaL_error(L, "luabanks[] index %d out of range (%d - %d)", i, 0, NUM_LUABANKS-1);
lua_pushinteger(L, luabanks[i]);
return 1;
}
static int lib_setluabanks(lua_State *L)
{
UINT8 i;
INT32 j = 0;
if (hud_running)
return luaL_error(L, "Do not alter luabanks[] in HUD rendering code!");
lua_remove(L, 1); // don't care about luabanks[] dummy userdata.
if (lua_isnumber(L, 1))
i = lua_tonumber(L, 1);
else
return luaL_error(L, "luabanks[] invalid index");
if (i >= NUM_LUABANKS)
luaL_error(L, "luabanks[] index %d out of range (%d - %d)", i, 0, NUM_LUABANKS-1);
if (lua_isnumber(L, 2))
j = lua_tonumber(L, 2);
else
return luaL_error(L, "luabanks[] invalid set");
luabanks[i] = j;
return 0;
}
static int lib_luabankslen(lua_State *L)
{
lua_pushinteger(L, NUM_LUABANKS);
return 1;
}
//////////////////////////////
//
// Now push all these functions into the Lua state!
@ -1147,6 +1203,18 @@ int LUA_InfoLib(lua_State *L)
lua_pushvalue(L, -1);
lua_setglobal(L, "S_sfx");
lua_setglobal(L, "sfxinfo");
luaL_newmetatable(L, META_LUABANKS);
lua_pushcfunction(L, lib_getluabanks);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lib_setluabanks);
lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, lib_luabankslen);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
return 0;
}

View file

@ -67,6 +67,8 @@ extern lua_State *gL;
#define META_ACTION "ACTIONF_T*"
#define META_LUABANKS "LUABANKS[]*"
boolean luaL_checkboolean(lua_State *L, int narg);
int LUA_EnumLib(lua_State *L);

View file

@ -2017,6 +2017,8 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->muspostbosspos);
else if (fastcmp(field,"muspostbossfadein"))
lua_pushinteger(L, header->muspostbossfadein);
else if (fastcmp(field,"musforcereset"))
lua_pushinteger(L, header->musforcereset);
else if (fastcmp(field,"forcecharacter"))
lua_pushstring(L, header->forcecharacter);
else if (fastcmp(field,"weather"))

View file

@ -262,6 +262,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->starposttime);
else if (fastcmp(field,"starpostangle"))
lua_pushangle(L, plr->starpostangle);
else if (fastcmp(field,"starpostscale"))
lua_pushfixed(L, plr->starpostscale);
else if (fastcmp(field,"angle_pos"))
lua_pushangle(L, plr->angle_pos);
else if (fastcmp(field,"old_angle_pos"))
@ -570,6 +572,8 @@ static int player_set(lua_State *L)
plr->starposttime = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"starpostangle"))
plr->starpostangle = luaL_checkangle(L, 3);
else if (fastcmp(field,"starpostscale"))
plr->starpostscale = luaL_checkfixed(L, 3);
else if (fastcmp(field,"angle_pos"))
plr->angle_pos = luaL_checkangle(L, 3);
else if (fastcmp(field,"old_angle_pos"))

View file

@ -52,6 +52,8 @@ enum skin {
skin_supercolor,
skin_prefoppositecolor,
skin_highresscale,
skin_contspeed,
skin_contangle,
skin_soundsid,
skin_availability
};
@ -88,6 +90,8 @@ static const char *const skin_opt[] = {
"supercolor",
"prefoppositecolor",
"highresscale",
"contspeed",
"contangle",
"soundsid",
"availability",
NULL};
@ -199,6 +203,12 @@ static int skin_get(lua_State *L)
case skin_highresscale:
lua_pushinteger(L, skin->highresscale);
break;
case skin_contspeed:
lua_pushinteger(L, skin->contspeed);
break;
case skin_contangle:
lua_pushinteger(L, skin->contangle);
break;
case skin_soundsid:
LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID);
break;

View file

@ -831,6 +831,12 @@ void Command_Savecheckpoint_f(void)
players[consoleplayer].starposty = players[consoleplayer].mo->y>>FRACBITS;
players[consoleplayer].starpostz = players[consoleplayer].mo->floorz>>FRACBITS;
players[consoleplayer].starpostangle = players[consoleplayer].mo->angle;
players[consoleplayer].starpostscale = players[consoleplayer].mo->destscale;
if (players[consoleplayer].mo->flags2 & MF2_OBJECTFLIP)
{
players[consoleplayer].starpostscale *= -1;
players[consoleplayer].starpostz += players[consoleplayer].mo->height;
}
CONS_Printf(M_GetText("Temporary checkpoint created at %d, %d, %d\n"), players[consoleplayer].starpostx, players[consoleplayer].starposty, players[consoleplayer].starpostz);
}

View file

@ -125,7 +125,7 @@ const char *quitmsg[NUM_QUITMESSAGES];
// Stuff for customizing the player select screen Tails 09-22-2003
description_t description[MAXSKINS];
INT16 char_on = -1, startchar = 1;
INT16 char_on = -1, startchar = 0;
static char *char_notes = NULL;
static fixed_t char_scroll = 0;
@ -272,6 +272,7 @@ static void M_ServerOptions(INT32 choice);
#ifndef NONET
static void M_StartServerMenu(INT32 choice);
static void M_ConnectMenu(INT32 choice);
static void M_ConnectMenuModChecks(INT32 choice);
static void M_Refresh(INT32 choice);
static void M_Connect(INT32 choice);
static void M_ChooseRoom(INT32 choice);
@ -282,9 +283,10 @@ menu_t MP_MainDef;
// Split into multiple parts due to size
// Controls
menu_t OP_ChangeControlsDef;
menu_t OP_MPControlsDef, OP_CameraControlsDef, OP_MiscControlsDef;
menu_t OP_MPControlsDef, OP_MiscControlsDef;
menu_t OP_P1ControlsDef, OP_P2ControlsDef, OP_MouseOptionsDef;
menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def;
menu_t OP_CameraOptionsDef, OP_Camera2OptionsDef;
static void M_VideoModeMenu(INT32 choice);
static void M_Setup1PControlsMenu(INT32 choice);
static void M_Setup2PControlsMenu(INT32 choice);
@ -891,12 +893,12 @@ static menuitem_t MP_SplitServerMenu[] =
static menuitem_t MP_MainMenu[] =
{
{IT_HEADER, NULL, "Host a game", NULL, 0},
{IT_STRING|IT_CALL, NULL, "Internet/LAN...", M_StartServerMenu, 12},
{IT_STRING|IT_CALL, NULL, "Splitscreen...", M_StartSplitServerMenu, 22},
{IT_HEADER, NULL, "Join a game", NULL, 40},
{IT_STRING|IT_CALL, NULL, "Server browser...", M_ConnectMenu, 52},
{IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 62},
{IT_HEADER, NULL, "Join a game", NULL, 0},
{IT_STRING|IT_CALL, NULL, "Server browser...", M_ConnectMenuModChecks, 12},
{IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 22},
{IT_HEADER, NULL, "Host a game", NULL, 54},
{IT_STRING|IT_CALL, NULL, "Internet/LAN...", M_StartServerMenu, 66},
{IT_STRING|IT_CALL, NULL, "Splitscreen...", M_StartSplitServerMenu, 76},
{IT_HEADER, NULL, "Player setup", NULL, 94},
{IT_STRING|IT_CALL, NULL, "Player 1...", M_SetupMultiPlayer, 106},
{IT_STRING|IT_CALL, NULL, "Player 2... ", M_SetupMultiPlayer2, 116},
@ -955,7 +957,7 @@ enum
static menuitem_t MP_RoomMenu[] =
{
{IT_STRING | IT_CALL, NULL, "<Offline Mode>", M_ChooseRoom, 9},
{IT_STRING | IT_CALL, NULL, "<Unlisted Mode>", M_ChooseRoom, 9},
{IT_DISABLED, NULL, "", M_ChooseRoom, 18},
{IT_DISABLED, NULL, "", M_ChooseRoom, 27},
{IT_DISABLED, NULL, "", M_ChooseRoom, 36},
@ -1009,13 +1011,11 @@ static menuitem_t OP_P1ControlsMenu[] =
{IT_SUBMENU | IT_STRING, NULL, "Mouse Options...", &OP_MouseOptionsDef, 20},
{IT_SUBMENU | IT_STRING, NULL, "Gamepad Options...", &OP_Joystick1Def , 30},
{IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 50},
{IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 60},
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 70},
{IT_SUBMENU | IT_STRING, NULL, "Camera Options...", &OP_CameraOptionsDef, 50},
//{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog, 90},
{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar, 90},
{IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake, 100},
//{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog, 100},
{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar, 70},
{IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake, 80},
};
static menuitem_t OP_P2ControlsMenu[] =
@ -1024,13 +1024,11 @@ static menuitem_t OP_P2ControlsMenu[] =
{IT_SUBMENU | IT_STRING, NULL, "Second Mouse Options...", &OP_Mouse2OptionsDef, 20},
{IT_SUBMENU | IT_STRING, NULL, "Second Gamepad Options...", &OP_Joystick2Def , 30},
{IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 50},
{IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 60},
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 70},
{IT_SUBMENU | IT_STRING, NULL, "Camera Options...", &OP_Camera2OptionsDef, 50},
//{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 90},
{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar2, 90},
{IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2, 100},
//{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 100},
{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar2, 70},
{IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2, 80},
};
static menuitem_t OP_ChangeControlsMenu[] =
@ -1159,6 +1157,34 @@ static menuitem_t OP_Mouse2OptionsMenu[] =
NULL, "Mouse Y Sensitivity", &cv_mouseysens2, 80},
};
static menuitem_t OP_CameraOptionsMenu[] =
{
{IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 10},
{IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 20},
{IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 30},
{IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 40},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 60},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 70},
{IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 80},
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 100},
};
static menuitem_t OP_Camera2OptionsMenu[] =
{
{IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 10},
{IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 20},
{IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 30},
{IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 40},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 60},
{IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 70},
{IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 80},
{IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 100},
};
static menuitem_t OP_VideoOptionsMenu[] =
{
{IT_HEADER, NULL, "Screen", NULL, 0},
@ -1329,6 +1355,12 @@ static menuitem_t OP_SoundOptionsMenu[] =
#define OPENMPT_MENUOFFSET 0
#endif
#ifdef HAVE_MIXERX
#define MIXERX_MENUOFFSET 81
#else
#define MIXERX_MENUOFFSET 0
#endif
static menuitem_t OP_SoundAdvancedMenu[] =
{
#ifdef HAVE_OPENMPT
@ -1340,12 +1372,15 @@ static menuitem_t OP_SoundAdvancedMenu[] =
{IT_HEADER, NULL, "MIDI Settings", NULL, OPENMPT_MENUOFFSET+10},
{IT_STRING | IT_CVAR, NULL, "MIDI Player", &cv_midiplayer, OPENMPT_MENUOFFSET+22},
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "FluidSynth Sound Font File", &cv_midisoundfontpath, OPENMPT_MENUOFFSET+34},
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "TiMidity++ Config Folder", &cv_miditimiditypath, OPENMPT_MENUOFFSET+61}
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "TiMidity++ Config Folder", &cv_miditimiditypath, OPENMPT_MENUOFFSET+61},
#endif
{IT_HEADER, NULL, "Miscellaneous", NULL, OPENMPT_MENUOFFSET+MIXERX_MENUOFFSET+10},
{IT_STRING | IT_CVAR, NULL, "Let Levels Force Reset Music", &cv_resetmusicbyheader, OPENMPT_MENUOFFSET+MIXERX_MENUOFFSET+22},
};
#undef OPENMPT_MENUOFFSET
#undef MIXERX_MENUOFFSET
#endif
static menuitem_t OP_DataOptionsMenu[] =
@ -1360,36 +1395,39 @@ static menuitem_t OP_ScreenshotOptionsMenu[] =
{
{IT_HEADER, NULL, "General", NULL, 0},
{IT_STRING|IT_CVAR, NULL, "Use color profile", &cv_screenshot_colorprofile, 6},
{IT_STRING|IT_CVAR, NULL, "Storage Location", &cv_screenshot_option, 11},
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_screenshot_folder, 16},
{IT_HEADER, NULL, "Screenshots (F8)", NULL, 30},
{IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memory, 36},
{IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_level, 41},
{IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategy, 46},
{IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bits, 51},
{IT_HEADER, NULL, "Screenshots (F8)", NULL, 16},
{IT_STRING|IT_CVAR, NULL, "Storage Location", &cv_screenshot_option, 22},
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_screenshot_folder, 27},
{IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memory, 42},
{IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_level, 47},
{IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategy, 52},
{IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bits, 57},
{IT_HEADER, NULL, "Movie Mode (F9)", NULL, 60},
{IT_STRING|IT_CVAR, NULL, "Capture Mode", &cv_moviemode, 66},
{IT_HEADER, NULL, "Movie Mode (F9)", NULL, 64},
{IT_STRING|IT_CVAR, NULL, "Storage Location", &cv_movie_option, 70},
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_movie_folder, 75},
{IT_STRING|IT_CVAR, NULL, "Capture Mode", &cv_moviemode, 90},
{IT_STRING|IT_CVAR, NULL, "Region Optimizing", &cv_gif_optimize, 71},
{IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_gif_downscale, 76},
{IT_STRING|IT_CVAR, NULL, "Region Optimizing", &cv_gif_optimize, 95},
{IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_gif_downscale, 100},
{IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memorya, 71},
{IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_levela, 76},
{IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategya, 81},
{IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bitsa, 86},
{IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memorya, 95},
{IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_levela, 100},
{IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategya, 105},
{IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bitsa, 110},
};
enum
{
op_screenshot_colorprofile = 1,
op_screenshot_folder = 3,
op_screenshot_capture = 10,
op_screenshot_gif_start = 11,
op_screenshot_gif_end = 12,
op_screenshot_apng_start = 13,
op_screenshot_apng_end = 16,
op_screenshot_folder = 4,
op_movie_folder = 11,
op_screenshot_capture = 12,
op_screenshot_gif_start = 13,
op_screenshot_gif_end = 14,
op_screenshot_apng_start = 15,
op_screenshot_apng_end = 18,
};
static menuitem_t OP_EraseDataMenu[] =
@ -1884,6 +1922,13 @@ menu_t OP_JoystickSetDef =
0,
NULL
};
menu_t OP_CameraOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1CAMERA << 12),
"M_CONTRO", OP_CameraOptionsMenu, &OP_P1ControlsDef, 35, 30);
menu_t OP_Camera2OptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2CAMERA << 12),
"M_CONTRO", OP_Camera2OptionsMenu, &OP_P2ControlsDef, 35, 30);
menu_t OP_VideoOptionsDef =
{
@ -2207,6 +2252,12 @@ void Addons_option_Onchange(void)
(cv_addons_option.value == 3 ? IT_CVAR|IT_STRING|IT_CV_STRING : IT_DISABLED);
}
void Moviemode_option_Onchange(void)
{
OP_ScreenshotOptionsMenu[op_movie_folder].status =
(cv_movie_option.value == 3 ? IT_CVAR|IT_STRING|IT_CV_STRING : IT_DISABLED);
}
// ==========================================================================
// END ORGANIZATION STUFF.
// ==========================================================================
@ -2745,14 +2796,28 @@ static void M_ChangeCvar(INT32 choice)
||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_INVISSLIDER)
||((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_NOMOD))
{
CV_SetValue(cv,cv->value+(choice));
}
else if (cv->flags & CV_FLOAT)
if (cv->flags & CV_FLOAT && (currentMenu->menuitems[itemOn].status & IT_CV_FLOATSLIDER) == IT_CV_FLOATSLIDER)
{
char s[20];
sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f));
CV_Set(cv,s);
}
else
CV_SetValue(cv,cv->value+(choice));
}
else if (cv->flags & CV_FLOAT)
{
if (currentMenu->menuitems[itemOn].status & IT_CV_INTEGERSTEP)
{
CV_SetValue(cv,FIXED_TO_FLOAT(cv->value)+(choice));
}
else
{
char s[20];
sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f));
CV_Set(cv,s);
}
}
else
CV_AddValue(cv,choice);
}
@ -3641,7 +3706,12 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv, boolean ontop)
for (i = 0; cv->PossibleValue[i+1].strvalue; i++);
if ((range = atoi(cv->defaultvalue)) != cv->value)
if (cv->flags & CV_FLOAT)
range = (INT32)(atof(cv->defaultvalue)*FRACUNIT);
else
range = atoi(cv->defaultvalue);
if (range != cv->value)
{
range = ((range - cv->PossibleValue[0].value) * 100 /
(cv->PossibleValue[i].value - cv->PossibleValue[0].value));
@ -4517,6 +4587,9 @@ static boolean M_CanShowLevelOnPlatter(INT32 mapnum, INT32 gt)
if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU)
return false;
if (G_IsSpecialStage(mapnum+1))
return false;
if (gt == GT_COOP && (mapheaderinfo[mapnum]->typeoflevel & TOL_COOP))
return true;
@ -5610,7 +5683,7 @@ static boolean M_AddonsRefresh(void)
{
S_StartSound(NULL, sfx_lose);
if (refreshdirmenu & REFRESHDIR_MAX)
message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you wish to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
else
message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
}
@ -6892,6 +6965,7 @@ static void M_StartTutorial(INT32 choice)
tutorialmode = true; // turn on tutorial mode
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
M_ClearMenus(true);
gamecomplete = false;
cursaveslot = 0;
@ -7058,7 +7132,7 @@ static void M_DrawLoadGameData(void)
}
}
y -= 13;
y -= 4;
// character heads, lives, and continues
{
@ -7067,7 +7141,7 @@ static void M_DrawLoadGameData(void)
patch_t *patch;
UINT8 *colormap = NULL;
INT32 tempx = (x+40)<<FRACBITS, tempy = y<<FRACBITS, flip = 0, calc;
INT32 tempx = (x+40)<<FRACBITS, flip = 0;
// botskin first
if (savegameinfo[savetodraw].botskin)
@ -7082,13 +7156,13 @@ static void M_DrawLoadGameData(void)
V_DrawFixedPatch(
tempx + (18<<FRACBITS),
tempy - (4<<FRACBITS),
y<<FRACBITS,
charbotskin->highresscale,
0, patch, colormap);
Z_Free(colormap);
tempx -= (15<<FRACBITS);
tempx -= (20<<FRACBITS);
flip = V_FLIP;
}
skipbot:
@ -7101,17 +7175,15 @@ skipbot:
goto skipsign;
sprframe = &sprdef->spriteframes[0];
patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
if ((calc = SHORT(patch->topoffset) - 42) > 0)
tempy += ((4+calc)<<FRACBITS);
V_DrawFixedPatch(
tempx,
tempy,
y<<FRACBITS,
charskin->highresscale,
flip, patch, colormap);
skipsign:
y += 25;
y += 16;
tempx = x + 10;
if (savegameinfo[savetodraw].lives != INFLIVES
@ -7300,7 +7372,29 @@ static void M_ReadSavegameInfo(UINT32 slot)
// File end marker check
CHECKPOS
if (READUINT8(save_p) != 0x1d) BADSAVE;
switch (READUINT8(save_p))
{
case 0xb7:
{
UINT8 i, banksinuse;
CHECKPOS
banksinuse = READUINT8(save_p);
CHECKPOS
if (banksinuse > NUM_LUABANKS)
BADSAVE
for (i = 0; i < banksinuse; i++)
{
(void)READINT32(save_p);
CHECKPOS
}
if (READUINT8(save_p) != 0x1d)
BADSAVE
}
case 0x1d:
break;
default:
BADSAVE
}
// done
Z_Free(savebuffer);
@ -8486,8 +8580,8 @@ static void M_NightsAttack(INT32 choice)
M_PatchSkinNameTable();
G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching
M_SetupNextMenu(&SP_NightsAttackDef);
titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please
M_SetupNextMenu(&SP_NightsAttackDef);
if (!M_CanShowLevelInList(cv_nextmap.value-1, -1) && levelselect.rows[0].maplist[0])
CV_SetValue(&cv_nextmap, levelselect.rows[0].maplist[0]);
else
@ -8502,6 +8596,7 @@ static void M_ChooseNightsAttack(INT32 choice)
char nameofdemo[256];
(void)choice;
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
M_ClearMenus(true);
modeattacking = ATTACKING_NIGHTS;
@ -8526,6 +8621,7 @@ static void M_ChooseTimeAttack(INT32 choice)
char nameofdemo[256];
(void)choice;
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
M_ClearMenus(true);
modeattacking = ATTACKING_RECORD;
@ -8879,7 +8975,7 @@ static void M_DrawConnectMenu(void)
// Room name
if (ms_RoomId < 0)
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_room].alphaKey,
V_YELLOWMAP, (itemOn == mp_connect_room) ? "<Select to change>" : "<Offline Mode>");
V_YELLOWMAP, (itemOn == mp_connect_room) ? "<Select to change>" : "<Unlisted Mode>");
else
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_room].alphaKey,
V_YELLOWMAP, room_list[menuRoomIndex].name);
@ -9029,11 +9125,32 @@ static void M_ConnectMenu(INT32 choice)
// first page of servers
serverlistpage = 0;
if (ms_RoomId < 0)
{
M_RoomMenu(0); // Select a room instead of staring at an empty list
// This prevents us from returning to the modified game alert.
currentMenu->prevMenu = &MP_MainDef;
}
else
M_SetupNextMenu(&MP_ConnectDef);
itemOn = 0;
M_Refresh(0);
}
static void M_ConnectMenuModChecks(INT32 choice)
{
(void)choice;
// okay never mind we want to COMMUNICATE to the player pre-emptively instead of letting them try and then get confused when it doesn't work
if (modifiedgame)
{
M_StartMessage(M_GetText("Add-ons are currently loaded.\n\nYou will only be able to join a server if\nit has the same ones loaded in the same order, which may be unlikely.\n\nIf you wish to play on other servers,\nrestart the game to clear existing add-ons.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER);
return;
}
M_ConnectMenu(-1);
}
static UINT32 roomIds[NUM_LIST_ROOMS];
static void M_RoomMenu(INT32 choice)
@ -9088,7 +9205,16 @@ static void M_ChooseRoom(INT32 choice)
}
serverlistpage = 0;
/*
We were on the Multiplayer menu? That means that we must have been trying to
view the server browser, but we hadn't selected a room yet. So we need to go
to the browser next, not back there.
*/
if (currentMenu->prevMenu == &MP_MainDef)
M_SetupNextMenu(&MP_ConnectDef);
else
M_SetupNextMenu(currentMenu->prevMenu);
if (currentMenu == &MP_ConnectDef)
M_Refresh(0);
}
@ -9147,7 +9273,7 @@ static void M_DrawServerMenu(void)
M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight/2, "Server settings", true, false);
if (ms_RoomId < 0)
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey,
V_YELLOWMAP, (itemOn == mp_server_room) ? "<Select to change>" : "<Offline Mode>");
V_YELLOWMAP, (itemOn == mp_server_room) ? "<Select to change>" : "<Unlisted Mode>");
else
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey,
V_YELLOWMAP, room_list[menuRoomIndex].name);
@ -9254,7 +9380,7 @@ static void M_StartServerMenu(INT32 choice)
// CONNECT VIA IP
// ==============
static char setupm_ip[16];
static char setupm_ip[28];
// Draw the funky Connect IP menu. Tails 11-19-2002
// So much work for such a little thing!
@ -9266,30 +9392,26 @@ static void M_DrawMPMainMenu(void)
// use generic drawer for cursor, items and title
M_DrawGenericMenu();
#if MAXPLAYERS == 32
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+12,
((itemOn == 1) ? V_YELLOWMAP : 0), "(2-32 players)");
#else
Update the maxplayers label...
#endif
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+66,
((itemOn == 4) ? V_YELLOWMAP : 0), va("(2-%d players)", MAXPLAYERS));
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+22,
((itemOn == 2) ? V_YELLOWMAP : 0), "(2 players)");
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+76,
((itemOn == 5) ? V_YELLOWMAP : 0), "(2 players)");
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+116,
((itemOn == 8) ? V_YELLOWMAP : 0), "(splitscreen)");
y += 62;
y += 22;
V_DrawFill(x+5, y+4+5, /*16*8 + 6,*/ BASEVIDWIDTH - 2*(x+5), 8+6, 159);
// draw name string
V_DrawString(x+8,y+12, V_MONOSPACE, setupm_ip);
V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, setupm_ip);
// draw text cursor for name
if (itemOn == 5 //0
if (itemOn == 2 //0
&& skullAnimCounter < 4) //blink cursor
V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_MONOSPACE),y+12,'_',false);
V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_ALLOWLOWERCASE),y+12,'_',false);
}
// Tails 11-19-2002
@ -9360,10 +9482,11 @@ static void M_HandleConnectIP(INT32 choice)
default:
l = strlen(setupm_ip);
if (l >= 16-1)
if (l >= 28-1)
break;
if (choice == 46 || (choice >= 48 && choice <= 57)) // Rudimentary number and period enforcing
// Rudimentary number and period enforcing - also allows letters so hostnames can be used instead
if ((choice >= '-' && choice <= ':') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z'))
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_ip[l] = (char)choice;

View file

@ -72,10 +72,12 @@ typedef enum
MN_OP_P1MOUSE,
MN_OP_P1JOYSTICK,
MN_OP_JOYSTICKSET, // OP_JoystickSetDef shared with P2
MN_OP_P1CAMERA,
MN_OP_P2CONTROLS,
MN_OP_P2MOUSE,
MN_OP_P2JOYSTICK,
MN_OP_P2CAMERA,
MN_OP_VIDEO,
MN_OP_VIDEOMODE,
@ -241,6 +243,8 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
#define IT_CV_NOPRINT 1536
#define IT_CV_NOMOD 2048
#define IT_CV_INVISSLIDER 2560
#define IT_CV_INTEGERSTEP 4096 // if IT_CV_NORMAL and cvar is CV_FLOAT, modify it by 1 instead of 0.0625
#define IT_CV_FLOATSLIDER 4608 // IT_CV_SLIDER, value modified by 0.0625 instead of 1 (for CV_FLOAT cvars)
//call/submenu specific
// There used to be a lot more here but ...
@ -400,6 +404,9 @@ void Screenshot_option_Onchange(void);
// Addons menu updating
void Addons_option_Onchange(void);
// Moviemode menu updating
void Moviemode_option_Onchange(void);
// These defines make it a little easier to make menus
#define DEFAULTMENUSTYLE(id, header, source, prev, x, y)\
{\

View file

@ -108,6 +108,9 @@ consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "Yes", CV_SAV
static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}};
consvar_t cv_moviemode = {"moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_movie_option = {"movie_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Moviemode_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_movie_folder = {"movie_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t zlib_mem_level_t[] = {
{1, "(Min Memory) 1"},
{2, "2"}, {3, "3"}, {4, "4"}, {5, "5"}, {6, "6"}, {7, "7"},
@ -1124,19 +1127,25 @@ static inline moviemode_t M_StartMovieGIF(const char *pathname)
void M_StartMovie(void)
{
#if NUMSCREENS > 2
const char *pathname = ".";
char pathname[MAX_WADPATH];
if (moviemode)
return;
if (cv_screenshot_option.value == 0)
pathname = usehome ? srb2home : srb2path;
else if (cv_screenshot_option.value == 1)
pathname = srb2home;
else if (cv_screenshot_option.value == 2)
pathname = srb2path;
else if (cv_screenshot_option.value == 3 && *cv_screenshot_folder.string != '\0')
pathname = cv_screenshot_folder.string;
if (cv_movie_option.value == 0)
strcpy(pathname, usehome ? srb2home : srb2path);
else if (cv_movie_option.value == 1)
strcpy(pathname, srb2home);
else if (cv_movie_option.value == 2)
strcpy(pathname, srb2path);
else if (cv_movie_option.value == 3 && *cv_movie_folder.string != '\0')
strcpy(pathname, cv_movie_folder.string);
if (cv_movie_option.value != 3)
{
strcat(pathname, PATHSEP"movies"PATHSEP);
I_mkdir(pathname, 0755);
}
if (rendermode == render_none)
I_Error("Can't make a movie without a render system\n");
@ -1474,7 +1483,8 @@ void M_ScreenShot(void)
void M_DoScreenShot(void)
{
#if NUMSCREENS > 2
const char *freename = NULL, *pathname = ".";
const char *freename = NULL;
char pathname[MAX_WADPATH];
boolean ret = false;
UINT8 *linear = NULL;
@ -1486,13 +1496,19 @@ void M_DoScreenShot(void)
return;
if (cv_screenshot_option.value == 0)
pathname = usehome ? srb2home : srb2path;
strcpy(pathname, usehome ? srb2home : srb2path);
else if (cv_screenshot_option.value == 1)
pathname = srb2home;
strcpy(pathname, srb2home);
else if (cv_screenshot_option.value == 2)
pathname = srb2path;
strcpy(pathname, srb2path);
else if (cv_screenshot_option.value == 3 && *cv_screenshot_folder.string != '\0')
pathname = cv_screenshot_folder.string;
strcpy(pathname, cv_screenshot_folder.string);
if (cv_screenshot_option.value != 3)
{
strcat(pathname, PATHSEP"screenshots"PATHSEP);
I_mkdir(pathname, 0755);
}
#ifdef USE_PNG
freename = Newsnapshotfile(pathname,"png");

View file

@ -30,7 +30,7 @@ typedef enum {
extern moviemode_t moviemode;
extern consvar_t cv_screenshot_option, cv_screenshot_folder, cv_screenshot_colorprofile;
extern consvar_t cv_moviemode;
extern consvar_t cv_moviemode, cv_movie_folder, cv_movie_option;
extern consvar_t cv_zlib_memory, cv_zlib_level, cv_zlib_strategy, cv_zlib_window_bits;
extern consvar_t cv_zlib_memorya, cv_zlib_levela, cv_zlib_strategya, cv_zlib_window_bitsa;
extern consvar_t cv_apng_delay;

View file

@ -14,10 +14,11 @@
#ifndef __M_SWAP__
#define __M_SWAP__
#include "endian.h"
// Endianess handling.
// WAD files are stored little endian.
#include "endian.h"
// Little to big endian
#ifdef SRB2_BIG_ENDIAN
#define SHORT(x) ((INT16)(\
@ -39,4 +40,13 @@
#define LONG(x) ((INT32)(x))
#endif
// Big to little endian
#ifdef SRB2_LITTLE_ENDIAN
#define BIGENDIAN_LONG(x) ((INT32)(((x)>>24)&0xff)|(((x)<<8)&0xff0000)|(((x)>>8)&0xff00)|(((x)<<24)&0xff000000))
#define BIGENDIAN_SHORT(x) ((INT16)(((x)>>8)|((x)<<8)))
#else
#define BIGENDIAN_LONG(x) ((INT32)(x))
#define BIGENDIAN_SHORT(x) ((INT16)(x))
#endif
#endif

View file

@ -3006,16 +3006,19 @@ void A_Boss7FireMissiles(mobj_t *actor)
// 0 - Boss 1 Left side
// 1 - Boss 1 Right side
// 2 - Triple laser
// >3 - Boss 1 Middle
// 3 - Boss 1 Middle
// >=3 - Generic middle
//
void A_Boss1Laser(mobj_t *actor)
{
fixed_t x, y, z, floorz, speed;
INT32 locvar1 = var1;
INT32 locvar2 = var2;
INT32 locvar2 = (var2 & 65535);
INT32 upperend = (var2>>16);
INT32 i;
angle_t angle;
mobj_t *point;
tic_t dur;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_Boss1Laser", actor))
@ -3024,19 +3027,24 @@ void A_Boss1Laser(mobj_t *actor)
if (!actor->target)
return;
if ((upperend & 1) && (actor->extravalue2 > 1))
actor->extravalue2--;
dur = actor->extravalue2;
switch (locvar2)
{
case 0:
x = actor->x + P_ReturnThrustX(actor, actor->angle+ANGLE_90, FixedMul(43*FRACUNIT, actor->scale));
y = actor->y + P_ReturnThrustY(actor, actor->angle+ANGLE_90, FixedMul(43*FRACUNIT, actor->scale));
x = actor->x + P_ReturnThrustX(actor, actor->angle+ANGLE_90, FixedMul(44*FRACUNIT, actor->scale));
y = actor->y + P_ReturnThrustY(actor, actor->angle+ANGLE_90, FixedMul(44*FRACUNIT, actor->scale));
if (actor->eflags & MFE_VERTICALFLIP)
z = actor->z + actor->height - FixedMul(56*FRACUNIT, actor->scale) - mobjinfo[locvar1].height;
else
z = actor->z + FixedMul(56*FRACUNIT, actor->scale);
break;
case 1:
x = actor->x + P_ReturnThrustX(actor, actor->angle-ANGLE_90, FixedMul(43*FRACUNIT, actor->scale));
y = actor->y + P_ReturnThrustY(actor, actor->angle-ANGLE_90, FixedMul(43*FRACUNIT, actor->scale));
x = actor->x + P_ReturnThrustX(actor, actor->angle-ANGLE_90, FixedMul(44*FRACUNIT, actor->scale));
y = actor->y + P_ReturnThrustY(actor, actor->angle-ANGLE_90, FixedMul(44*FRACUNIT, actor->scale));
if (actor->eflags & MFE_VERTICALFLIP)
z = actor->z + actor->height - FixedMul(56*FRACUNIT, actor->scale) - mobjinfo[locvar1].height;
else
@ -3051,6 +3059,11 @@ void A_Boss1Laser(mobj_t *actor)
A_Boss1Laser(actor);
return;
break;
case 3:
x = actor->x + P_ReturnThrustX(actor, actor->angle, FixedMul(42*FRACUNIT, actor->scale));
y = actor->y + P_ReturnThrustY(actor, actor->angle, FixedMul(42*FRACUNIT, actor->scale));
z = actor->z + actor->height/2;
break;
default:
x = actor->x;
y = actor->y;
@ -3058,7 +3071,7 @@ void A_Boss1Laser(mobj_t *actor)
break;
}
if (!(actor->flags2 & MF2_FIRING) && actor->tics > 1)
if (!(actor->flags2 & MF2_FIRING) && dur > 1)
{
actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);
if (mobjinfo[locvar1].seesound)
@ -3067,7 +3080,7 @@ void A_Boss1Laser(mobj_t *actor)
{
point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET);
point->angle = actor->angle;
point->fuse = actor->tics+1;
point->fuse = dur+1;
P_SetTarget(&point->target, actor->target);
P_SetTarget(&actor->target, point);
}
@ -3076,9 +3089,9 @@ void A_Boss1Laser(mobj_t *actor)
else if (actor->target && !(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH))
actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);*/
if (actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)
angle = FixedAngle(FixedDiv(actor->tics*160*FRACUNIT, actor->state->tics*FRACUNIT) + 10*FRACUNIT);
else
/*if (actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)
angle = FixedAngle(FixedDiv(dur*160*FRACUNIT, actor->state->tics*FRACUNIT) + 10*FRACUNIT);
else*/
angle = R_PointToAngle2(z + (mobjinfo[locvar1].height>>1), 0, actor->target->z, R_PointToDist2(x, y, actor->target->x, actor->target->y));
point = P_SpawnMobj(x, y, z, locvar1);
@ -3112,7 +3125,7 @@ void A_Boss1Laser(mobj_t *actor)
point->fuse = TICRATE;
}
if (actor->tics > 1)
if (dur > 1)
actor->flags2 |= MF2_FIRING;
else
actor->flags2 &= ~MF2_FIRING;
@ -3256,6 +3269,7 @@ void A_Boss4Raise(mobj_t *actor)
// 0 - Fly at the player
// 1 - Fly away from the player
// 2 - Strafe in relation to the player
// 3 - Dynamic mode - don't get too close to walls
// var2:
// 0 - Fly horizontally and vertically
// 1 - Fly horizontal-only (momz = 0)
@ -3286,16 +3300,83 @@ void A_SkullAttack(mobj_t *actor)
S_StartSound(actor, actor->info->activesound);
A_FaceTarget(actor);
dist = P_AproxDistance(dest->x - actor->x, dest->y - actor->y);
if (locvar1 == 1)
actor->angle += ANGLE_180;
else if (locvar1 == 2)
actor->angle += (P_RandomChance(FRACUNIT/2)) ? ANGLE_90 : -ANGLE_90;
else if (locvar1 == 3)
{
statenum_t oldspawnstate = mobjinfo[MT_NULL].spawnstate;
UINT32 oldflags = mobjinfo[MT_NULL].flags;
fixed_t oldradius = mobjinfo[MT_NULL].radius;
fixed_t oldheight = mobjinfo[MT_NULL].height;
mobj_t *check;
INT32 i, j, k;
boolean allow;
angle_t testang;
mobjinfo[MT_NULL].spawnstate = S_INVISIBLE;
mobjinfo[MT_NULL].flags = MF_NOGRAVITY|MF_NOTHINK|MF_NOCLIPTHING|MF_NOBLOCKMAP;
mobjinfo[MT_NULL].radius = mobjinfo[actor->type].radius;
mobjinfo[MT_NULL].height = mobjinfo[actor->type].height;
if (P_RandomChance(FRACUNIT/2)) // port priority 1?
{
i = 9;
j = 27;
}
else
{
i = 27;
j = 9;
}
#define dostuff(q) check = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_NULL);\
testang = actor->angle + ((i+(q))*ANG10);\
allow = (P_TryMove(check,\
P_ReturnThrustX(check, testang, dist + 2*actor->radius),\
P_ReturnThrustY(check, testang, dist + 2*actor->radius),\
true));\
P_RemoveMobj(check);\
if (allow)\
break;
if (P_RandomChance(FRACUNIT/2)) // port priority 2?
{
for (k = 0; k < 9; k++)
{
dostuff(i+k)
dostuff(i-k)
dostuff(j+k)
dostuff(j-k)
}
}
else
{
for (k = 0; k < 9; k++)
{
dostuff(i-k)
dostuff(i+k)
dostuff(j-k)
dostuff(j+k)
}
}
actor->angle = testang;
#undef dostuff
mobjinfo[MT_NULL].spawnstate = oldspawnstate;
mobjinfo[MT_NULL].flags = oldflags;
mobjinfo[MT_NULL].radius = oldradius;
mobjinfo[MT_NULL].height = oldheight;
}
an = actor->angle >> ANGLETOFINESHIFT;
actor->momx = FixedMul(speed, FINECOSINE(an));
actor->momy = FixedMul(speed, FINESINE(an));
dist = P_AproxDistance(dest->x - actor->x, dest->y - actor->y);
dist = dist / speed;
if (dist < 1)
@ -3445,11 +3526,13 @@ void A_Pain(mobj_t *actor)
//
// Description: Changes a dying object's flags to reflect its having fallen to the ground.
//
// var1 = unused
// var1 = value to set repeat to if nonzero
// var2 = unused
//
void A_Fall(mobj_t *actor)
{
INT32 locvar1 = var1;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_Fall", actor))
return;
@ -3462,6 +3545,9 @@ void A_Fall(mobj_t *actor)
// So change this if corpse objects
// are meant to be obstacles.
if (locvar1)
actor->extravalue2 = locvar1;
}
#define LIVESBOXDISPLAYPLAYER // Use displayplayer instead of closest player
@ -3857,6 +3943,72 @@ bossjustdie:
else if (P_MobjWasRemoved(mo))
return;
#endif
// Spawn your junk
switch (mo->type)
{
default:
break;
case MT_EGGMOBILE: // twin laser pods
{
mo2 = P_SpawnMobjFromMobj(mo,
P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<<FRACBITS),
P_ReturnThrustY(mo, mo->angle - ANGLE_90, 32<<FRACBITS),
32<<FRACBITS, MT_BOSSJUNK);
mo2->angle = mo->angle;
P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale);
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
P_SetMobjState(mo2, S_BOSSEGLZ1);
mo2 = P_SpawnMobjFromMobj(mo,
P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<<FRACBITS),
P_ReturnThrustY(mo, mo->angle + ANGLE_90, 32<<FRACBITS),
32<<FRACBITS, MT_BOSSJUNK);
mo2->angle = mo->angle;
P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale);
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
P_SetMobjState(mo2, S_BOSSEGLZ2);
}
break;
case MT_EGGMOBILE2: // twin tanks + spigot
{
mo2 = P_SpawnMobjFromMobj(mo,
P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<<FRACBITS),
P_ReturnThrustY(mo, mo->angle - ANGLE_90, 32<<FRACBITS),
32<<FRACBITS, MT_BOSSJUNK);
mo2->angle = mo->angle;
P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale);
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
P_SetMobjState(mo2, S_BOSSTANK1);
mo2 = P_SpawnMobjFromMobj(mo,
P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<<FRACBITS),
P_ReturnThrustY(mo, mo->angle + ANGLE_90, 32<<FRACBITS),
32<<FRACBITS, MT_BOSSJUNK);
mo2->angle = mo->angle;
P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale);
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
P_SetMobjState(mo2, S_BOSSTANK2);
mo2 = P_SpawnMobjFromMobj(mo, 0, 0,
mobjinfo[MT_EGGMOBILE2].height + (32<<FRACBITS),
MT_BOSSJUNK);
mo2->angle = mo->angle;
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
mo2->momz += mo->momz;
P_SetMobjState(mo2, S_BOSSSPIGOT);
}
break;
case MT_EGGMOBILE3:
{
mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK);
mo2->angle = mo->angle;
P_SetMobjState(mo2, S_BOSSSEBH1);
}
break;
}
// now do another switch case for escaping
switch (mo->type)
{
case MT_BLACKEGGMAN:
@ -3954,7 +4106,7 @@ bossjustdie:
mo->movedir = 0;
mo->extravalue1 = 35;
mo->flags2 |= MF2_BOSSFLEE;
mo->momz = 2*mo->scale;
mo->momz = P_MobjFlip(mo)*2*mo->scale;
if (mo->target)
{
@ -3972,50 +4124,6 @@ bossjustdie:
break;
}
}
if (mo->type == MT_EGGMOBILE2)
{
mo2 = P_SpawnMobj(mo->x + P_ReturnThrustX(mo, mo->angle - ANGLE_90, FixedMul(32*FRACUNIT, mo->scale)),
mo->y + P_ReturnThrustY(mo, mo->angle - ANGLE_90, FixedMul(32*FRACUNIT, mo->scale)),
mo->z + mo->height/2 + ((mo->eflags & MFE_VERTICALFLIP)? FixedMul(8*FRACUNIT, mo->scale)-mobjinfo[MT_BOSSTANK1].height : -FixedMul(8*FRACUNIT, mo->scale)), MT_BOSSTANK1); // Right tank
mo2->angle = mo->angle;
mo2->destscale = mo->scale;
P_SetScale(mo2, mo2->destscale);
if (mo->eflags & MFE_VERTICALFLIP)
{
mo2->eflags |= MFE_VERTICALFLIP;
mo2->flags2 |= MF2_OBJECTFLIP;
}
P_InstaThrust(mo2, mo2->angle - ANGLE_90, FixedMul(4*FRACUNIT, mo2->scale));
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
mo2 = P_SpawnMobj(mo->x + P_ReturnThrustX(mo, mo->angle + ANGLE_90, FixedMul(32*FRACUNIT, mo->scale)),
mo->y + P_ReturnThrustY(mo, mo->angle + ANGLE_90, FixedMul(32*FRACUNIT, mo->scale)),
mo->z + mo->height/2 + ((mo->eflags & MFE_VERTICALFLIP)? FixedMul(8*FRACUNIT, mo->scale)-mobjinfo[MT_BOSSTANK2].height : -FixedMul(8*FRACUNIT, mo->scale)), MT_BOSSTANK2); // Left tank
mo2->angle = mo->angle;
mo2->destscale = mo->scale;
P_SetScale(mo2, mo2->destscale);
if (mo->eflags & MFE_VERTICALFLIP)
{
mo2->eflags |= MFE_VERTICALFLIP;
mo2->flags2 |= MF2_OBJECTFLIP;
}
P_InstaThrust(mo2, mo2->angle + ANGLE_90, FixedMul(4*FRACUNIT, mo2->scale));
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
mo2 = P_SpawnMobj(mo->x, mo->y,
mo->z + ((mo->eflags & MFE_VERTICALFLIP)? mobjinfo[MT_BOSSSPIGOT].height-FixedMul(32*FRACUNIT,mo->scale): mo->height + FixedMul(32*FRACUNIT, mo->scale)), MT_BOSSSPIGOT);
mo2->angle = mo->angle;
mo2->destscale = mo->scale;
P_SetScale(mo2, mo2->destscale);
if (mo->eflags & MFE_VERTICALFLIP)
{
mo2->eflags |= MFE_VERTICALFLIP;
mo2->flags2 |= MF2_OBJECTFLIP;
}
P_SetObjectMomZ(mo2, 4*FRACUNIT, false);
return;
}
}
// Function: A_CustomPower
@ -6358,6 +6466,7 @@ void A_MixUp(mobj_t *actor)
INT32 starpostnum;
tic_t starposttime;
angle_t starpostangle;
fixed_t starpostscale;
INT32 mflags2;
@ -6405,6 +6514,7 @@ void A_MixUp(mobj_t *actor)
starposty = players[one].starposty;
starpostz = players[one].starpostz;
starpostangle = players[one].starpostangle;
starpostscale = players[one].starpostscale;
starpostnum = players[one].starpostnum;
starposttime = players[one].starposttime;
@ -6413,15 +6523,11 @@ void A_MixUp(mobj_t *actor)
P_MixUp(players[one].mo, players[two].mo->x, players[two].mo->y, players[two].mo->z, players[two].mo->angle,
players[two].starpostx, players[two].starposty, players[two].starpostz,
players[two].starpostnum, players[two].starposttime, players[two].starpostangle,
players[two].mo->flags2);
players[one].drawangle = players[two].drawangle;
players[two].starpostscale, players[two].drawangle, players[two].mo->flags2);
P_MixUp(players[two].mo, x, y, z, angle, starpostx, starposty, starpostz,
starpostnum, starposttime, starpostangle,
mflags2);
players[two].drawangle = drawangle;
starpostscale, drawangle, mflags2);
//carry set after mixup. Stupid P_ResetPlayer() takes away some of the stuff we look for...
//but not all of it! So we need to make sure they aren't set wrong or anything.
@ -6448,6 +6554,7 @@ void A_MixUp(mobj_t *actor)
INT32 starpostnum[MAXPLAYERS];
tic_t starposttime[MAXPLAYERS];
angle_t starpostangle[MAXPLAYERS];
fixed_t starpostscale[MAXPLAYERS];
INT32 flags2[MAXPLAYERS];
@ -6485,6 +6592,7 @@ void A_MixUp(mobj_t *actor)
starpostnum[counter] = players[i].starpostnum;
starposttime[counter] = players[i].starposttime;
starpostangle[counter] = players[i].starpostangle;
starpostscale[counter] = players[i].starpostscale;
flags2[counter] = players[i].mo->flags2;
@ -6525,9 +6633,7 @@ void A_MixUp(mobj_t *actor)
P_MixUp(players[i].mo, position[teleportfrom][0], position[teleportfrom][1], position[teleportfrom][2], anglepos[teleportfrom][0],
spposition[teleportfrom][0], spposition[teleportfrom][1], spposition[teleportfrom][2],
starpostnum[teleportfrom], starposttime[teleportfrom], starpostangle[teleportfrom],
flags2[teleportfrom]);
players[i].drawangle = anglepos[teleportfrom][1];
starpostscale[teleportfrom], anglepos[teleportfrom][1], flags2[teleportfrom]);
//...carry after. same reasoning.
players[i].powers[pw_carry] = transcarry[teleportfrom];
@ -8702,7 +8808,7 @@ void A_SetObjectFlags2(mobj_t *actor)
//
// var1:
// 0 - Triple jet fume pattern
// 1 - Boss 3's propeller
// 1 - Unused (formerly Boss 3's propeller)
// 2 - Metal Sonic jet fume
// 3 - Boss 4 jet flame
// var2 = unused
@ -8762,7 +8868,7 @@ void A_BossJetFume(mobj_t *actor)
P_SetTarget(&actor->tracer, filler);
}
else if (locvar1 == 1) // Boss 3 propeller
/*else if (locvar1 == 1) // Boss 3 propeller
{
fixed_t jetx, jety, jetz;
@ -8782,14 +8888,14 @@ void A_BossJetFume(mobj_t *actor)
filler->angle = actor->angle - ANGLE_180;
P_SetTarget(&actor->tracer, filler);
}
}*/
else if (locvar1 == 2) // Metal Sonic jet fumes
{
filler = P_SpawnMobj(actor->x, actor->y, actor->z, MT_JETFUME1);
P_SetTarget(&filler->target, actor);
filler->fuse = 59;
P_SetTarget(&actor->tracer, filler);
filler->destscale = actor->scale/2;
filler->destscale = actor->scale/3;
P_SetScale(filler, filler->destscale);
if (actor->eflags & MFE_VERTICALFLIP)
filler->flags2 |= MF2_OBJECTFLIP;

View file

@ -1427,6 +1427,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
players[i].starposty = player->mo->y>>FRACBITS;
players[i].starpostz = special->z>>FRACBITS;
players[i].starpostangle = special->angle;
players[i].starpostscale = player->mo->destscale;
if (special->flags2 & MF2_OBJECTFLIP)
{
players[i].starpostscale *= -1;
players[i].starpostz += special->height>>FRACBITS;
}
players[i].starpostnum = special->health;
if (cv_coopstarposts.value == 2 && (players[i].playerstate == PST_DEAD || players[i].spectator) && P_GetLives(&players[i]))
@ -1443,6 +1449,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->starposty = toucher->y>>FRACBITS;
player->starpostz = special->z>>FRACBITS;
player->starpostangle = special->angle;
player->starpostscale = player->mo->destscale;
if (special->flags2 & MF2_OBJECTFLIP)
{
player->starpostscale *= -1;
player->starpostz += special->height>>FRACBITS;
}
player->starpostnum = special->health;
S_StartSound(toucher, special->info->painsound);
}
@ -1583,6 +1595,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
// Buenos Dias Mandy
P_SetPlayerMobjState(toucher, S_PLAY_STUN);
player->pflags &= ~PF_APPLYAUTOBRAKE;
P_ResetPlayer(player);
player->drawangle = special->angle + ANGLE_180;
P_InstaThrust(toucher, special->angle, FixedMul(3*special->info->speed, special->scale/2));
toucher->z += P_MobjFlip(toucher);
@ -1688,13 +1701,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return;
if (mariomode)
return;
if (special->state-states != S_EXTRALARGEBUBBLE)
return; // Don't grab the bubble during its spawn animation
else if (toucher->eflags & MFE_VERTICALFLIP)
{
if (special->z+special->height < toucher->z + toucher->height / 3
if (special->z+special->height < toucher->z
|| special->z+special->height > toucher->z + (toucher->height*2/3))
return; // Only go in the mouth
}
else if (special->z < toucher->z + toucher->height / 3
else if (special->z < toucher->z
|| special->z > toucher->z + (toucher->height*2/3))
return; // Only go in the mouth
@ -2469,8 +2484,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
else if (P_IsLocalPlayer(target->player))
gameovermus = true;
if (gameovermus)
P_PlayJingle(target->player, JT_GOVER); // Yousa dead now, Okieday? Tails 03-14-2000
if (gameovermus) // Yousa dead now, Okieday? Tails 03-14-2000
S_ChangeMusicEx("_gover", 0, 0, 0, (2*MUSICRATE) - (MUSICRATE/25), 0); // 1.96 seconds
//P_PlayJingle(target->player, JT_GOVER); // can't be used because incompatible with track fadeout
if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && numgameovers < maxgameovers)
{
@ -2594,6 +2610,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
case MT_EGGMOBILE3:
{
mobj_t *mo2;
thinker_t *th;
UINT32 i = 0; // to check how many clones we've removed
@ -2614,6 +2631,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
mo->scalespeed = (mo->scale - mo->destscale)/(2*TICRATE);
mo->momz = mo->info->speed;
mo->angle = FixedAngle((P_RandomKey(36)*10)<<FRACBITS);
mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK);
mo2->angle = mo->angle;
P_SetMobjState(mo2, S_BOSSSEBH2);
if (++i == 2) // we've already removed 2 of these, let's stop now
break;
else
@ -3418,7 +3440,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false;
// Make sure that boxes cannot be popped by enemies, red rings, etc.
if (target->flags & MF_MONITOR && ((!source || !source->player || source->player->bot) || (inflictor && !inflictor->player)))
if (target->flags & MF_MONITOR && ((!source || !source->player || source->player->bot)
|| (inflictor && inflictor->type >= MT_REDRING && inflictor->type <= MT_GRENADERING)))
return false;
}
@ -3500,7 +3523,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return true;
}
if (G_IsSpecialStage(gamemap))
if (G_IsSpecialStage(gamemap) && !(damagetype & DMG_DEATHMASK))
{
P_SpecialStageDamage(player, inflictor, source);
return true;
@ -3524,10 +3547,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
// Instant-Death
if (damagetype & DMG_DEATHMASK)
{
P_KillPlayer(player, source, damage);
player->rings = player->spheres = 0;
}
else if (metalrecording)
{
if (!inflictor)

View file

@ -115,10 +115,10 @@ typedef struct camera_s
extern camera_t camera, camera2;
extern consvar_t cv_cam_dist, cv_cam_still, cv_cam_height;
extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed;
extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed, cv_cam_orbit, cv_cam_adjust;
extern consvar_t cv_cam2_dist, cv_cam2_still, cv_cam2_height;
extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed;
extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed, cv_cam2_orbit, cv_cam2_adjust;
extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate;
extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate;
@ -509,7 +509,7 @@ extern INT32 ceilmovesound;
void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
INT16 starpostx, INT16 starposty, INT16 starpostz,
INT32 starpostnum, tic_t starposttime, angle_t starpostangle,
INT32 flags2);
fixed_t starpostscale, angle_t drawangle, INT32 flags2);
boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, boolean flash, boolean dontstopmove);
boolean P_SetMobjStateNF(mobj_t *mobj, statenum_t state);
boolean P_CheckMissileSpawn(mobj_t *th);

View file

@ -345,8 +345,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
if (horizspeed)
{
object->player->drawangle = spring->angle;
if (vertispeed || (object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0))
{
object->angle = spring->angle;
if (!demoplayback || P_AnalogMove(object->player))
@ -357,7 +355,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
localangle2 = spring->angle;
}
}
}
pflags = object->player->pflags & (PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING); // I still need these.
secondjump = object->player->secondjump;
@ -1022,7 +1019,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // underneath
if (tmthing->flags & MF_SHOOTABLE && thing->health > 0)
{
UINT8 damagetype = (thing->info->mass & 0xFF);
UINT32 damagetype = (thing->info->mass & 0xFF);
if (!damagetype && thing->flags & MF_FIRE) // BURN!
damagetype = DMG_FIRE;
if (P_DamageMobj(tmthing, thing, thing, 1, damagetype) && (damagetype = (thing->info->mass>>8)))
@ -1039,7 +1036,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // underneath
if (thing->flags & MF_SHOOTABLE && tmthing->health > 0)
{
UINT8 damagetype = (tmthing->info->mass & 0xFF);
UINT32 damagetype = (tmthing->info->mass & 0xFF);
if (!damagetype && tmthing->flags & MF_FIRE) // BURN!
damagetype = DMG_FIRE;
if (P_DamageMobj(thing, tmthing, tmthing, 1, damagetype) && (damagetype = (tmthing->info->mass>>8)))
@ -2884,11 +2881,8 @@ static boolean P_ThingHeightClip(mobj_t *thing)
thing->z = thing->ceilingz - thing->height;
}
if (thing->z != oldz)
{
if (thing->player)
if (P_MobjFlip(thing)*(thing->z - oldz) > 0 && thing->player)
P_PlayerHitFloor(thing->player, !onfloor);
}
// debug: be sure it falls to the floor
thing->eflags &= ~MFE_ONGROUND;
@ -3202,7 +3196,7 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
&& glidesector->sector->ceilingpic == skyflatnum)
return false;
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz)
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < floorz)
|| (player->mo->z >= ceilingz))
floorclimb = true;
}

View file

@ -2381,21 +2381,41 @@ boolean P_CheckDeathPitCollide(mobj_t *mo)
boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover)
{
fixed_t topheight;
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
// not a lava block with solid planes
if (!(rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
&& !(rover->master->flags & ML_BLOCKMONSTERS)))
return false;
// is solid from the sides
if (rover->master->flags & ML_EFFECT3)
return true;
if (mo->eflags & MFE_VERTICALFLIP)
{
fixed_t topheight =
topheight =
#ifdef ESLOPE
*rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) :
#endif
*rover->bottomheight;
if (mo->z+mo->height-mo->momz < topheight + FixedMul(16*FRACUNIT, mo->scale))
return true;
return false;
}
topheight =
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) :
#endif
*rover->topheight;
if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
&& !(rover->master->flags & ML_BLOCKMONSTERS)
&& ((rover->master->flags & ML_EFFECT3) || mo->z-mo->momz > topheight - FixedMul(16*FRACUNIT, mo->scale)))
if (mo->z-mo->momz > topheight - FixedMul(16*FRACUNIT, mo->scale))
return true;
}
return false;
}
@ -2954,7 +2974,7 @@ static void P_PlayerZMovement(mobj_t *mo)
}
// Get up if you fell.
if (mo->player->panim == PA_PAIN)
P_SetPlayerMobjState(mo, S_PLAY_STND);
P_SetPlayerMobjState(mo, S_PLAY_WALK);
#ifdef ESLOPE
if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) {
@ -3760,7 +3780,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
if (thiscam->momx || thiscam->momy)
{
if (!P_TryCameraMove(thiscam->x + thiscam->momx, thiscam->y + thiscam->momy, thiscam))
if (!P_TryCameraMove(thiscam->x + thiscam->momx, thiscam->y + thiscam->momy, thiscam)) // Thanks for the greatly improved camera, Lach -- Sev
{ // Never fails for 2D mode.
mobj_t dummy;
dummy.thinker.function.acp1 = (actionf_p1)P_MobjThinker;
@ -3770,9 +3790,22 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
dummy.z = thiscam->z;
dummy.height = thiscam->height;
if (!resetcalled && !(player->pflags & PF_NOCLIP) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead.
{
P_ResetCamera(player, thiscam);
resetcalled = true;
}
else
{
fixed_t camspeed = P_AproxDistance(thiscam->momx, thiscam->momy);
P_SlideCameraMove(thiscam);
if (!resetcalled && P_AproxDistance(thiscam->momx, thiscam->momy) == camspeed)
{
P_ResetCamera(player, thiscam);
resetcalled = true;
}
}
if (resetcalled) // Okay this means the camera is fully reset.
return true;
}
@ -3981,6 +4014,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
}
else
{
#if 0 // i don't know why this is here, it's causing a few undesired state glitches, and disabling it doesn't appear to negatively affect the game, but i don't want it gone permanently just in case some obscure bug crops up
if (!(mobj->player->powers[pw_carry] == CR_NIGHTSMODE)) // used for drilling
mobj->player->pflags &= ~PF_STARTJUMP;
mobj->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
@ -3990,6 +4024,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
mobj->player->powers[pw_tailsfly] = 0;
P_SetPlayerMobjState(mobj, S_PLAY_WALK);
}
#endif
mobj->eflags &= ~MFE_JUSTHITFLOOR;
}
@ -4359,12 +4394,6 @@ static void P_Boss3Thinker(mobj_t *mobj)
if (mobj->flags2 & MF2_FRET)
mobj->movedir = 1;
if (!mobj->tracer)
{
var1 = 1;
A_BossJetFume(mobj);
}
if (mobj->health <= 0)
return;
/*
@ -4493,7 +4522,7 @@ static void P_Boss3Thinker(mobj_t *mobj)
if (mobj->health <= mobj->info->damage) // pinch phase
mobj->movecount--; // limited number of shots before diving again
if (mobj->movecount)
P_SetMobjState(mobj, mobj->info->missilestate);
P_SetMobjState(mobj, mobj->info->missilestate+1);
}
}
else if (mobj->threshold >= 0) // Traveling mode
@ -4592,6 +4621,15 @@ static void P_Boss3Thinker(mobj_t *mobj)
ang += (ANGLE_MAX/64);
}
S_StartSound(mobj, sfx_fizzle);
// look for a new target
P_BossTargetPlayer(mobj, false);
if (mobj->target && mobj->target->player)
{
A_FaceTarget(mobj);
P_SetMobjState(mobj, mobj->info->missilestate);
}
}
else if (mobj->flags2 & (MF2_STRONGBOX|MF2_CLASSICPUSH)) // just hit the bottom of your tube
{
@ -5527,8 +5565,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
mobj->tracer->destscale = FRACUNIT + (4*TICRATE - mobj->fuse)*(FRACUNIT/2)/TICRATE + FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT),FRACUNIT/2);
P_SetScale(mobj->tracer, mobj->tracer->destscale);
}
else
mobj->tracer->frame &= ~FF_TRANSMASK; // this causes a flicker but honestly i like it this way
P_TeleportMove(mobj->tracer, mobj->x, mobj->y, mobj->z + mobj->height/2 - mobj->tracer->height/2);
mobj->tracer->momx = mobj->momx;
mobj->tracer->momy = mobj->momy;
@ -5645,12 +5682,12 @@ static void P_Boss9Thinker(mobj_t *mobj)
if (mobj->health > mobj->info->damage)
{
P_SetScale(missile, FRACUNIT/2);
P_SetScale(missile, FRACUNIT/3);
missile->color = SKINCOLOR_GOLD; // sonic cd electric power
}
else
{
P_SetScale(missile, FRACUNIT/4);
P_SetScale(missile, FRACUNIT/5);
missile->color = SKINCOLOR_MAGENTA; // sonic OVA/4 purple power
}
missile->destscale = missile->scale*2;
@ -5940,9 +5977,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
P_SetTarget(&mobj->tracer, shield);
P_SetTarget(&shield->target, mobj);
shield->height -= 20*FRACUNIT; // different offset...
shield->color = SKINCOLOR_MAGENTA;
shield->colorized = true;
P_SetMobjState(shield, S_FIRS1);
P_SetMobjState(shield, S_MSSHIELD_F2);
//P_LinedefExecute(LE_PINCHPHASE, mobj, NULL); -- why does this happen twice? see case 2...
}
mobj->fuse = 4*TICRATE;
@ -7093,9 +7128,7 @@ void P_MobjThinker(mobj_t *mobj)
switch (mobj->type)
{
case MT_BOSSTANK1:
case MT_BOSSTANK2:
case MT_BOSSSPIGOT:
case MT_BOSSJUNK:
mobj->flags2 ^= MF2_DONTDRAW;
break;
case MT_MACEPOINT:
@ -7681,12 +7714,22 @@ void P_MobjThinker(mobj_t *mobj)
switch (mobj->type)
{
case MT_EGGMOBILE:
if (mobj->health < mobj->info->damage+1 && leveltime & 1 && mobj->health > 0)
P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMOKE);
if (mobj->health < mobj->info->damage+1 && leveltime & 2)
{
fixed_t rad = mobj->radius>>FRACBITS;
fixed_t hei = mobj->height>>FRACBITS;
mobj_t *particle = P_SpawnMobjFromMobj(mobj,
P_RandomRange(rad, -rad)<<FRACBITS,
P_RandomRange(rad, -rad)<<FRACBITS,
P_RandomRange(hei/2, hei)<<FRACBITS,
MT_SMOKE);
P_SetObjectMomZ(particle, 2<<FRACBITS, false);
particle->momz += mobj->momz;
}
if (mobj->flags2 & MF2_SKULLFLY)
#if 1
P_SpawnGhostMobj(mobj);
#else
#else // all the way back from final demo... MT_THOK isn't even the same size anymore!
{
mobj_t *spawnmobj;
spawnmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->info->painchance);
@ -7697,12 +7740,48 @@ void P_MobjThinker(mobj_t *mobj)
P_Boss1Thinker(mobj);
break;
case MT_EGGMOBILE2:
if (mobj->health < mobj->info->damage+1 && leveltime & 2)
{
fixed_t rad = mobj->radius>>FRACBITS;
fixed_t hei = mobj->height>>FRACBITS;
mobj_t *particle = P_SpawnMobjFromMobj(mobj,
P_RandomRange(rad, -rad)<<FRACBITS,
P_RandomRange(rad, -rad)<<FRACBITS,
P_RandomRange(hei/2, hei)<<FRACBITS,
MT_SMOKE);
P_SetObjectMomZ(particle, 2<<FRACBITS, false);
particle->momz += mobj->momz;
}
P_Boss2Thinker(mobj);
break;
case MT_EGGMOBILE3:
if (mobj->health < mobj->info->damage+1 && leveltime & 2)
{
fixed_t rad = mobj->radius>>FRACBITS;
fixed_t hei = mobj->height>>FRACBITS;
mobj_t *particle = P_SpawnMobjFromMobj(mobj,
P_RandomRange(rad, -rad)<<FRACBITS,
P_RandomRange(rad, -rad)<<FRACBITS,
P_RandomRange(hei/2, hei)<<FRACBITS,
MT_SMOKE);
P_SetObjectMomZ(particle, 2<<FRACBITS, false);
particle->momz += mobj->momz;
}
P_Boss3Thinker(mobj);
break;
case MT_EGGMOBILE4:
if (mobj->health < mobj->info->damage+1 && leveltime & 2)
{
fixed_t rad = mobj->radius>>FRACBITS;
fixed_t hei = mobj->height>>FRACBITS;
mobj_t *particle = P_SpawnMobjFromMobj(mobj,
P_RandomRange(rad, -rad)<<FRACBITS,
P_RandomRange(rad, -rad)<<FRACBITS,
P_RandomRange(hei/2, hei)<<FRACBITS,
MT_SMOKE);
P_SetObjectMomZ(particle, 2<<FRACBITS, false);
particle->momz += mobj->momz;
}
P_Boss4Thinker(mobj);
break;
case MT_FANG:
@ -8318,30 +8397,6 @@ void P_MobjThinker(mobj_t *mobj)
mobj->fuse++;
}
break;
case MT_PROPELLER:
{
fixed_t jetx, jety;
if (!mobj->target // if you have no target
|| (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now
{ // then remove yourself as well!
P_RemoveMobj(mobj);
return;
}
jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale));
jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale));
P_UnsetThingPosition(mobj);
mobj->x = jetx;
mobj->y = jety;
mobj->z = mobj->target->z + FixedMul(17*FRACUNIT, mobj->target->scale);
mobj->angle = mobj->target->angle - ANGLE_180;
mobj->floorz = mobj->z;
mobj->ceilingz = mobj->z+mobj->height;
P_SetThingPosition(mobj);
}
break;
case MT_JETFLAME:
{
if (!mobj->target // if you have no target
@ -8405,6 +8460,17 @@ void P_MobjThinker(mobj_t *mobj)
}
else
{
fixed_t basex = mobj->cusval, basey = mobj->cvmem;
if (mobj->spawnpoint && mobj->spawnpoint->options & (MTF_AMBUSH|MTF_OBJECTSPECIAL))
{
angle_t sideang = mobj->movedir + ((mobj->spawnpoint->options & MTF_AMBUSH) ? ANGLE_90 : -ANGLE_90);
fixed_t oscillate = FixedMul(FINESINE(((leveltime*ANG1)>>(ANGLETOFINESHIFT+2)) & FINEMASK), 250*mobj->scale);
basex += P_ReturnThrustX(mobj, sideang, oscillate);
basey += P_ReturnThrustY(mobj, sideang, oscillate);
}
mobj->z = mobj->threshold + FixedMul(FINESINE(((leveltime + mobj->movecount)*ANG2>>(ANGLETOFINESHIFT-2)) & FINEMASK), 8*mobj->scale);
if (mobj->state != &states[mobj->info->meleestate])
{
@ -8433,8 +8499,8 @@ void P_MobjThinker(mobj_t *mobj)
if (players[i].mo->z + players[i].mo->height < mobj->z - 8*mobj->scale)
continue;
compdist = P_AproxDistance(
players[i].mo->x + players[i].mo->momx - mobj->cusval,
players[i].mo->y + players[i].mo->momy - mobj->cvmem);
players[i].mo->x + players[i].mo->momx - basex,
players[i].mo->y + players[i].mo->momy - basey);
if (compdist >= dist)
continue;
dist = compdist;
@ -8448,14 +8514,14 @@ void P_MobjThinker(mobj_t *mobj)
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y);
if (P_AproxDistance(
mobj->x - mobj->cusval,
mobj->y - mobj->cvmem)
mobj->x - basex,
mobj->y - basey)
< mobj->scale)
S_StartSound(mobj, mobj->info->seesound);
P_TeleportMove(mobj,
(15*(mobj->x>>4)) + (mobj->cusval>>4) + P_ReturnThrustX(mobj, mobj->angle, SPECTATORRADIUS>>4),
(15*(mobj->y>>4)) + (mobj->cvmem>>4) + P_ReturnThrustY(mobj, mobj->angle, SPECTATORRADIUS>>4),
(15*(mobj->x>>4)) + (basex>>4) + P_ReturnThrustX(mobj, mobj->angle, SPECTATORRADIUS>>4),
(15*(mobj->y>>4)) + (basey>>4) + P_ReturnThrustY(mobj, mobj->angle, SPECTATORRADIUS>>4),
mobj->z);
}
else
@ -8478,18 +8544,12 @@ void P_MobjThinker(mobj_t *mobj)
if (!didmove)
{
if (P_AproxDistance(
mobj->x - mobj->cusval,
mobj->y - mobj->cvmem)
< mobj->scale)
P_TeleportMove(mobj,
mobj->cusval,
mobj->cvmem,
mobj->z);
if (P_AproxDistance(mobj->x - basex, mobj->y - basey) < mobj->scale)
P_TeleportMove(mobj, basex, basey, mobj->z);
else
P_TeleportMove(mobj,
(15*(mobj->x>>4)) + (mobj->cusval>>4),
(15*(mobj->y>>4)) + (mobj->cvmem>>4),
(15*(mobj->x>>4)) + (basex>>4),
(15*(mobj->y>>4)) + (basey>>4),
mobj->z);
}
}
@ -9038,9 +9098,9 @@ void P_MobjThinker(mobj_t *mobj)
{
if (mobj->state->action.acp1 == (actionf_p1)A_Boss1Laser)
{
var1 = mobj->state->var1;
var2 = mobj->state->var2;
mobj->state->action.acp1(mobj);
/*var1 = mobj->state->var1;
var2 = mobj->state->var2 & 65535;
mobj->state->action.acp1(mobj);*/
}
else if (leveltime & 1) // Fire mode
{
@ -10387,7 +10447,7 @@ void P_SpawnPlayer(INT32 playernum)
mobj_t *mobj;
if (p->playerstate == PST_REBORN)
G_PlayerReborn(playernum);
G_PlayerReborn(playernum, false);
// spawn as spectator determination
if (!G_GametypeHasSpectators())
@ -10395,9 +10455,9 @@ void P_SpawnPlayer(INT32 playernum)
p->spectator = p->outofcoop =
(((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop
&& ((leveltime > 0
&& ((G_IsSpecialStage(gamemap) && (maptol & TOL_NIGHTS)) // late join special stage
&& ((G_IsSpecialStage(gamemap)) // late join special stage
|| (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->outofcoop)))) // late join or die in new coop
|| (((cv_cooplives.value == 1) || !P_GetLives(p)) && p->lives <= 0))); // game over and can't redistribute lives
|| (!P_GetLives(p) && p->lives <= 0))); // game over and can't redistribute lives
}
else
{
@ -10464,7 +10524,6 @@ void P_SpawnPlayer(INT32 playernum)
P_SetupStateAnimation(mobj, mobj->state);
mobj->health = 1;
p->rings = p->spheres = 0;
p->playerstate = PST_LIVE;
p->bonustime = false;
@ -10521,10 +10580,6 @@ void P_AfterPlayerSpawn(INT32 playernum)
else
p->viewz = p->mo->z + p->viewheight;
if (p->powers[pw_carry] != CR_NIGHTSMODE)
P_SetPlayerMobjState(p->mo, S_PLAY_STND);
p->pflags &= ~PF_SPINNING;
if (playernum == consoleplayer)
{
// wake up the status bar
@ -10609,6 +10664,8 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
mobj->eflags |= MFE_VERTICALFLIP;
mobj->flags2 |= MF2_OBJECTFLIP;
}
if (mthing->options & MTF_AMBUSH)
P_SetPlayerMobjState(mobj, S_PLAY_FALL);
}
else
z = floor;
@ -10627,7 +10684,12 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
P_SetThingPosition(mobj);
mobj->z = z;
if (mobj->z == mobj->floorz)
if (mobj->flags2 & MF2_OBJECTFLIP)
{
if (mobj->z + mobj->height == mobj->ceilingz)
mobj->eflags |= MFE_ONGROUND;
}
else if (mobj->z == mobj->floorz)
mobj->eflags |= MFE_ONGROUND;
mobj->angle = angle;
@ -10663,17 +10725,29 @@ void P_MovePlayerToStarpost(INT32 playernum)
sector->ceilingheight;
z = p->starpostz << FRACBITS;
if (z < floor)
P_SetScale(mobj, (mobj->destscale = abs(p->starpostscale)));
if (p->starpostscale < 0)
{
mobj->flags2 |= MF2_OBJECTFLIP;
if (z >= ceiling)
{
mobj->eflags |= MFE_ONGROUND;
z = ceiling;
}
z -= mobj->height;
}
else if (z <= floor)
{
mobj->eflags |= MFE_ONGROUND;
z = floor;
else if (z > ceiling - mobjinfo[MT_PLAYER].height)
z = ceiling - mobjinfo[MT_PLAYER].height;
}
mobj->floorz = floor;
mobj->ceilingz = ceiling;
mobj->z = z;
if (mobj->z == mobj->floorz)
mobj->eflags |= MFE_ONGROUND;
mobj->angle = p->starpostangle;

View file

@ -189,6 +189,7 @@ static void P_NetArchivePlayers(void)
WRITEINT16(save_p, players[i].starpostz);
WRITEINT32(save_p, players[i].starpostnum);
WRITEANGLE(save_p, players[i].starpostangle);
WRITEFIXED(save_p, players[i].starpostscale);
WRITEANGLE(save_p, players[i].angle_pos);
WRITEANGLE(save_p, players[i].old_angle_pos);
@ -397,6 +398,7 @@ static void P_NetUnArchivePlayers(void)
players[i].starpostz = READINT16(save_p);
players[i].starpostnum = READINT32(save_p);
players[i].starpostangle = READANGLE(save_p);
players[i].starpostscale = READFIXED(save_p);
players[i].angle_pos = READANGLE(save_p);
players[i].old_angle_pos = READANGLE(save_p);
@ -4117,12 +4119,54 @@ static inline boolean P_NetUnArchiveMisc(void)
return true;
}
static inline void P_ArchiveLuabanksAndConsistency(void)
{
UINT8 i, banksinuse = NUM_LUABANKS;
while (banksinuse && !luabanks[banksinuse-1])
banksinuse--; // get the last used bank
if (banksinuse)
{
WRITEUINT8(save_p, 0xb7); // luabanks marker
WRITEUINT8(save_p, banksinuse);
for (i = 0; i < banksinuse; i++)
WRITEINT32(save_p, luabanks[i]);
}
WRITEUINT8(save_p, 0x1d); // consistency marker
}
static inline boolean P_UnArchiveLuabanksAndConsistency(void)
{
switch (READUINT8(save_p))
{
case 0xb7:
{
UINT8 i, banksinuse = READUINT8(save_p);
if (banksinuse > NUM_LUABANKS)
return false;
for (i = 0; i < banksinuse; i++)
luabanks[i] = READINT32(save_p);
if (READUINT8(save_p) != 0x1d)
return false;
}
case 0x1d:
break;
default:
return false;
}
return true;
}
void P_SaveGame(void)
{
P_ArchiveMisc();
P_ArchivePlayer();
WRITEUINT8(save_p, 0x1d); // consistency marker
// yes, even in non HAVE_BLUA
P_ArchiveLuabanksAndConsistency();
}
void P_SaveNetGame(void)
@ -4161,7 +4205,7 @@ void P_SaveNetGame(void)
LUA_Archive();
#endif
WRITEUINT8(save_p, 0x1d); // consistency marker
P_ArchiveLuabanksAndConsistency();
}
boolean P_LoadGame(INT16 mapoverride)
@ -4173,8 +4217,7 @@ boolean P_LoadGame(INT16 mapoverride)
P_UnArchiveSPGame(mapoverride);
P_UnArchivePlayer();
// Savegame end marker
if (READUINT8(save_p) != 0x1d)
if (!P_UnArchiveLuabanksAndConsistency())
return false;
// Only do this after confirming savegame is ok
@ -4215,5 +4258,5 @@ boolean P_LoadNetGame(void)
// precipitation when loading a netgame save. Instead, precip has to be spawned here.
// This is done in P_NetUnArchiveSpecials now.
return READUINT8(save_p) == 0x1d;
return P_UnArchiveLuabanksAndConsistency();
}

View file

@ -221,6 +221,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->muspostbosstrack = 0;
mapheaderinfo[num]->muspostbosspos = 0;
mapheaderinfo[num]->muspostbossfadein = 0;
mapheaderinfo[num]->musforcereset = -1;
mapheaderinfo[num]->forcecharacter[0] = '\0';
mapheaderinfo[num]->weather = 0;
mapheaderinfo[num]->skynum = 1;
@ -573,6 +574,11 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
// store the flat lump number
levelflat->lumpnum = R_GetFlatNumForName(flatname);
levelflat->texturenum = R_CheckTextureNumForName(flatname);
levelflat->lasttexturenum = levelflat->texturenum;
levelflat->baselumpnum = LUMPERROR;
levelflat->basetexturenum = -1;
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
@ -617,6 +623,11 @@ INT32 P_AddLevelFlatRuntime(const char *flatname)
// store the flat lump number
levelflat->lumpnum = R_GetFlatNumForName(flatname);
levelflat->texturenum = R_CheckTextureNumForName(flatname);
levelflat->lasttexturenum = levelflat->texturenum;
levelflat->baselumpnum = LUMPERROR;
levelflat->basetexturenum = -1;
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
@ -1480,6 +1491,7 @@ static void P_LoadRawSideDefs2(void *data)
case 425: // Calls P_SetMobjState on calling mobj
case 434: // Custom Power
case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
case 461: // Spawns an object on the map based on texture offsets
{
char process[8*3+1];
memset(process,0,8*3+1);
@ -2234,6 +2246,8 @@ static void P_LevelInitStuff(void)
for (i = 0; i < MAXPLAYERS; i++)
{
G_PlayerReborn(i, true);
if (canresetlives && (netgame || multiplayer) && playeringame[i] && (gametype == GT_COMPETITION || players[i].lives <= 0))
{
// In Co-Op, replenish a user's lives if they are depleted.
@ -2241,41 +2255,18 @@ static void P_LevelInitStuff(void)
}
// obliteration station...
players[i].rings = players[i].spheres =\
players[i].xtralife = players[i].deadtimer =\
players[i].numboxes = players[i].totalring =\
players[i].laps = players[i].aiming =\
players[i].losstime = players[i].timeshit =\
players[i].marescore = players[i].lastmarescore =\
players[i].maxlink = players[i].startedtime =\
players[i].finishedtime = players[i].finishedspheres =\
players[i].finishedrings = players[i].lastmare =\
players[i].lastmarelap = players[i].lastmarebonuslap =\
players[i].totalmarelap = players[i].totalmarebonuslap =\
players[i].marebegunat = players[i].textvar =\
players[i].texttimer = players[i].linkcount =\
players[i].linktimer = players[i].flyangle =\
players[i].anotherflyangle = players[i].nightstime =\
players[i].oldscale = players[i].mare = players[i].marelap =\
players[i].marebonuslap = players[i].lapbegunat =\
players[i].lapstartedtime = players[i].totalmarescore =\
players[i].realtime = players[i].exiting = 0;
players[i].laps = players[i].marescore = players[i].lastmarescore =\
players[i].mare = players[i].exiting = 0;
// i guess this could be part of the above but i feel mildly uncomfortable implicitly casting
players[i].gotcontinue = false;
// aha, the first evidence this shouldn't be a memset!
players[i].drillmeter = 40*20;
P_ResetPlayer(&players[i]);
// hit these too
players[i].pflags &= ~(PF_GAMETYPEOVER|PF_TRANSFERTOCLOSEST);
// unset ALL the pointers. P_SetTarget isn't needed here because if this
// function is being called we're just going to clobber the data anyways
players[i].mo = players[i].followmobj = players[i].awayviewmobj =\
players[i].capsule = players[i].axis1 = players[i].axis2 = players[i].drone = NULL;
players[i].pflags &= ~(PF_GAMETYPEOVER);
}
if (botingame)
CV_SetValue(&cv_analog2, true);
}
//
@ -2692,7 +2683,7 @@ boolean P_SetupLevel(boolean skipprecip)
S_StartSound(NULL, sfx_s3kaf);
// Fade music! Time it to S3KAF: 0.25 seconds is snappy.
if (cv_resetmusic.value ||
if (RESETMUSIC ||
strnicmp(S_MusicName(),
(mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap-1]->musname : mapmusname, 7))
S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_towhite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE)
@ -2725,7 +2716,7 @@ boolean P_SetupLevel(boolean skipprecip)
// Fade out music here. Deduct 2 tics so the fade volume actually reaches 0.
// But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug.
if (!titlemapinaction && (cv_resetmusic.value ||
if (!titlemapinaction && (RESETMUSIC ||
strnicmp(S_MusicName(),
(mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap-1]->musname : mapmusname, 7)))
S_FadeMusic(0, FixedMul(

View file

@ -37,12 +37,19 @@ typedef struct
{
char name[9]; // resource name from wad
lumpnum_t lumpnum; // lump number of the flat
INT32 texturenum, lasttexturenum; // texture number of the flat
UINT16 width, height;
fixed_t topoffset, leftoffset;
// for flat animation
lumpnum_t baselumpnum;
INT32 basetexturenum;
INT32 animseq; // start pos. in the anim sequence
INT32 numpics;
INT32 speed;
// for patchflats
UINT8 *flatpatch;
} levelflat_t;
extern size_t numlevelflats;

View file

@ -205,8 +205,8 @@ void P_InitPicAnims(void)
if ((W_CheckNumForName(animdefs[i].startname)) == LUMPERROR)
continue;
lastanim->picnum = R_FlatNumForName(animdefs[i].endname);
lastanim->basepic = R_FlatNumForName(animdefs[i].startname);
lastanim->picnum = R_GetFlatNumForName(animdefs[i].endname);
lastanim->basepic = R_GetFlatNumForName(animdefs[i].startname);
}
lastanim->istexture = animdefs[i].istexture;
@ -464,7 +464,19 @@ static inline void P_FindAnimatedFlat(INT32 animnum)
for (i = 0; i < numlevelflats; i++, foundflats++)
{
// is that levelflat from the flat anim sequence ?
if (foundflats->lumpnum >= startflatnum && foundflats->lumpnum <= endflatnum)
if ((anims[animnum].istexture) && (foundflats->texturenum != 0 && foundflats->texturenum != -1)
&& ((UINT16)foundflats->texturenum >= startflatnum && (UINT16)foundflats->texturenum <= endflatnum))
{
foundflats->basetexturenum = startflatnum;
foundflats->animseq = foundflats->texturenum - startflatnum;
foundflats->numpics = endflatnum - startflatnum + 1;
foundflats->speed = anims[animnum].speed;
CONS_Debug(DBG_SETUP, "animflat: #%03d name:%.8s animseq:%d numpics:%d speed:%d\n",
atoi(sizeu1(i)), foundflats->name, foundflats->animseq,
foundflats->numpics,foundflats->speed);
}
else if (foundflats->lumpnum >= startflatnum && foundflats->lumpnum <= endflatnum)
{
foundflats->baselumpnum = startflatnum;
foundflats->animseq = foundflats->lumpnum - startflatnum;
@ -488,11 +500,8 @@ void P_SetupLevelFlatAnims(void)
// the original game flat anim sequences
for (i = 0; anims[i].istexture != -1; i++)
{
if (!anims[i].istexture)
P_FindAnimatedFlat(i);
}
}
//
// UTILITIES
@ -3953,6 +3962,39 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
}
break;
case 461: // Spawns an object on the map based on texture offsets
{
const mobjtype_t type = (mobjtype_t)(sides[line->sidenum[0]].toptexture);
mobj_t *mobj;
fixed_t x, y, z;
x = sides[line->sidenum[0]].textureoffset;
y = sides[line->sidenum[0]].rowoffset;
z = line->frontsector->floorheight;
if (line->flags & ML_NOCLIMB) // If noclimb is set, spawn randomly within a range
{
if (line->sidenum[1] != 0xffff) // Make sure the linedef has a back side
{
x = P_RandomRange(sides[line->sidenum[0]].textureoffset>>FRACBITS, sides[line->sidenum[1]].textureoffset>>FRACBITS)<<FRACBITS;
y = P_RandomRange(sides[line->sidenum[0]].rowoffset>>FRACBITS, sides[line->sidenum[1]].rowoffset>>FRACBITS)<<FRACBITS;
z = P_RandomRange(line->frontsector->floorheight>>FRACBITS, line->frontsector->ceilingheight>>FRACBITS)<<FRACBITS;
}
else
{
CONS_Alert(CONS_WARNING,"Linedef Type %d - Spawn Object: Linedef is set for random range but has no back side.\n", line->special);
break;
}
}
mobj = P_SpawnMobj(x, y, z, type);
if (mobj)
CONS_Debug(DBG_GAMELOGIC, "Linedef Type %d - Spawn Object: %d spawned at (%d, %d, %d)\n", line->special, mobj->type, mobj->x>>FRACBITS, mobj->y>>FRACBITS, mobj->z>>FRACBITS); //TODO: Convert mobj->type to a string somehow.
else
CONS_Alert(CONS_ERROR,"Linedef Type %d - Spawn Object: Object did not spawn!\n", line->special);
}
break;
#ifdef POLYOBJECTS
case 480: // Polyobj_DoorSlide
case 481: // Polyobj_DoorSwing
@ -4942,7 +4984,7 @@ DoneSection2:
CONS_Printf(M_GetText("%s started lap %u\n"), player_names[player-players], (UINT32)player->laps+1);
// Reset starposts (checkpoints) info
player->starpostangle = player->starposttime = player->starpostnum = 0;
player->starpostscale = player->starpostangle = player->starposttime = player->starpostnum = 0;
player->starpostx = player->starposty = player->starpostz = 0;
P_ResetStarposts();
@ -5636,9 +5678,12 @@ void P_UpdateSpecials(void)
{
if (foundflats->speed) // it is an animated flat
{
// update the levelflat texture number
if (foundflats->basetexturenum != -1)
foundflats->texturenum = foundflats->basetexturenum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics);
// update the levelflat lump number
foundflats->lumpnum = foundflats->baselumpnum +
((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics);
else if (foundflats->baselumpnum != LUMPERROR)
foundflats->lumpnum = foundflats->baselumpnum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics);
}
}
}

View file

@ -33,7 +33,7 @@
void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
INT16 starpostx, INT16 starposty, INT16 starpostz,
INT32 starpostnum, tic_t starposttime, angle_t starpostangle,
INT32 flags2)
fixed_t starpostscale, angle_t drawangle, INT32 flags2)
{
const INT32 takeflags2 = MF2_TWOD|MF2_OBJECTFLIP;
@ -89,8 +89,11 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
thing->player->starpostz = starpostz;
thing->player->starposttime = starposttime;
thing->player->starpostangle = starpostangle;
thing->player->starpostscale = starpostscale;
thing->player->starpostnum = starpostnum;
thing->player->drawangle = drawangle;
// Reset map starposts for the player's new info.
P_ResetStarposts();
P_ClearStarPost(starpostnum);

View file

@ -1109,7 +1109,7 @@ boolean P_PlayerCanDamage(player_t *player, mobj_t *thing)
}
else if (P_MobjFlip(player->mo)*(topheight - (thing->z + thing->height/2)) < 0)
{
if (player->charability == CA_FLY && player->panim == PA_ABILITY && (P_MobjFlip(player->mo)*(player->mo->momz - thing->momz) > 0))
if (player->charability == CA_FLY && player->panim == PA_ABILITY && !(player->mo->eflags & MFE_UNDERWATER) && (P_MobjFlip(player->mo)*(player->mo->momz - thing->momz) > 0))
return true;
}
@ -2217,6 +2217,20 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
player->pflags &= ~PF_SPINNING;
}
if (player->pflags & PF_BOUNCING)
{
if (dorollstuff && player->mo->state-states != S_PLAY_BOUNCE_LANDING)
{
P_MobjCheckWater(player->mo);
player->mo->momz *= -1;
P_DoAbilityBounce(player, true);
if (player->scoreadd)
player->scoreadd--;
}
clipmomz = false;
}
else
{
if (player->pflags & PF_SPINNING)
{
if (player->mo->state-states != S_PLAY_ROLL && !(player->pflags & PF_STARTDASH))
@ -2349,15 +2363,6 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
clipmomz = false;
}
}
if (player->pflags & PF_BOUNCING)
{
P_MobjCheckWater(player->mo);
player->mo->momz *= -1;
P_DoAbilityBounce(player, true);
if (player->scoreadd)
player->scoreadd--;
clipmomz = false;
}
}
@ -2964,22 +2969,19 @@ static void P_DoBubbleBreath(player_t *player)
P_SetScale(bubble, bubble->destscale);
}
if (player->powers[pw_carry] == CR_NIGHTSMODE) // NiGHTS Super doesn't spawn flight bubbles
return;
// Tails stirs up the water while flying in it
if (player->powers[pw_tailsfly] && (leveltime & 1) && player->charability != CA_SWIM)
{
fixed_t radius = (3*player->mo->radius)>>1;
fixed_t radius = player->mo->radius;
angle_t fa = ((leveltime%45)*FINEANGLES/8) & FINEMASK;
fixed_t stirwaterx = FixedMul(FINECOSINE(fa),radius);
fixed_t stirwatery = FixedMul(FINESINE(fa),radius);
fixed_t stirwaterz;
if (player->mo->eflags & MFE_VERTICALFLIP)
stirwaterz = player->mo->z + player->mo->height - FixedDiv(player->mo->height,3*FRACUNIT/2);
stirwaterz = player->mo->z + player->mo->height - (4<<FRACBITS);
else
stirwaterz = player->mo->z + FixedDiv(player->mo->height,3*FRACUNIT/2);
stirwaterz = player->mo->z + (4<<FRACBITS);
bubble = P_SpawnMobj(
player->mo->x + stirwaterx,
@ -4886,56 +4888,185 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range)
//
static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
{
mobj_t *lockon = NULL;
mobj_t *lockonthok = NULL, *lockonshield = NULL, *visual = NULL;
if (player->pflags & PF_JUMPSTASIS)
return;
if ((player->charability == CA_HOMINGTHOK) && !player->homing && (player->pflags & PF_JUMPED) && (!(player->pflags & PF_THOKKED) || (player->charflags & SF_MULTIABILITY)) && (lockon = P_LookForEnemies(player, true, false)))
if ((player->charability == CA_HOMINGTHOK) && !player->homing && (player->pflags & PF_JUMPED) && (!(player->pflags & PF_THOKKED) || (player->charflags & SF_MULTIABILITY)) && (lockonthok = P_LookForEnemies(player, true, false)))
{
if (P_IsLocalPlayer(player)) // Only display it on your own view.
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
P_SetTarget(&visual->target, lockon);
visual = P_SpawnMobj(lockonthok->x, lockonthok->y, lockonthok->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
P_SetTarget(&visual->target, lockonthok);
}
}
if (cmd->buttons & BT_USE && !(player->pflags & PF_JUMPDOWN) && !player->exiting && !P_PlayerInPain(player))
//////////////////
//SHIELD ACTIVES//
//& SUPER FLOAT!//
//////////////////
if ((player->pflags & PF_JUMPED) && !player->exiting && !P_PlayerInPain(player))
{
if (player->mo->tracer && player->powers[pw_carry] == CR_MACESPIN)
{}
else if (onground || player->climbing || (player->mo->tracer && player->powers[pw_carry]))
{}
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND
&& !(player->pflags & PF_JUMPED)
&& !(player->pflags & PF_USEDOWN))
if (onground || player->climbing || player->powers[pw_carry])
;
else if (gametype == GT_CTF && player->gotflag)
;
else if (player->pflags & (PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) // If the player has used an ability previously
;
else if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_USEDOWN)
&& ((!(player->pflags & PF_THOKKED) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP && player->secondjump == UINT8_MAX)))) // thokked is optional if you're bubblewrapped
{
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT)
{
if ((lockonshield = P_LookForEnemies(player, false, false)))
{
if (P_IsLocalPlayer(player)) // Only display it on your own view.
{
boolean dovis = true;
if (lockonshield == lockonthok)
{
if (leveltime & 2)
dovis = false;
else if (visual)
P_RemoveMobj(visual);
}
if (dovis)
{
visual = P_SpawnMobj(lockonshield->x, lockonshield->y, lockonshield->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
P_SetTarget(&visual->target, lockonshield);
P_SetMobjStateNF(visual, visual->info->spawnstate+1);
}
}
}
}
if (cmd->buttons & BT_USE // Spin button effects
#ifdef HAVE_BLUA
&& !LUAh_ShieldSpecial(player)
#endif
)
{
// Force stop
if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE)
{
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->mo->momx = player->mo->momy = player->mo->momz = 0;
S_StartSound(player->mo, sfx_ngskid);
}
else
{
switch (player->powers[pw_shield] & SH_NOSTACK)
{
// Whirlwind jump/Thunder jump
case SH_WHIRLWIND:
case SH_THUNDERCOIN:
P_DoJumpShield(player);
else if (!(player->pflags & PF_SLIDING) && ((gametype != GT_CTF) || (!player->gotflag)))
break;
// Armageddon pow
case SH_ARMAGEDDON:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
P_BlackOw(player);
break;
// Attraction blast
case SH_ATTRACT:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->homing = 2;
P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockonshield));
if (lockonshield)
{
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockonshield->x, lockonshield->y);
player->pflags &= ~PF_NOJUMPDAMAGE;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_s3k40);
player->homing = 3*TICRATE;
}
else
S_StartSound(player->mo, sfx_s3ka6);
break;
// Elemental stomp/Bubble bounce
case SH_ELEMENTAL:
case SH_BUBBLEWRAP:
{
boolean elem = ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL);
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
if (elem)
{
player->pflags |= PF_NOJUMPDAMAGE;
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
S_StartSound(player->mo, sfx_s3k43);
}
else
{
player->pflags &= ~PF_NOJUMPDAMAGE;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_s3k44);
}
player->secondjump = 0;
player->mo->momx = player->mo->momy = 0;
P_SetObjectMomZ(player->mo, -24*FRACUNIT, false);
break;
}
// Flame burst
case SH_FLAMEAURA:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
P_Thrust(player->mo, player->mo->angle, FixedMul(30*FRACUNIT - FixedSqrt(FixedDiv(player->speed, player->mo->scale)), player->mo->scale));
player->drawangle = player->mo->angle;
S_StartSound(player->mo, sfx_s3k43);
default:
break;
}
}
}
}
else if ((cmd->buttons & BT_USE))
{
if (!(player->pflags & PF_USEDOWN) && P_SuperReady(player))
{
// If you can turn super and aren't already,
// and you don't have a shield, do it!
P_DoSuperTransformation(player, false);
}
else
#ifdef HAVE_BLUA
if (!LUAh_JumpSpinSpecial(player))
#endif
switch (player->charability)
{
case CA_TELEKINESIS:
if (player->pflags & PF_JUMPED)
case CA_THOK:
if (player->powers[pw_super]) // Super Sonic float
{
if (!(player->pflags & PF_THOKKED) || (player->charflags & SF_MULTIABILITY))
if ((player->speed > 5*player->mo->scale) // FixedMul(5<<FRACBITS, player->mo->scale), but scale is FRACUNIT-based
&& (P_MobjFlip(player->mo)*player->mo->momz <= 0))
{
if (player->panim != PA_RUN && player->panim != PA_WALK)
{
if (player->speed >= FixedMul(player->runspeed, player->mo->scale))
P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN);
else
P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT);
}
player->mo->momz = 0;
player->pflags &= ~(PF_STARTJUMP|PF_SPINNING);
}
}
break;
case CA_TELEKINESIS:
if (!(player->pflags & (PF_THOKKED|PF_USEDOWN)) || (player->charflags & SF_MULTIABILITY))
{
P_Telekinesis(player,
-FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player)
FixedMul(384*FRACUNIT, player->mo->scale));
}
}
break;
case CA_AIRDRILL:
if (player->pflags & PF_JUMPED)
case CA_TWINSPIN:
if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_USEDOWN)) || player->charflags & SF_MULTIABILITY))
{
if (player->pflags & PF_THOKKED) // speed up falling down
{
if (player->secondjump < 42)
player->secondjump ++;
}
player->pflags |= PF_THOKKED;
S_StartSound(player->mo, sfx_s3k42);
player->mo->frame = 0;
P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN);
}
break;
default:
@ -4948,6 +5079,9 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
{
if (player->pflags & PF_JUMPED)
{
if (cmd->buttons & BT_USE && player->secondjump < 42) // speed up falling down
player->secondjump++;
if (player->flyangle > 0 && player->pflags & PF_THOKKED)
{
player->flyangle--;
@ -4966,6 +5100,11 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
}
}
///////////////
// CHARACTER //
// ABILITIES!//
///////////////
if (cmd->buttons & BT_JUMP && !player->exiting && !P_PlayerInPain(player))
{
#ifdef HAVE_BLUA
@ -5035,7 +5174,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
}
P_InstaThrust(player->mo, player->mo->angle, FixedMul(actionspd, player->mo->scale));
player->drawangle = player->mo->angle;
if (maptol & TOL_2D)
{
@ -5050,11 +5188,11 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
if (player->charability == CA_HOMINGTHOK)
{
P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockon));
if (lockon)
P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockonthok));
if (lockonthok)
{
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y);
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockonthok->x, lockonthok->y);
player->homing = 3*TICRATE;
}
else
@ -5066,6 +5204,8 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
player->pflags &= ~PF_NOJUMPDAMAGE;
}
player->drawangle = player->mo->angle;
if (player->mo->info->attacksound && !player->spectator)
S_StartSound(player->mo, player->mo->info->attacksound); // Play the THOK sound
@ -5212,6 +5352,60 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
P_DoJumpShield(player);
}
// HOMING option.
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT // Sonic 3D Blast.
&& player->pflags & PF_SHIELDABILITY)
{
if (player->homing && player->mo->tracer)
{
if (!P_HomingAttack(player->mo, player->mo->tracer))
{
P_SetObjectMomZ(player->mo, 6*FRACUNIT, false);
if (player->mo->eflags & MFE_UNDERWATER)
player->mo->momz = FixedMul(player->mo->momz, FRACUNIT/3);
player->homing = 0;
}
}
// If you're not jumping, then you obviously wouldn't be homing.
if (!(player->pflags & PF_JUMPED))
player->homing = 0;
}
else if (player->charability == CA_HOMINGTHOK) // Sonic Adventure.
{
// If you've got a target, chase after it!
if (player->homing && player->mo->tracer)
{
P_SpawnThokMobj(player);
// But if you don't, then stop homing.
if (!P_HomingAttack(player->mo, player->mo->tracer))
{
if (player->mo->eflags & MFE_UNDERWATER)
P_SetObjectMomZ(player->mo, FixedDiv(457*FRACUNIT,72*FRACUNIT), false);
else
P_SetObjectMomZ(player->mo, 10*FRACUNIT, false);
player->mo->momx = player->mo->momy = player->homing = 0;
if (player->mo->tracer->flags2 & MF2_FRET)
P_InstaThrust(player->mo, player->mo->angle, -(player->speed>>3));
if (!(player->mo->tracer->flags & MF_BOSS))
player->pflags &= ~PF_THOKKED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPRING);
player->pflags |= PF_NOJUMPDAMAGE;
}
}
// If you're not jumping, then you obviously wouldn't be homing.
if (!(player->pflags & PF_JUMPED))
player->homing = 0;
}
else
player->homing = 0;
if (cmd->buttons & BT_JUMP)
{
player->pflags |= PF_JUMPDOWN;
@ -5238,7 +5432,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
player->pflags &= ~PF_JUMPDOWN;
// Repeat abilities, but not double jump!
if (player->secondjump == 1 && player->charability != CA_DOUBLEJUMP)
if (player->secondjump == 1 && player->charability != CA_DOUBLEJUMP && player->charability != CA_AIRDRILL)
{
if (player->charflags & SF_MULTIABILITY)
{
@ -7891,7 +8085,7 @@ static void P_MovePlayer(player_t *player)
}
else if (player->pflags & PF_BOUNCING)
{
if (!(player->pflags & PF_JUMPDOWN) || (onground && P_MobjFlip(player->mo)*player->mo->momz <= 0)) // If not holding the jump button OR on flat ground
if (!(player->pflags & PF_JUMPDOWN)) // If not holding the jump button
{
P_ResetPlayer(player); // down, stop bouncing.
player->pflags |= PF_THOKKED;
@ -7991,16 +8185,22 @@ static void P_MovePlayer(player_t *player)
if (P_MobjFlip(player->mo)*player->mo->momz < FixedMul(5*actionspd, player->mo->scale))
P_SetObjectMomZ(player->mo, actionspd/2, true);
P_SetPlayerMobjState(player->mo, player->mo->state->nextstate);
player->fly1--;
}
}
// Tails Put-Put noise
if (player->charability == CA_FLY && player->bot != 1 && leveltime % 10 == 0 && !player->spectator)
if (player->charability == CA_FLY
&& player->bot != 1
&& !(player->mo->eflags & MFE_UNDERWATER)
&& leveltime % 10 == 0
&& !player->spectator)
S_StartSound(player->mo, sfx_putput);
// Descend
if (cmd->buttons & BT_USE && !(player->pflags & PF_STASIS) && !player->exiting)
if (cmd->buttons & BT_USE && !(player->pflags & PF_STASIS) && !player->exiting && !(player->mo->eflags & MFE_GOOWATER))
if (P_MobjFlip(player->mo)*player->mo->momz > -FixedMul(5*actionspd, player->mo->scale))
P_SetObjectMomZ(player->mo, -actionspd/2, true);
@ -8008,11 +8208,12 @@ static void P_MovePlayer(player_t *player)
else
{
// Tails-gets-tired Stuff
if (player->panim == PA_ABILITY)
if (player->panim == PA_ABILITY && player->mo->state-states != S_PLAY_FLY_TIRED)
P_SetPlayerMobjState(player->mo, S_PLAY_FLY_TIRED);
if (player->charability == CA_FLY && (leveltime % 10 == 0)
&& player->mo->state-states == S_PLAY_FLY_TIRED
&& !(player->mo->eflags & MFE_UNDERWATER)
&& !player->spectator)
S_StartSound(player->mo, sfx_pudpud);
}
@ -8117,178 +8318,6 @@ static void P_MovePlayer(player_t *player)
localangle2 = player->mo->angle;
}
//////////////////
//SHIELD ACTIVES//
//& SUPER FLOAT!//
//////////////////
if (player->pflags & PF_JUMPED && !player->exiting && player->mo->health)
{
mobj_t *lockon = NULL;
if (!player->powers[pw_super] && player->powers[pw_shield] == SH_ATTRACT && !(player->pflags & PF_THOKKED))
{
if ((lockon = P_LookForEnemies(player, false, false)))
{
if (P_IsLocalPlayer(player)) // Only display it on your own view.
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
P_SetTarget(&visual->target, lockon);
P_SetMobjStateNF(visual, visual->info->spawnstate+1);
}
}
}
if (cmd->buttons & BT_USE) // Spin button effects
{
if (player->powers[pw_super]) // Super can't use shield actives, only passives
{
if ((player->charability == CA_THOK) // Super Sonic float
&& (player->speed > 5*player->mo->scale) // FixedMul(5<<FRACBITS, player->mo->scale), but scale is FRACUNIT-based
&& (P_MobjFlip(player->mo)*player->mo->momz <= 0))
{
if (player->panim != PA_RUN && player->panim != PA_WALK)
{
if (player->speed >= FixedMul(player->runspeed, player->mo->scale))
P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN);
else
P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT);
}
player->mo->momz = 0;
player->pflags &= ~(PF_STARTJUMP|PF_SPINNING);
}
}
else
#ifdef HAVE_BLUA
if (!LUAh_ShieldSpecial(player))
#endif
{
if (!(player->pflags & (PF_USEDOWN|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) // If the player is not holding down BT_USE, or having used an ability previously
&& (!(player->powers[pw_shield] & SH_NOSTACK) || !(player->pflags & PF_THOKKED) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP && player->secondjump == UINT8_MAX))) // thokked is optional if you're bubblewrapped/turning super
{
// Force stop
if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE)
{
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->mo->momx = player->mo->momy = player->mo->momz = 0;
S_StartSound(player->mo, sfx_ngskid);
}
else
{
switch (player->powers[pw_shield] & SH_NOSTACK)
{
// Super!
case SH_NONE:
if (P_SuperReady(player))
P_DoSuperTransformation(player, false);
break;
// Whirlwind jump/Thunder jump
case SH_WHIRLWIND:
case SH_THUNDERCOIN:
P_DoJumpShield(player);
break;
// Armageddon pow
case SH_ARMAGEDDON:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
P_BlackOw(player);
break;
// Attraction blast
case SH_ATTRACT:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->homing = 2;
P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockon));
if (lockon)
{
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y);
player->pflags &= ~PF_NOJUMPDAMAGE;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_s3k40);
player->homing = 3*TICRATE;
}
else
S_StartSound(player->mo, sfx_s3ka6);
break;
// Elemental stomp/Bubble bounce
case SH_ELEMENTAL:
case SH_BUBBLEWRAP:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->pflags &= ~PF_NOJUMPDAMAGE;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
player->secondjump = 0;
player->mo->momx = player->mo->momy = 0;
P_SetObjectMomZ(player->mo, -24*FRACUNIT, false);
S_StartSound(player->mo,
((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
? sfx_s3k43
: sfx_s3k44);
break;
// Flame burst
case SH_FLAMEAURA:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
P_Thrust(player->mo, player->mo->angle, FixedMul(30*FRACUNIT - FixedSqrt(FixedDiv(player->speed, player->mo->scale)), player->mo->scale));
player->drawangle = player->mo->angle;
S_StartSound(player->mo, sfx_s3k43);
default:
break;
}
}
}
}
}
}
// HOMING option.
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT // Sonic 3D Blast.
&& player->pflags & PF_SHIELDABILITY)
{
if (player->homing && player->mo->tracer)
{
if (!P_HomingAttack(player->mo, player->mo->tracer))
{
P_SetObjectMomZ(player->mo, 6*FRACUNIT, false);
if (player->mo->eflags & MFE_UNDERWATER)
player->mo->momz = FixedMul(player->mo->momz, FRACUNIT/3);
player->homing = 0;
}
}
// If you're not jumping, then you obviously wouldn't be homing.
if (!(player->pflags & PF_JUMPED))
player->homing = 0;
}
else if (player->charability == CA_HOMINGTHOK) // Sonic Adventure.
{
// If you've got a target, chase after it!
if (player->homing && player->mo->tracer)
{
P_SpawnThokMobj(player);
// But if you don't, then stop homing.
if (!P_HomingAttack(player->mo, player->mo->tracer))
{
if (player->mo->eflags & MFE_UNDERWATER)
P_SetObjectMomZ(player->mo, FixedDiv(457*FRACUNIT,72*FRACUNIT), false);
else
P_SetObjectMomZ(player->mo, 10*FRACUNIT, false);
player->mo->momx = player->mo->momy = player->homing = 0;
if (player->mo->tracer->flags2 & MF2_FRET)
P_InstaThrust(player->mo, player->mo->angle, -(player->speed>>3));
if (!(player->mo->tracer->flags & MF_BOSS))
player->pflags &= ~PF_THOKKED;
// P_SetPlayerMobjState(player->mo, S_PLAY_SPRING); -- Speed didn't like it, RIP
}
}
// If you're not jumping, then you obviously wouldn't be homing.
if (!(player->pflags & PF_JUMPED))
player->homing = 0;
}
else
player->homing = 0;
if (player->climbing == 1)
P_DoClimbing(player);
@ -8332,7 +8361,7 @@ static void P_MovePlayer(player_t *player)
// Less height while spinning. Good for spinning under things...?
if ((player->mo->state == &states[player->mo->info->painstate])
|| ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE && player->charflags & SF_NOJUMPSPIN))
|| ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE))
|| (player->pflags & PF_SPINNING)
|| player->powers[pw_tailsfly] || player->pflags & PF_GLIDING
|| (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED))
@ -8843,7 +8872,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
// Looks for something you can hit - Used for homing attack
// If nonenemies is true, includes monitors and springs!
// If bullet is true, you can look up and the distance is further,
// but your total angle span you can look is limited to compensate.
// but your total angle span you can look is limited to compensate. (Also, allows monitors.)
//
mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet)
{
@ -8853,6 +8882,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet)
const fixed_t maxdist = FixedMul((bullet ? RING_DIST*2 : RING_DIST), player->mo->scale);
const angle_t span = (bullet ? ANG30 : ANGLE_90);
fixed_t dist, closestdist = 0;
const mobjflag_t nonenemiesdisregard = (bullet ? 0 : MF_MONITOR)|MF_SPRING;
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
{
@ -8872,7 +8902,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet)
if (mo->flags2 & MF2_FRET)
continue;
if (!nonenemies && mo->flags & (MF_MONITOR|MF_SPRING))
if (!nonenemies && mo->flags & nonenemiesdisregard)
continue;
if (!bullet && mo->type == MT_DETON) // Don't be STUPID, Sonic!
@ -9027,19 +9057,22 @@ boolean P_GetLives(player_t *player)
INT32 i, maxlivesplayer = -1, livescheck = 1;
if (!(netgame || multiplayer)
|| (gametype != GT_COOP)
|| (cv_cooplives.value == 1)
|| (player->lives == INFLIVES))
return true;
if ((cv_cooplives.value == 2 || cv_cooplives.value == 0) && player->lives > 0)
return true;
if (cv_cooplives.value == 0) // infinite lives
{
player->lives++;
if (player->lives < 1)
player->lives = 1;
return true;
}
if ((cv_cooplives.value == 2 || cv_cooplives.value == 1) && player->lives > 0)
return true;
if (cv_cooplives.value == 1)
return false;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
@ -9146,7 +9179,7 @@ static void P_DeathThink(player_t *player)
// continue logic
if (!(netgame || multiplayer) && player->lives <= 0)
{
if (player->deadtimer > TICRATE && (cmd->buttons & BT_USE || cmd->buttons & BT_JUMP) && player->continues > 0)
if (player->deadtimer > (3*TICRATE) && (cmd->buttons & BT_USE || cmd->buttons & BT_JUMP) && player->continues > 0)
G_UseContinue();
else if (player->deadtimer >= gameovertics)
G_UseContinue(); // Even if we don't have one this handles ending the game
@ -9170,12 +9203,12 @@ static void P_DeathThink(player_t *player)
// Force respawn if idle for more than 30 seconds in shooter modes.
if (player->deadtimer > 30*TICRATE && !G_PlatformGametype())
player->playerstate = PST_REBORN;
else if ((player->lives > 0 || j != MAXPLAYERS) && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages!
else if ((player->lives > 0 || j != MAXPLAYERS) && !(!(netgame || multiplayer) && G_IsSpecialStage(gamemap))) // Don't allow "click to respawn" in special stages!
{
if (gametype == GT_COOP && (netgame || multiplayer) && cv_coopstarposts.value == 2)
{
P_ConsiderAllGone();
if ((player->deadtimer > 5*TICRATE) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))
if ((player->deadtimer > TICRATE<<1) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))
{
//player->spectator = true;
player->outofcoop = true;
@ -9191,14 +9224,9 @@ static void P_DeathThink(player_t *player)
player->playerstate = PST_REBORN;
else switch(gametype) {
case GT_COOP:
if (player->deadtimer > TICRATE)
player->playerstate = PST_REBORN;
break;
case GT_COMPETITION:
if (player->deadtimer > TICRATE)
player->playerstate = PST_REBORN;
break;
case GT_RACE:
if (player->deadtimer > TICRATE)
player->playerstate = PST_REBORN;
break;
default:
@ -9209,7 +9237,7 @@ static void P_DeathThink(player_t *player)
}
// Single player auto respawn
if (!(netgame || multiplayer) && player->deadtimer > 5*TICRATE)
if (!(netgame || multiplayer) && player->deadtimer > TICRATE<<1)
player->playerstate = PST_REBORN;
}
}
@ -9309,12 +9337,16 @@ consvar_t cv_cam_still = {"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL,
consvar_t cv_cam_speed = {"cam_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam_rotate = {"cam_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam_rotspeed = {"cam_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam_orbit = {"cam_orbit", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam_adjust = {"cam_adjust", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_dist = {"cam2_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_height = {"cam2_height", "25", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_still = {"cam2_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_speed = {"cam2_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_rotate = {"cam2_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate2_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_rotspeed = {"cam2_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_orbit = {"cam2_orbit", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_adjust = {"cam2_adjust", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
fixed_t t_cam_dist = -42;
fixed_t t_cam_height = -42;
@ -9368,9 +9400,9 @@ void P_ResetCamera(player_t *player, camera_t *thiscam)
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled)
{
angle_t angle = 0, focusangle = 0, focusaiming = 0;
fixed_t x, y, z, dist, checkdist, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight;
fixed_t x, y, z, dist, distxy, distz, checkdist, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight, slopez = 0;
INT32 camrotate;
boolean camstill, cameranoclip;
boolean camstill, cameranoclip, camorbit;
mobj_t *mo;
subsector_t *newsubsec;
fixed_t f1, f2;
@ -9451,6 +9483,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
// force defaults because we have a camera look section
camspeed = (INT32)(atof(cv_cam_speed.defaultvalue) * FRACUNIT);
camstill = (!stricmp(cv_cam_still.defaultvalue, "off")) ? false : true;
camorbit = (!stricmp(cv_cam_orbit.defaultvalue, "off")) ? false : true;
camrotate = atoi(cv_cam_rotate.defaultvalue);
camdist = FixedMul((INT32)(atof(cv_cam_dist.defaultvalue) * FRACUNIT), mo->scale);
camheight = FixedMul((INT32)(atof(cv_cam_height.defaultvalue) * FRACUNIT), FixedMul(player->camerascale, mo->scale));
@ -9459,6 +9492,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
{
camspeed = cv_cam_speed.value;
camstill = cv_cam_still.value;
camorbit = cv_cam_orbit.value;
camrotate = cv_cam_rotate.value;
camdist = FixedMul(cv_cam_dist.value, mo->scale);
camheight = FixedMul(cv_cam_height.value, FixedMul(player->camerascale, mo->scale));
@ -9467,6 +9501,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
{
camspeed = cv_cam2_speed.value;
camstill = cv_cam2_still.value;
camorbit = cv_cam2_orbit.value;
camrotate = cv_cam2_rotate.value;
camdist = FixedMul(cv_cam2_dist.value, mo->scale);
camheight = FixedMul(cv_cam2_height.value, FixedMul(player->camerascale, mo->scale));
@ -9576,13 +9611,50 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
dist <<= 1;
}
checkdist = (dist = FixedMul(dist, player->camerascale));
if (checkdist < 128*FRACUNIT)
checkdist = 128*FRACUNIT;
x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
if (!(twodlevel || (mo->flags2 & MF2_TWOD)) && !(player->powers[pw_carry] == CR_NIGHTSMODE)) // This block here is like 90% Lach's work, thanks bud
{
if ((thiscam == &camera && cv_cam_adjust.value) || (thiscam == &camera2 && cv_cam2_adjust.value))
{
if (!(mo->eflags & MFE_JUSTHITFLOOR) && (P_IsObjectOnGround(mo)) // Check that player is grounded
&& thiscam->ceilingz - thiscam->floorz >= P_GetPlayerHeight(player)) // Check that camera's sector is large enough for the player to fit into, at least
{
if (mo->eflags & MFE_VERTICALFLIP) // if player is upside-down
{
//z = min(z, thiscam->ceilingz); // solution 1: change new z coordinate to be at LEAST its ground height
slopez += min(thiscam->ceilingz - mo->z, 0); // solution 2: change new z coordinate by the difference between camera's ground and top of player
}
else // player is not upside-down
{
//z = max(z, thiscam->floorz); // solution 1: change new z coordinate to be at LEAST its ground height
slopez += max(thiscam->floorz - mo->z - mo->height, 0); // solution 2: change new z coordinate by the difference between camera's ground and top of player
}
}
}
}
if (camorbit) //Sev here, I'm guessing this is where orbital cam lives
{
if (rendermode == render_opengl)
distxy = FixedMul(dist, FINECOSINE((focusaiming>>ANGLETOFINESHIFT) & FINEMASK));
else
distxy = dist;
distz = -FixedMul(dist, FINESINE((focusaiming>>ANGLETOFINESHIFT) & FINEMASK)) + slopez;
}
else
{
distxy = dist;
distz = slopez;
}
x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy);
#if 0
if (twodlevel || (mo->flags2 & MF2_TWOD))
@ -9619,9 +9691,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
pviewheight = FixedMul(41*player->height/48, mo->scale);
if (mo->eflags & MFE_VERTICALFLIP)
z = mo->z + mo->height - pviewheight - camheight;
z = mo->z + mo->height - pviewheight - camheight + distz;
else
z = mo->z + pviewheight + camheight;
z = mo->z + pviewheight + camheight + distz;
// move camera down to move under lower ceilings
newsubsec = R_IsPointInSubsector(((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1), ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1));
@ -9934,6 +10006,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
}
return (x == thiscam->x && y == thiscam->y && z == thiscam->z && angle == thiscam->aiming);
}
boolean P_SpectatorJoinGame(player_t *player)
@ -10585,7 +10658,8 @@ static void P_DoTailsOverlay(player_t *player, mobj_t *tails)
angle_t horizangle = player->drawangle;
fixed_t zoffs = 0;
fixed_t backwards = -1*FRACUNIT;
boolean doroll = (player->panim == PA_ROLL || player->panim == PA_JUMP);
boolean doswim = (player->panim == PA_ABILITY && (player->mo->eflags & MFE_UNDERWATER));
boolean doroll = (player->panim == PA_ROLL || (player->panim == PA_JUMP && !(player->charflags & SF_NOJUMPSPIN)) || doswim);
angle_t rollangle;
boolean panimchange;
INT32 ticnum = 0;
@ -10612,17 +10686,25 @@ static void P_DoTailsOverlay(player_t *player, mobj_t *tails)
if (testval < FRACUNIT)
testval = FRACUNIT;
}
if (smilesonground && !player->mo->reactiontime)
if (doswim)
zdist = player->mo->momz<<1;
else if (smilesonground && !player->mo->reactiontime)
zdist = (player->mo->z - tails->threshold);
else
zdist = player->mo->momz;
rollangle = R_PointToAngle2(0, 0, testval, -P_MobjFlip(player->mo)*zdist);
if (!doswim)
{
zoffs = 3*FRACUNIT + 12*FINESINE(rollangle >> ANGLETOFINESHIFT);
backwards = -12*FINECOSINE(rollangle >> ANGLETOFINESHIFT);
}
}
else if (player->panim == PA_RUN)
backwards = -5*FRACUNIT;
else if (player->panim == PA_SPRING)
else if (player->panim == PA_SPRING || player->panim == PA_JUMP)
{
zoffs += 4*FRACUNIT;
backwards /= 2;
@ -10644,7 +10726,7 @@ static void P_DoTailsOverlay(player_t *player, mobj_t *tails)
zoffs = -7*FRACUNIT;
backwards = -9*FRACUNIT;
}
else if (player->mo->sprite2 == SPR2_FLY || player->mo->sprite2 == SPR2_TIRE)
else if (player->panim == PA_ABILITY)
backwards = -5*FRACUNIT;
// sprite...
@ -10661,7 +10743,7 @@ static void P_DoTailsOverlay(player_t *player, mobj_t *tails)
else
chosenstate = S_TAILSOVERLAY_0DEGREES;
}
else if (player->panim == PA_SPRING)
else if (player->panim == PA_SPRING || player->panim == PA_JUMP)
chosenstate = S_TAILSOVERLAY_MINUS60DEGREES;
else if (player->panim == PA_FALL || player->mo->state-states == S_PLAY_RIDE)
chosenstate = S_TAILSOVERLAY_PLUS60DEGREES;
@ -10684,6 +10766,8 @@ static void P_DoTailsOverlay(player_t *player, mobj_t *tails)
}
else if (player->mo->sprite2 == SPR2_FLY)
chosenstate = S_TAILSOVERLAY_FLY;
else if (player->mo->sprite2 == SPR2_SWIM)
chosenstate = S_TAILSOVERLAY_FLY;
else if (player->mo->sprite2 == SPR2_TIRE)
chosenstate = S_TAILSOVERLAY_TIRE;
else if (player->panim == PA_ABILITY2)
@ -10709,8 +10793,10 @@ static void P_DoTailsOverlay(player_t *player, mobj_t *tails)
}
}
#if 0
if (player->fly1 != 0 && player->powers[pw_tailsfly] != 0 && !smilesonground)
P_SetMobjState(tails, chosenstate);
#endif
// animation...
if (player->panim == PA_SPRING || player->panim == PA_FALL || player->mo->state-states == S_PLAY_RIDE)
@ -10725,7 +10811,7 @@ static void P_DoTailsOverlay(player_t *player, mobj_t *tails)
else if (player->mo->state-states == S_PLAY_GASP)
tails->tics = -1;
else if (player->mo->sprite2 == SPR2_TIRE)
ticnum = 4;
ticnum = (doswim ? 2 : 4);
else if (player->panim != PA_IDLE)
ticnum = player->mo->tics;
@ -10948,7 +11034,8 @@ void P_PlayerThink(player_t *player)
if (player->exiting == 2 || countdown2 == 2)
{
if (cv_playersforexit.value) // Count to be sure everyone's exited
UINT8 numneeded = (G_IsSpecialStage(gamemap) ? 4 : cv_playersforexit.value);
if (numneeded) // Count to be sure everyone's exited
{
INT32 i, total = 0, exiting = 0;
@ -10964,7 +11051,7 @@ void P_PlayerThink(player_t *player)
exiting++;
}
if (!total || ((4*exiting)/total) >= cv_playersforexit.value)
if (!total || ((4*exiting)/total) >= numneeded)
{
if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
@ -11011,8 +11098,6 @@ void P_PlayerThink(player_t *player)
{
if (gametype != GT_COOP)
player->score = 0;
player->mo->health = 1;
player->rings = player->spheres = 0;
}
else if ((netgame || multiplayer) && player->lives <= 0 && gametype != GT_COOP)
{
@ -11252,8 +11337,8 @@ void P_PlayerThink(player_t *player)
{
boolean currentlyonground = P_IsObjectOnGround(player->mo);
if (!player->powers[pw_carry]
&& ((player->pflags & (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE)) == (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE))
if (!player->powers[pw_carry] && !player->powers[pw_nocontrol]
&& ((player->pflags & (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE|PF_STASIS)) == (PF_AUTOBRAKE|PF_APPLYAUTOBRAKE))
&& !(cmd->forwardmove || cmd->sidemove)
&& (player->rmomx || player->rmomy)
&& (!player->capsule || (player->capsule->reactiontime != (player-players)+1)))
@ -11264,7 +11349,7 @@ void P_PlayerThink(player_t *player)
if (!currentlyonground)
acceleration /= 2;
// fake skidding! see P_SkidStuff for reference on conditionals
else if (!player->skidtime && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID) && P_AproxDistance(player->mo->momx, player->mo->momy) >= FixedMul(player->runspeed/2, player->mo->scale))
else if (!player->skidtime && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID) && P_AproxDistance(player->mo->momx, player->mo->momy) >= FixedMul(player->runspeed, player->mo->scale)) // modified from player->runspeed/2 'cuz the skid was just TOO frequent ngl
{
if (player->mo->state-states != S_PLAY_SKID)
P_SetPlayerMobjState(player->mo, S_PLAY_SKID);
@ -11752,7 +11837,7 @@ void P_PlayerAfterThink(player_t *player)
{
if ((tails->z + tails->height + player->mo->height + FixedMul(FRACUNIT, player->mo->scale)) <= tails->ceilingz
&& (tails->eflags & MFE_VERTICALFLIP)) // Reverse gravity check for the carrier - Flame
player->mo->z = tails->z + tails->height + FixedMul(FRACUNIT, player->mo->scale);
player->mo->z = tails->z + tails->height + 12*player->mo->scale;
else
player->powers[pw_carry] = CR_NONE;
}
@ -11760,7 +11845,7 @@ void P_PlayerAfterThink(player_t *player)
{
if ((tails->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale)) >= tails->floorz
&& !(tails->eflags & MFE_VERTICALFLIP)) // Correct gravity check for the carrier - Flame
player->mo->z = tails->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale);
player->mo->z = tails->z - player->mo->height - 12*player->mo->scale;
else
player->powers[pw_carry] = CR_NONE;
}
@ -11769,7 +11854,7 @@ void P_PlayerAfterThink(player_t *player)
player->powers[pw_carry] = CR_NONE;
else
{
P_TryMove(player->mo, tails->x, tails->y, true);
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true);
player->mo->momx = tails->momx;
player->mo->momy = tails->momy;
player->mo->momz = tails->momz;
@ -11795,6 +11880,8 @@ void P_PlayerAfterThink(player_t *player)
{
if (player->mo->state-states != S_PLAY_RIDE)
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
if ((tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER))
tails->player->powers[pw_tailsfly] = 0;
}
else
P_SetTarget(&player->mo->tracer, NULL);

View file

@ -1088,9 +1088,9 @@ static void R_Subsector(size_t num)
{
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic,
polysec->lightlevel, polysec->floor_xoffs, polysec->floor_yoffs,
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floor_xoffs, polysec->floor_yoffs,
polysec->floorpic_angle-po->angle,
NULL, NULL, po
(light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po
#ifdef ESLOPE
, NULL // will ffloors be slopable eventually?
#endif
@ -1115,10 +1115,10 @@ static void R_Subsector(size_t num)
&& polysec->ceilingheight <= ceilingcenterz
&& (viewz > polysec->ceilingheight))
{
light = R_GetPlaneLight(frontsector, polysec->ceilingheight, viewz < polysec->ceilingheight);
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic,
polysec->lightlevel, polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle,
NULL, NULL, po
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle,
(light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po
#ifdef ESLOPE
, NULL // will ffloors be slopable eventually?
#endif

File diff suppressed because it is too large Load diff

View file

@ -16,13 +16,19 @@
#include "r_defs.h"
#include "r_state.h"
#include "p_setup.h" // levelflats
#ifdef __GNUG__
#pragma interface
#endif
// Possible alpha types for a patch.
enum patchalphastyle {AST_COPY, AST_TRANSLUCENT}; // , AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY};
enum patchalphastyle {AST_COPY, AST_TRANSLUCENT, AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY};
UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha);
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
// moved here for r_sky.c (texpatch_t is used)
@ -55,12 +61,17 @@ typedef struct
texpatch_t patches[0];
} texture_t;
typedef struct
{
UINT8 *flat;
INT16 width, height;
} textureflat_t;
// all loaded and prepared textures from the start of the game
extern texture_t **textures;
extern textureflat_t *texflats;
// texture width is a power of 2, so it can easily repeat along sidedefs using a simple mask
extern INT32 *texturewidthmask;
extern INT32 *texturewidth;
extern fixed_t *textureheight; // needed for texture pegging
extern INT16 color8to16[256]; // remap color index to highcolor
@ -88,7 +99,6 @@ void R_PrecacheLevel(void);
// Floor/ceiling opaque texture tiles,
// lookup by name. For animation?
lumpnum_t R_GetFlatNumForName(const char *name);
#define R_FlatNumForName(x) R_GetFlatNumForName(x)
// Called by P_Ticker for switches and animations,
// returns the texture number for the texture name.
@ -148,6 +158,20 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap);
#define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b))
#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);
#ifndef NO_PNG_LUMPS
boolean R_IsLumpPNG(const UINT8 *d, size_t s);
UINT8 *R_PNGToFlat(levelflat_t *levelflat, 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
extern INT32 numtextures;
#endif

View file

@ -99,6 +99,8 @@ INT32 dc_numlights = 0, dc_maxlights, dc_texheight;
INT32 ds_y, ds_x1, ds_x2;
lighttable_t *ds_colormap;
fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
UINT16 ds_flatwidth, ds_flatheight;
boolean ds_powersoftwo;
UINT8 *ds_source; // start of a 64*64 tile image
UINT8 *ds_transmap; // one of the translucency tables
@ -557,9 +559,16 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
// White!
if (skinnum == TC_BOSS)
dest_colormap[31] = 0;
{
for (i = 0; i < 16; i++)
dest_colormap[31-i] = i;
}
else if (skinnum == TC_METALSONIC)
dest_colormap[159] = 0;
{
for (i = 0; i < 6; i++)
dest_colormap[Color_Index[SKINCOLOR_BLUE-1][12-i]] = Color_Index[SKINCOLOR_BLUE-1][i];
dest_colormap[159] = dest_colormap[253] = dest_colormap[254] = 0;
}
return;
}
else if (color == SKINCOLOR_NONE)

View file

@ -57,7 +57,9 @@ extern INT32 dc_texheight;
extern INT32 ds_y, ds_x1, ds_x2;
extern lighttable_t *ds_colormap;
extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
extern UINT8 *ds_source; // start of a 64*64 tile image
extern UINT16 ds_flatwidth, ds_flatheight;
extern boolean ds_powersoftwo;
extern UINT8 *ds_source;
extern UINT8 *ds_transmap;
#ifdef ESLOPE
@ -128,6 +130,8 @@ void R_FillBackScreen(void);
void R_DrawViewBorder(void);
#endif
#define TRANSPARENTPIXEL 255
// -----------------
// 8bpp DRAWING CODE
// -----------------
@ -169,6 +173,13 @@ void R_DrawFogSpan_8(void);
void R_DrawFogColumn_8(void);
void R_DrawColumnShadowed_8(void);
#ifndef NOWATER
void R_DrawTranslucentWaterSpan_8(void);
extern INT32 ds_bgofs;
extern INT32 ds_waterofs;
#endif
// ------------------
// 16bpp DRAWING CODE
// ------------------

View file

@ -105,8 +105,6 @@ void R_DrawColumn_8(void)
}
}
#define TRANSPARENTPIXEL 255
void R_Draw2sMultiPatchColumn_8(void)
{
INT32 count;
@ -543,16 +541,19 @@ void R_DrawTranslatedColumn_8(void)
*/
void R_DrawSpan_8 (void)
{
UINT32 xposition;
UINT32 yposition;
UINT32 xstep, ystep;
fixed_t xposition;
fixed_t yposition;
fixed_t xstep, ystep;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
size_t count;
size_t count = (ds_x2 - ds_x1 + 1);
xposition = ds_xfrac; yposition = ds_yfrac;
xstep = ds_xstep; ystep = ds_ystep;
// SoM: we only need 6 bits for the integer part (0 thru 63) so the rest
// can be used for the fraction part. This allows calculation of the memory address in the
@ -561,51 +562,76 @@ void R_DrawSpan_8 (void)
// bit per power of two (obviously)
// Ok, because I was able to eliminate the variable spot below, this function is now FASTER
// than the original span renderer. Whodathunkit?
xposition = ds_xfrac << nflatshiftup; yposition = ds_yfrac << nflatshiftup;
xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup;
if (ds_powersoftwo)
{
xposition <<= nflatshiftup; yposition <<= nflatshiftup;
xstep <<= nflatshiftup; ystep <<= nflatshiftup;
}
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
count = ds_x2 - ds_x1 + 1;
if (dest+8 > deststop)
return;
if (!ds_powersoftwo)
{
while (count-- && dest <= deststop)
{
fixed_t x = (xposition >> FRACBITS);
fixed_t y = (yposition >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest++ = colormap[source[((y * ds_flatwidth) + x)]];
xposition += xstep;
yposition += ystep;
}
}
else
{
while (count >= 8)
{
// SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't
// have the uber complicated math to calculate it now, so that was a memory write we didn't
// need!
dest[0] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]];
dest[0] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[1] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]];
dest[1] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[2] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]];
dest[2] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[3] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]];
dest[3] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[4] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]];
dest[4] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[5] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]];
dest[5] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[6] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]];
dest[6] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
dest[7] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]];
dest[7] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
@ -614,11 +640,12 @@ void R_DrawSpan_8 (void)
}
while (count-- && dest <= deststop)
{
*dest++ = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]];
*dest++ = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]];
xposition += xstep;
yposition += ystep;
}
}
}
#ifdef ESLOPE
// R_CalcTiltedLighting
@ -697,6 +724,23 @@ void R_DrawTiltedSpan_8(void)
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest = colormap[source[((y * ds_flatwidth) + x)]];
}
else
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
dest++;
iz += ds_sz.x;
@ -734,6 +778,23 @@ void R_DrawTiltedSpan_8(void)
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest = colormap[source[((y * ds_flatwidth) + x)]];
}
else
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
dest++;
u += stepu;
@ -750,6 +811,23 @@ void R_DrawTiltedSpan_8(void)
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest = colormap[source[((y * ds_flatwidth) + x)]];
}
else
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
}
else
@ -771,6 +849,23 @@ void R_DrawTiltedSpan_8(void)
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest = colormap[source[((y * ds_flatwidth) + x)]];
}
else
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
dest++;
u += stepu;
@ -832,6 +927,23 @@ void R_DrawTiltedTranslucentSpan_8(void)
v = (INT64)(vz*z) + viewy;
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest);
}
else
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
dest++;
iz += ds_sz.x;
@ -869,6 +981,23 @@ void R_DrawTiltedTranslucentSpan_8(void)
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest);
}
else
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
dest++;
u += stepu;
@ -885,6 +1014,23 @@ void R_DrawTiltedTranslucentSpan_8(void)
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest);
}
else
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
}
else
@ -906,6 +1052,23 @@ void R_DrawTiltedTranslucentSpan_8(void)
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest);
}
else
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
dest++;
u += stepu;
@ -967,9 +1130,28 @@ void R_DrawTiltedSplat_8(void)
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
}
else
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
*dest = colormap[val];
dest++;
iz += ds_sz.x;
uz += ds_su.x;
@ -1006,6 +1188,23 @@ void R_DrawTiltedSplat_8(void)
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
}
else
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
*dest = colormap[val];
@ -1024,6 +1223,23 @@ void R_DrawTiltedSplat_8(void)
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
}
else
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
*dest = colormap[val];
@ -1048,6 +1264,24 @@ void R_DrawTiltedSplat_8(void)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
}
else
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
*dest = colormap[val];
dest++;
@ -1065,17 +1299,21 @@ void R_DrawTiltedSplat_8(void)
*/
void R_DrawSplat_8 (void)
{
UINT32 xposition;
UINT32 yposition;
UINT32 xstep, ystep;
fixed_t xposition;
fixed_t yposition;
fixed_t xstep, ystep;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
size_t count;
size_t count = (ds_x2 - ds_x1 + 1);
UINT32 val;
xposition = ds_xfrac; yposition = ds_yfrac;
xstep = ds_xstep; ystep = ds_ystep;
// SoM: we only need 6 bits for the integer part (0 thru 63) so the rest
// can be used for the fraction part. This allows calculation of the memory address in the
// texture with two shifts, an OR and one AND. (see below)
@ -1083,14 +1321,42 @@ void R_DrawSplat_8 (void)
// bit per power of two (obviously)
// Ok, because I was able to eliminate the variable spot below, this function is now FASTER
// than the original span renderer. Whodathunkit?
xposition = ds_xfrac << nflatshiftup; yposition = ds_yfrac << nflatshiftup;
xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup;
if (ds_powersoftwo)
{
xposition <<= nflatshiftup; yposition <<= nflatshiftup;
xstep <<= nflatshiftup; ystep <<= nflatshiftup;
}
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
count = ds_x2 - ds_x1 + 1;
if (!ds_powersoftwo)
{
while (count-- && dest <= deststop)
{
fixed_t x = (xposition >> FRACBITS);
fixed_t y = (yposition >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
if (val != TRANSPARENTPIXEL)
*dest = colormap[val];
dest++;
xposition += xstep;
yposition += ystep;
}
}
else
{
while (count >= 8)
{
// SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't
@ -1098,7 +1364,7 @@ void R_DrawSplat_8 (void)
// need!
//
// <Callum> 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size)
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
@ -1106,7 +1372,7 @@ void R_DrawSplat_8 (void)
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
@ -1114,7 +1380,7 @@ void R_DrawSplat_8 (void)
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
@ -1122,7 +1388,7 @@ void R_DrawSplat_8 (void)
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
@ -1130,7 +1396,7 @@ void R_DrawSplat_8 (void)
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
@ -1138,7 +1404,7 @@ void R_DrawSplat_8 (void)
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
@ -1146,7 +1412,7 @@ void R_DrawSplat_8 (void)
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
@ -1154,7 +1420,7 @@ void R_DrawSplat_8 (void)
xposition += xstep;
yposition += ystep;
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
val &= 4194303;
val = source[val];
if (val != TRANSPARENTPIXEL)
@ -1165,35 +1431,37 @@ void R_DrawSplat_8 (void)
dest += 8;
count -= 8;
}
while (count--)
while (count-- && dest <= deststop)
{
val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift);
val &= 4194303;
val = source[val];
val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
*dest = colormap[val];
dest++;
xposition += xstep;
yposition += ystep;
}
}
}
/** \brief The R_DrawTranslucentSplat_8 function
Just like R_DrawSplat_8, but is translucent!
*/
void R_DrawTranslucentSplat_8 (void)
{
UINT32 xposition;
UINT32 yposition;
UINT32 xstep, ystep;
fixed_t xposition;
fixed_t yposition;
fixed_t xstep, ystep;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
size_t count;
UINT8 val;
size_t count = (ds_x2 - ds_x1 + 1);
UINT32 val;
xposition = ds_xfrac; yposition = ds_yfrac;
xstep = ds_xstep; ystep = ds_ystep;
// SoM: we only need 6 bits for the integer part (0 thru 63) so the rest
// can be used for the fraction part. This allows calculation of the memory address in the
@ -1202,62 +1470,90 @@ void R_DrawTranslucentSplat_8 (void)
// bit per power of two (obviously)
// Ok, because I was able to eliminate the variable spot below, this function is now FASTER
// than the original span renderer. Whodathunkit?
xposition = ds_xfrac << nflatshiftup; yposition = ds_yfrac << nflatshiftup;
xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup;
if (ds_powersoftwo)
{
xposition <<= nflatshiftup; yposition <<= nflatshiftup;
xstep <<= nflatshiftup; ystep <<= nflatshiftup;
}
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
count = ds_x2 - ds_x1 + 1;
if (!ds_powersoftwo)
{
while (count-- && dest <= deststop)
{
fixed_t x = (xposition >> FRACBITS);
fixed_t y = (yposition >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
if (val != TRANSPARENTPIXEL)
*dest = *(ds_transmap + (colormap[val] << 8) + *dest);
dest++;
xposition += xstep;
yposition += ystep;
}
}
else
{
while (count >= 8)
{
// SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't
// have the uber complicated math to calculate it now, so that was a memory write we didn't
// need!
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[0] = *(ds_transmap + (colormap[val] << 8) + dest[0]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[1] = *(ds_transmap + (colormap[val] << 8) + dest[1]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[2] = *(ds_transmap + (colormap[val] << 8) + dest[2]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[3] = *(ds_transmap + (colormap[val] << 8) + dest[3]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[4] = *(ds_transmap + (colormap[val] << 8) + dest[4]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[5] = *(ds_transmap + (colormap[val] << 8) + dest[5]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[6] = *(ds_transmap + (colormap[val] << 8) + dest[6]);
xposition += xstep;
yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
dest[7] = *(ds_transmap + (colormap[val] << 8) + dest[7]);
xposition += xstep;
@ -1266,32 +1562,37 @@ void R_DrawTranslucentSplat_8 (void)
dest += 8;
count -= 8;
}
while (count--)
while (count-- && dest <= deststop)
{
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
*dest = *(ds_transmap + (colormap[val] << 8) + *dest);
dest++;
xposition += xstep;
yposition += ystep;
}
}
}
/** \brief The R_DrawTranslucentSpan_8 function
Draws the actual span with translucent.
*/
void R_DrawTranslucentSpan_8 (void)
{
UINT32 xposition;
UINT32 yposition;
UINT32 xstep, ystep;
fixed_t xposition;
fixed_t yposition;
fixed_t xstep, ystep;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
size_t count;
size_t count = (ds_x2 - ds_x1 + 1);
UINT32 val;
xposition = ds_xfrac; yposition = ds_yfrac;
xstep = ds_xstep; ystep = ds_ystep;
// SoM: we only need 6 bits for the integer part (0 thru 63) so the rest
// can be used for the fraction part. This allows calculation of the memory address in the
@ -1300,62 +1601,160 @@ void R_DrawTranslucentSpan_8 (void)
// bit per power of two (obviously)
// Ok, because I was able to eliminate the variable spot below, this function is now FASTER
// than the original span renderer. Whodathunkit?
xposition = ds_xfrac << nflatshiftup; yposition = ds_yfrac << nflatshiftup;
xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup;
if (ds_powersoftwo)
{
xposition <<= nflatshiftup; yposition <<= nflatshiftup;
xstep <<= nflatshiftup; ystep <<= nflatshiftup;
}
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
count = ds_x2 - ds_x1 + 1;
if (!ds_powersoftwo)
{
while (count-- && dest <= deststop)
{
fixed_t x = (xposition >> FRACBITS);
fixed_t y = (yposition >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = ((y * ds_flatwidth) + x);
*dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest);
dest++;
xposition += xstep;
yposition += ystep;
}
}
else
{
while (count >= 8)
{
// SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't
// have the uber complicated math to calculate it now, so that was a memory write we didn't
// need!
dest[0] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[0]);
dest[0] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[0]);
xposition += xstep;
yposition += ystep;
dest[1] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[1]);
dest[1] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[1]);
xposition += xstep;
yposition += ystep;
dest[2] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[2]);
dest[2] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[2]);
xposition += xstep;
yposition += ystep;
dest[3] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[3]);
dest[3] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[3]);
xposition += xstep;
yposition += ystep;
dest[4] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[4]);
dest[4] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[4]);
xposition += xstep;
yposition += ystep;
dest[5] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[5]);
dest[5] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[5]);
xposition += xstep;
yposition += ystep;
dest[6] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[6]);
dest[6] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[6]);
xposition += xstep;
yposition += ystep;
dest[7] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[7]);
dest[7] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[7]);
xposition += xstep;
yposition += ystep;
dest += 8;
count -= 8;
}
while (count--)
while (count-- && dest <= deststop)
{
*dest = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + *dest);
val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift);
*dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest);
dest++;
xposition += xstep;
yposition += ystep;
}
}
}
#ifndef NOWATER
void R_DrawTranslucentWaterSpan_8(void)
{
fixed_t xposition;
fixed_t yposition;
fixed_t xstep, ystep;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
UINT8 *dsrc;
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
size_t count = (ds_x2 - ds_x1 + 1);
xposition = ds_xfrac; yposition = (ds_yfrac + ds_waterofs);
xstep = ds_xstep; ystep = ds_ystep;
// SoM: we only need 6 bits for the integer part (0 thru 63) so the rest
// can be used for the fraction part. This allows calculation of the memory address in the
// texture with two shifts, an OR and one AND. (see below)
// for texture sizes > 64 the amount of precision we can allow will decrease, but only by one
// bit per power of two (obviously)
// Ok, because I was able to eliminate the variable spot below, this function is now FASTER
// than the original span renderer. Whodathunkit?
if (ds_powersoftwo)
{
xposition <<= nflatshiftup; yposition <<= nflatshiftup;
xstep <<= nflatshiftup; ystep <<= nflatshiftup;
}
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
if (!ds_powersoftwo)
{
while (count-- && dest <= deststop)
{
fixed_t x = (xposition >> FRACBITS);
fixed_t y = (yposition >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest++ = colormap[*(ds_transmap + (source[((y * ds_flatwidth) + x)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
}
}
else
{
while (count-- && dest <= deststop)
{
*dest++ = colormap[*(ds_transmap + (source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
}
}
}
#endif
/** \brief The R_DrawFogSpan_8 function
Draws the actual span with fogging.

View file

@ -1182,6 +1182,8 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_cam_speed);
CV_RegisterVar(&cv_cam_rotate);
CV_RegisterVar(&cv_cam_rotspeed);
CV_RegisterVar(&cv_cam_orbit);
CV_RegisterVar(&cv_cam_adjust);
CV_RegisterVar(&cv_cam2_dist);
CV_RegisterVar(&cv_cam2_still);
@ -1189,6 +1191,8 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_cam2_speed);
CV_RegisterVar(&cv_cam2_rotate);
CV_RegisterVar(&cv_cam2_rotspeed);
CV_RegisterVar(&cv_cam2_orbit);
CV_RegisterVar(&cv_cam2_adjust);
CV_RegisterVar(&cv_showhud);
CV_RegisterVar(&cv_translucenthud);

View file

@ -127,91 +127,13 @@ void R_InitPlanes(void)
// viewheight
#ifndef NOWATER
static INT32 bgofs;
INT32 ds_bgofs;
INT32 ds_waterofs;
static INT32 wtofs=0;
static INT32 waterofs;
static boolean itswater;
#endif
#ifndef NOWATER
static void R_DrawTranslucentWaterSpan_8(void)
{
UINT32 xposition;
UINT32 yposition;
UINT32 xstep, ystep;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
UINT8 *dsrc;
size_t count;
// SoM: we only need 6 bits for the integer part (0 thru 63) so the rest
// can be used for the fraction part. This allows calculation of the memory address in the
// texture with two shifts, an OR and one AND. (see below)
// for texture sizes > 64 the amount of precision we can allow will decrease, but only by one
// bit per power of two (obviously)
// Ok, because I was able to eliminate the variable spot below, this function is now FASTER
// than the original span renderer. Whodathunkit?
xposition = ds_xfrac << nflatshiftup; yposition = (ds_yfrac + waterofs) << nflatshiftup;
xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup;
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
dsrc = screens[1] + (ds_y+bgofs)*vid.width + ds_x1;
count = ds_x2 - ds_x1 + 1;
while (count >= 8)
{
// SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't
// have the uber complicated math to calculate it now, so that was a memory write we didn't
// need!
dest[0] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[1] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[2] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[3] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[4] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[5] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[6] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest[7] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
dest += 8;
count -= 8;
}
while (count--)
{
*dest++ = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)];
xposition += xstep;
yposition += ystep;
}
}
#endif
void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
{
angle_t angle, planecos, planesin;
@ -258,17 +180,17 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
{
const INT32 yay = (wtofs + (distance>>9) ) & 8191;
// ripples da water texture
bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS;
ds_bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS;
angle = (currentplane->viewangle + currentplane->plangle + xtoviewangle[x1])>>ANGLETOFINESHIFT;
angle = (angle + 2048) & 8191; // 90 degrees
ds_xfrac += FixedMul(FINECOSINE(angle), (bgofs<<FRACBITS));
ds_yfrac += FixedMul(FINESINE(angle), (bgofs<<FRACBITS));
ds_xfrac += FixedMul(FINECOSINE(angle), (ds_bgofs<<FRACBITS));
ds_yfrac += FixedMul(FINESINE(angle), (ds_bgofs<<FRACBITS));
if (y+bgofs>=viewheight)
bgofs = viewheight-y-1;
if (y+bgofs<0)
bgofs = -y;
if (y+ds_bgofs>=viewheight)
ds_bgofs = viewheight-y-1;
if (y+ds_bgofs<0)
ds_bgofs = -y;
}
#endif
@ -680,7 +602,7 @@ void R_DrawPlanes(void)
}
}
#ifndef NOWATER
waterofs = (leveltime & 1)*16384;
ds_waterofs = (leveltime & 1)*16384;
wtofs = leveltime * 140;
#endif
}
@ -728,13 +650,169 @@ static void R_DrawSkyPlane(visplane_t *pl)
}
}
boolean R_CheckPowersOfTwo(void)
{
boolean wpow2 = (!(ds_flatwidth & (ds_flatwidth - 1)));
boolean hpow2 = (!(ds_flatheight & (ds_flatheight - 1)));
// Initially, the flat isn't powers-of-two-sized.
ds_powersoftwo = false;
// But if the width and height are powers of two,
// and are EQUAL, then it's okay :]
if ((ds_flatwidth == ds_flatheight) && (wpow2 && hpow2))
ds_powersoftwo = true;
// Just return ds_powersoftwo.
return ds_powersoftwo;
}
void R_CheckFlatLength(size_t size)
{
switch (size)
{
case 4194304: // 2048x2048 lump
nflatmask = 0x3FF800;
nflatxshift = 21;
nflatyshift = 10;
nflatshiftup = 5;
ds_flatwidth = ds_flatheight = 2048;
break;
case 1048576: // 1024x1024 lump
nflatmask = 0xFFC00;
nflatxshift = 22;
nflatyshift = 12;
nflatshiftup = 6;
ds_flatwidth = ds_flatheight = 1024;
break;
case 262144:// 512x512 lump
nflatmask = 0x3FE00;
nflatxshift = 23;
nflatyshift = 14;
nflatshiftup = 7;
ds_flatwidth = ds_flatheight = 512;
break;
case 65536: // 256x256 lump
nflatmask = 0xFF00;
nflatxshift = 24;
nflatyshift = 16;
nflatshiftup = 8;
ds_flatwidth = ds_flatheight = 256;
break;
case 16384: // 128x128 lump
nflatmask = 0x3F80;
nflatxshift = 25;
nflatyshift = 18;
nflatshiftup = 9;
ds_flatwidth = ds_flatheight = 128;
break;
case 1024: // 32x32 lump
nflatmask = 0x3E0;
nflatxshift = 27;
nflatyshift = 22;
nflatshiftup = 11;
ds_flatwidth = ds_flatheight = 32;
break;
default: // 64x64 lump
nflatmask = 0xFC0;
nflatxshift = 26;
nflatyshift = 20;
nflatshiftup = 10;
ds_flatwidth = ds_flatheight = 64;
break;
}
}
static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boolean ispng)
{
UINT8 *flat;
textureflat_t *texflat = &texflats[levelflat->texturenum];
patch_t *patch = NULL;
boolean texturechanged = (leveltexture ? (levelflat->texturenum != levelflat->lasttexturenum) : false);
// Check if the texture changed.
if (leveltexture && (!texturechanged))
{
if (texflat != NULL && texflat->flat)
{
flat = texflat->flat;
ds_flatwidth = texflat->width;
ds_flatheight = texflat->height;
texturechanged = false;
}
else
texturechanged = true;
}
// If the texture changed, or the patch doesn't exist, convert either of them to a flat.
if (levelflat->flatpatch == NULL || texturechanged)
{
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);
R_TextureToFlat(levelflat->texturenum, texflat->flat);
flat = texflat->flat;
levelflat->flatpatch = flat;
levelflat->width = ds_flatwidth;
levelflat->height = ds_flatheight;
}
else
{
patch = (patch_t *)ds_source;
#ifndef NO_PNG_LUMPS
if (ispng)
{
levelflat->flatpatch = R_PNGToFlat(levelflat, ds_source, W_LumpLength(levelflat->lumpnum));
levelflat->topoffset = levelflat->leftoffset = 0;
ds_flatwidth = levelflat->width;
ds_flatheight = levelflat->height;
}
else
#endif
{
levelflat->width = ds_flatwidth = SHORT(patch->width);
levelflat->height = ds_flatheight = SHORT(patch->height);
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);
R_PatchToFlat(patch, levelflat->flatpatch);
}
flat = levelflat->flatpatch;
}
}
else
{
flat = levelflat->flatpatch;
ds_flatwidth = levelflat->width;
ds_flatheight = levelflat->height;
xoffs += levelflat->leftoffset;
yoffs += levelflat->topoffset;
}
levelflat->lasttexturenum = levelflat->texturenum;
return flat;
}
void R_DrawSinglePlane(visplane_t *pl)
{
UINT8 *flat;
INT32 light = 0;
INT32 x;
INT32 stop, angle;
size_t size;
ffloor_t *rover;
levelflat_t *levelflat;
boolean rawflat = false;
if (!(pl->minx <= pl->maxx))
return;
@ -874,64 +952,51 @@ void R_DrawSinglePlane(visplane_t *pl)
viewangle = pl->viewangle+pl->plangle;
}
currentplane = pl;
ds_source = (UINT8 *)
W_CacheLumpNum(levelflats[pl->picnum].lumpnum,
PU_STATIC); // Stay here until Z_ChangeTag
size = W_LumpLength(levelflats[pl->picnum].lumpnum);
switch (size)
{
case 4194304: // 2048x2048 lump
nflatmask = 0x3FF800;
nflatxshift = 21;
nflatyshift = 10;
nflatshiftup = 5;
break;
case 1048576: // 1024x1024 lump
nflatmask = 0xFFC00;
nflatxshift = 22;
nflatyshift = 12;
nflatshiftup = 6;
break;
case 262144:// 512x512 lump'
nflatmask = 0x3FE00;
nflatxshift = 23;
nflatyshift = 14;
nflatshiftup = 7;
break;
case 65536: // 256x256 lump
nflatmask = 0xFF00;
nflatxshift = 24;
nflatyshift = 16;
nflatshiftup = 8;
break;
case 16384: // 128x128 lump
nflatmask = 0x3F80;
nflatxshift = 25;
nflatyshift = 18;
nflatshiftup = 9;
break;
case 1024: // 32x32 lump
nflatmask = 0x3E0;
nflatxshift = 27;
nflatyshift = 22;
nflatshiftup = 11;
break;
default: // 64x64 lump
nflatmask = 0xFC0;
nflatxshift = 26;
nflatyshift = 20;
nflatshiftup = 10;
break;
}
xoffs = pl->xoffs;
yoffs = pl->yoffs;
planeheight = abs(pl->height - pl->viewz);
currentplane = pl;
levelflat = &levelflats[pl->picnum];
size = W_LumpLength(levelflat->lumpnum);
ds_source = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_STATIC); // Stay here until Z_ChangeTag
// Check if the flat is actually a wall texture.
if (levelflat->texturenum != 0 && levelflat->texturenum != -1)
flat = R_GetPatchFlat(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);
#endif
// Maybe it's just a patch, then?
else if (R_CheckIfPatch(levelflat->lumpnum))
flat = R_GetPatchFlat(levelflat, false, false);
// It's a raw flat.
else
{
rawflat = true;
R_CheckFlatLength(size);
flat = ds_source;
}
Z_ChangeTag(ds_source, PU_CACHE);
ds_source = flat;
if (ds_source == NULL)
return;
// Raw flats always have dimensions that are powers-of-two numbers.
if (rawflat)
ds_powersoftwo = true;
// Otherwise, check if this texture or patch has such dimensions.
else if (R_CheckPowersOfTwo())
{
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
if (spanfunc == basespanfunc)
spanfunc = mmxspanfunc;
}
if (light >= LIGHTLEVELS)
light = LIGHTLEVELS-1;
@ -945,16 +1010,19 @@ void R_DrawSinglePlane(visplane_t *pl)
floatv3_t p, m, n;
float ang;
float vx, vy, vz;
float fudge = 0;
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
// use this as a temp var to store P_GetZAt's return value each time
fixed_t temp;
// Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red
const float fudge = ((1<<nflatshiftup)+1.0f)/(1<<nflatshiftup);
angle_t hack = (pl->plangle & (ANGLE_90-1));
yoffs *= 1;
if (ds_powersoftwo)
{
// Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red
fudge = ((1<<nflatshiftup)+1.0f)/(1<<nflatshiftup);
if (hack)
{
/*
@ -996,9 +1064,9 @@ void R_DrawSinglePlane(visplane_t *pl)
xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
}
xoffs = (fixed_t)(xoffs*fudge);
yoffs = (fixed_t)(yoffs/fudge);
}
vx = FIXED_TO_FLOAT(pl->viewx+xoffs);
vy = FIXED_TO_FLOAT(pl->viewy-yoffs);
@ -1033,6 +1101,8 @@ void R_DrawSinglePlane(visplane_t *pl)
temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang)));
n.y = FIXED_TO_FLOAT(temp) - zeroheight;
if (ds_powersoftwo)
{
m.x /= fudge;
m.y /= fudge;
m.z /= fudge;
@ -1040,6 +1110,7 @@ void R_DrawSinglePlane(visplane_t *pl)
n.x *= fudge;
n.y *= fudge;
n.z *= fudge;
}
// Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using.
#define CROSS(d, v1, v2) \
@ -1056,13 +1127,26 @@ void R_DrawSinglePlane(visplane_t *pl)
ds_sz.z *= focallengthf;
// Premultiply the texture vectors with the scale factors
#define SFMULT 65536.f*(1<<nflatshiftup)
#define SFMULT 65536.f
if (ds_powersoftwo)
{
ds_su.x *= (SFMULT * (1<<nflatshiftup));
ds_su.y *= (SFMULT * (1<<nflatshiftup));
ds_su.z *= (SFMULT * (1<<nflatshiftup));
ds_sv.x *= (SFMULT * (1<<nflatshiftup));
ds_sv.y *= (SFMULT * (1<<nflatshiftup));
ds_sv.z *= (SFMULT * (1<<nflatshiftup));
}
else
{
// I'm essentially multiplying the vectors by FRACUNIT...
ds_su.x *= SFMULT;
ds_su.y *= SFMULT;
ds_su.z *= SFMULT;
ds_sv.x *= SFMULT;
ds_sv.y *= SFMULT;
ds_sv.z *= SFMULT;
}
#undef SFMULT
if (spanfunc == R_DrawTranslucentSpan_8)
@ -1170,8 +1254,6 @@ using the palette colors.
}
}
#endif
Z_ChangeTag(ds_source, PU_CACHE);
}
void R_PlaneBounds(visplane_t *plane)

View file

@ -96,6 +96,8 @@ void R_PlaneBounds(visplane_t *plane);
// Draws a single visplane.
void R_DrawSinglePlane(visplane_t *pl);
void R_CheckFlatLength(size_t size);
boolean R_CheckPowersOfTwo(void);
typedef struct planemgr_s
{

View file

@ -254,6 +254,19 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
// store sprite info in lookup tables
//FIXME : numspritelumps do not duplicate sprite replacements
W_ReadLumpHeaderPwad(wadnum, l, &patch, sizeof (patch_t), 0);
#ifndef NO_PNG_LUMPS
{
patch_t *png = W_CacheLumpNumPwad(wadnum, l, PU_STATIC);
size_t len = W_LumpLengthPwad(wadnum, l);
// lump is a png so convert it
if (R_IsLumpPNG((UINT8 *)png, len))
{
png = R_PNGToPatch((UINT8 *)png, len, NULL, true);
M_Memcpy(&patch, png, sizeof(INT16)*4);
}
Z_Free(png);
}
#endif
spritecachedinfo[numspritelumps].width = SHORT(patch.width)<<FRACBITS;
spritecachedinfo[numspritelumps].offset = SHORT(patch.leftoffset)<<FRACBITS;
spritecachedinfo[numspritelumps].topoffset = SHORT(patch.topoffset)<<FRACBITS;
@ -701,7 +714,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
INT32 texturecolumn;
#endif
fixed_t frac;
patch_t *patch = W_CacheLumpNum(vis->patch, PU_CACHE);
patch_t *patch = W_CachePatchNum(vis->patch, PU_CACHE);
fixed_t this_scale = vis->mobj->scale;
INT32 x1, x2;
INT64 overflow_test;
@ -870,7 +883,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
INT64 overflow_test;
//Fab : R_InitSprites now sets a wad lump number
patch = W_CacheLumpNum(vis->patch, PU_CACHE);
patch = W_CachePatchNum(vis->patch, PU_CACHE);
if (!patch)
return;
@ -2511,7 +2524,7 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
if (!skin)
return 0;
if ((unsigned)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
return 0;
while (!(skin->sprites[spr2].numframes)
@ -2603,6 +2616,8 @@ static void Sk_SetDefaultValue(skin_t *skin)
skin->followitem = 0;
skin->highresscale = FRACUNIT;
skin->contspeed = 17;
skin->contangle = 0;
skin->availability = 0;
@ -2869,6 +2884,8 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski
for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
R_AddSingleSpriteDef((spritename = spr2names[sprite2]), &skin->sprites[sprite2], wadnum, *lump, *lastlump);
if (skin->sprites[0].numframes == 0)
I_Error("R_LoadSkinSprites: no frames found for sprite SPR2_%s\n", spr2names[0]);
}
// returns whether found appropriate property
@ -2907,6 +2924,8 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
GETINT(thrustfactor)
GETINT(accelstart)
GETINT(acceleration)
GETINT(contspeed)
GETINT(contangle)
#undef GETINT
#define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) skin->field = R_GetColorByName(value);

View file

@ -122,6 +122,8 @@ typedef struct
UINT8 prefoppositecolor; // if 0 use tables instead
fixed_t highresscale; // scale of highres, default is 0.5
UINT8 contspeed; // continue screen animation speed
UINT8 contangle; // initial angle on continue screen
// specific sounds per skin
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table

View file

@ -108,7 +108,9 @@ consvar_t cv_closedcaptioning = {"closedcaptioning", "Off", CV_SAVE|CV_CALL, CV_
consvar_t cv_numChannels = {"snd_channels", "32", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL};
static consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_resetmusic = {"resetmusic", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_resetmusic = {"resetmusic", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_resetmusicbyheader = {"resetmusicbyheader", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
// Sound system toggles, saved into the config
consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameDigiMusic_OnChange, 0, NULL, NULL, 0, 0, NULL};
@ -275,6 +277,7 @@ void S_RegisterSoundStuff(void)
CV_RegisterVar(&surround);
CV_RegisterVar(&cv_samplerate);
CV_RegisterVar(&cv_resetmusic);
CV_RegisterVar(&cv_resetmusicbyheader);
CV_RegisterVar(&cv_gamesounds);
CV_RegisterVar(&cv_gamedigimusic);
CV_RegisterVar(&cv_gamemidimusic);
@ -2096,7 +2099,7 @@ void S_StartEx(boolean reset)
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
}
if (cv_resetmusic.value || reset)
if (RESETMUSIC || reset)
S_StopMusic();
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);

View file

@ -31,7 +31,16 @@ openmpt_module *openmpt_mhandle;
extern consvar_t stereoreverse;
extern consvar_t cv_soundvolume, cv_closedcaptioning, cv_digmusicvolume, cv_midimusicvolume;
extern consvar_t cv_numChannels;
extern consvar_t cv_resetmusic;
extern consvar_t cv_resetmusicbyheader;
#define RESETMUSIC (!modeattacking && \
(cv_resetmusicbyheader.value ? \
(mapheaderinfo[gamemap-1]->musforcereset != -1 ? mapheaderinfo[gamemap-1]->musforcereset : cv_resetmusic.value) \
: cv_resetmusic.value) \
)
extern consvar_t cv_gamedigimusic;
extern consvar_t cv_gamemidimusic;
extern consvar_t cv_gamesounds;

View file

@ -49,6 +49,7 @@ void (*fuzzcolfunc)(void); // standard fuzzy effect column drawer
void (*transcolfunc)(void); // translation column drawer
void (*shadecolfunc)(void); // smokie test..
void (*spanfunc)(void); // span drawer, use a 64x64 tile
void (*mmxspanfunc)(void); // span drawer in MMX assembly
void (*splatfunc)(void); // span drawer w/ transparency
void (*basespanfunc)(void); // default span func for color mode
void (*transtransfunc)(void); // translucent translated column drawer
@ -112,7 +113,7 @@ void SCR_SetMode(void)
//
if (true)//vid.bpp == 1) //Always run in 8bpp. todo: remove all 16bpp code?
{
spanfunc = basespanfunc = R_DrawSpan_8;
spanfunc = basespanfunc = mmxspanfunc = R_DrawSpan_8;
splatfunc = R_DrawSplat_8;
transcolfunc = R_DrawTranslatedColumn_8;
transtransfunc = R_DrawTranslatedTranslucentColumn_8;
@ -133,7 +134,7 @@ void SCR_SetMode(void)
//fuzzcolfunc = R_DrawTranslucentColumn_8_ASM;
walldrawerfunc = R_DrawWallColumn_8_MMX;
twosmultipatchfunc = R_Draw2sMultiPatchColumn_8_MMX;
spanfunc = basespanfunc = R_DrawSpan_8_MMX;
mmxspanfunc = R_DrawSpan_8_MMX;
}
else
{

View file

@ -123,6 +123,7 @@ extern void (*transcolfunc)(void);
extern void (*shadecolfunc)(void);
extern void (*spanfunc)(void);
extern void (*basespanfunc)(void);
extern void (*mmxspanfunc)(void);
extern void (*splatfunc)(void);
extern void (*transtransfunc)(void);
extern void (*twosmultipatchfunc)(void);

View file

@ -1,6 +1,6 @@
/*
SDL_image: An example image loading library for use with SDL
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -34,7 +34,7 @@
*
* Besides the standard API, also provides
*
* SDL_Surface *IMG_ReadXPMFromArray(char **xpm)
* SDL_Surface *IMG_ReadXPMFromArray(const char **xpm)
*
* that reads the image data from an XPM file included in the C source.
*
@ -88,8 +88,8 @@ struct color_hash {
struct hash_entry **table;
struct hash_entry *entries; /* array of all entries */
struct hash_entry *next_free;
int size;
int maxnum;
size_t size;
size_t maxnum;
};
static int hash_key(const char *key, int cpp, int size)
@ -103,14 +103,14 @@ static int hash_key(const char *key, int cpp, int size)
return hash & (size - 1);
}
static struct color_hash *create_colorhash(int maxnum)
static struct color_hash *create_colorhash(size_t maxnum)
{
int bytes, s;
size_t bytes, s;
struct color_hash *hash;
/* we know how many entries we need, so we can allocate
everything here */
hash = (struct color_hash *)SDL_malloc(sizeof *hash);
hash = (struct color_hash *)SDL_calloc(1, sizeof(*hash));
if (!hash)
return NULL;
@ -119,15 +119,29 @@ static struct color_hash *create_colorhash(int maxnum)
;
hash->size = s;
hash->maxnum = maxnum;
bytes = hash->size * sizeof(struct hash_entry **);
hash->entries = NULL; /* in case malloc fails */
hash->table = (struct hash_entry **)SDL_malloc(bytes);
/* Check for overflow */
if ((bytes / sizeof(struct hash_entry **)) != hash->size) {
IMG_SetError("memory allocation overflow");
SDL_free(hash);
return NULL;
}
hash->table = (struct hash_entry **)SDL_calloc(1, bytes);
if (!hash->table) {
SDL_free(hash);
return NULL;
}
SDL_memset(hash->table, 0, bytes);
hash->entries = (struct hash_entry *)SDL_malloc(maxnum * sizeof(struct hash_entry));
bytes = maxnum * sizeof(struct hash_entry);
/* Check for overflow */
if ((bytes / sizeof(struct hash_entry)) != maxnum) {
IMG_SetError("memory allocation overflow");
SDL_free(hash->table);
SDL_free(hash);
return NULL;
}
hash->entries = (struct hash_entry *)SDL_calloc(1, bytes);
if (!hash->entries) {
SDL_free(hash->table);
SDL_free(hash);
@ -138,7 +152,7 @@ static struct color_hash *create_colorhash(int maxnum)
}
static int add_colorhash(struct color_hash *hash,
char *key, int cpp, Uint32 color)
const char *key, int cpp, Uint32 color)
{
int index = hash_key(key, cpp, hash->size);
struct hash_entry *e = hash->next_free++;
@ -995,10 +1009,11 @@ static SDL_Surface *load_xpm(const char **xpm, SDL_RWops *src)
{
Sint64 start = 0;
SDL_Surface *image = NULL;
int index;
size_t index;
int x, y;
int w, h, ncolors, cpp;
int indexed;
int w, h, cpp;
size_t ncolors;
size_t indexed;
Uint8 *dst;
struct color_hash *colors = NULL;
SDL_Color *im_colors = NULL;
@ -1029,12 +1044,17 @@ static SDL_Surface *load_xpm(const char **xpm, SDL_RWops *src)
* Right now we don't use the hotspots but it should be handled
* one day.
*/
if (SDL_sscanf(line, "%d %d %d %d", &w, &h, &ncolors, &cpp) != 4
if (SDL_sscanf(line, "%d %d %lu %d", &w, &h, &ncolors, &cpp) != 4
|| w <= 0 || h <= 0 || ncolors <= 0 || cpp <= 0) {
error = "Invalid format description";
goto done;
}
/* Check for allocation overflow */
if ((size_t)(ncolors * cpp)/cpp != ncolors) {
error = "Invalid color specification";
goto done;
}
keystrings = (char *)SDL_malloc(ncolors * cpp);
if (!keystrings) {
error = "Out of memory";
@ -1102,8 +1122,9 @@ static SDL_Surface *load_xpm(const char **xpm, SDL_RWops *src)
c->g = (Uint8)(rgb >> 8);
c->b = (Uint8)(rgb);
pixel = index;
} else
} else {
pixel = rgb;
}
add_colorhash(colors, nextkey, cpp, pixel);
nextkey += cpp;
if (rgb == 0xffffffff)
@ -1192,7 +1213,7 @@ SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src)
return(NULL);
}
SDL_Surface *IMG_ReadXPMFromArray(char **xpm)
SDL_Surface *IMG_ReadXPMFromArray(const char **xpm)
{
return NULL;
}

View file

@ -1,163 +1,99 @@
/* XPM */
const char * SDL_icon_xpm[] = {
"96 96 64 1",
static const char *SDL_icon_xpm[] = {
"64 64 32 1",
" c None",
". c #040656",
"+ c #0100B2",
"@ c #04056E",
"# c #0000BD",
"$ c #0B0C09",
"% c #0B0D26",
"& c #090C42",
"* c #060AA7",
"= c #1604DA",
"- c #020CD5",
"; c #100F8D",
"> c #040DE4",
", c #11129B",
"' c #1D1A83",
") c #2A10FD",
"! c #1318FA",
"~ c #25225B",
"{ c #252271",
"] c #312E2B",
"^ c #33334D",
"/ c #363775",
"( c #3D3B69",
"_ c #3A3B8B",
": c #373AFF",
"< c #4142AA",
"[ c #4B4864",
"} c #4D4B4A",
"| c #60492F",
"1 c #4F4C57",
"2 c #4A4A9E",
"3 c #4F4E85",
"4 c #474ADE",
"5 c #4E4FFE",
"6 c #5D5CB3",
"7 c #686663",
"8 c #666682",
"9 c #676875",
"0 c #66659E",
"a c #8B6538",
"b c #6465D5",
"c c #7F694F",
"d c #6767FF",
"e c #7272FF",
"f c #91795C",
"g c #7677FD",
"h c #828396",
"i c #A78153",
"j c #888989",
"k c #8D897E",
"l c #9190FD",
"m c #CA9048",
"n c #C09968",
"o c #A9A8A1",
"p c #A6A8B0",
"q c #B0B1FB",
"r c #EEAC61",
"s c #E3B478",
"t c #C3C4BE",
"u c #FFC68C",
"v c #FCCD90",
"w c #D4D7D3",
"x c #E3E5E0",
"y c #FCFFFB",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ttj7777777joot ",
" 9hh8830000088hh9 ",
" 9888(//__<bbbb2////3[888hpp ",
" oj}^/_6bbbbgggggggb2///_bgbbbbb631kt ",
" (80066bgeeegggggggb22262/bbggeggb66081 ",
" p9^jj pp8(_2bgggggeeeeeeeegb2~_bgb//6geegged5*'(hp ",
" ^2<3[7 j^/2bbggggeeeeeeeeeeggb2_({'4eb/2ggge5:!!!>-*{^kt ",
" &,5b60^ (02<beggggeeeeeeeeeegb62__7}~:5g/_bgd5!))))))=+;20k ",
" @#:egb3^ pp({4dgggeeeeeeeeeeeeegg6/__3im}+:e//bd:!)))))))))!#;87 ",
" p'-!:dgb3] 7['4egeeeeeeeeeeeeeeeegg2/__[armc,-523<:!)))))))))))!>*{} ",
" tp,-)!5egb3} ~_<4dgggeeeeeeeeeeeeeegb6/_2[amusf'#!<_'>))))))))))))!)>+{~ ",
" p;-))!5gb2^^'#5eggeeeeeeeeeeeeeeegg6/_23amrusi{#!+;;>))))))))))))))!!-'8p ",
" tp'#!)):d6(@*>5egeeeeeeeeeeeeeeeegg6_/<(amrrvvn{+)-,;>))))))!!!!!!)))!!>,~j ",
" p;#!))-'{'+-5eggeeeeeeeeeeeeeeeegb222(cmrruvvn{+)>,@>!)!!)!!>>>>======>-,/8 ",
" ;#)!-*.;-!5eggeeeeeeeeeeeeeeeegb2_<6|mrrsvvvn{+)!,.-!!!!>>=--######+++-#@(k ",
" h@-)+@.*>!5egeeeeeeeeeeeeeeeeeegb_</]mrrruvvvn{+))*@->>--###++++++###+;@{(9j ",
" kh,#+@@,>!:dggeeeeeeeeeeeeeeeeeeebbb_]mrruuvvsf'#)!*.+-###+++++++##+*;'3(&^9 ",
" 8*,@@*)):dggeeeeeeeeeeeeeeeeeeeeggg<(|iruvvvsc,=!!*.;*++++++++###+,@&1o ",
" 8@@@-!)!5eeeeeeeeeeeeeeeeeeeeeeeeeggb2[csvvvn^#)!!+@;*#+++++###*@~[ ",
" 9&@*!)):5geeeeeeeeeeeeeeeeeeeeeeeeegge637nsvf{>))!+;;*-######*;{.^ ",
" 9%;!!)):dgeeeeeeeeeeeeeeeeeeeeeeeeeeeggb_1ir7;>))!+;;,++++++*'(} ",
" 9{+!))!5egeeeeeeeeeeeeeeeeeddddeeeeeeeege2}|~#!))!#;@...@@@.^hp ",
" 8,=!))):dggeeeeeeeeeeeeeeeeggggeeeeeeeeggb_~,>!))!+@@@;;;;@&^o ",
" }(-)))))!:eegeeeeeeeeeeeeeegllllgeeeeeeeegd5+=))))!+;,#>--#,'/hj ",
" o8.>))))))!:dgggeeeeeeeeeeellqqqqlgeeeeggg5:!!!)))))-*+>)!:55db631 ",
" p8<*!)))))))!:5deggggggeeeegqqqqqqqqlggged5:!))))))))>->!!:5ddeegb3/ ",
" oh'#!))))))))))!:ddeeeeeeeeglqqqqqqqqlgedd:!)))))))))))))!:dggggeggg239 ",
" ^*>!))!)))))))))!::55dddeegglll600333_4:!!)))))))))))))):dggeeeeeeggb6(9o ",
" ~+=-+#>))))))))))!!!:::::5554<3889988[/,=)))))))))))))):5gggeeeeeeeggb6087 ",
" ~**@~'+>!))))))))))))))))!!>*{1kkooook7(,-!)))))))))))!:5deeeeeeeeeeeggb289 ",
" ~,'1o7(*>!))))))))))))))))=,[jtttwxxxwto^;>!))))))))))!!!::5deggeeeeeeegbb3] ",
" ~@/oxt7'#))))))))))))))))=,3ktwxxyyyyyyxk/+!))))))))))))))!:::5degggeeegggb3^ ",
" ^&8xyyt^,)))))))))))))))>,3otwxyyyyyyyyyxh'>)))))))))))))))))):5ddeeeeeeeggb3^ ",
" 771pyyyx7'=!)))))))))))!!#(jtxxyyyyyyyyyyyt3-)))))))))))))))))))!!::degggeeegb2[o ",
" 77tyyyxk/+!!)))))))))))-;9owxyyyyyyyyyyyywh*>)))))))))))))))))))))!::5ddgggggb68j ",
" owyyyyt8;>))))))))))))*(otwyyyyyyyyyyyyyxp'-)))))))))))))))))))))))!!:5deeeggg_8j ",
" jtxyyyyxh'>)))))))))!!#_ktxyyyyyyyyyyyyyyyt_+))))))))))))))))))))))))))!!:5deggg63j ",
" 7jwyyyyyyp/=))))))))))>,3owxyyyyyyyyyyyyyyyw/+))))))))))))))))))))))))))))!::5degb689 ",
" 7xyyyyyyo[#))))))))))-/jtwyyyyyyyyyyyyyyyyw/*)))))))))))))))))))))))))))))))!:5dgg_/ ",
" }xyyyyyyt9*=))))))))=*9owyyyyyyyyyyyyyyyyyw/*)))))))))))))))))))))))))))))))))!!:5d3} ",
" }xyyyyyywj'#!))))))!#@7oxyyyyyyyyyyyyyyyyyw/*)))))))))))))))))))))))))))))))))))!!:4/7 ",
" 7xyyyyyyxj&,!!))))!!,%}oyyyyyyyyyyyyyyyyyyw/*))))))))))))))))))))))))))))))))))))))>487 ",
" 7xyyyyyywk$@!!)))!!-.$]oyyyyyyyyyyyyyyyyyyw/+))))))))))))))))))))))))))))))!!!!))))!>' ",
" }xyyyyyywj$&+!!)!)>;%$]jyyyyyyyyyyyyyyyyyyt{#)))))))))))))))))))))!!!!!!))!)!!!!!!))!#' ",
" 7xyyyyyyt7$%@-!)!>*[]$$jyyyyyyyyyyyyyyyyyxp;-))))))))))))))))))!!!!!!!!!!!!>>>>>>>>>>!,^ ",
" 7xyyyyyyt}$][;-)=,(o7$$7yyyyyyyyyyyyyyyyyxp,-)))))))))))!!!!)!!!!>>>>=-----########--=+'9 ",
" jwyyyyyyo}$}o(';@~7wj$$7yyyyyyyyyyyyyyyyywh*>)))))))))))!>>>=>=---#####+########+++***;@17 ",
" otxyyyyyt}$7t7}1}7kw7$$7yyyyyyyyyyyyyyyyyt0-)))))))))!!!>--####+++++++++++++##+***,;''.&] ",
" ooowyyyyyt}$}j7owwojo}$$jyyyyyyyyyyyyyyyyyp2>)))))))!!!=##++++++++++++++###+*;@.~[8[9hph ",
" ojtyyyyywj$$}jwyyxo}$$]jyyyyyyyyyyyyyyyyyp'>))))))!>>-#++++++++++++####+,;'_3/&^}77kot ",
" 7tyyyyyxo]$$oxyyyt]$$}tyyyyyyyyyyyyyyyyx0*!)))!!!>-#++++++++++++#+##+*;.&1ko ",
" 7tyyyyyyx7]}xyyyyxj}]oxyyyyyyyyyyyyyyyyp<=)!!!!>-#++++++++++++####*;.(8h ",
" owxyxxyytooywptwwtppxyyyyyyyyyyyyyyyxp3,-=!)!>-#++++++++++###+*,'_{&1k ",
" jtwwttwtwwtj7kjowxyyyyyyyyyyyyyyyyxt7~'',+>=#+++++++++++###*;@&^j ",
" ]joojj7}]}]|innfc7jtwyyyyyyyyyyyxtjcfnnnf[@*#+++++++++###+@.&%% ",
" ]$}77}}$$$$]fsssnnifkkotwwwwwwwtpjkfinvvvsi}@*#++++++###*;@.@@&[ ",
" o7$]]]]]$$]|isvvvvvusifckopppopok7cisvvvvvvvn(,#++++++#+*@.&@*#;3o ",
" }}$]|||fnnsvvvuvvvuuvvsniffffffnnsvvvvuuuvvvc{*+#++##*@&.@*+#--<7 ",
" }]cninsuvvvvuuuuuuvvvvusnnnnnssuvvvvvuuuuvvc~*+#+++*@.@;*##=>>,^ ",
" 7fvvvvvvuuuuuuuuuuuuvvvvvvvvvvvuuuuuuuuuvvc~*+#+#+,.@*###->!!*~ ",
" pkivvvvuuuuuuuuuuuuuuuvvvvvvvvuuuvsnsuuuvvf~*+#++++*+++->!!)!#. ",
" kfsuvvuuuuuuuuuuuuuuuuuuuuuuuuuvvnfsuvuvvc{++#++++###->!!))!-;h ",
" kisvvvuuuuuuuuuuuuuuuuuuuuuuuvvvicsvvvvs1@##+++++++#>!!))))=,ho ",
" 7imuvvvuuuuuuuuuuuuuuuuuuuuvusfcivvuvvn~;##+++++++#>!!))))!#8k ",
" cimruuuuuvuuuuuuuuuuuuuuuuvsnfisuvvvsc@*#+++++++++#>!!))))-3} ",
" 7amrruuuuuuuuuuuuuuuuuuuuvsnnsvvuvvi^,##++++++++++#>!!)))>/^ ",
" kfamrruuuuvvvuuuuuuuuuuuuuvvvvvvvn1@+#++++++++++++#>!)))>{~ ",
" 7|iimrrruuuuuuuuuuuuuuuuvvvvuusn1'+#########++++++->!))>; ",
" 7cammrrrrruuuuuuvvvvvuuuuurrm|.*-#+#######+###+++->!!!*' ",
" ookcaimmrrrrrruuuuurrrrrmi|]%.@@@@@;,*,*+########->!!*6o ",
" p7}|ainiimmmmmmmmmmminnia|$%.....{3322_{''',,**+#=!!#6k ",
" j7||aaiiiiiaa||7j ookok711^&.';,*+=!><k ",
" koooook hph[~@+>><k ",
" ppppp tk7^3_,+<j ",
" o7^@3j ",
" 9jj ",
" o ",
" ",
" ",
" ",
" ",
" ",
" ",
". c #000271",
"+ c #03035D",
"@ c #00009F",
"# c #0A0A1B",
"$ c #08058E",
"% c #060E4C",
"& c #11110E",
"* c #101339",
"= c #0D11CC",
"- c #1B1CFD",
"; c #342B24",
"> c #2325EC",
", c #3C3883",
"' c #3D3A9E",
") c #5B5170",
"! c #4B4CFF",
"~ c #795339",
"{ c #5E5B5C",
"] c #5F5ED3",
"^ c #5E5EFB",
"/ c #7271FF",
"( c #B37F5D",
"_ c #8F8883",
": c #8887FF",
"< c #D59E76",
"[ c #ABABA9",
"} c #A9AAFF",
"| c #C1C3C1",
"1 c #FAC296",
"2 c #D4D6D3",
"3 c #F9FCF8",
" ",
" ",
" #***,,,**** ",
" *,,]]]]]]]]]]]]]',,** ",
" *,']//////////////////]]',* ",
" *,']/////////////////////////]'% ",
" *,]////////////////////^^!!>>>>>>>$+ ",
" *,]////////////////////!>---------->=@% ",
" * ,]///////////////////]^>------->==@@@$.# ",
" +', *']//////////////////],,,=---->=@@@@@$.% ",
" #.=^'* ,]//////////////////],']^]$--=@@@@@@@$+# ",
" %$=-^'* ,]/////////////////],]/!>-^'=@@@@@@@$.% ",
" +$=->/,*,//////////////////]'/^!,$-!,$@@@@@@$+* ",
" +@=--!''/////////////////]']^!,(()->%$@@@@@$+# ",
" +@=--='/////////////////]']^${(<<)->,$@@@@$% ",
" +@=->']/////////:::////]]/^'(<111)->,$@@@$% ",
" #+@@>$]////////::}}}://///!,(<1111)--%$@@.% ",
" #+@@$$^////////:}}}}}://^>$(<<1111)--+$@.% ",
" +@$.>^///////:}}}}}}:/^>->,(<111<'--+$$*# ",
" +$.=-!///////:}}}}}:^!-----@(111<@--+$,'],,* ",
" %+%=->^///////:}}}:!--------@(11(=--$=^////],* ",
" ,]]'>->^//////^^!!-----------'<1_>--@-!//////]'* ",
" '!->@--->>>>>>--->===>--------)<,-->@->^///////]', ",
" *$--->----------='){__{'>------>'=--=@-->!^///////],* ",
" %$.=---------->$)[22332[)=----------=>----->^^//////], ",
" %$_,--------->'_|3333333['----------=--------->!^////],# ",
" *'[{=--------'_2333333333_=---------------------->!^///,* ",
" #)[_@-------@_|33333333332,------------------------->!^/'* ",
" #)2[$------=)|333332|23333{>--------------------------->^'* ",
" {2|,------$[233333___3333_=----------------------------->$ ",
" ;22)=---->)|333332{2_2333[@-------------------------------$ ",
" &22{@----$_233333|{2||333|'--------------------------------$ ",
" &|3_.----,|333333[;2|[333|'--------------------------------=+ ",
" [3_%=--={2333333[&___333|'-------------------->>>====>>----@ ",
" _3[#$=@.[2333333[&&&_333[$------------->>==@@@@@@@@@@@@@@@==+",
" {3|;+$$)|3333333[&&&[333_=-------->==@@@@@@@@@@@@@@@$$$$.+++%",
" {23{*$${23333333|;&&|332)>----->=@@@@@@@@@@@@@@$$$.++%** ",
";{{;[3{&*)[333333333{&&|332,=---==@@@@@@@@@@@@$$.++%* ",
"{22_{|[;_|2333333333_&;233_$@@@@@@@@@@@@@@@@$$+%* ",
"&_|2{;{{[233333333332_[33[,$@@@@@@@@@@@@@$$+%# ",
" &;{&&&;~(_|3333333333332)$@@@@@@@@@@@@$.+%# ",
" &&&&&;(11([33333333332{$@@@@@@@@@@@$...$@$* ",
" &~((1111<[333333332{%.$@@@@@@@@@$$$$@=--$ ",
" ~<<11111<[33333|[_(<~,$@@@@@@@@@@@@@>-->. ",
" ;(<111111<(____(11111(+@@@@@@@@@@@@=----=% ",
" ~(<11111111<11111<(<<;$@@$$@@@@@@@=-----. ",
" ~(<1111111111111(~<1{$$$.$@@@@@@@=-----= ",
" ~(<1111111<<(((<11<*$+.$@@@@@@@@@>---->+ ",
" ;(<1111111<<1111<~%+$@@@@@@@@@@@=-----$ ",
" ~(<<111111111(~&*+$$$@@@@@@@@@@=----=% ",
" ;~((<<<<(~~; *%+$$@@@@@@@@@>----+ ",
" ;;; #%+$$@@@@@@@----. ",
" *+$$@@@@@=---@ ",
" *+$@@@@@>--= ",
" *.$@@@@-->% ",
" #%.$@@=->+ ",
" *+$@@>-$ ",
" %$@=-$ ",
" %.@>@ ",
" +=@ ",
" .. ",
" * ",
" ",
" "};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View file

@ -26,6 +26,8 @@
#include <unistd.h>
#endif
#include "time.h" // For log timestamps
#ifdef HAVE_SDL
#ifdef HAVE_TTF
@ -114,6 +116,7 @@ int main(int argc, char **argv)
#endif
{
const char *logdir = NULL;
char logfile[MAX_WADPATH];
myargc = argc;
myargv = argv; /// \todo pull out path to exe from this string
@ -125,15 +128,36 @@ int main(int argc, char **argv)
#endif
#endif
#ifdef LOGMESSAGES
if (!M_CheckParm("-nolog"))
{
time_t my_time;
struct tm * timeinfo;
char buf[26];
logdir = D_Home();
#ifdef LOGMESSAGES
my_time = time(NULL);
timeinfo = localtime(&my_time);
strftime(buf, 26, "%Y-%m-%d %H-%M-%S", timeinfo);
strcpy(logfile, va("log-%s.txt", buf));
#ifdef DEFAULTDIR
if (logdir)
logstream = fopen(va("%s/"DEFAULTDIR"/log.txt",logdir), "wt");
{
// Create dirs here because D_SRB2Main() is too late.
I_mkdir(va("%s%s"DEFAULTDIR, logdir, PATHSEP), 0755);
I_mkdir(va("%s%s"DEFAULTDIR"%slogs",logdir, PATHSEP, PATHSEP), 0755);
logstream = fopen(va("%s%s"DEFAULTDIR"%slogs%s%s",logdir, PATHSEP, PATHSEP, PATHSEP, logfile), "wt");
}
else
#endif
logstream = fopen("./log.txt", "wt");
{
I_mkdir("."PATHSEP"logs"PATHSEP, 0755);
logstream = fopen(va("."PATHSEP"logs"PATHSEP"%s", logfile), "wt");
}
}
#endif
//I_OutputMsg("I_StartupSystem() ...\n");
@ -160,6 +184,10 @@ int main(int argc, char **argv)
// startup SRB2
CONS_Printf("Setting up SRB2...\n");
D_SRB2Main();
#ifdef LOGMESSAGES
if (!M_CheckParm("-nolog"))
CONS_Printf("Logfile: %s\n", logfile);
#endif
CONS_Printf("Entering main game loop...\n");
// never return
D_SRB2Loop();

View file

@ -530,7 +530,7 @@ static void Impl_HandleKeyboardConsoleEvent(KEY_EVENT_RECORD evt, HANDLE co)
break;
case VK_RETURN:
entering_con_command = false;
// Fall through.
/* FALLTHRU */
default:
event.data1 = MapVirtualKey(evt.wVirtualKeyCode,2); // convert in to char
}

View file

@ -41,7 +41,7 @@
#ifdef HAVE_IMAGE
#include "SDL_image.h"
#elif 1
#elif defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) // Windows doesn't need this, as SDL will do it for us.
#define LOAD_XPM //I want XPM!
#include "IMG_xpm.c" //Alam: I don't want to add SDL_Image.dll/so
#define HAVE_IMAGE //I have SDL_Image, sortof

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View file

@ -35,6 +35,23 @@ sfxinfo_t S_sfx[NUMSFX] =
// name, singularity, priority, pitch, volume, data, length, skinsound, usefulness, lumpnum, caption
{"none" , false, 0, 0, -1, NULL, 0, -1, -1, LUMPERROR, "///////////////////////////////"}, // maximum length
// A HUMBLE REQUEST FROM YOUR FRIENDLY NEIGHBORHOOD toaster!
//
// If you see a caption that's just "" (shows the lumpname in-game),
// and you intend to use the sound associated with it in a mod,
// PLEASE give it a caption through SOC or Lua.
//
// If the first character of the caption is '/', no caption will be
// produced; only do this for "unimportant" sounds that aren't used
// to indicate gameplay.
//
// (to whomstever updates the sounds list wiki page for 2.2, please
// either copy this comment across, or make sure its desire is
// codified in the initial paragraph of the page.)
//
// Closed Captioning may be a niche feature, but it's an important one.
// Thank you! ^u^
// Skin Sounds
{"altdi1", false, 192, 16, -1, NULL, 0, SKSPLDET1, -1, LUMPERROR, "Dying"},
{"altdi2", false, 192, 16, -1, NULL, 0, SKSPLDET2, -1, LUMPERROR, "Dying"},
@ -290,6 +307,139 @@ sfxinfo_t S_sfx[NUMSFX] =
{"brakrl", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Rocket launch"},
{"brakrx", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Rocket explosion"},
// Sonic 1 sounds
{"s1a0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1a1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1a2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1a3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1a4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1a5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1a6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1a7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1a8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1a9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1aa", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1ab", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1ac", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1ad", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1ae", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1af", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1b0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1b1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1b2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1b3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1b4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1b5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1b6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1b7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1b8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1b9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1ba", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1bb", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1bc", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1bd", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1be", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1bf", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1c0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1c1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1c2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1c3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1c4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1c5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1c6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1c7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1c8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1c9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1ca", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1cb", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1cc", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1cd", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1ce", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s1cf", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
// Sonic 2 sounds
{"s220", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s221", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s222", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s223", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s224", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s225", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s226", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s227", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s228", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s229", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s22a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s22b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s22c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s22d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s22e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s22f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s230", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s231", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s232", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s233", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s234", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s235", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s236", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s237", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s238", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s239", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s23a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s23b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s23c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s23d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s23e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s23f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s240", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s241", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s242", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s243", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s244", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s245", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s246", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s247", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s248", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s249", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s24a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s24b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s24c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s24d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s24e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s24f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s250", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s251", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s252", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s253", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s254", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s255", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s256", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s257", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s258", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s259", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s25a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s25b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s25c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s25d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s25e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s25f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s260", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s261", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s262", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s263", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s264", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s265", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s266", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s267", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s268", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s269", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s26a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s26b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s26c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s26d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s26e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s26f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s270", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
// S3&K sounds
{"s3k33", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"}, // stereo in original game, identical to latter
{"s3k34", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"}, // mono in original game, identical to previous
@ -492,6 +642,174 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3kdbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running on water"},
{"s3kdbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running on water"}, // ditto
// 3D Blast sounds (the "missing" ones are direct copies of S3K's, no minor differences what-so-ever)
{"3db06", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Collection"},
{"3db09", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Peep"},
{"3db14", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Chirp"},
{"3db16", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
// Sonic CD sounds
{"cdfm00", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Skid"},
{"cdfm01", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm02", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"},
{"cdfm03", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Dying"},
{"cdfm04", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ring loss"},
{"cdfm05", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"},
{"cdfm06", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pop"},
{"cdfm07", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Shield"},
{"cdfm08", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spring"},
{"cdfm09", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm10", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm11", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm12", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm13", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm14", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm15", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm16", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm17", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm18", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm19", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm20", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm21", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm22", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm23", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm24", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm25", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm26", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm27", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm28", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm29", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bubble gasp"},
{"cdfm30", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Starpost"},
{"cdfm31", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Warp"},
{"cdfm32", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm33", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm34", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm35", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm36", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm37", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm38", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drowning"},
{"cdfm39", false, 128, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm41", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm44", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Extra time"},
{"cdfm45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm46", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm47", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aquaphobia"},
{"cdfm50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm51", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm54", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm55", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm56", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Warp"},
{"cdfm57", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm58", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm59", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm60", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm64", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm65", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm70", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm71", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm72", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm73", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm74", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm75", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm76", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm77", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm78", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdfm79", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdpcm0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Future."},
{"cdpcm1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Past."},
{"cdpcm2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "All right!"},
{"cdpcm3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "I'm outta here..."},
{"cdpcm4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Yes!"},
{"cdpcm5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Yeah!"},
{"cdpcm6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Giggles"},
{"cdpcm7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Eep!"},
{"cdpcm8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"cdpcm9", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"},
// Knuckles Chaotix sounds
{"kc2a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc2b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc2c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc2d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc2e", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc2f", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc30", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc31", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc32", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc33", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc34", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc35", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc36", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc37", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc38", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc39", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc3a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc3b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc3c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc3d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc3e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc3f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc41", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Confirm"},
{"kc43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc44", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc46", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc47", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Select"},
{"kc49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc51", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc54", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc55", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc56", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc57", false, 128, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Sheer terror"},
{"kc58", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc59", false, 128, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Shrink"},
{"kc5a", false, 128, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Grow"},
{"kc5b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc5c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc5d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc5e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc5f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc60", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc64", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Terrifying rumble"},
{"kc65", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ascending"},
{"kc6c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc6d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"kc6e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
// skin sounds free slots to add sounds at run time (Boris HACK!!!)
// initialized to NULL
};

View file

@ -356,6 +356,139 @@ typedef enum
sfx_brakrl, // Rocket launcher
sfx_brakrx, // Rocket explodes
// S1 sounds
sfx_s1a0,
sfx_s1a1,
sfx_s1a2,
sfx_s1a3,
sfx_s1a4,
sfx_s1a5,
sfx_s1a6,
sfx_s1a7,
sfx_s1a8,
sfx_s1a9,
sfx_s1aa,
sfx_s1ab,
sfx_s1ac,
sfx_s1ad,
sfx_s1ae,
sfx_s1af,
sfx_s1b0,
sfx_s1b1,
sfx_s1b2,
sfx_s1b3,
sfx_s1b4,
sfx_s1b5,
sfx_s1b6,
sfx_s1b7,
sfx_s1b8,
sfx_s1b9,
sfx_s1ba,
sfx_s1bb,
sfx_s1bc,
sfx_s1bd,
sfx_s1be,
sfx_s1bf,
sfx_s1c0,
sfx_s1c1,
sfx_s1c2,
sfx_s1c3,
sfx_s1c4,
sfx_s1c5,
sfx_s1c6,
sfx_s1c7,
sfx_s1c8,
sfx_s1c9,
sfx_s1ca,
sfx_s1cb,
sfx_s1cc,
sfx_s1cd,
sfx_s1ce,
sfx_s1cf,
// S2 sounds
sfx_s220,
sfx_s221,
sfx_s222,
sfx_s223,
sfx_s224,
sfx_s225,
sfx_s226,
sfx_s227,
sfx_s228,
sfx_s229,
sfx_s22a,
sfx_s22b,
sfx_s22c,
sfx_s22d,
sfx_s22e,
sfx_s22f,
sfx_s230,
sfx_s231,
sfx_s232,
sfx_s233,
sfx_s234,
sfx_s235,
sfx_s236,
sfx_s237,
sfx_s238,
sfx_s239,
sfx_s23a,
sfx_s23b,
sfx_s23c,
sfx_s23d,
sfx_s23e,
sfx_s23f,
sfx_s240,
sfx_s241,
sfx_s242,
sfx_s243,
sfx_s244,
sfx_s245,
sfx_s246,
sfx_s247,
sfx_s248,
sfx_s249,
sfx_s24a,
sfx_s24b,
sfx_s24c,
sfx_s24d,
sfx_s24e,
sfx_s24f,
sfx_s250,
sfx_s251,
sfx_s252,
sfx_s253,
sfx_s254,
sfx_s255,
sfx_s256,
sfx_s257,
sfx_s258,
sfx_s259,
sfx_s25a,
sfx_s25b,
sfx_s25c,
sfx_s25d,
sfx_s25e,
sfx_s25f,
sfx_s260,
sfx_s261,
sfx_s262,
sfx_s263,
sfx_s264,
sfx_s265,
sfx_s266,
sfx_s267,
sfx_s268,
sfx_s269,
sfx_s26a,
sfx_s26b,
sfx_s26c,
sfx_s26d,
sfx_s26e,
sfx_s26f,
sfx_s270,
// S3&K sounds
sfx_s3k33,
sfx_s3k34,
@ -558,6 +691,174 @@ typedef enum
sfx_s3kdbs,
sfx_s3kdbl,
// 3DB sounds
sfx_3db06,
sfx_3db09,
sfx_3db14,
sfx_3db16,
// SCD sounds
sfx_cdfm00,
sfx_cdfm01,
sfx_cdfm02,
sfx_cdfm03,
sfx_cdfm04,
sfx_cdfm05,
sfx_cdfm06,
sfx_cdfm07,
sfx_cdfm08,
sfx_cdfm09,
sfx_cdfm10,
sfx_cdfm11,
sfx_cdfm12,
sfx_cdfm13,
sfx_cdfm14,
sfx_cdfm15,
sfx_cdfm16,
sfx_cdfm17,
sfx_cdfm18,
sfx_cdfm19,
sfx_cdfm20,
sfx_cdfm21,
sfx_cdfm22,
sfx_cdfm23,
sfx_cdfm24,
sfx_cdfm25,
sfx_cdfm26,
sfx_cdfm27,
sfx_cdfm28,
sfx_cdfm29,
sfx_cdfm30,
sfx_cdfm31,
sfx_cdfm32,
sfx_cdfm33,
sfx_cdfm34,
sfx_cdfm35,
sfx_cdfm36,
sfx_cdfm37,
sfx_cdfm38,
sfx_cdfm39,
sfx_cdfm40,
sfx_cdfm41,
sfx_cdfm42,
sfx_cdfm43,
sfx_cdfm44,
sfx_cdfm45,
sfx_cdfm46,
sfx_cdfm47,
sfx_cdfm48,
sfx_cdfm49,
sfx_cdfm50,
sfx_cdfm51,
sfx_cdfm52,
sfx_cdfm53,
sfx_cdfm54,
sfx_cdfm55,
sfx_cdfm56,
sfx_cdfm57,
sfx_cdfm58,
sfx_cdfm59,
sfx_cdfm60,
sfx_cdfm61,
sfx_cdfm62,
sfx_cdfm63,
sfx_cdfm64,
sfx_cdfm65,
sfx_cdfm66,
sfx_cdfm67,
sfx_cdfm68,
sfx_cdfm69,
sfx_cdfm70,
sfx_cdfm71,
sfx_cdfm72,
sfx_cdfm73,
sfx_cdfm74,
sfx_cdfm75,
sfx_cdfm76,
sfx_cdfm77,
sfx_cdfm78,
sfx_cdfm79,
sfx_cdpcm0,
sfx_cdpcm1,
sfx_cdpcm2,
sfx_cdpcm3,
sfx_cdpcm4,
sfx_cdpcm5,
sfx_cdpcm6,
sfx_cdpcm7,
sfx_cdpcm8,
sfx_cdpcm9,
// KC sounds
sfx_kc2a,
sfx_kc2b,
sfx_kc2c,
sfx_kc2d,
sfx_kc2e,
sfx_kc2f,
sfx_kc30,
sfx_kc31,
sfx_kc32,
sfx_kc33,
sfx_kc34,
sfx_kc35,
sfx_kc36,
sfx_kc37,
sfx_kc38,
sfx_kc39,
sfx_kc3a,
sfx_kc3b,
sfx_kc3c,
sfx_kc3d,
sfx_kc3e,
sfx_kc3f,
sfx_kc40,
sfx_kc41,
sfx_kc42,
sfx_kc43,
sfx_kc44,
sfx_kc45,
sfx_kc46,
sfx_kc47,
sfx_kc48,
sfx_kc49,
sfx_kc4a,
sfx_kc4b,
sfx_kc4c,
sfx_kc4d,
sfx_kc4e,
sfx_kc4f,
sfx_kc50,
sfx_kc51,
sfx_kc52,
sfx_kc53,
sfx_kc54,
sfx_kc55,
sfx_kc56,
sfx_kc57,
sfx_kc58,
sfx_kc59,
sfx_kc5a,
sfx_kc5b,
sfx_kc5c,
sfx_kc5d,
sfx_kc5e,
sfx_kc5f,
sfx_kc60,
sfx_kc61,
sfx_kc62,
sfx_kc63,
sfx_kc64,
sfx_kc65,
sfx_kc66,
sfx_kc67,
sfx_kc68,
sfx_kc69,
sfx_kc6b,
sfx_kc6c,
sfx_kc6d,
sfx_kc6e,
// free slots for S_AddSoundFx() at run-time --------------------
sfx_freeslot0,
//

View file

@ -64,11 +64,12 @@ patch_t *sbotime; // Time logo
patch_t *sbocolon; // Colon for time
patch_t *sboperiod; // Period for time centiseconds
patch_t *livesback; // Lives icon background
patch_t *stlivex;
static patch_t *nrec_timer; // Timer for NiGHTS records
static patch_t *sborings;
static patch_t *sboover;
static patch_t *timeover;
static patch_t *stlivex;
static patch_t *slidgame;
static patch_t *slidtime;
static patch_t *slidover;
static patch_t *sboredrings;
static patch_t *sboredtime;
static patch_t *getall; // Special Stage HUD
@ -253,8 +254,10 @@ void ST_LoadGraphics(void)
sbocolon = W_CachePatchName("STTCOLON", PU_HUDGFX); // Colon for time
sboperiod = W_CachePatchName("STTPERIO", PU_HUDGFX); // Period for time centiseconds
sboover = W_CachePatchName("SBOOVER", PU_HUDGFX);
timeover = W_CachePatchName("TIMEOVER", PU_HUDGFX);
slidgame = W_CachePatchName("SLIDGAME", PU_HUDGFX);
slidtime = W_CachePatchName("SLIDTIME", PU_HUDGFX);
slidover = W_CachePatchName("SLIDOVER", PU_HUDGFX);
stlivex = W_CachePatchName("STLIVEX", PU_HUDGFX);
livesback = W_CachePatchName("STLIVEBK", PU_HUDGFX);
nrec_timer = W_CachePatchName("NGRTIMER", PU_HUDGFX); // Timer for NiGHTS
@ -768,7 +771,12 @@ static inline void ST_drawRings(void)
ST_DrawPatchFromHud(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS));
ringnum = ((objectplacing) ? op_currentdoomednum : max(stplyr->rings, 0));
if (objectplacing)
ringnum = op_currentdoomednum;
else if (stplyr->rings < 0 || stplyr->spectator || stplyr->playerstate == PST_REBORN)
ringnum = 0;
else
ringnum = stplyr->rings;
if (cv_timetic.value == 2) // Yes, even in modeattacking
ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS));
@ -877,6 +885,8 @@ static void ST_drawLivesArea(void)
'\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false);
else
{
if (stplyr->playerstate == PST_DEAD && !(stplyr->spectator) && (livescount || stplyr->deadtimer < (TICRATE<<1)))
livescount++;
if (livescount > 99)
livescount = 99;
V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8,
@ -2029,42 +2039,7 @@ static void ST_drawTextHUD(void)
textHUDdraw(va("Lap:""\x82 %u/%d", stplyr->laps+1, cv_numlaps.value))
}
if (!stplyr->spectator && stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP)
{
INT32 i, total = 0, exiting = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
if (players[i].lives <= 0)
continue;
total++;
if (players[i].exiting)
exiting++;
}
if (cv_playersforexit.value != 4)
{
total *= cv_playersforexit.value;
if (total & 3)
total += 4; // round up
total /= 4;
}
if (exiting < total)
{
if (!splitscreen && !donef12)
{
textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view"))
donef12 = true;
}
total -= exiting;
textHUDdraw(va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s")))
}
}
else if (gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)))
if (gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)))
{
if (!splitscreen && !donef12)
{
@ -2092,7 +2067,7 @@ static void ST_drawTextHUD(void)
textHUDdraw(M_GetText("\x82""JUMP:""\x80 Rise"))
textHUDdraw(M_GetText("\x82""SPIN:""\x80 Lower"))
if (G_IsSpecialStage(gamemap) && (maptol & TOL_NIGHTS))
if (G_IsSpecialStage(gamemap))
textHUDdraw(M_GetText("\x82""Wait for the stage to end..."))
else if (gametype == GT_COOP)
{
@ -2125,7 +2100,46 @@ static void ST_drawTextHUD(void)
textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game"))
}
if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator))
if (gametype == GT_COOP && (!stplyr->spectator || (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))) && stplyr->exiting)
{
UINT8 numneeded = (G_IsSpecialStage(gamemap) ? 4 : cv_playersforexit.value);
if (numneeded)
{
INT32 i, total = 0, exiting = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
if (players[i].lives <= 0)
continue;
total++;
if (players[i].exiting)
exiting++;
}
if (numneeded != 4)
{
total *= cv_playersforexit.value;
if (total & 3)
total += 4; // round up
total /= 4;
}
if (exiting < total)
{
if (!splitscreen && !donef12)
{
textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view"))
donef12 = true;
}
total -= exiting;
textHUDdraw(va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s")))
}
}
}
else if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator))
{
if (leveltime < hidetime * TICRATE)
{
@ -2409,25 +2423,20 @@ static void ST_overlayDrawer(void)
}
}
// GAME OVER pic
// GAME OVER hud
if ((gametype == GT_COOP)
&& (netgame || multiplayer)
&& (cv_cooplives.value == 0))
;
else if (G_GametypeUsesLives() && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer)))
else if ((G_GametypeUsesLives() || gametype == GT_RACE) && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer)))
{
patch_t *p;
if (countdown == 1)
p = timeover;
else
p = sboover;
INT32 i = MAXPLAYERS;
INT32 deadtimer = stplyr->spectator ? TICRATE : (stplyr->deadtimer-(TICRATE<<1));
if ((gametype == GT_COOP)
&& (netgame || multiplayer)
&& (cv_cooplives.value != 1))
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
@ -2437,15 +2446,18 @@ static void ST_overlayDrawer(void)
continue;
if (players[i].lives > 0)
{
p = NULL;
break;
}
}
}
if (p)
V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, BASEVIDHEIGHT/2 - (SHORT(p->height)/2), V_PERPLAYER|(stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS), p);
if (i == MAXPLAYERS && deadtimer >= 0)
{
INT32 lvlttlx = min(6*deadtimer, BASEVIDWIDTH/2);
UINT32 flags = V_PERPLAYER|(stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS);
V_DrawScaledPatch(lvlttlx - 8, BASEVIDHEIGHT/2, flags, (countdown == 1 ? slidtime : slidgame));
V_DrawScaledPatch(BASEVIDWIDTH + 8 - lvlttlx, BASEVIDHEIGHT/2, flags, slidover);
}
}
if (G_GametypeHasTeams())

View file

@ -70,6 +70,7 @@ extern patch_t *sboperiod;
extern patch_t *faceprefix[MAXSKINS]; // face status patches
extern patch_t *superprefix[MAXSKINS]; // super face status patches
extern patch_t *livesback;
extern patch_t *stlivex;
extern patch_t *ngradeletters[7];
/** HUD location information (don't move this comment)

View file

@ -1045,9 +1045,15 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
dest = desttop;
dest += FixedInt(FixedMul(topdelta<<FRACBITS,fdup))*vid.width;
if (topdelta-sy > 0)
{
dest += FixedInt(FixedMul((topdelta-sy)<<FRACBITS,fdup))*vid.width;
ofs = 0;
}
else
ofs = (sy-topdelta)<<FRACBITS;
for (ofs = sy<<FRACBITS; dest < deststop && (ofs>>FRACBITS) < column->length && (((ofs>>FRACBITS) - sy) + topdelta) < h; ofs += rowfrac)
for (; dest < deststop && (ofs>>FRACBITS) < column->length && (((ofs>>FRACBITS) - sy) + topdelta) < h; ofs += rowfrac)
{
if (dest >= screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = patchdrawfunc(dest, source, ofs);
@ -1064,17 +1070,17 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
//
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
{
if (skinnum < 0 || skinnum >= numskins || (skins[skinnum].flags & SF_HIRES))
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
else
if (skinnum >= 0 && skinnum < numskins && skins[skinnum].sprites[SPR2_XTRA].numframes >= 4)
{
spriteframe_t *sprframe = &skins[skinnum].sprites[SPR2_WAIT].spriteframes[0];
patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
spriteframe_t *sprframe = &sprdef->spriteframes[3];
patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);
// No variant for translucency
V_DrawTinyMappedPatch(x, y, flags, patch, colormap);
V_DrawMappedPatch(x, y, flags, patch, colormap);
}
else
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
}
//

View file

@ -789,6 +789,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile)
// set up caching
//
Z_Calloc(numlumps * sizeof (*wadfile->lumpcache), PU_STATIC, &wadfile->lumpcache);
Z_Calloc(numlumps * sizeof (*wadfile->patchcache), PU_STATIC, &wadfile->patchcache);
#ifdef HWRENDER
// allocates GLPatch info structures and store them in a tree
@ -1182,8 +1183,6 @@ void zerr(int ret)
}
#endif
#define NO_PNG_LUMPS
#ifdef NO_PNG_LUMPS
static void ErrorIfPNG(UINT8 *d, size_t s, char *f, char *l)
{
@ -1459,6 +1458,38 @@ boolean W_IsLumpCached(lumpnum_t lumpnum, void *ptr)
return W_IsLumpCachedPWAD(WADFILENUM(lumpnum),LUMPNUM(lumpnum), ptr);
}
//
// W_IsPatchCached
//
// If a patch is already cached return true, otherwise
// return false.
//
// no outside code uses the PWAD form, for now
static inline boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
{
void *lcache;
if (!TestValidLump(wad, lump))
return false;
lcache = wadfiles[wad]->patchcache[lump];
if (ptr)
{
if (ptr == lcache)
return true;
}
else if (lcache)
return true;
return false;
}
boolean W_IsPatchCached(lumpnum_t lumpnum, void *ptr)
{
return W_IsPatchCachedPWAD(WADFILENUM(lumpnum),LUMPNUM(lumpnum), ptr);
}
// ==========================================================================
// W_CacheLumpName
// ==========================================================================
@ -1482,18 +1513,53 @@ void *W_CacheLumpName(const char *name, INT32 tag)
// Cache a patch into heap memory, convert the patch format as necessary
//
// Software-only compile cache the data without conversion
#ifdef HWRENDER
static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
{
#ifdef HWRENDER
GLPatch_t *grPatch;
if (rendermode == render_soft || rendermode == render_none)
return W_CacheLumpNumPwad(wad, lump, tag);
#endif
if (!TestValidLump(wad, lump))
return NULL;
#ifdef HWRENDER
// Software-only compile cache the data without conversion
if (rendermode == render_soft || rendermode == render_none)
{
#endif
lumpcache_t *lumpcache = wadfiles[wad]->patchcache;
if (!lumpcache[lump])
{
size_t len = W_LumpLengthPwad(wad, lump);
void *ptr, *lumpdata, *srcdata = NULL;
ptr = Z_Malloc(len, tag, &lumpcache[lump]);
lumpdata = Z_Malloc(len, tag, NULL);
// read the lump in full
W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0);
#ifndef NO_PNG_LUMPS
// lump is a png so convert it
if (R_IsLumpPNG((UINT8 *)lumpdata, len))
{
size_t newlen;
srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen, true);
ptr = Z_Realloc(ptr, newlen, tag, &lumpcache[lump]);
M_Memcpy(ptr, srcdata, newlen);
Z_Free(srcdata);
}
else // just copy it into the patch cache
#endif
M_Memcpy(ptr, lumpdata, len);
}
else
Z_ChangeTag(lumpcache[lump], tag);
return lumpcache[lump];
#ifdef HWRENDER
}
grPatch = HWR_GetCachedGLPatchPwad(wad, lump);
if (grPatch->mipmap.grInfo.data)
@ -1517,6 +1583,7 @@ static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
// return GLPatch_t, which can be casted to (patch_t) with valid patch header info
return (void *)grPatch;
#endif
}
void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag)
@ -1524,8 +1591,6 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag)
return W_CachePatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag);
}
#endif // HWRENDER
void W_UnlockCachedPatch(void *patch)
{
// The hardware code does its own memory management, as its patches
@ -1621,13 +1686,145 @@ void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5)
#endif
}
// Verify versions for different archive
// formats. checklist assumed to be valid.
static int
W_VerifyName (const char *name, lumpchecklist_t *checklist, boolean status)
{
size_t j;
for (j = 0; checklist[j].len && checklist[j].name; ++j)
{
if (( strncmp(name, checklist[j].name,
checklist[j].len) != false ) == status)
{
return true;
}
}
return false;
}
static int
W_VerifyWAD (FILE *fp, lumpchecklist_t *checklist, boolean status)
{
size_t i;
// assume wad file
wadinfo_t header;
filelump_t lumpinfo;
// read the header
if (fread(&header, 1, sizeof header, fp) == sizeof header
&& header.numlumps < INT16_MAX
&& strncmp(header.identification, "ZWAD", 4)
&& strncmp(header.identification, "IWAD", 4)
&& strncmp(header.identification, "PWAD", 4)
&& strncmp(header.identification, "SDLL", 4))
{
return true;
}
header.numlumps = LONG(header.numlumps);
header.infotableofs = LONG(header.infotableofs);
// let seek to the lumpinfo list
if (fseek(fp, header.infotableofs, SEEK_SET) == -1)
return true;
for (i = 0; i < header.numlumps; i++)
{
// fill in lumpinfo for this wad file directory
if (fread(&lumpinfo, sizeof (lumpinfo), 1 , fp) != 1)
return true;
lumpinfo.filepos = LONG(lumpinfo.filepos);
lumpinfo.size = LONG(lumpinfo.size);
if (lumpinfo.size == 0)
continue;
if (! W_VerifyName(lumpinfo.name, checklist, status))
return false;
}
return true;
}
static int
W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
{
zend_t zend;
zentry_t zentry;
UINT16 numlumps;
size_t i;
char pat_central[] = {0x50, 0x4b, 0x01, 0x02, 0x00};
char pat_end[] = {0x50, 0x4b, 0x05, 0x06, 0x00};
char lumpname[9];
// Haha the ResGetLumpsZip function doesn't
// check for file errors, so neither will I.
// Central directory bullshit
fseek(fp, 0, SEEK_END);
if (!ResFindSignature(fp, pat_end, max(0, ftell(fp) - (22 + 65536))))
return true;
fseek(fp, -4, SEEK_CUR);
if (fread(&zend, 1, sizeof zend, fp) < sizeof zend)
return true;
numlumps = zend.entries;
fseek(fp, zend.cdiroffset, SEEK_SET);
for (i = 0; i < numlumps; i++)
{
char* fullname;
char* trimname;
char* dotpos;
if (fread(&zentry, 1, sizeof(zentry_t), fp) < sizeof(zentry_t))
return true;
if (memcmp(zentry.signature, pat_central, 4))
return true;
fullname = malloc(zentry.namelen + 1);
if (fgets(fullname, zentry.namelen + 1, fp) != fullname)
return true;
// Strip away file address and extension for the 8char name.
if ((trimname = strrchr(fullname, '/')) != 0)
trimname++;
else
trimname = fullname; // Care taken for root files.
if (*trimname) // Ignore directories
{
if ((dotpos = strrchr(trimname, '.')) == 0)
dotpos = fullname + strlen(fullname); // Watch for files without extension.
memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
strncpy(lumpname, trimname, min(8, dotpos - trimname));
if (! W_VerifyName(lumpname, checklist, status))
return false;
}
free(fullname);
}
return true;
}
// Note: This never opens lumps themselves and therefore doesn't have to
// deal with compressed lumps.
static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist,
boolean status)
{
FILE *handle;
size_t i, j;
int goodfile = false;
if (!checklist)
@ -1636,66 +1833,18 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist,
if ((handle = W_OpenWadFile(&filename, false)) == NULL)
return -1;
if (stricmp(&filename[strlen(filename) - 4], ".pk3") == 0)
goodfile = W_VerifyPK3(handle, checklist, status);
else
{
// detect wad file by the absence of the other supported extensions
if (stricmp(&filename[strlen(filename) - 4], ".soc")
#ifdef HAVE_BLUA
&& stricmp(&filename[strlen(filename) - 4], ".lua")
#endif
&& stricmp(&filename[strlen(filename) - 4], ".pk3"))
)
{
// assume wad file
wadinfo_t header;
filelump_t lumpinfo;
// read the header
if (fread(&header, 1, sizeof header, handle) == sizeof header
&& header.numlumps < INT16_MAX
&& strncmp(header.identification, "ZWAD", 4)
&& strncmp(header.identification, "IWAD", 4)
&& strncmp(header.identification, "PWAD", 4)
&& strncmp(header.identification, "SDLL", 4))
{
fclose(handle);
return true;
}
header.numlumps = LONG(header.numlumps);
header.infotableofs = LONG(header.infotableofs);
// let seek to the lumpinfo list
if (fseek(handle, header.infotableofs, SEEK_SET) == -1)
{
fclose(handle);
return false;
}
goodfile = true;
for (i = 0; i < header.numlumps; i++)
{
// fill in lumpinfo for this wad file directory
if (fread(&lumpinfo, sizeof (lumpinfo), 1 , handle) != 1)
{
fclose(handle);
return -1;
}
lumpinfo.filepos = LONG(lumpinfo.filepos);
lumpinfo.size = LONG(lumpinfo.size);
if (lumpinfo.size == 0)
continue;
for (j = 0; j < NUMSPRITES; j++)
if (sprnames[j] && !strncmp(lumpinfo.name, sprnames[j], 4)) // Sprites
continue;
goodfile = false;
for (j = 0; checklist[j].len && checklist[j].name && !goodfile; j++)
if ((strncmp(lumpinfo.name, checklist[j].name, checklist[j].len) != false) == status)
goodfile = true;
if (!goodfile)
break;
goodfile = W_VerifyWAD(handle, checklist, status);
}
}
fclose(handle);

View file

@ -102,6 +102,7 @@ typedef struct wadfile_s
restype_t type;
lumpinfo_t *lumpinfo;
lumpcache_t *lumpcache;
lumpcache_t *patchcache;
#ifdef HWRENDER
aatree_t *hwrcache; // patches are cached in renderer's native format
#endif
@ -167,17 +168,13 @@ void *W_CacheLumpNum(lumpnum_t lump, INT32 tag);
void *W_CacheLumpNumForce(lumpnum_t lumpnum, INT32 tag);
boolean W_IsLumpCached(lumpnum_t lump, void *ptr);
boolean W_IsPatchCached(lumpnum_t lump, void *ptr);
void *W_CacheLumpName(const char *name, INT32 tag);
void *W_CachePatchName(const char *name, INT32 tag);
#ifdef HWRENDER
//void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); // return a patch_t
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); // return a patch_t
void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); // return a patch_t
#else
//#define W_CachePatchNumPwad(wad, lump, tag) W_CacheLumpNumPwad(wad, lump, tag)
#define W_CachePatchNum(lumpnum, tag) W_CacheLumpNum(lumpnum, tag)
#endif
void W_UnlockCachedPatch(void *patch);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View file

@ -1,6 +1,7 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#include "winver.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
@ -62,9 +63,11 @@ END
// Version
//
#include "../doomdef.h" // Needed for version string
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,9,0
PRODUCTVERSION 1,0,9,0
FILEVERSION 2,2,0,0
PRODUCTVERSION 2,2,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -82,14 +85,14 @@ BEGIN
VALUE "Comments", "Visit our web site at www.srb2.org for news and updates!\0"
VALUE "CompanyName", "Sonic Team Junior\0"
VALUE "FileDescription", "Sonic Robo Blast 2\0"
VALUE "FileVersion", "1, 09\0"
VALUE "FileVersion", VERSIONSTRING
VALUE "InternalName", "srb2\0"
VALUE "LegalCopyright", "Copyright <EFBFBD> 1998-2018 by Sonic Team Junior\0"
VALUE "LegalCopyright", "Copyright 1998-2019 by Sonic Team Junior\0"
VALUE "LegalTrademarks", "Sonic the Hedgehog and related characters are trademarks of Sega.\0"
VALUE "OriginalFilename", "srb2win.exe\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Sonic Robo Blast 2\0"
VALUE "ProductVersion", "1, 09\0"
VALUE "ProductVersion", VERSIONSTRING
VALUE "SpecialBuild", "\0"
END
END

View file

@ -327,7 +327,7 @@ static inline VOID I_GetConsoleEvents(VOID)
break;
case VK_RETURN:
entering_con_command = false;
// Fall through.
/* FALLTHRU */
default:
ev.data1 = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char
}

View file

@ -322,9 +322,9 @@ static inline boolean I_SkipFrame(void)
case GS_LEVEL:
if (!paused)
return false;
/* FALLTHRU */
//case GS_TIMEATTACK: -- sorry optimisation but now we have a cool level platter and that being laggardly looks terrible
#ifndef CLIENT_LOADINGSCREEN
/* FALLTHRU */
case GS_WAITINGPLAYERS:
#endif
return skip; // Skip odd frames

View file

@ -261,7 +261,7 @@ void Y_IntermissionDrawer(void)
// draw time
ST_DrawPatchFromHud(HUD_TIME, sbotime);
if (cv_timetic.value == 1)
if (cv_timetic.value == 3)
ST_DrawNumFromHud(HUD_SECONDS, data.coop.tics);
else
{
@ -275,8 +275,7 @@ void Y_IntermissionDrawer(void)
ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon); // Colon
ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2); // Seconds
// we should show centiseconds on the intermission screen too, if the conditions are right.
if (modeattacking || cv_timetic.value == 2)
if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying!
{
ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period
ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics
@ -429,7 +428,7 @@ void Y_IntermissionDrawer(void)
{
if ((data.spec.continues & 0x80) && i == continues-1 && (endtic < 0 || intertic%20 < 10))
break;
V_DrawContinueIcon(246 + xoffset5 - (i*12), 162+yoffset, 0, *data.spec.playerchar, *data.spec.playercolor);
V_DrawContinueIcon(246 + xoffset5 - (i*20), 162+yoffset, 0, *data.spec.playerchar, *data.spec.playercolor);
}
}
}