Merge branch 'master' into newmenus

This commit is contained in:
Steel Titanium 2019-10-01 16:52:31 -04:00
commit 6b10ffb88f
No known key found for this signature in database
GPG Key ID: 924BA411F18DFDBE
70 changed files with 4167 additions and 1833 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

@ -62,7 +62,7 @@ static const UINT8 NOCLIMBYELLOWS = (11*16);
#define NOCLIMBCDWALLCOLORS NOCLIMBYELLOWS
#define THINGCOLORS GREENS
#define GRIDCOLORS (GRAYS + GRAYSRANGE/2)
#define XHAIRCOLORS GRAYS
#define XHAIRCOLORS DWHITE
// controls
#define AM_PANUPKEY KEY_UPARROW
@ -111,11 +111,6 @@ typedef struct
mpoint_t a, b;
} mline_t;
typedef struct
{
fixed_t slp, islp;
} islope_t;
//
// The vector graphics for the automap.
// A line drawing of the player pointing right,
@ -137,16 +132,14 @@ static const mline_t player_arrow[] = {
#undef R
#define NUMPLYRLINES (sizeof (player_arrow)/sizeof (mline_t))
#if 0
#define R (FRACUNIT)
static mline_t triangle_guy[] = {
{ { (fixed_t)-.867f*R, (fixed_t)-.5f*R }, { (fixed_t) .867f*R, (fixed_t)-.5f*R } },
{ { (fixed_t) .867f*R, (fixed_t)-.5f*R }, { (fixed_t) 0, (fixed_t) R } },
{ { (fixed_t) 0, (fixed_t) R }, { (fixed_t)-.867f*R, (fixed_t)-.5f*R } }
static const mline_t cross_mark[] =
{
{ { -R, 0 }, { R, 0} },
{ { 0, -R }, { 0, R } },
};
#undef R
#define NUMTRIANGLEGUYLINES (sizeof (triangle_guy)/sizeof (mline_t))
#endif
#define NUMCROSSMARKLINES (sizeof(cross_mark)/sizeof(mline_t))
#define R (FRACUNIT)
static const mline_t thintriangle_guy[] = {
@ -206,7 +199,7 @@ static fixed_t scale_ftom;
static player_t *plr; // the player represented by an arrow
static INT32 followplayer = true; // specifies whether to follow the player around
static boolean followplayer = true; // specifies whether to follow the player around
// function for drawing lines, depends on rendermode
typedef void (*AMDRAWFLINEFUNC) (const fline_t *fl, INT32 color);
@ -816,17 +809,18 @@ static void AM_drawGrid(INT32 color)
fixed_t x, y;
fixed_t start, end;
mline_t ml;
fixed_t gridsize = (MAPBLOCKUNITS<<MAPBITS);
// Figure out start of vertical gridlines
start = m_x;
if ((start - bmaporgx) % (MAPBLOCKUNITS<<FRACBITS))
start += (MAPBLOCKUNITS<<FRACBITS) - ((start - bmaporgx) % (MAPBLOCKUNITS<<FRACBITS));
if ((start - (bmaporgx>>FRACTOMAPBITS)) % gridsize)
start += gridsize - ((start - (bmaporgx>>FRACTOMAPBITS)) % gridsize);
end = m_x + m_w;
// draw vertical gridlines
ml.a.y = m_y;
ml.b.y = m_y + m_h;
for (x = start; x < end; x += (MAPBLOCKUNITS<<FRACBITS))
for (x = start; x < end; x += gridsize)
{
ml.a.x = x;
ml.b.x = x;
@ -835,14 +829,14 @@ static void AM_drawGrid(INT32 color)
// Figure out start of horizontal gridlines
start = m_y;
if ((start - bmaporgy) % (MAPBLOCKUNITS<<FRACBITS))
start += (MAPBLOCKUNITS<<FRACBITS) - ((start - bmaporgy) % (MAPBLOCKUNITS<<FRACBITS));
if ((start - (bmaporgy>>FRACTOMAPBITS)) % gridsize)
start += gridsize - ((start - (bmaporgy>>FRACTOMAPBITS)) % gridsize);
end = m_y + m_h;
// draw horizontal gridlines
ml.a.x = m_x;
ml.b.x = m_x + m_w;
for (y = start; y < end; y += (MAPBLOCKUNITS<<FRACBITS))
for (y = start; y < end; y += gridsize)
{
ml.a.y = y;
ml.b.y = y;
@ -1039,7 +1033,7 @@ static inline void AM_drawPlayers(void)
if (!multiplayer)
{
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 0, plr->mo->angle, DWHITE, plr->mo->x, plr->mo->y);
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 16<<FRACBITS, plr->mo->angle, DWHITE, plr->mo->x, plr->mo->y);
return;
}
@ -1053,7 +1047,7 @@ static inline void AM_drawPlayers(void)
if (p->skincolor > 0)
color = R_GetTranslationColormap(TC_DEFAULT, p->skincolor, GTC_CACHE)[GREENS + 8];
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 0, p->mo->angle, color, p->mo->x, p->mo->y);
AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 16<<FRACBITS, p->mo->angle, color, p->mo->x, p->mo->y);
}
}
@ -1073,13 +1067,30 @@ static inline void AM_drawThings(UINT8 colors)
}
}
/** Draws the crosshair, actually just a dot in software mode.
/** Draws the crosshair.
*
* \param color Color for the crosshair.
*/
static inline void AM_drawCrosshair(UINT8 color)
{
V_DrawFill(f_w/2 + f_x, f_h/2 + f_y, 1, 1, color|V_NOSCALESTART);
const fixed_t scale = 4<<FRACBITS;
size_t i;
fline_t fl;
for (i = 0; i < NUMCROSSMARKLINES; i++)
{
fl.a.x = FixedMul(cross_mark[i].a.x, scale) >> FRACBITS;
fl.a.y = FixedMul(cross_mark[i].a.y, scale) >> FRACBITS;
fl.b.x = FixedMul(cross_mark[i].b.x, scale) >> FRACBITS;
fl.b.y = FixedMul(cross_mark[i].b.y, scale) >> FRACBITS;
fl.a.x += f_x + (f_w / 2);
fl.a.y += f_y + (f_h / 2);
fl.b.x += f_x + (f_w / 2);
fl.b.y += f_y + (f_h / 2);
AM_drawFline(&fl, color);
}
}
/** Draws the automap.
@ -1095,5 +1106,5 @@ void AM_Drawer(void)
AM_drawPlayers();
AM_drawThings(THINGCOLORS);
AM_drawCrosshair(XHAIRCOLORS);
if (!followplayer) AM_drawCrosshair(XHAIRCOLORS);
}

View File

@ -26,11 +26,6 @@ typedef struct
fpoint_t a, b;
} fline_t;
// Used by ST StatusBar stuff.
#define AM_MSGHEADER (('a'<<24)+('m'<<16))
#define AM_MSGENTERED (AM_MSGHEADER | ('e'<<8))
#define AM_MSGEXITED (AM_MSGHEADER | ('x'<<8))
extern boolean am_recalc; // true if screen size changes
extern boolean automapactive; // In AutoMap mode?

View File

@ -2417,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++)
{
@ -2427,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;
}
}
}
}

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
@ -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

@ -246,20 +246,20 @@ INT32 cv_debug;
consvar_t cv_usemouse = {"use_mouse", "On", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_usemouse2 = {"use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse2, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t,
consvar_t cv_usejoystick = {"use_gamepad", "1", CV_SAVE|CV_CALL, usejoystick_cons_t,
I_InitJoystick, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_usejoystick2 = {"use_joystick2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t,
consvar_t cv_usejoystick2 = {"use_gamepad2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t,
I_InitJoystick2, 0, NULL, NULL, 0, 0, NULL};
#if (defined (LJOYSTICK) || defined (HAVE_SDL))
#ifdef LJOYSTICK
consvar_t cv_joyport = {"joyport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_joyport2 = {"joyport2", "/dev/js0", CV_SAVE, joyport_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: for later
consvar_t cv_joyport = {"padport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_joyport2 = {"padport2", "/dev/js0", CV_SAVE, joyport_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: for later
#endif
consvar_t cv_joyscale = {"joyscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_joyscale2 = {"joyscale2", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale2, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_joyscale = {"padscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_joyscale2 = {"padscale2", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale2, 0, NULL, NULL, 0, 0, NULL};
#else
consvar_t cv_joyscale = {"joyscale", "1", CV_SAVE|CV_HIDEN, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: Dummy for save
consvar_t cv_joyscale2 = {"joyscale2", "1", CV_SAVE|CV_HIDEN, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: Dummy for save
consvar_t cv_joyscale = {"padscale", "1", CV_SAVE|CV_HIDEN, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: Dummy for save
consvar_t cv_joyscale2 = {"padscale2", "1", CV_SAVE|CV_HIDEN, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; //Alam: Dummy for save
#endif
#if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)
consvar_t cv_mouse2port = {"mouse2port", "/dev/gpmdata", CV_SAVE, mouse2port_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -637,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);
@ -1916,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)
{
@ -2714,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();
@ -3608,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;
@ -4111,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

@ -2334,6 +2334,7 @@ static actionpointer_t actionpointers[] =
{{A_Boss1Spikeballs}, "A_BOSS1SPIKEBALLS"},
{{A_Boss3TakeDamage}, "A_BOSS3TAKEDAMAGE"},
{{A_Boss3Path}, "A_BOSS3PATH"},
{{A_Boss3ShockThink}, "A_BOSS3SHOCKTHINK"},
{{A_LinedefExecute}, "A_LINEDEFEXECUTE"},
{{A_PlaySeeSound}, "A_PLAYSEESOUND"},
{{A_PlayAttackSound}, "A_PLAYATTACKSOUND"},
@ -2440,6 +2441,7 @@ static actionpointer_t actionpointers[] =
{{A_Boss5CheckFalling}, "A_BOSS5CHECKFALLING"},
{{A_Boss5PinchShot}, "A_BOSS5PINCHSHOT"},
{{A_Boss5MakeItRain}, "A_BOSS5MAKEITRAIN"},
{{A_Boss5MakeJunk}, "A_BOSS5MAKEJUNK"},
{{A_LookForBetter}, "A_LOOKFORBETTER"},
{{A_Boss5BombExplode}, "A_BOSS5BOMBEXPLODE"},
{{A_DustDevilThink}, "A_DUSTDEVILTHINK"},
@ -4751,6 +4753,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_BOSSSEBH1",
"S_BOSSSEBH2",
// Boss 3 Shockwave
"S_SHOCKWAVE1",
"S_SHOCKWAVE2",
// Boss 4
"S_EGGMOBILE4_STND",
"S_EGGMOBILE4_LATK1",
@ -4793,6 +4800,25 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_EGGROBOJET",
// Boss 5
"S_FANG_SETUP",
"S_FANG_INTRO0",
"S_FANG_INTRO1",
"S_FANG_INTRO2",
"S_FANG_INTRO3",
"S_FANG_INTRO4",
"S_FANG_INTRO5",
"S_FANG_INTRO6",
"S_FANG_INTRO7",
"S_FANG_INTRO8",
"S_FANG_INTRO9",
"S_FANG_INTRO10",
"S_FANG_INTRO11",
"S_FANG_INTRO12",
"S_FANG_CLONE1",
"S_FANG_CLONE2",
"S_FANG_CLONE3",
"S_FANG_CLONE4",
"S_FANG_IDLE0",
"S_FANG_IDLE1",
"S_FANG_IDLE2",
"S_FANG_IDLE3",
@ -4864,6 +4890,26 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FANG_FLEEBOUNCE2",
"S_FANG_KO",
"S_BROKENROBOTRANDOM",
"S_BROKENROBOTA",
"S_BROKENROBOTB",
"S_BROKENROBOTC",
"S_BROKENROBOTD",
"S_BROKENROBOTE",
"S_BROKENROBOTF",
"S_ALART1",
"S_ALART2",
"S_VWREF",
"S_VWREB",
"S_PROJECTORLIGHT1",
"S_PROJECTORLIGHT2",
"S_PROJECTORLIGHT3",
"S_PROJECTORLIGHT4",
"S_PROJECTORLIGHT5",
"S_FBOMB1",
"S_FBOMB2",
"S_FBOMB_EXPL1",
@ -5587,14 +5633,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",
@ -5602,6 +5646,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",
@ -5746,6 +5795,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",
@ -7255,7 +7308,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
// Boss 3
"MT_EGGMOBILE3",
"MT_FAKEMOBILE",
"MT_SHOCK",
"MT_SHOCKWAVE",
// Boss 4
"MT_EGGMOBILE4",
@ -7266,6 +7319,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
// Boss 5
"MT_FANG",
"MT_BROKENROBOT",
"MT_VWREF",
"MT_VWREB",
"MT_PROJECTORLIGHT",
"MT_FBOMB",
"MT_TNTDUST", // also used by barrel
"MT_FSGNA",
@ -7464,11 +7521,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
@ -7528,6 +7589,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",

View File

@ -506,6 +506,9 @@ INT32 I_GetKey(void);
#define max(x, y) (((x) > (y)) ? (x) : (y))
#endif
// Max gamepad/joysticks that can be detected/used.
#define MAX_JOYSTICKS 4
// Floating point comparison epsilons from float.h
#ifndef FLT_EPSILON
#define FLT_EPSILON 1.1920928955078125e-7f

View File

@ -420,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

@ -2466,6 +2466,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);
@ -2489,7 +2494,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;
}
//
@ -2498,47 +2540,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;
for (i = 0; i < ncontinues; ++i)
V_DrawContinueIcon(x + (i*12), 140, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
V_DrawLevelTitle(x - (V_LevelNameWidth("CONTINUE")>>1), 16, 0, "CONTINUE");
V_DrawCenteredString(BASEVIDWIDTH/2, 168, 0, va("\x82*\x80" " %02d " "\x82*\x80", timetonext/TICRATE));
// 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)
{
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;
}
// 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)
Command_ExitGame_f();
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;
}
}
@ -2569,8 +2762,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;
@ -885,6 +886,7 @@ static fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
{
boolean forcestrafe = false;
boolean forcefullinput = false;
INT32 tspeed, forward, side, axis, altaxis, i;
const INT32 speed = 1;
// these ones used for multiple conditions
@ -958,6 +960,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
if (turnleft)
cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]);
}
if (twodlevel
|| (player->mo && (player->mo->flags2 & MF2_TWOD))
|| (!demoplayback && (player->pflags & PF_SLIDING)))
forcefullinput = true;
if (twodlevel
|| (player->mo && (player->mo->flags2 & MF2_TWOD))
|| (!demoplayback && (player->climbing
@ -1171,11 +1177,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
// No additional acceleration when moving forward/backward and strafing simultaneously.
// do this AFTER we cap to MAXPLMOVE so people can't find ways to cheese around this.
// 9-18-2017: ALSO, only do this when using keys to move. Gamepad analog sticks get severely gimped by this
if (!forcestrafe && (((movefkey || movebkey) && side) || ((strafelkey || straferkey) && forward)))
if (!forcefullinput && forward && side)
{
forward = FixedMul(forward, 3*FRACUNIT/4);
side = FixedMul(side, 3*FRACUNIT/4);
angle_t angle = R_PointToAngle2(0, 0, side << FRACBITS, forward << FRACBITS);
INT32 maxforward = abs(P_ReturnThrustY(NULL, angle, MAXPLMOVE));
INT32 maxside = abs(P_ReturnThrustX(NULL, angle, MAXPLMOVE));
forward = max(min(forward, maxforward), -maxforward);
side = max(min(side, maxside), -maxside);
}
//Silly hack to make 2d mode *somewhat* playable with no chasecam.
@ -1211,6 +1219,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
{
boolean forcestrafe = false;
boolean forcefullinput = false;
INT32 tspeed, forward, side, axis, altaxis, i;
const INT32 speed = 1;
// these ones used for multiple conditions
@ -1282,6 +1291,10 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
if (turnleft)
cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]);
}
if (twodlevel
|| (player->mo && (player->mo->flags2 & MF2_TWOD))
|| (!demoplayback && (player->pflags & PF_SLIDING)))
forcefullinput = true;
if (twodlevel
|| (player->mo && (player->mo->flags2 & MF2_TWOD))
|| player->climbing
@ -1492,11 +1505,13 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
// No additional acceleration when moving forward/backward and strafing simultaneously.
// do this AFTER we cap to MAXPLMOVE so people can't find ways to cheese around this.
// 9-18-2017: ALSO, only do this when using keys to move. Gamepad analog sticks get severely gimped by this
if (!forcestrafe && (((movefkey || movebkey) && side) || ((strafelkey || straferkey) && forward)))
if (!forcefullinput && forward && side)
{
forward = FixedMul(forward, 3*FRACUNIT/4);
side = FixedMul(side, 3*FRACUNIT/4);
angle_t angle = R_PointToAngle2(0, 0, side << FRACBITS, forward << FRACBITS);
INT32 maxforward = abs(P_ReturnThrustY(NULL, angle, MAXPLMOVE));
INT32 maxside = abs(P_ReturnThrustX(NULL, angle, MAXPLMOVE));
forward = max(min(forward, maxforward), -maxforward);
side = max(min(side, maxside), -maxside);
}
//Silly hack to make 2d mode *somewhat* playable with no chasecam.
@ -2099,7 +2114,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;
@ -2147,6 +2162,8 @@ void G_PlayerReborn(INT32 player)
boolean outofcoop;
INT16 bot;
SINT8 pity;
INT16 rings;
INT16 spheres;
score = players[player].score;
lives = players[player].lives;
@ -2202,6 +2219,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));
@ -2256,6 +2284,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;
@ -2263,12 +2293,33 @@ 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
// Check to make sure their color didn't change somehow...
if (G_GametypeHasTeams())
{
if (p->ctfteam == 1 && p->skincolor != skincolor_redteam)
{
if (p == &players[consoleplayer])
CV_SetValue(&cv_playercolor, skincolor_redteam);
else if (p == &players[secondarydisplayplayer])
CV_SetValue(&cv_playercolor2, skincolor_redteam);
}
else if (p->ctfteam == 2 && p->skincolor != skincolor_blueteam)
{
if (p == &players[consoleplayer])
CV_SetValue(&cv_playercolor, skincolor_blueteam);
else if (p == &players[secondarydisplayplayer])
CV_SetValue(&cv_playercolor2, skincolor_blueteam);
}
}
if (betweenmaps)
return;
if (p-players == consoleplayer)
{
if (mapmusflags & MUSIC_RELOADRESET)
@ -2288,9 +2339,6 @@ void G_PlayerReborn(INT32 player)
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();
@ -2298,27 +2346,6 @@ void G_PlayerReborn(INT32 player)
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())
{
if (p->ctfteam == 1 && p->skincolor != skincolor_redteam)
{
if (p == &players[consoleplayer])
CV_SetValue(&cv_playercolor, skincolor_redteam);
else if (p == &players[secondarydisplayplayer])
CV_SetValue(&cv_playercolor2, skincolor_redteam);
}
else if (p->ctfteam == 2 && p->skincolor != skincolor_blueteam)
{
if (p == &players[consoleplayer])
CV_SetValue(&cv_playercolor, skincolor_blueteam);
else if (p == &players[secondarydisplayplayer])
CV_SetValue(&cv_playercolor2, skincolor_blueteam);
}
}
}
//
@ -2374,8 +2401,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);
@ -2598,7 +2623,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;
@ -3788,7 +3813,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);

View File

@ -103,7 +103,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

@ -149,7 +149,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
@ -159,7 +159,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
@ -263,7 +263,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
@ -273,7 +273,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
colortemp.rgba = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
@ -694,7 +694,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
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);
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false);
#endif
HWR_DrawTexturePatchInCache(&grtex->mipmap,
blockwidth, blockheight,
@ -724,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)
{
@ -926,7 +933,7 @@ static void HWR_LoadPatchFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
#ifndef NO_PNG_LUMPS
if (R_IsLumpPNG((UINT8 *)patch, lumplength))
patch = R_PNGToPatch((UINT8 *)patch, lumplength);
patch = R_PNGToPatch((UINT8 *)patch, lumplength, NULL, false);
#endif
grMipmap->width = (UINT16)SHORT(patch->width);

View File

@ -47,7 +47,6 @@ EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal, RGBA_t *pgamma);
EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl);
EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);
EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform);
EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags);
EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor);
EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo);
@ -90,7 +89,6 @@ struct hwdriver_s
FinishUpdate pfnFinishUpdate;
Draw2DLine pfnDraw2DLine;
DrawPolygon pfnDrawPolygon;
RenderSkyDome pfnRenderSkyDome;
SetBlend pfnSetBlend;
ClearBuffer pfnClearBuffer;
SetTexture pfnSetTexture;

View File

@ -197,6 +197,7 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_EGGO
&lspr[NOLIGHT], // SPR_SEBH
&lspr[NOLIGHT], // SPR_FAKE
&lspr[NOLIGHT], // SPR_SHCK
// Boss 4 (Castle Eggman)
&lspr[NOLIGHT], // SPR_EGGP
@ -204,11 +205,15 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_EGR1
// Boss 5 (Arid Canyon)
&lspr[NOLIGHT], //SPR_FANG // replaces EGGQ
&lspr[NOLIGHT], //SPR_FBOM
&lspr[NOLIGHT], //SPR_FSGN
&lspr[REDBALL_L], //SPR_BARX // bomb explosion (also used by barrel)
&lspr[NOLIGHT], //SPR_BARD // bomb dust (also used by barrel)
&lspr[NOLIGHT], // SPR_FANG // replaces EGGQ
&lspr[NOLIGHT], // SPR_BRKN
&lspr[NOLIGHT], // SPR_WHAT
&lspr[INVINCIBLE_L], // SPR_VWRE
&lspr[INVINCIBLE_L], // SPR_PROJ
&lspr[NOLIGHT], // SPR_FBOM
&lspr[NOLIGHT], // SPR_FSGN
&lspr[REDBALL_L], // SPR_BARX // bomb explosion (also used by barrel)
&lspr[NOLIGHT], // SPR_BARD // bomb dust (also used by barrel)
// Boss 6 (Red Volcano)
&lspr[NOLIGHT], // SPR_EEGR

View File

@ -5869,122 +5869,86 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
// ==========================================================================
//
// ==========================================================================
static void HWR_DrawSkyBackground(player_t *player)
static void HWR_DrawSkyBackground(void)
{
if (cv_grskydome.value)
FOutVector v[4];
angle_t angle;
float dimensionmultiply;
float aspectratio;
float angleturn;
HWR_GetTexture(texturetranslation[skytexture]);
aspectratio = (float)vid.width/(float)vid.height;
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
// because it's called just after clearing the screen
// and thus, the near clipping plane is set to 3.99
// Sryder: Just use the near clipping plane value then
// 3--2
// | /|
// |/ |
// 0--1
v[0].x = v[3].x = -ZCLIP_PLANE-1;
v[1].x = v[2].x = ZCLIP_PLANE+1;
v[0].y = v[1].y = -ZCLIP_PLANE-1;
v[2].y = v[3].y = ZCLIP_PLANE+1;
v[0].z = v[1].z = v[2].z = v[3].z = ZCLIP_PLANE+1;
// X
// NOTE: This doesn't work right with texture widths greater than 1024
// software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly
// The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture
angle = (dup_viewangle + gr_xtoviewangle[0]);
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f);
v[0].sow = v[3].sow = (-1.0f * angle) / ((ANGLE_90-1)*dimensionmultiply); // left
v[2].sow = v[1].sow = v[0].sow + (1.0f/dimensionmultiply); // right (or left + 1.0f)
// use +angle and -1.0f above instead if you wanted old backwards behavior
// Y
angle = aimingangle;
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio));
if (splitscreen)
{
FTransform transform;
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
postimg_t *type;
dimensionmultiply *= 2;
angle *= 2;
}
if (splitscreen && player == &players[secondarydisplayplayer])
type = &postimgtype2;
else
type = &postimgtype;
memset(&transform, 0x00, sizeof(FTransform));
//04/01/2000: Hurdler: added for T&L
// It should replace all other gr_viewxxx when finished
transform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
transform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
if (*type == postimg_flip)
transform.flip = true;
else
transform.flip = false;
transform.scalex = 1;
transform.scaley = (float)vid.width/vid.height;
transform.scalez = 1;
transform.fovxangle = fpov; // Tails
transform.fovyangle = fpov; // Tails
transform.splitscreen = splitscreen;
HWR_GetTexture(texturetranslation[skytexture]);
HWD.pfnRenderSkyDome(skytexture, textures[skytexture]->width, textures[skytexture]->height, transform);
// Middle of the sky should always be at angle 0
// need to keep correct aspect ratio with X
if (atransform.flip)
{
// During vertical flip the sky should be flipped and it's y movement should also be flipped obviously
v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply)); // top
v[0].tow = v[1].tow = v[3].tow - (1.0f/dimensionmultiply); // bottom (or top - 1.0f)
}
else
{
FOutVector v[4];
angle_t angle;
float dimensionmultiply;
float aspectratio;
float angleturn;
HWR_GetTexture(texturetranslation[skytexture]);
aspectratio = (float)vid.width/(float)vid.height;
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
// because it's called just after clearing the screen
// and thus, the near clipping plane is set to 3.99
// Sryder: Just use the near clipping plane value then
// 3--2
// | /|
// |/ |
// 0--1
v[0].x = v[3].x = -ZCLIP_PLANE-1;
v[1].x = v[2].x = ZCLIP_PLANE+1;
v[0].y = v[1].y = -ZCLIP_PLANE-1;
v[2].y = v[3].y = ZCLIP_PLANE+1;
v[0].z = v[1].z = v[2].z = v[3].z = ZCLIP_PLANE+1;
// X
// NOTE: This doesn't work right with texture widths greater than 1024
// software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly
// The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture
angle = (dup_viewangle + gr_xtoviewangle[0]);
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f);
v[0].sow = v[3].sow = (-1.0f * angle) / ((ANGLE_90-1)*dimensionmultiply); // left
v[2].sow = v[1].sow = v[0].sow + (1.0f/dimensionmultiply); // right (or left + 1.0f)
// use +angle and -1.0f above instead if you wanted old backwards behavior
// Y
angle = aimingangle;
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio));
if (splitscreen)
{
dimensionmultiply *= 2;
angle *= 2;
}
// Middle of the sky should always be at angle 0
// need to keep correct aspect ratio with X
if (atransform.flip)
{
// During vertical flip the sky should be flipped and it's y movement should also be flipped obviously
v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply)); // top
v[0].tow = v[1].tow = v[3].tow - (1.0f/dimensionmultiply); // bottom (or top - 1.0f)
}
else
{
v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply)); // bottom
v[3].tow = v[2].tow = v[0].tow - (1.0f/dimensionmultiply); // top (or bottom - 1.0f)
}
angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply;
if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa
{
angle = InvAngle(angle);
v[3].tow = v[2].tow += ((float) angle / angleturn);
v[0].tow = v[1].tow += ((float) angle / angleturn);
}
else
{
v[3].tow = v[2].tow -= ((float) angle / angleturn);
v[0].tow = v[1].tow -= ((float) angle / angleturn);
}
HWD.pfnDrawPolygon(NULL, v, 4, 0);
v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply)); // bottom
v[3].tow = v[2].tow = v[0].tow - (1.0f/dimensionmultiply); // top (or bottom - 1.0f)
}
angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply;
if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa
{
angle = InvAngle(angle);
v[3].tow = v[2].tow += ((float) angle / angleturn);
v[0].tow = v[1].tow += ((float) angle / angleturn);
}
else
{
v[3].tow = v[2].tow -= ((float) angle / angleturn);
v[0].tow = v[1].tow -= ((float) angle / angleturn);
}
HWD.pfnDrawPolygon(NULL, v, 4, 0);
}
@ -6136,7 +6100,7 @@ if (0)
}
if (drawsky)
HWR_DrawSkyBackground(player);
HWR_DrawSkyBackground();
//Hurdler: it doesn't work in splitscreen mode
drawsky = splitscreen;
@ -6353,7 +6317,7 @@ if (0)
}
if (!skybox && drawsky) // Don't draw the regular sky if there's a skybox
HWR_DrawSkyBackground(player);
HWR_DrawSkyBackground();
//Hurdler: it doesn't work in splitscreen mode
drawsky = splitscreen;

View File

@ -98,7 +98,6 @@ extern consvar_t cv_voodoocompatibility;
extern consvar_t cv_grfovchange;
extern consvar_t cv_grsolvetjoin;
extern consvar_t cv_grspritebillboarding;
extern consvar_t cv_grskydome;
extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowy;

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");
@ -845,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;
}
@ -911,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)
{
@ -956,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)
{
@ -1202,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

@ -1427,232 +1427,6 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf,
Clamp2D(GL_TEXTURE_WRAP_T);
}
// PRBoom sky dome
typedef struct vbo_vertex_s
{
float x, y, z;
float u, v;
unsigned char r, g, b, a;
} vbo_vertex_t;
typedef struct
{
int mode;
int vertexcount;
int vertexindex;
int use_texture;
} GLSkyLoopDef;
typedef struct
{
int id;
int rows, columns;
int loopcount;
GLSkyLoopDef *loops;
vbo_vertex_t *data;
} GLSkyVBO;
// The texture offset to be applied to the texture coordinates in SkyVertex().
static int rows, columns;
static boolean yflip;
static int texw, texh;
static float yMult, yAdd;
static boolean foglayer;
static float delta = 0.0f;
static int gl_sky_detail = 16;
static INT32 lasttex = -1;
static RGBA_t SkyColor;
#define MAP_COEFF 128.0f
#define MAP_SCALE (MAP_COEFF*(float)FRACUNIT)
static void SkyVertex(vbo_vertex_t *vbo, int r, int c)
{
static fixed_t scale = 10000 << FRACBITS;
static angle_t maxSideAngle = ANGLE_180 / 3;
angle_t topAngle = (angle_t)(c / (float)columns * ANGLE_MAX);
angle_t sideAngle = maxSideAngle * (rows - r) / rows;
fixed_t height = FINESINE(sideAngle>>ANGLETOFINESHIFT);
fixed_t realRadius = FixedMul(scale, FINECOSINE(sideAngle>>ANGLETOFINESHIFT));
fixed_t x = FixedMul(realRadius, FINECOSINE(topAngle>>ANGLETOFINESHIFT));
fixed_t y = (!yflip) ? FixedMul(scale, height) : FixedMul(scale, height) * -1;
fixed_t z = FixedMul(realRadius, FINESINE(topAngle>>ANGLETOFINESHIFT));
float timesRepeat;
timesRepeat = (short)(4 * (256.0f / texw));
if (timesRepeat == 0.0f)
timesRepeat = 1.0f;
if (!foglayer)
{
boolean flip = yflip;
vbo->r = 255;
vbo->g = 255;
vbo->b = 255;
vbo->a = (r == 0 ? 0 : 255);
// Flip Y coordinate anyway for the top part of the hemisphere
if (r <= 1)
flip = !flip;
// And the texture coordinates.
vbo->u = (-timesRepeat * c / (float)columns);
if (!flip) // Flipped Y is for the lower hemisphere.
vbo->v = (r / (float)rows) * 1.f * yMult + yAdd;
else
vbo->v = ((rows-r)/(float)rows) * 1.f * yMult + yAdd;
}
// And finally the vertex.
vbo->x = (float)x/(float)MAP_SCALE;
vbo->y = (float)y/(float)MAP_SCALE + delta;
vbo->z = (float)z/(float)MAP_SCALE;
}
GLSkyVBO sky_vbo;
static void gld_BuildSky(int row_count, int col_count)
{
int c, r;
vbo_vertex_t *vertex_p;
int vertex_count = 2 * row_count * (col_count * 2 + 2) + col_count * 2;
GLSkyVBO *vbo = &sky_vbo;
if ((vbo->columns != col_count) || (vbo->rows != row_count))
{
free(vbo->loops);
free(vbo->data);
memset(vbo, 0, sizeof(&vbo));
}
if (!vbo->data)
{
memset(vbo, 0, sizeof(&vbo));
vbo->loops = malloc((row_count * 2 + 2) * sizeof(vbo->loops[0]));
// create vertex array
vbo->data = malloc(vertex_count * sizeof(vbo->data[0]));
}
vbo->columns = col_count;
vbo->rows = row_count;
vertex_p = &vbo->data[0];
vbo->loopcount = 0;
memset(&SkyColor, 0xFF, sizeof(SkyColor));
// Why not?
for (yflip = false; yflip <= true; yflip++)
{
vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_FAN;
vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0];
vbo->loops[vbo->loopcount].vertexcount = col_count;
vbo->loops[vbo->loopcount].use_texture = false;
vbo->loopcount++;
yAdd = 0.5f;
yMult = 1.0f;
/*if (yflip == 0)
SkyColor = &sky->CeilingSkyColor[vbo_idx];
else
SkyColor = &sky->FloorSkyColor[vbo_idx];*/
delta = 0.0f;
foglayer = true;
for (c = 0; c < col_count; c++)
{
SkyVertex(vertex_p, 1, c);
vertex_p->r = SkyColor.s.red;
vertex_p->g = SkyColor.s.green;
vertex_p->b = SkyColor.s.blue;
vertex_p->a = 255;
vertex_p++;
}
foglayer = false;
delta = (yflip ? 5.0f : -5.0f) / MAP_COEFF;
for (r = 0; r < row_count; r++)
{
vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_STRIP;
vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0];
vbo->loops[vbo->loopcount].vertexcount = 2 * col_count + 2;
vbo->loops[vbo->loopcount].use_texture = true; //(r > 1) ? true : false;
vbo->loopcount++;
for (c = 0; c <= col_count; c++)
{
SkyVertex(vertex_p++, r + (yflip ? 1 : 0), (c ? c : 0));
SkyVertex(vertex_p++, r + (yflip ? 0 : 1), (c ? c : 0));
}
}
}
}
static void RenderDomeForReal(INT32 skytexture)
{
int i, j;
GLSkyVBO *vbo = &sky_vbo;
pglRotatef(270.f, 0.f, 1.f, 0.f);
rows = 4;
columns = 4 * gl_sky_detail;
if (lasttex != skytexture)
{
lasttex = skytexture;
gld_BuildSky(rows, columns);
}
pglScalef(1.0f, (float)texh / 230.0f, 1.0f);
for (j = 0; j < 2; j++)
{
for (i = 0; i < vbo->loopcount; i++)
{
GLSkyLoopDef *loop = &vbo->loops[i];
if (j == 0 ? loop->use_texture : !loop->use_texture)
continue;
else
{
int k;
pglBegin(loop->mode);
for (k = loop->vertexindex; k < (loop->vertexindex + loop->vertexcount); k++)
{
vbo_vertex_t *v = &vbo->data[k];
if (loop->use_texture)
pglTexCoord2f(v->u, v->v);
pglColor4f(v->r, v->g, v->b, v->a);
pglVertex3f(v->x, v->y, v->z);
}
pglEnd();
}
}
}
pglScalef(1.0f, 1.0f, 1.0f);
// current color is undefined after glDrawArrays
pglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform)
{
SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
SetTransform(&transform);
texw = texture_width;
texh = texture_height;
RenderDomeForReal(tex);
// HWR_DrawSkyBackground left no blend flags after rendering the sky
SetBlend(0);
}
// ==========================================================================
//

View File

@ -85,6 +85,7 @@ char sprnames[NUMSPRITES + 1][5] =
"EGGO", // Boss 3
"SEBH", // Boss 3 Junk
"FAKE", // Boss 3 Fakemobile
"SHCK", // Boss 3 Shockwave
// Boss 4 (Castle Eggman)
"EGGP",
@ -93,6 +94,10 @@ char sprnames[NUMSPRITES + 1][5] =
// Boss 5 (Arid Canyon)
"FANG", // replaces EGGQ
"BRKN", // broken robot chunk
"WHAT", // alart
"VWRE",
"PROJ", // projector light
"FBOM",
"FSGN",
"BARX", // bomb explosion (also used by barrel)
@ -212,11 +217,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
@ -246,7 +251,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
@ -576,8 +581,14 @@ char spr2names[NUMPLAYERSPRITES][5] =
"TALA",
"TALB",
"CNT1",
"CNT2",
"CNT3",
"CNT4",
"SIGN",
"LIFE",
"XTRA",
};
playersprite_t free_spr2 = SPR2_FIRSTFREESLOT;
@ -673,8 +684,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)
};
@ -727,7 +744,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
@ -1294,6 +1311,11 @@ state_t states[NUMSTATES] =
{SPR_SEBH, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSEBH1
{SPR_SEBH, 1, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSEBH2
// Boss 3 Shockwave
{SPR_SHCK, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, 8, {A_Boss3ShockThink}, 4, 2, S_SHOCKWAVE2}, // S_SHOCKWAVE1
{SPR_SHCK, 3|FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, 8, {A_Boss3ShockThink}, 4, 2, S_SHOCKWAVE1}, // S_SHOCKWAVE2
// 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
@ -1336,6 +1358,28 @@ state_t states[NUMSTATES] =
{SPR_EFIR, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_NULL}, // S_EGGROBOJET
// Boss 5
{SPR_NULL, 0, 2, {A_CheckFlags2}, MF2_AMBUSH, S_FANG_IDLE0, S_FANG_INTRO0}, // S_FANG_SETUP
{SPR_NULL, 0, 2, {NULL}, 0, 0, S_FANG_INTRO1}, // S_FANG_INTRO0
{SPR_NULL, 0, 2, {A_Boss5MakeJunk}, -S_FANG_CLONE1, 0, S_FANG_INTRO2}, // S_FANG_INTRO1
{SPR_NULL, 0, 0, {A_Repeat}, 25, S_FANG_INTRO1, S_FANG_INTRO3}, // S_FANG_INTRO2
{SPR_NULL, 0, 0, {A_Boss5MakeJunk}, 0, 1, S_FANG_INTRO4}, // S_FANG_INTRO3
{SPR_FANG, 30, 1, {A_ZThrust}, 9, (1<<16)|1, S_FANG_INTRO5}, // S_FANG_INTRO4
{SPR_FANG, 27, 1, {A_Boss5CheckOnGround}, S_FANG_INTRO9, 0, S_FANG_INTRO6}, // S_FANG_INTRO5
{SPR_FANG, 28, 1, {A_Boss5CheckOnGround}, S_FANG_INTRO9, 0, S_FANG_INTRO7}, // S_FANG_INTRO6
{SPR_FANG, 29, 1, {A_Boss5CheckOnGround}, S_FANG_INTRO9, 0, S_FANG_INTRO8}, // S_FANG_INTRO7
{SPR_FANG, 30, 1, {A_Boss5CheckOnGround}, S_FANG_INTRO9, 0, S_FANG_INTRO5}, // S_FANG_INTRO8
{SPR_FANG, 23|FF_ANIMATE, 50, {NULL}, 1, 4, S_FANG_INTRO10}, // S_FANG_INTRO9
{SPR_FANG, 25, 5, {NULL}, 0, 0, S_FANG_INTRO11}, // S_FANG_INTRO10
{SPR_FANG, 26, 2, {A_Boss5MakeJunk}, S_BROKENROBOTD, 2, S_FANG_INTRO12}, // S_FANG_INTRO11
{SPR_FANG, 31|FF_ANIMATE, 50, {NULL}, 3, 4, S_FANG_IDLE1}, // S_FANG_INTRO12
{SPR_FANG, 11, 2, {A_Boss5MakeJunk}, 0, -1, S_FANG_CLONE2}, // S_FANG_CLONE1
{SPR_FANG, 11, 0, {A_Repeat}, 49, S_FANG_CLONE1, S_FANG_CLONE3}, // S_FANG_INTRO2
{SPR_FANG, 12, 0, {A_SetObjectFlags}, MF_NOGRAVITY, 1, S_FANG_CLONE4}, // S_FANG_CLONE3
{SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_IDLE0, 0, S_FANG_CLONE4}, // S_FANG_CLONE4
{SPR_FANG, 0, 0, {A_SetObjectFlags}, MF_NOCLIPTHING, 1, S_FANG_IDLE1}, // S_FANG_IDLE0
{SPR_FANG, 2, 16, {A_Look}, 1, 0, S_FANG_IDLE2}, // S_FANG_IDLE1
{SPR_FANG, 3, 16, {A_Look}, 1, 0, S_FANG_IDLE3}, // S_FANG_IDLE2
{SPR_FANG, 3, 16, {A_Look}, 1, 0, S_FANG_IDLE4}, // S_FANG_IDLE3
@ -1410,8 +1454,8 @@ state_t states[NUMSTATES] =
{SPR_FANG, 21, 0, {A_DoNPCPain}, 0, 0, S_FANG_DIE2}, // S_FANG_DIE1
{SPR_FANG, 21, 1, {A_Boss5CheckOnGround}, S_FANG_DIE3, 0, S_FANG_DIE2}, // S_FANG_DIE2
{SPR_FANG, 22, 0, {A_Scream}, 0, 0, S_FANG_DIE4}, // S_FANG_DIE3
{SPR_FANG, 22, 104, {NULL}, 0, 0, S_FANG_DIE5}, // S_FANG_DIE4
{SPR_FANG, 22, 0, {A_Scream}, 0, 0, S_FANG_DIE4}, // S_FANG_DIE3
{SPR_FANG, 22, -1, {A_SetFuse}, 70, 0, S_FANG_DIE5}, // S_FANG_DIE4
{SPR_FANG, 11, 0, {A_PlaySound}, sfx_jump, 0, S_FANG_DIE6}, // S_FANG_DIE5
{SPR_FANG, 11, 1, {A_ZThrust}, 6, (1<<16)|1, S_FANG_DIE7}, // S_FANG_DIE6
@ -1425,6 +1469,26 @@ state_t states[NUMSTATES] =
{SPR_FANG, 17, 7*TICRATE, {NULL}, 0, 0, S_NULL}, // S_FANG_KO
{SPR_NULL, 0, -1, {A_RandomStateRange}, S_BROKENROBOTA, S_BROKENROBOTF, S_NULL}, // S_BROKENROBOTRANDOM
{SPR_BRKN, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 3, 4, S_NULL}, // S_BROKENROBOTA
{SPR_BRKN, 4|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 3, 4, S_NULL}, // S_BROKENROBOTB
{SPR_BRKN, 8|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 3, 4, S_NULL}, // S_BROKENROBOTC
{SPR_BRKN, 12|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 3, 4, S_NULL}, // S_BROKENROBOTD
{SPR_BRKN, 16|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 3, 4, S_NULL}, // S_BROKENROBOTE
{SPR_BRKN, 20|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 3, 4, S_NULL}, // S_BROKENROBOTF
{SPR_WHAT, FF_ANIMATE|FF_FULLBRIGHT, 4, {NULL}, 1, 2, S_ALART2}, // S_ALART1
{SPR_WHAT, 2|FF_ANIMATE|FF_FULLBRIGHT, -1, {NULL}, 1, 2, S_NULL}, // S_ALART2
{SPR_VWRE, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_VWREF
{SPR_VWRE, 1|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_VWREB
{SPR_PROJ, FF_TRANS20|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PROJECTORLIGHT2}, // S_PROJECTORLIGHT1
{SPR_PROJ, 1|FF_TRANS40|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_PROJECTORLIGHT3}, // S_PROJECTORLIGHT2
{SPR_PROJ, 2|FF_TRANS20|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_PROJECTORLIGHT4}, // S_PROJECTORLIGHT3
{SPR_PROJ, 3|FF_TRANS40|FF_FULLBRIGHT, 2, {A_Repeat}, 39, S_PROJECTORLIGHT2, S_PROJECTORLIGHT5}, // S_PROJECTORLIGHT4
{SPR_PROJ, 4|FF_TRANS60|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_PROJECTORLIGHT5
{SPR_FBOM, 0, 1, {A_GhostMe}, 0, 0, S_FBOMB2}, // S_FBOMB1
{SPR_FBOM, 1, 1, {A_GhostMe}, 0, 0, S_FBOMB1}, // S_FBOMB2
{SPR_BARX, 0|FF_FULLBRIGHT, 3, {A_SetObjectFlags}, MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP, 0, S_FBOMB_EXPL2}, // S_FBOMB_EXPL1
@ -1584,7 +1648,7 @@ state_t states[NUMSTATES] =
{SPR_FLME, FF_FULLBRIGHT|2, -1, {NULL}, 0, 0, S_CYBRAKDEMONFLAMESHOT_FLY3}, // S_CYBRAKDEMONFLAMESHOT_FLY3
{SPR_FLME, FF_FULLBRIGHT|2, 0, {A_SpawnObjectRelative}, 0, MT_CYBRAKDEMON_FLAMEREST, S_NULL}, // S_CYBRAKDEMONFLAMESHOT_DIE
{SPR_FLAM, FF_FULLBRIGHT, 0, {A_SetFuse}, 10*TICRATE, 0, S_FLAMEREST}, // S_CYBRAKDEMONFLAMEREST
{SPR_FLAM, FF_FULLBRIGHT, 1, {A_SetFuse}, 10*TICRATE, 0, S_FLAMEREST}, // S_CYBRAKDEMONFLAMEREST
{SPR_ELEC, 0 + FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_CYBRAKDEMONELECTRICBARRIER_INIT2}, // S_CYBRAKDEMONELECTRICBARRIER_INIT1
{SPR_ELEC, 0 + FF_FULLBRIGHT, 0, {A_RemoteAction}, -1, S_CYBRAKDEMON_INVINCIBLERIZE, S_CYBRAKDEMONELECTRICBARRIER_PLAYSOUND}, // S_CYBRAKDEMONELECTRICBARRIER_INIT2
@ -2152,14 +2216,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
@ -2167,6 +2229,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
@ -2311,16 +2378,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
@ -3797,21 +3868,21 @@ state_t states[NUMSTATES] =
{SPR_NULL, 0, 1, {A_RockSpawn}, 0, 0, S_ROCKSPAWN}, // S_ROCKSPAWN
{SPR_ROIA, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEA
{SPR_ROIB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEB
{SPR_ROIC, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEC
{SPR_ROID, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLED
{SPR_ROIE, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEE
{SPR_ROIF, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEF
{SPR_ROIG, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEG
{SPR_ROIH, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEH
{SPR_ROII, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEI
{SPR_ROIJ, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEJ
{SPR_ROIK, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEK
{SPR_ROIL, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEL
{SPR_ROIM, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEM
{SPR_ROIN, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEN
{SPR_ROIO, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEO
{SPR_ROIP, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEP
{SPR_ROIB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEB
{SPR_ROIC, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEC
{SPR_ROID, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLED
{SPR_ROIE, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEE
{SPR_ROIF, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEF
{SPR_ROIG, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEG
{SPR_ROIH, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEH
{SPR_ROII, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEI
{SPR_ROIJ, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEJ
{SPR_ROIK, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEK
{SPR_ROIL, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEL
{SPR_ROIM, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEM
{SPR_ROIN, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEN
{SPR_ROIO, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEO
{SPR_ROIP, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 7, 2, S_NULL}, // S_ROCKCRUMBLEP
{SPR_BRIC, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL}, // S_BRICKDEBRIS
@ -5442,30 +5513,30 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_SHOCK
{ // MT_SHOCKWAVE
-1, // doomednum
S_THUNDERCOIN_SPARK, // spawnstate
S_SHOCKWAVE1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
sfx_s3k5e, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
8*TICRATE, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_SPRK1, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
10*FRACUNIT, // speed
16*FRACUNIT, // radius
35*FRACUNIT, // height
12*FRACUNIT, // speed
48*FRACUNIT, // radius
8*FRACUNIT, // height
0, // display offset
DMG_ELECTRIC|(sfx_buzz2<<8), // mass
20, // damage
3, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags
MF_NOBLOCKMAP|MF_MISSILE|MF_PAIN|MF_NOGRAVITY|MF_PAPERCOLLISION, // flags
S_NULL // raisestate
},
@ -5606,7 +5677,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_FANG
204, // doomednum
S_FANG_IDLE1, // spawnstate
S_FANG_SETUP, // spawnstate
8, // spawnhealth
S_FANG_PATHINGSTART1, // seestate
sfx_None, // seesound
@ -5627,10 +5698,118 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // mass
3, // damage
sfx_boingf, // activesound
MF_SPECIAL|MF_BOSS|MF_SHOOTABLE|MF_GRENADEBOUNCE, // flags
MF_RUNSPAWNFUNC|MF_SPECIAL|MF_BOSS|MF_SHOOTABLE|MF_GRENADEBOUNCE|MF_NOCLIPTHING, // flags -- MF_NOCLIPTHING will be removed after intro event ends
S_NULL // raisestate
},
{ // MT_BROKENROBOT
-1, // doomednum
S_BROKENROBOTRANDOM, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_ambint, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
255, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
1000, // mass
0, // damage
sfx_crumbl, // activesound
MF_RUNSPAWNFUNC|MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
},
{ // MT_VWREF
-1, // doomednum
S_VWREF, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
3, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
42*FRACUNIT, // radius
12*FRACUNIT, // height
1, // display offset
1000, // mass
8, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_VWREB
-1, // doomednum
S_VWREB, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
3, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
42*FRACUNIT, // radius
12*FRACUNIT, // height
-1, // display offset
1000, // mass
8, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_PROJECTORLIGHT
-1, // doomednum
S_PROJECTORLIGHT1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
3, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
42*FRACUNIT, // radius
52*FRACUNIT, // height
-1, // display offset
1000, // mass
8, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_FBOMB
-1, // doomednum
S_FBOMB1, // spawnstate
@ -6485,8 +6664,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
@ -6566,8 +6745,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
@ -10022,7 +10201,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
4, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_SPAWNCEILING|MF_NOGRAVITY, // flags
MF_NOBLOCKMAP|MF_NOCLIP|MF_SPAWNCEILING|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
@ -10049,7 +10228,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
8, // mass
0, // damage
sfx_None, // activesound
MF_SPECIAL|MF_SCENERY, // flags
MF_SPECIAL|MF_SCENERY, // flags
S_NULL // raisestate
},
@ -10070,13 +10249,13 @@ 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
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
S_NULL // raisestate
},
@ -10097,13 +10276,13 @@ 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
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
S_NULL // raisestate
},
@ -10124,13 +10303,67 @@ 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
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
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
S_NULL // raisestate
},
@ -10157,13 +10390,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
4, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_KELP
1007, // doomednum
S_KELP, // spawnstate
S_KELP, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -10178,19 +10411,73 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
292*FRACUNIT, // height
16*FRACUNIT, // radius
292*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOBLOCKMAP, // flags
MF_SCENERY|MF_NOBLOCKMAP, // flags
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
S_DSZSTALAGMITE,// spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -10206,12 +10493,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
116*FRACUNIT, // height
116*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_SOLID, // flags
MF_SCENERY|MF_SOLID, // flags
S_NULL // raisestate
},
@ -10233,18 +10520,18 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
116*FRACUNIT, // height
116*FRACUNIT, // height
0, // display offset
4, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_SOLID, // flags
MF_SCENERY|MF_SOLID, // flags
S_NULL // raisestate
},
{ // MT_LIGHTBEAM
1010, // doomednum
S_LIGHTBEAM1, // spawnstate
S_LIGHTBEAM1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -10259,7 +10546,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
4, // mass
@ -10325,7 +10612,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_FLAMEPARTICLE
-1, // doomednum
S_FLAMEPARTICLE, // spawnstate
S_FLAMEPARTICLE,// spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -11447,13 +11734,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
},
@ -11474,13 +11761,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
},
@ -11501,13 +11788,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
},
@ -11528,13 +11815,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
},
@ -11558,7 +11845,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
@ -11585,7 +11872,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
@ -11610,9 +11897,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // deathsound
0, // speed
24*FRACUNIT, // radius
224*FRACUNIT, // height
224*FRACUNIT, // height
0, // display offset
100, // mass
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SCENERY|MF_PAIN, // flags
@ -11637,9 +11924,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // deathsound
0, // speed
24*FRACUNIT, // radius
256*FRACUNIT, // height
256*FRACUNIT, // height
0, // display offset
100, // mass
DMG_SPIKE, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SCENERY|MF_PAIN, // flags
@ -11666,13 +11953,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

@ -138,6 +138,7 @@ void A_SetReactionTime();
void A_Boss1Spikeballs();
void A_Boss3TakeDamage();
void A_Boss3Path();
void A_Boss3ShockThink();
void A_LinedefExecute();
void A_PlaySeeSound();
void A_PlayAttackSound();
@ -252,6 +253,7 @@ void A_Boss5CheckOnGround();
void A_Boss5CheckFalling();
void A_Boss5PinchShot();
void A_Boss5MakeItRain();
void A_Boss5MakeJunk();
void A_LookForBetter();
void A_Boss5BombExplode();
void A_DustDevilThink();
@ -331,6 +333,7 @@ typedef enum sprite
SPR_EGGO, // Boss 3
SPR_SEBH, // Boss 3 Junk
SPR_FAKE, // Boss 3 Fakemobile
SPR_SHCK, // Boss 3 Shockwave
// Boss 4 (Castle Eggman)
SPR_EGGP,
@ -339,6 +342,10 @@ typedef enum sprite
// Boss 5 (Arid Canyon)
SPR_FANG, // replaces EGGQ
SPR_BRKN,
SPR_WHAT,
SPR_VWRE,
SPR_PROJ, // projector light
SPR_FBOM,
SPR_FSGN,
SPR_BARX, // bomb explosion (also used by barrel)
@ -458,11 +465,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
@ -492,7 +499,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
@ -832,9 +839,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,
@ -1454,6 +1467,10 @@ typedef enum state
S_BOSSSEBH1,
S_BOSSSEBH2,
// Boss 3 Shockwave
S_SHOCKWAVE1,
S_SHOCKWAVE2,
// Boss 4
S_EGGMOBILE4_STND,
S_EGGMOBILE4_LATK1,
@ -1496,6 +1513,25 @@ typedef enum state
S_EGGROBOJET,
// Boss 5
S_FANG_SETUP,
S_FANG_INTRO0,
S_FANG_INTRO1,
S_FANG_INTRO2,
S_FANG_INTRO3,
S_FANG_INTRO4,
S_FANG_INTRO5,
S_FANG_INTRO6,
S_FANG_INTRO7,
S_FANG_INTRO8,
S_FANG_INTRO9,
S_FANG_INTRO10,
S_FANG_INTRO11,
S_FANG_INTRO12,
S_FANG_CLONE1,
S_FANG_CLONE2,
S_FANG_CLONE3,
S_FANG_CLONE4,
S_FANG_IDLE0,
S_FANG_IDLE1,
S_FANG_IDLE2,
S_FANG_IDLE3,
@ -1567,6 +1603,26 @@ typedef enum state
S_FANG_FLEEBOUNCE2,
S_FANG_KO,
S_BROKENROBOTRANDOM,
S_BROKENROBOTA,
S_BROKENROBOTB,
S_BROKENROBOTC,
S_BROKENROBOTD,
S_BROKENROBOTE,
S_BROKENROBOTF,
S_ALART1,
S_ALART2,
S_VWREF,
S_VWREB,
S_PROJECTORLIGHT1,
S_PROJECTORLIGHT2,
S_PROJECTORLIGHT3,
S_PROJECTORLIGHT4,
S_PROJECTORLIGHT5,
S_FBOMB1,
S_FBOMB2,
S_FBOMB_EXPL1,
@ -2290,14 +2346,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,
@ -2305,6 +2359,11 @@ typedef enum state
// Kelp,
S_KELP,
// Animated algae
S_ANIMALGAETOP1,
S_ANIMALGAETOP2,
S_ANIMALGAESEG,
// DSZ Stalagmites
S_DSZSTALAGMITE,
S_DSZ2STALAGMITE,
@ -2439,7 +2498,7 @@ typedef enum state
S_LITTLETUMBLEWEED_ROLL7,
S_LITTLETUMBLEWEED_ROLL8,
// Cacti Sprites
// Cacti
S_CACTI1,
S_CACTI2,
S_CACTI3,
@ -2449,8 +2508,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,
@ -3980,7 +4043,7 @@ typedef enum mobj_type
// Boss 3
MT_EGGMOBILE3,
MT_FAKEMOBILE,
MT_SHOCK,
MT_SHOCKWAVE,
// Boss 4
MT_EGGMOBILE4,
@ -3991,6 +4054,10 @@ typedef enum mobj_type
// Boss 5
MT_FANG,
MT_BROKENROBOT,
MT_VWREF,
MT_VWREB,
MT_PROJECTORLIGHT,
MT_FBOMB,
MT_TNTDUST, // also used by barrel
MT_FSGNA,
@ -4189,11 +4256,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
@ -4244,15 +4315,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

@ -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

@ -66,6 +66,13 @@
// And just some randomness for the exits.
#include "m_random.h"
#if defined(HAVE_SDL)
#include "SDL.h"
#if SDL_VERSION_ATLEAST(2,0,0)
#include "sdl/sdlmain.h" // JOYSTICK_HOTPLUG
#endif
#endif
#ifdef PC_DOS
#include <stdio.h> // for snprintf
int snprintf(char *str, size_t n, const char *fmt, ...);
@ -118,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;
boolean menuactive = false;
@ -135,7 +142,7 @@ typedef enum
levellist_mode_t levellistmode = LLM_CREATESERVER;
UINT8 maplistoption = 0;
static char joystickInfo[8][29];
static char joystickInfo[MAX_JOYSTICKS+1][29];
#ifndef NONET
static UINT32 serverlistpage;
#endif
@ -285,9 +292,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);
@ -317,7 +325,8 @@ static void M_Addons(INT32 choice);
static void M_AddonsOptions(INT32 choice);
static patch_t *addonsp[NUM_EXT+5];
#define numaddonsshown 4
#define addonmenusize 9 // number of items actually displayed in the addons menu view, formerly (2*numaddonsshown + 1)
#define numaddonsshown 4 // number of items to each side of the currently selected item, unless at top/bottom ends of directory
static void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlight, boolean allowlowercase);
@ -1012,13 +1021,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[] =
@ -1027,13 +1034,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[] =
@ -1123,14 +1128,7 @@ static menuitem_t OP_Joystick2Menu[] =
{IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook2, 130},
};
static menuitem_t OP_JoystickSetMenu[] =
{
{IT_CALL | IT_NOTHING, "None", NULL, M_AssignJoystick, '0'},
{IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '1'},
{IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '2'},
{IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '3'},
{IT_CALL | IT_NOTHING, "", NULL, M_AssignJoystick, '4'},
};
static menuitem_t OP_JoystickSetMenu[1+MAX_JOYSTICKS];
static menuitem_t OP_MouseOptionsMenu[] =
{
@ -1162,6 +1160,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},
@ -1372,36 +1398,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[] =
@ -1896,6 +1925,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 =
{
@ -2219,6 +2255,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.
// ==========================================================================
@ -2757,13 +2799,27 @@ 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));
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)
{
char s[20];
sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f));
CV_Set(cv,s);
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);
@ -3503,6 +3559,8 @@ void M_Ticker(void)
//
void M_Init(void)
{
int i;
CV_RegisterVar(&cv_nextmap);
CV_RegisterVar(&cv_newgametype);
CV_RegisterVar(&cv_chooseskin);
@ -3552,6 +3610,17 @@ void M_Init(void)
OP_ScreenshotOptionsMenu[op_screenshot_colorprofile].status = IT_GRAYEDOUT;
#endif
/*
Well the menu sucks for forcing us to have an item set
at all if every item just calls the same function, and
nothing more. Now just automate the definition.
*/
for (i = 0; i <= MAX_JOYSTICKS; ++i)
{
OP_JoystickSetMenu[i].status = ( IT_NOTHING|IT_CALL );
OP_JoystickSetMenu[i].itemaction = M_AssignJoystick;
}
#ifndef NONET
CV_RegisterVar(&cv_serversort);
#endif
@ -3660,7 +3729,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));
@ -4536,6 +4610,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;
@ -5913,7 +5990,8 @@ static boolean M_AddonsRefresh(void)
static void M_DrawAddons(void)
{
INT32 x, y;
ssize_t i, m;
size_t i, m;
size_t t, b; // top and bottom item #s to draw in directory
const UINT8 *flashcol = NULL;
UINT8 hilicol;
@ -5952,52 +6030,63 @@ static void M_DrawAddons(void)
hilicol = 0; // white
#define boxwidth (MAXSTRINGLENGTH*8+6)
// draw the file path and the top white + black lines of the box
V_DrawString(x-21, (y - 16) + (lsheadingheight - 12), highlightflags|V_ALLOWLOWERCASE, M_AddonsHeaderPath());
V_DrawFill(x-21, (y - 16) + (lsheadingheight - 3), MAXSTRINGLENGTH*8+6, 1, hilicol);
V_DrawFill(x-21, (y - 16) + (lsheadingheight - 2), MAXSTRINGLENGTH*8+6, 1, 30);
V_DrawFill(x-21, (y - 16) + (lsheadingheight - 3), boxwidth, 1, hilicol);
V_DrawFill(x-21, (y - 16) + (lsheadingheight - 2), boxwidth, 1, 30);
m = (BASEVIDHEIGHT - currentMenu->y + 2) - (y - 1);
// addons menu back color
V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, m, 159);
V_DrawFill(x-21, y - 1, boxwidth, m, 159);
// scrollbar!
if (sizedirmenu <= (2*numaddonsshown + 1))
i = 0;
// The directory is too small for a scrollbar, so just draw a tall white line
if (sizedirmenu <= addonmenusize)
{
t = 0; // first item
b = sizedirmenu - 1; // last item
i = 0; // "scrollbar" at "top" position
}
else
{
ssize_t q = m;
m = ((2*numaddonsshown + 1) * m)/sizedirmenu;
size_t q = m;
m = (addonmenusize * m)/sizedirmenu; // height of scroll bar
if (dir_on[menudepthleft] <= numaddonsshown) // all the way up
i = 0;
else if (sizedirmenu <= (dir_on[menudepthleft] + numaddonsshown + 1)) // all the way down
i = q-m;
else
i = ((dir_on[menudepthleft] - numaddonsshown) * (q-m))/(sizedirmenu - (2*numaddonsshown + 1));
{
t = 0; // first item
b = addonmenusize - 1; //9th item
i = 0; // scrollbar at top position
}
else if (dir_on[menudepthleft] >= sizedirmenu - (numaddonsshown + 1)) // all the way down
{
t = sizedirmenu - addonmenusize; // # 9th last
b = sizedirmenu - 1; // last item
i = q-m; // scrollbar at bottom position
}
else // somewhere in the middle
{
t = dir_on[menudepthleft] - numaddonsshown; // 4 items above
b = dir_on[menudepthleft] + numaddonsshown; // 4 items below
i = (t * (q-m))/(sizedirmenu - addonmenusize); // calculate position of scrollbar
}
}
V_DrawFill(x + MAXSTRINGLENGTH*8+5 - 21, (y - 1) + i, 1, m, hilicol);
// draw the scrollbar!
V_DrawFill((x-21) + boxwidth-1, (y - 1) + i, 1, m, hilicol);
// get bottom...
m = dir_on[menudepthleft] + numaddonsshown + 1;
if (m > (ssize_t)sizedirmenu)
m = sizedirmenu;
#undef boxwidth
// then compute top and adjust bottom if needed!
if (m < (2*numaddonsshown + 1))
{
m = min(sizedirmenu, 2*numaddonsshown + 1);
i = 0;
}
else
i = m - (2*numaddonsshown + 1);
if (i != 0)
// draw up arrow that bobs up and down
if (t != 0)
V_DrawString(19, y+4 - (skullAnimCounter/5), highlightflags, "\x1A");
// make the selection box flash yellow
if (skullAnimCounter < 4)
flashcol = V_GetStringColormap(highlightflags);
for (; i < m; i++)
// draw icons and item names
for (i = t; i <= b; i++)
{
UINT32 flags = V_ALLOWLOWERCASE;
if (y > BASEVIDHEIGHT) break;
@ -6013,12 +6102,14 @@ static void M_DrawAddons(void)
else
V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[(type & ~EXT_LOADED)]);
// draw selection box for the item currently selected
if ((size_t)i == dir_on[menudepthleft])
{
V_DrawFixedPatch((x-(16+4))<<FRACBITS, (y)<<FRACBITS, FRACUNIT/2, 0, addonsp[NUM_EXT+1], flashcol);
flags = V_ALLOWLOWERCASE|highlightflags;
}
// draw name of the item, use ... if too long
#define charsonside 14
if (dirmenu[i][DIR_LEN] > (charsonside*2 + 3))
V_DrawString(x, y+4, flags, va("%.*s...%s", charsonside, dirmenu[i]+DIR_STRING, dirmenu[i]+DIR_STRING+dirmenu[i][DIR_LEN]-(charsonside+1)));
@ -6030,9 +6121,11 @@ static void M_DrawAddons(void)
y += 16;
}
if (m != (ssize_t)sizedirmenu)
// draw down arrow that bobs down and up
if (b != sizedirmenu)
V_DrawString(19, y-12 + (skullAnimCounter/5), highlightflags, "\x1B");
// draw search box
y = BASEVIDHEIGHT - currentMenu->y + 1;
M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1);
@ -6044,9 +6137,11 @@ static void M_DrawAddons(void)
V_DrawCharacter(x - 18 + V_StringWidth(menusearch+1, 0), y + 8,
'_' | 0x80, false);
// draw search icon
x -= (21 + 5 + 16);
V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+3]);
// draw save icon
x = BASEVIDWIDTH - x - 16;
V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]);
@ -7169,6 +7264,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;
@ -7335,7 +7431,7 @@ static void M_DrawLoadGameData(void)
}
}
y -= 13;
y -= 4;
// character heads, lives, and continues
{
@ -7344,7 +7440,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)
@ -7359,13 +7455,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:
@ -7378,17 +7474,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
@ -7577,7 +7671,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);
@ -8904,6 +9020,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;
@ -8928,6 +9045,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;
@ -10294,18 +10412,33 @@ static void M_ScreenshotOptions(INT32 choice)
static void M_DrawJoystick(void)
{
INT32 i;
INT32 i, compareval2, compareval;
// draw title (or big pic)
M_DrawMenuTitle();
for (i = 0; i <= 4; i++) // See MAX_JOYSTICKS
for (i = 0; i <= MAX_JOYSTICKS; i++) // See MAX_JOYSTICKS
{
M_DrawTextBox(OP_JoystickSetDef.x-8, OP_JoystickSetDef.y+LINEHEIGHT*i-12, 28, 1);
//M_DrawSaveLoadBorder(OP_JoystickSetDef.x+4, OP_JoystickSetDef.y+1+LINEHEIGHT*i);
if ((setupcontrols_secondaryplayer && (i == cv_usejoystick2.value))
|| (!setupcontrols_secondaryplayer && (i == cv_usejoystick.value)))
#ifdef JOYSTICK_HOTPLUG
if (atoi(cv_usejoystick2.string) > I_NumJoys())
compareval2 = atoi(cv_usejoystick2.string);
else
compareval2 = cv_usejoystick2.value;
if (atoi(cv_usejoystick.string) > I_NumJoys())
compareval = atoi(cv_usejoystick.string);
else
compareval = cv_usejoystick.value;
#else
compareval2 = cv_usejoystick2.value;
compareval = cv_usejoystick.value
#endif
if ((setupcontrols_secondaryplayer && (i == compareval2))
|| (!setupcontrols_secondaryplayer && (i == compareval)))
V_DrawString(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i-4,V_GREENMAP,joystickInfo[i]);
else
V_DrawString(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i-4,0,joystickInfo[i]);
@ -10318,7 +10451,7 @@ static void M_DrawJoystick(void)
}
}
static void M_SetupJoystickMenu(INT32 choice)
void M_SetupJoystickMenu(INT32 choice)
{
INT32 i = 0;
const char *joyNA = "Unavailable";
@ -10327,12 +10460,27 @@ static void M_SetupJoystickMenu(INT32 choice)
strcpy(joystickInfo[i], "None");
for (i = 1; i < 8; i++)
for (i = 1; i <= MAX_JOYSTICKS; i++)
{
if (i <= n && (I_GetJoyName(i)) != NULL)
strncpy(joystickInfo[i], I_GetJoyName(i), 28);
else
strcpy(joystickInfo[i], joyNA);
#ifdef JOYSTICK_HOTPLUG
// We use cv_usejoystick.string as the USER-SET var
// and cv_usejoystick.value as the INTERNAL var
//
// In practice, if cv_usejoystick.string == 0, this overrides
// cv_usejoystick.value and always disables
//
// Update cv_usejoystick.string here so that the user can
// properly change this value.
if (i == cv_usejoystick.value)
CV_SetValue(&cv_usejoystick, i);
if (i == cv_usejoystick2.value)
CV_SetValue(&cv_usejoystick2, i);
#endif
}
M_SetupNextMenu(&OP_JoystickSetDef);
@ -10362,10 +10510,76 @@ static void M_Setup2PJoystickMenu(INT32 choice)
static void M_AssignJoystick(INT32 choice)
{
#ifdef JOYSTICK_HOTPLUG
INT32 oldchoice, oldstringchoice;
INT32 numjoys = I_NumJoys();
if (setupcontrols_secondaryplayer)
{
oldchoice = oldstringchoice = atoi(cv_usejoystick2.string) > numjoys ? atoi(cv_usejoystick2.string) : cv_usejoystick2.value;
CV_SetValue(&cv_usejoystick2, choice);
// Just in case last-minute changes were made to cv_usejoystick.value,
// update the string too
// But don't do this if we're intentionally setting higher than numjoys
if (choice <= numjoys)
{
CV_SetValue(&cv_usejoystick2, cv_usejoystick2.value);
// reset this so the comparison is valid
if (oldchoice > numjoys)
oldchoice = cv_usejoystick2.value;
if (oldchoice != choice)
{
if (choice && oldstringchoice > numjoys) // if we did not select "None", we likely selected a used device
CV_SetValue(&cv_usejoystick2, (oldstringchoice > numjoys ? oldstringchoice : oldchoice));
if (oldstringchoice ==
(atoi(cv_usejoystick2.string) > numjoys ? atoi(cv_usejoystick2.string) : cv_usejoystick2.value))
M_StartMessage("This gamepad is used by another\n"
"player. Reset the gamepad\n"
"for that player first.\n\n"
"(Press a key)\n", NULL, MM_NOTHING);
}
}
}
else
{
oldchoice = oldstringchoice = atoi(cv_usejoystick.string) > numjoys ? atoi(cv_usejoystick.string) : cv_usejoystick.value;
CV_SetValue(&cv_usejoystick, choice);
// Just in case last-minute changes were made to cv_usejoystick.value,
// update the string too
// But don't do this if we're intentionally setting higher than numjoys
if (choice <= numjoys)
{
CV_SetValue(&cv_usejoystick, cv_usejoystick.value);
// reset this so the comparison is valid
if (oldchoice > numjoys)
oldchoice = cv_usejoystick.value;
if (oldchoice != choice)
{
if (choice && oldstringchoice > numjoys) // if we did not select "None", we likely selected a used device
CV_SetValue(&cv_usejoystick, (oldstringchoice > numjoys ? oldstringchoice : oldchoice));
if (oldstringchoice ==
(atoi(cv_usejoystick.string) > numjoys ? atoi(cv_usejoystick.string) : cv_usejoystick.value))
M_StartMessage("This gamepad is used by another\n"
"player. Reset the gamepad\n"
"for that player first.\n\n"
"(Press a key)\n", NULL, MM_NOTHING);
}
}
}
#else
if (setupcontrols_secondaryplayer)
CV_SetValue(&cv_usejoystick2, choice);
else
CV_SetValue(&cv_usejoystick, choice);
#endif
}
// =============

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,
@ -206,7 +208,6 @@ void M_QuitResponse(INT32 ch);
// Determines whether to show a level in the list (platter version does not need to be exposed)
boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
// flags for items in the menu
// menu handle (what we do when key is pressed
#define IT_TYPE 14 // (2+4+8)
@ -242,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 ...
@ -309,6 +312,10 @@ extern menu_t *currentMenu;
extern menu_t MainDef;
extern menu_t SP_LoadDef;
// Call upon joystick hotplug
void M_SetupJoystickMenu(INT32 choice);
extern menu_t OP_JoystickSetDef;
// Stuff for customizing the player select screen
typedef struct
{
@ -399,6 +406,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,29 +14,39 @@
#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)(\
(((UINT16)(x) & (UINT16)0x00ffU) << 8) \
| \
(((UINT16)(x) & (UINT16)0xff00U) >> 8))) \
#define SHORT(x) ((INT16)(\
(((UINT16)(x) & (UINT16)0x00ffU) << 8) \
| \
(((UINT16)(x) & (UINT16)0xff00U) >> 8))) \
#define LONG(x) ((INT32)(\
(((UINT32)(x) & (UINT32)0x000000ffUL) << 24) \
| \
(((UINT32)(x) & (UINT32)0x0000ff00UL) << 8) \
| \
(((UINT32)(x) & (UINT32)0x00ff0000UL) >> 8) \
| \
(((UINT32)(x) & (UINT32)0xff000000UL) >> 24)))
#define LONG(x) ((INT32)(\
(((UINT32)(x) & (UINT32)0x000000ffUL) << 24) \
| \
(((UINT32)(x) & (UINT32)0x0000ff00UL) << 8) \
| \
(((UINT32)(x) & (UINT32)0x00ff0000UL) >> 8) \
| \
(((UINT32)(x) & (UINT32)0xff000000UL) >> 24)))
#else
#define SHORT(x) ((INT16)(x))
#define LONG(x) ((INT32)(x))
#define SHORT(x) ((INT16)(x))
#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

@ -170,6 +170,7 @@ void A_SetReactionTime(mobj_t *actor);
void A_Boss1Spikeballs(mobj_t *actor);
void A_Boss3TakeDamage(mobj_t *actor);
void A_Boss3Path(mobj_t *actor);
void A_Boss3ShockThink(mobj_t *actor);
void A_LinedefExecute(mobj_t *actor);
void A_PlaySeeSound(mobj_t *actor);
void A_PlayAttackSound(mobj_t *actor);
@ -282,6 +283,7 @@ void A_Boss5CheckOnGround(mobj_t *actor);
void A_Boss5CheckFalling(mobj_t *actor);
void A_Boss5PinchShot(mobj_t *actor);
void A_Boss5MakeItRain(mobj_t *actor);
void A_Boss5MakeJunk(mobj_t *actor);
void A_LookForBetter(mobj_t *actor);
void A_Boss5BombExplode(mobj_t *actor);
void A_DustDevilThink(mobj_t *actor);
@ -3027,10 +3029,15 @@ void A_Boss1Laser(mobj_t *actor)
if (!actor->target)
return;
if ((upperend & 1) && (actor->extravalue2 > 1))
actor->extravalue2--;
if (actor->state->tics > 1)
dur = actor->tics;
else
{
if ((upperend & 1) && (actor->extravalue2 > 1))
actor->extravalue2--;
dur = actor->extravalue2;
dur = actor->extravalue2;
}
switch (locvar2)
{
@ -3076,23 +3083,15 @@ void A_Boss1Laser(mobj_t *actor)
actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);
if (mobjinfo[locvar1].seesound)
S_StartSound(actor, mobjinfo[locvar1].seesound);
if (!(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH))
{
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 = dur+1;
P_SetTarget(&point->target, actor->target);
P_SetTarget(&actor->target, point);
}
}
/* -- the following was relevant when the MT_EGGMOBILE_TARGET was allowed to move left and right from its path
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(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 + 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 = dur+1;
P_SetTarget(&point->target, actor->target);
P_SetTarget(&actor->target, point);
}
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);
P_SetTarget(&point->target, actor);
@ -4028,13 +4027,17 @@ bossjustdie:
}
case MT_FANG:
{
if (mo->flags2 & MF2_SLIDEPUSH)
{
P_RemoveMobj(mo);
return;
}
if (mo->tracer)
{
var1 = var2 = 0;
A_Boss5Jump(mo);
mo->momx = ((16 - 1)*mo->momx)/16;
mo->momy = ((16 - 1)*mo->momy)/16;
if (!(mo->flags2 & MF2_AMBUSH))
{
const fixed_t time = FixedHypot(mo->tracer->x - mo->x, mo->tracer->y - mo->y)/FixedHypot(mo->momx, mo->momy);
const fixed_t speed = 64*FRACUNIT;
@ -8079,6 +8082,57 @@ void A_Boss3Path(mobj_t *actor)
}
}
// Function: A_Boss3ShockThink
//
// Description: Inserts new interstitial shockwave objects when the space between others spreads too much.
//
// var1 = unused
// var2 = unused
//
void A_Boss3ShockThink(mobj_t *actor)
{
#ifdef HAVE_BLUA
if (LUA_CallAction("A_Boss3ShockThink", actor))
return;
#endif
if (actor->momx || actor->momy)
actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy) + ANGLE_90;
if (actor->hnext && !P_MobjWasRemoved(actor->hnext))
{
mobj_t *snext = actor->hnext;
mobj_t *snew;
fixed_t x0, y0, x1, y1;
// Break the link if movements are too different
if (FixedHypot(snext->momx - actor->momx, snext->momy - actor->momy) > 12*actor->scale)
{
P_SetTarget(&actor->hnext, NULL);
return;
}
// Check distance between shockwave objects to determine whether interstitial ones should be spawned
x0 = actor->x;
y0 = actor->y;
x1 = snext->x;
y1 = snext->y;
if (FixedHypot(x1 - x0, y1 - y0) > 2*actor->radius)
{
snew = P_SpawnMobj((x0 + x1) >> 1, (y0 + y1) >> 1, (actor->z + snext->z) >> 1, actor->type);
snew->momx = (actor->momx + snext->momx) >> 1;
snew->momy = (actor->momy + snext->momy) >> 1;
snew->momz = (actor->momz + snext->momz) >> 1; // is this really needed?
snew->angle = (actor->angle + snext->angle) >> 1;
P_SetTarget(&snew->target, actor->target);
snew->fuse = actor->fuse;
P_SetTarget(&actor->hnext, snew);
P_SetTarget(&snew->hnext, snext);
}
}
}
// Function: A_LinedefExecute
//
// Description: Object's location is used to set the calling sector. The tag used is var1. Optionally, if var2 is set, the actor's angle (multiplied by var2) is added to the tag number as well.
@ -12978,6 +13032,100 @@ void A_Boss5MakeItRain(mobj_t *actor)
actor->extravalue2 = 0;
}
// Function: A_Boss5MakeJunk
//
// Description: Make a mess.
//
// var1 = state # to set on MT_BROKENROBOT (if 0 do nothing, if -1 go to if colorized)
// var2 = mode (-1 = spin, 0 = make 1, & 1 make 8, & 2 alart mode)
//
void A_Boss5MakeJunk(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
mobj_t *broked;
angle_t ang;
INT32 i = ((locvar2 & 1) ? 8 : 1);
#ifdef HAVE_BLUA
if (LUA_CallAction("A_Boss5MakeJunk", actor))
return;
#endif
if (locvar1 < 0 && (actor->flags2 & MF2_SLIDEPUSH)) // this entire action is a hack, don't judge me
{
INT32 curextravalue2 = actor->extravalue2;
P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_PROJECTORLIGHT);
actor->z += P_MobjFlip(actor)*actor->height;
actor->flags |= MF_NOGRAVITY;
S_StartSound(actor, sfx_vwre);
actor->extravalue2 = 49;
P_SetMobjState(actor, -locvar1);
actor->extravalue2 = curextravalue2;
actor->angle -= FixedAngle((49*45)<<FRACBITS);
return;
}
if (locvar2 == -1)
{
INT32 trans = (10*actor->extravalue2)/50;
if (trans > 9)
trans = 9;
if (trans < 0)
trans = 0;
if (!(actor->extravalue2 & 1))
{
if (actor->extravalue2 > 10)
{
mobj_t *front = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_VWREF);
broked = P_SpawnMobjFromMobj(front, 0, 0, 0, MT_VWREB);
front->z = broked->z = front->z - broked->height;
P_SetObjectMomZ(front, (4<<FRACBITS), false);
broked->momz = front->momz;
broked->fuse = front->fuse = (actor->height+(2*front->height))/front->momz;
}
if (!(actor->colorized = !actor->colorized))
actor->frame |= FF_FULLBRIGHT;
}
actor->angle += ANGLE_45;
actor->frame = (actor->frame & ~FF_TRANSMASK)|(trans<<FF_TRANSSHIFT);
return;
}
ang = FixedAngle((P_RandomKey(36)*10)<<FRACBITS);
while (i--)
{
broked = P_SpawnMobjFromMobj(actor, 0, 0, FRACUNIT, MT_BROKENROBOT);
if (locvar2 & 2)
broked->fuse = TICRATE;
else
broked->fuse = (((locvar2 & 1) ? 4 : 2)*TICRATE)/3;
broked->angle = ang;
P_InstaThrust(broked, ang, ((locvar2 & 2) ? 8 : 5)*actor->scale);
P_SetObjectMomZ(broked, (((locvar2) ? 4 : 0) + P_RandomRange(2, 5))<<FRACBITS, false);
if (locvar1 > 0)
P_SetMobjState(broked, locvar1);
if (!P_MobjWasRemoved(broked))
P_TeleportMove(broked, broked->x + broked->momx, broked->y + broked->momy, broked->z);
ang += ANGLE_45;
}
if (locvar2 & 2)
{
broked = P_SpawnMobjFromMobj(actor, 0, 0, 64<<FRACBITS, MT_GHOST);
S_StartSound(broked, sfx_alart);
broked->fuse = states[S_FANG_INTRO12].tics+10;
P_SetMobjState(broked, S_ALART1);
}
else if (locvar2 & 1)
{
broked->z += broked->momz;
S_StartSound(actor, sfx_s3kccs);
actor->flags &= ~MF_NOCLIPTHING;
}
else
S_StartSound(actor, sfx_s3kd3s);
}
// Function: A_LookForBetter
//
// Description: A_Look, except it finds a better target in multiplayer, and doesn't lose the target in singleplayer.
@ -13104,11 +13252,14 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing)
if (dustdevil->height - pos > thresh)
{
fixed_t dist = FixedHypot(thing->x - dustdevil->x, thing->y - dustdevil->y);
fixed_t dragamount = 6 * FRACUNIT;
fixed_t dragamount = player->speed;
fixed_t x, y;
if (player->powers[pw_nocontrol] == 0)
{
P_ResetPlayer(player);
A_PlayActiveSound(dustdevil);
}
player->powers[pw_nocontrol] = 2;
player->drawangle += ANG20;
P_SetPlayerMobjState(thing, S_PLAY_PAIN);

View File

@ -1595,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);
@ -1700,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
|| special->z+special->height > toucher->z + (toucher->height*2/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
@ -2481,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)
{
@ -3404,7 +3408,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false;
// Spectator handling
if (netgame)
if (multiplayer)
{
if (damagetype != DMG_SPECTATOR && target->player && target->player->spectator)
return false;
@ -3436,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;
}
@ -3518,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;
@ -3542,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)
@ -3580,7 +3582,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype))
return true;
#endif
else if (player->powers[pw_shield] || player->bot) //If One-Hit Shield
else if (player->powers[pw_shield] || (player->bot && !ultimatemode)) //If One-Hit Shield
{
P_ShieldDamage(player, inflictor, source, damage, damagetype);
damage = 0;

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;

View File

@ -345,17 +345,14 @@ 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;
object->angle = spring->angle;
if (!demoplayback || P_AnalogMove(object->player))
{
if (object->player == &players[consoleplayer])
localangle = spring->angle;
else if (object->player == &players[secondarydisplayplayer])
localangle2 = spring->angle;
}
if (!demoplayback || P_AnalogMove(object->player))
{
if (object->player == &players[consoleplayer])
localangle = spring->angle;
else if (object->player == &players[secondarydisplayplayer])
localangle2 = spring->angle;
}
}
@ -749,7 +746,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true;
}
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE|MF_SPRING)))
if ((thing->flags & MF_NOCLIPTHING) || !(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE|MF_SPRING)))
return true;
// Don't collide with your buddies while NiGHTS-flying.
@ -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)
P_PlayerHitFloor(thing->player, !onfloor);
}
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,22 +2381,42 @@ 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));
{
fixed_t topheight =
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) :
#endif
*rover->topheight;
// 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;
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)))
// is solid from the sides
if (rover->master->flags & ML_EFFECT3)
return true;
if (mo->eflags & MFE_VERTICALFLIP)
{
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 (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;
}
@ -4570,22 +4605,37 @@ static void P_Boss3Thinker(mobj_t *mobj)
if (!mobj->movefactor) // to firing mode
{
UINT8 i;
angle_t ang = 0;
UINT8 i, numtospawn = 24;
angle_t ang = 0, interval = FixedAngle((360 << FRACBITS) / numtospawn);
mobj_t *shock, *sfirst, *sprev = NULL;
mobj->movecount = mobj->health+1;
mobj->movefactor = -512*FRACUNIT;
// shock the water!
for (i = 0; i < 64; i++)
for (i = 0; i < numtospawn; i++)
{
mobj_t *shock = P_SpawnMobjFromMobj(mobj, 0, 0, 4*FRACUNIT, MT_SHOCK);
shock = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SHOCKWAVE);
P_SetTarget(&shock->target, mobj);
P_InstaThrust(shock, ang, shock->info->speed);
P_CheckMissileSpawn(shock);
ang += (ANGLE_MAX/64);
shock->fuse = shock->info->painchance;
if (i % 2 == 0)
P_SetMobjState(shock, shock->state->nextstate);
if (!sprev)
sfirst = shock;
else
{
if (i == numtospawn - 1)
P_SetTarget(&shock->hnext, sfirst);
P_SetTarget(&sprev->hnext, shock);
}
P_Thrust(shock, ang, shock->info->speed);
ang += interval;
sprev = shock;
}
S_StartSound(mobj, sfx_fizzle);
S_StartSound(mobj, shock->info->seesound);
// look for a new target
P_BossTargetPlayer(mobj, false);
@ -5028,6 +5078,24 @@ static void P_Boss5Thinker(mobj_t *mobj)
{
if (!mobj->health)
{
if (mobj->fuse)
{
if (mobj->flags2 & MF2_SLIDEPUSH)
{
INT32 trans = 10-((10*mobj->fuse)/70);
if (trans > 9)
trans = 9;
if (trans < 0)
trans = 0;
mobj->frame = (mobj->frame & ~FF_TRANSMASK)|(trans<<FF_TRANSSHIFT);
if (!(mobj->fuse & 1))
{
mobj->colorized = !mobj->colorized;
mobj->frame ^= FF_FULLBRIGHT;
}
}
return;
}
if (mobj->state == &states[mobj->info->xdeathstate])
mobj->momz -= (2*FRACUNIT)/3;
else if (mobj->tracer && P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y) < 2*mobj->radius)
@ -7276,7 +7344,8 @@ void P_MobjThinker(mobj_t *mobj)
case MT_FLAMEAURA_ORB:
if (!(mobj->flags2 & MF2_SHIELD))
return;
mobj->angle = mobj->target->angle; // implicitly okay because of P_AddShield
if ((statenum_t)(mobj->state-states) < mobj->info->painstate)
mobj->angle = mobj->target->angle; // implicitly okay because of P_AddShield
if (mobj->tracer
/* && mobj->target -- the following is implicit by P_AddShield
&& mobj->target->player
@ -7614,6 +7683,17 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->movedir)
mobj->angle += mobj->movedir;
break;
case MT_VWREF:
case MT_VWREB:
{
INT32 strength;
++mobj->movedir;
mobj->frame &= ~FF_TRANSMASK;
strength = min(mobj->fuse, mobj->movedir)*3;
if (strength < 10)
mobj->frame |= ((10-strength)<<(FF_TRANSSHIFT));
}
/* FALLTHRU */
default:
if (mobj->fuse)
{ // Scenery object fuse! Very basic!
@ -9063,9 +9143,12 @@ void P_MobjThinker(mobj_t *mobj)
{
if (mobj->state->action.acp1 == (actionf_p1)A_Boss1Laser)
{
/*var1 = mobj->state->var1;
var2 = mobj->state->var2 & 65535;
mobj->state->action.acp1(mobj);*/
if (mobj->state->tics > 1)
{
var1 = mobj->state->var1;
var2 = mobj->state->var2 & 65535;
mobj->state->action.acp1(mobj);
}
}
else if (leveltime & 1) // Fire mode
{
@ -9231,6 +9314,18 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
}
P_RemoveMobj(mobj);
return;
case MT_FANG:
if (mobj->flags2 & MF2_SLIDEPUSH)
{
var1 = 0;
var2 = 0;
A_BossDeath(mobj);
return;
}
P_SetMobjState(mobj, mobj->state->nextstate);
if (P_MobjWasRemoved(mobj))
return;
break;
case MT_METALSONIC_BATTLE:
break; // don't remove
case MT_SPIKE:
@ -9829,7 +9924,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break;
}
if (sc != -1)
if (sc != -1 && !(mobj->flags2 & MF2_SLIDEPUSH))
{
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
@ -9841,6 +9936,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
{
mobj->color = SKINCOLOR_SILVER;
mobj->colorized = true;
mobj->flags2 |= MF2_SLIDEPUSH;
break;
}
}
@ -10412,7 +10508,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())
@ -10420,9 +10516,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
{
@ -10489,7 +10585,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;
@ -11188,6 +11283,16 @@ You should think about modifying the deathmatch starts to take full advantage of
else
mobj->health = FixedMul(ss->sector->ceilingheight-ss->sector->floorheight, 3*(FRACUNIT/4))>>FRACBITS;
break;
case MT_FANG:
case MT_METALSONIC_RACE:
case MT_METALSONIC_BATTLE:
if (mthing->options & MTF_EXTRA)
{
mobj->color = SKINCOLOR_SILVER;
mobj->colorized = true;
mobj->flags2 |= MF2_SLIDEPUSH;
}
break;
case MT_BALLOON:
if (mthing->angle > 0)
mobj->color = ((mthing->angle-1) % (MAXSKINCOLORS-1))+1;

View File

@ -4119,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)
@ -4163,7 +4205,7 @@ void P_SaveNetGame(void)
LUA_Archive();
#endif
WRITEUINT8(save_p, 0x1d); // consistency marker
P_ArchiveLuabanksAndConsistency();
}
boolean P_LoadGame(INT16 mapoverride)
@ -4175,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
@ -4217,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

@ -2250,6 +2250,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.
@ -2257,41 +2259,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].numboxes = players[i].totalring =\
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);
}
//

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@
#include "z_zone.h"
#include "p_setup.h" // levelflats
#include "v_video.h" // pMasterPalette
#include "byteptr.h"
#include "dehacked.h"
#ifdef _WIN32
@ -241,7 +242,7 @@ static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, tex
}
}
RGBA_t ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha)
UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha)
{
RGBA_t output;
if (style == AST_TRANSLUCENT)
@ -261,6 +262,9 @@ RGBA_t ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph
// if there's no pixel in here
if (!background.rgba)
output.s.alpha = foreground.s.alpha;
else
output.s.alpha = 0xFF;
return output.rgba;
}
#define clamp(c) max(min(c, 0xFF), 0x00);
else
@ -298,30 +302,38 @@ RGBA_t ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph
}
// just copy the pixel
else if (style == AST_COPY)
return background;
output.rgba = foreground.rgba;
output.s.alpha = 0xFF;
return output.rgba;
}
#undef clamp
// unimplemented blend modes return the background pixel
output = background;
output.s.alpha = 0xFF;
return output;
return 0;
}
UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha)
{
if ((style == AST_TRANSLUCENT) && (alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency?
// Alpha style set to translucent?
if (style == AST_TRANSLUCENT)
{
UINT8 *mytransmap;
if (alpha < 255/11) // Is the patch way too translucent? Don't render then.
return background;
// The equation's not exact but it works as intended. I'll call it a day for now.
mytransmap = transtables + ((8*(alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT);
if (background != 0xFF)
return *(mytransmap + (background<<8) + foreground);
// Is the alpha small enough for translucency?
if (alpha <= (10*255/11))
{
UINT8 *mytransmap;
// Is the patch way too translucent? Don't blend then.
if (alpha < 255/11)
return background;
// The equation's not exact but it works as intended. I'll call it a day for now.
mytransmap = transtables + ((8*(alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT);
if (background != 0xFF)
return *(mytransmap + (background<<8) + foreground);
}
else // just copy the pixel
return foreground;
}
// just copy the pixel
else if (style == AST_COPY)
return background;
return foreground;
// use ASTBlendPixel for all other blend modes
// and find the nearest colour in the palette
else if (style != AST_TRANSLUCENT)
@ -329,7 +341,7 @@ UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 al
RGBA_t texel;
RGBA_t bg = V_GetColor(background);
RGBA_t fg = V_GetColor(foreground);
texel = ASTBlendPixel(bg, fg, style, alpha);
texel.rgba = ASTBlendPixel(bg, fg, style, alpha);
return NearestColor(texel.s.red, texel.s.green, texel.s.blue);
}
// fallback if all above fails, somehow
@ -374,7 +386,7 @@ static inline void R_DrawBlendColumnInCache(column_t *patch, UINT8 *cache, texpa
if (count > 0)
{
for (; dest < cache + position + count; source++, dest++)
if (*dest != 0xFF)
if (*source != 0xFF)
*dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha);
}
@ -383,7 +395,7 @@ static inline void R_DrawBlendColumnInCache(column_t *patch, UINT8 *cache, texpa
}
//
// R_DrawTransColumnInCache
// R_DrawBlendFlippedColumnInCache
// Similar to the one above except that the column is inverted.
//
static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
@ -418,7 +430,7 @@ static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache
if (count > 0)
{
for (; dest < cache + position + count; --source, dest++)
if (*dest != 0xFF)
if (*source != 0xFF)
*dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha);
}
@ -476,7 +488,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
#ifndef NO_PNG_LUMPS
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
{
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength);
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false);
goto multipatch;
}
#endif
@ -569,7 +581,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
#ifndef NO_PNG_LUMPS
if (R_IsLumpPNG((UINT8 *)realpatch, lumplength))
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength);
realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false);
#endif
x1 = patch->originx;
@ -2588,7 +2600,7 @@ void R_PatchToFlat(patch_t *patch, UINT8 *flat)
}
#ifndef NO_PNG_LUMPS
boolean R_IsLumpPNG(UINT8 *d, size_t s)
boolean R_IsLumpPNG(const UINT8 *d, size_t s)
{
if (s < 67) // http://garethrees.org/2007/11/14/pngcrush/
return false;
@ -2599,21 +2611,49 @@ boolean R_IsLumpPNG(UINT8 *d, size_t s)
}
#ifdef HAVE_PNG
#if PNG_LIBPNG_VER_DLLNUM < 14
typedef PNG_CONST png_byte *png_const_bytep;
#endif
typedef struct {
png_bytep buffer;
png_const_bytep buffer;
png_uint_32 bufsize;
png_uint_32 current_pos;
} png_ioread;
} png_io_t;
static void PNG_IOReader(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_ioread *f = png_get_io_ptr(png_ptr);
png_io_t *f = png_get_io_ptr(png_ptr);
if (length > (f->bufsize - f->current_pos))
png_error(png_ptr, "PNG_IOReader: buffer overrun");
memcpy(data, f->buffer + f->current_pos, length);
f->current_pos += length;
}
typedef struct
{
char name[4];
void *data;
size_t size;
} png_chunk_t;
static png_byte *chunkname = NULL;
static png_chunk_t chunk;
static int PNG_ChunkReader(png_structp png_ptr, png_unknown_chunkp chonk)
{
(void)png_ptr;
if (!memcmp(chonk->name, chunkname, 4))
{
memcpy(chunk.name, chonk->name, 4);
chunk.size = chonk->size;
chunk.data = Z_Malloc(chunk.size, PU_STATIC, NULL);
memcpy(chunk.data, chonk->data, chunk.size);
return 1;
}
return 0;
}
static void PNG_error(png_structp PNG, png_const_charp pngtext)
{
CONS_Debug(DBG_RENDER, "libpng error at %p: %s", PNG, pngtext);
@ -2625,7 +2665,7 @@ static void PNG_warn(png_structp PNG, png_const_charp pngtext)
CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext);
}
static png_bytep *PNG_Read(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
static png_bytep *PNG_Read(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topoffset, INT16 *leftoffset, size_t size)
{
png_structp png_ptr;
png_infop png_info_ptr;
@ -2638,11 +2678,13 @@ static png_bytep *PNG_Read(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
#endif
#endif
png_ioread png_io;
png_io_t png_io;
png_bytep *row_pointers;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
PNG_error, PNG_warn);
png_byte grAb_chunk[5] = {'g', 'r', 'A', 'b', (png_byte)'\0'};
png_voidp *user_chunk_ptr;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn);
if (!png_ptr)
{
CONS_Debug(DBG_RENDER, "PNG_Load: Error on initialize libpng\n");
@ -2672,19 +2714,24 @@ static png_bytep *PNG_Read(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
#endif
// set our own read_function
png_io.buffer = (png_bytep)png;
png_io.buffer = (png_const_bytep)png;
png_io.bufsize = size;
png_io.current_pos = 0;
png_set_read_fn(png_ptr, &png_io, PNG_IOReader);
memset(&chunk, 0x00, sizeof(png_chunk_t));
chunkname = grAb_chunk; // I want to read a grAb chunk
user_chunk_ptr = png_get_user_chunk_ptr(png_ptr);
png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, PNG_ChunkReader);
png_set_keep_unknown_chunks(png_ptr, 2, chunkname, 1);
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
png_set_user_limits(png_ptr, 2048, 2048);
#endif
png_read_info(png_ptr, png_info_ptr);
png_get_IHDR(png_ptr, png_info_ptr, &width, &height, &bit_depth, &color_type,
NULL, NULL, NULL);
png_get_IHDR(png_ptr, png_info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
if (bit_depth == 16)
png_set_strip_16(png_ptr);
@ -2712,7 +2759,24 @@ static png_bytep *PNG_Read(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
for (y = 0; y < height; y++)
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png_ptr, png_info_ptr));
png_read_image(png_ptr, row_pointers);
// Read grAB chunk
if ((topoffset || leftoffset) && (chunk.data != NULL))
{
INT32 *offsets = (INT32 *)chunk.data;
// read left offset
if (leftoffset != NULL)
*leftoffset = (INT16)BIGENDIAN_LONG(*offsets);
offsets++;
// read top offset
if (topoffset != NULL)
*topoffset = (INT16)BIGENDIAN_LONG(*offsets);
}
// bye
png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL);
if (chunk.data)
Z_Free(chunk.data);
*w = (INT32)width;
*h = (INT32)height;
@ -2720,11 +2784,11 @@ static png_bytep *PNG_Read(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
}
// Convert a PNG to a raw image.
static UINT8 *PNG_RawConvert(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
static UINT8 *PNG_RawConvert(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topoffset, INT16 *leftoffset, size_t size)
{
UINT8 *flat;
png_uint_32 x, y;
png_bytep *row_pointers = PNG_Read(png, w, h, size);
png_bytep *row_pointers = PNG_Read(png, w, h, topoffset, leftoffset, size);
png_uint_32 width = *w, height = *h;
if (!row_pointers)
@ -2751,34 +2815,30 @@ static UINT8 *PNG_RawConvert(UINT8 *png, UINT16 *w, UINT16 *h, size_t size)
// Convert a PNG to a flat.
UINT8 *R_PNGToFlat(levelflat_t *levelflat, UINT8 *png, size_t size)
{
return PNG_RawConvert(png, &levelflat->width, &levelflat->height, size);
return PNG_RawConvert(png, &levelflat->width, &levelflat->height, NULL, NULL, size);
}
// Convert a PNG to a patch.
static unsigned char imgbuf[1<<26];
patch_t *R_PNGToPatch(UINT8 *png, size_t size)
patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency)
{
UINT16 width, height;
UINT8 *raw = PNG_RawConvert(png, &width, &height, size);
INT16 topoffset = 0, leftoffset = 0;
UINT8 *raw = PNG_RawConvert(png, &width, &height, &topoffset, &leftoffset, size);
UINT32 x, y;
UINT8 *img;
UINT8 *imgptr = imgbuf;
UINT8 *colpointers, *startofspan;
#define WRITE8(buf, a) ({*buf = (a); buf++;})
#define WRITE16(buf, a) ({*buf = (a)&255; buf++; *buf = (a)>>8; buf++;})
#define WRITE32(buf, a) ({WRITE16(buf, (a)&65535); WRITE16(buf, (a)>>16);})
if (!raw)
I_Error("R_PNGToPatch: conversion failed");
// Write image size and offset
WRITE16(imgptr, width);
WRITE16(imgptr, height);
// no offsets
WRITE16(imgptr, 0);
WRITE16(imgptr, 0);
WRITEINT16(imgptr, width);
WRITEINT16(imgptr, height);
WRITEINT16(imgptr, leftoffset);
WRITEINT16(imgptr, topoffset);
// Leave placeholder to column pointers
colpointers = imgptr;
@ -2793,12 +2853,22 @@ patch_t *R_PNGToPatch(UINT8 *png, size_t size)
//printf("%d ", x);
// Write column pointer (@TODO may be wrong)
WRITE32(colpointers, imgptr - imgbuf);
WRITEINT32(colpointers, imgptr - imgbuf);
// Write pixels
for (y = 0; y < height; y++)
{
UINT8 paletteIndex = raw[((y * width) + x)];
boolean opaque = transparency ? (paletteIndex != TRANSPARENTPIXEL) : true;
// End span if we have a transparent pixel
if (!opaque)
{
if (startofspan)
WRITEUINT8(imgptr, 0);
startofspan = NULL;
continue;
}
// Start new column if we need to
if (!startofspan || spanSize == 255)
@ -2807,15 +2877,15 @@ patch_t *R_PNGToPatch(UINT8 *png, size_t size)
// If we reached the span size limit, finish the previous span
if (startofspan)
WRITE8(imgptr, 0);
WRITEUINT8(imgptr, 0);
if (y > 254)
{
// Make sure we're aligned to 254
if (lastStartY < 254)
{
WRITE8(imgptr, 254);
WRITE8(imgptr, 0);
WRITEUINT8(imgptr, 254);
WRITEUINT8(imgptr, 0);
imgptr += 2;
lastStartY = 254;
}
@ -2825,15 +2895,15 @@ patch_t *R_PNGToPatch(UINT8 *png, size_t size)
while (writeY > 254)
{
WRITE8(imgptr, 254);
WRITE8(imgptr, 0);
WRITEUINT8(imgptr, 254);
WRITEUINT8(imgptr, 0);
imgptr += 2;
writeY -= 254;
}
}
startofspan = imgptr;
WRITE8(imgptr, writeY);///@TODO calculate starting y pos
WRITEUINT8(imgptr, writeY);///@TODO calculate starting y pos
imgptr += 2;
spanSize = 0;
@ -2841,27 +2911,25 @@ patch_t *R_PNGToPatch(UINT8 *png, size_t size)
}
// Write the pixel
WRITE8(imgptr, paletteIndex);
WRITEUINT8(imgptr, paletteIndex);
spanSize++;
startofspan[1] = spanSize;
}
if (startofspan)
WRITE8(imgptr, 0);
WRITEUINT8(imgptr, 0);
WRITE8(imgptr, 0xFF);
WRITEUINT8(imgptr, 0xFF);
}
#undef WRITE8
#undef WRITE16
#undef WRITE32
size = imgptr-imgbuf;
img = malloc(size);
img = Z_Malloc(size, PU_STATIC, NULL);
memcpy(img, imgbuf, size);
Z_Free(raw);
if (destsize != NULL)
*destsize = size;
return (patch_t *)img;
}
@ -2877,7 +2945,7 @@ boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size)
#endif
#endif
png_ioread png_io;
png_io_t png_io;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
PNG_error, PNG_warn);

View File

@ -25,7 +25,7 @@
// Possible alpha types for a patch.
enum patchalphastyle {AST_COPY, AST_TRANSLUCENT, AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY};
RGBA_t ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
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);
@ -165,10 +165,10 @@ void R_PatchToFlat(patch_t *patch, UINT8 *flat);
void R_TextureToFlat(size_t tex, UINT8 *flat);
#ifndef NO_PNG_LUMPS
boolean R_IsLumpPNG(UINT8 *d, size_t s);
boolean R_IsLumpPNG(const UINT8 *d, size_t s);
UINT8 *R_PNGToFlat(levelflat_t *levelflat, UINT8 *png, size_t size);
patch_t *R_PNGToPatch(UINT8 *png, size_t size);
patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency);
boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size);
#endif

View File

@ -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);
@ -1215,7 +1219,6 @@ void R_RegisterEngineStuff(void)
#endif
CV_RegisterVar(&cv_grmd2);
CV_RegisterVar(&cv_grspritebillboarding);
CV_RegisterVar(&cv_grskydome);
#endif
#ifdef HWRENDER

View File

@ -652,12 +652,18 @@ static void R_DrawSkyPlane(visplane_t *pl)
boolean R_CheckPowersOfTwo(void)
{
if (ds_flatwidth & (ds_flatwidth - 1))
ds_powersoftwo = false;
else if (ds_flatheight & (ds_flatheight - 1))
ds_powersoftwo = false;
else if (ds_flatwidth == ds_flatheight)
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;
}
@ -806,6 +812,7 @@ void R_DrawSinglePlane(visplane_t *pl)
size_t size;
ffloor_t *rover;
levelflat_t *levelflat;
boolean rawflat = false;
if (!(pl->minx <= pl->maxx))
return;
@ -968,6 +975,7 @@ void R_DrawSinglePlane(visplane_t *pl)
// It's a raw flat.
else
{
rawflat = true;
R_CheckFlatLength(size);
flat = ds_source;
}
@ -978,8 +986,11 @@ void R_DrawSinglePlane(visplane_t *pl)
if (ds_source == NULL)
return;
// Check if the flat has dimensions that are powers-of-two numbers.
if (R_CheckPowersOfTwo())
// 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)
@ -1116,26 +1127,27 @@ void R_DrawSinglePlane(visplane_t *pl)
ds_sz.z *= focallengthf;
// Premultiply the texture vectors with the scale factors
#define SFMULT 65536.f
if (ds_powersoftwo)
{
#define SFMULT 65536.f*(1<<nflatshiftup)
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
}
else
{
ds_su.x *= 65536.f;
ds_su.y *= 65536.f;
ds_su.z *= 65536.f;
ds_sv.x *= 65536.f;
ds_sv.y *= 65536.f;
ds_sv.z *= 65536.f;
}
if (spanfunc == R_DrawTranslucentSpan_8)
spanfunc = R_DrawTiltedTranslucentSpan_8;

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

@ -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

@ -79,7 +79,6 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(Init);
GETFUNC(Draw2DLine);
GETFUNC(DrawPolygon);
GETFUNC(RenderSkyDome);
GETFUNC(SetBlend);
GETFUNC(ClearBuffer);
GETFUNC(SetTexture);

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
logdir = D_Home();
#ifdef LOGMESSAGES
if (!M_CheckParm("-nolog"))
{
time_t my_time;
struct tm * timeinfo;
char buf[26];
logdir = D_Home();
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");
else
if (logdir)
{
// 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

@ -827,6 +827,23 @@ void I_JoyScale2(void)
JoyInfo2.scale = Joystick2.bGamepadStyle?1:cv_joyscale2.value;
}
// Cheat to get the device index for a joystick handle
INT32 I_GetJoystickDeviceIndex(SDL_Joystick *dev)
{
INT32 i, count = SDL_NumJoysticks();
for (i = 0; dev && i < count; i++)
{
SDL_Joystick *test = SDL_JoystickOpen(i);
if (test && test == dev)
return i;
else if (JoyInfo.dev != test && JoyInfo2.dev != test)
SDL_JoystickClose(test);
}
return -1;
}
/** \brief Joystick 1 buttons states
*/
static UINT64 lastjoybuttons = 0;
@ -842,7 +859,7 @@ static UINT64 lastjoyhats = 0;
*/
static void I_ShutdownJoystick(void)
void I_ShutdownJoystick(void)
{
INT32 i;
event_t event;
@ -876,14 +893,8 @@ static void I_ShutdownJoystick(void)
joystick_started = 0;
JoyReset(&JoyInfo);
if (!joystick_started && !joystick2_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
if (cv_usejoystick.value == 0)
{
I_OutputMsg("I_Joystick: SDL's Joystick system has been shutdown\n");
}
}
// don't shut down the subsystem here, because hotplugging
}
void I_GetJoystickEvents(void)
@ -1024,74 +1035,66 @@ void I_GetJoystickEvents(void)
*/
static int joy_open(const char *fname)
static int joy_open(int joyindex)
{
int joyindex = atoi(fname);
SDL_Joystick *newdev = NULL;
int num_joy = 0;
int i;
if (joystick_started == 0 && joystick2_started == 0)
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
{
CONS_Printf(M_GetText("Couldn't initialize gamepad: %s\n"), SDL_GetError());
return -1;
}
else
{
num_joy = SDL_NumJoysticks();
}
CONS_Printf(M_GetText("Joystick subsystem not started\n"));
return -1;
}
if (num_joy < joyindex)
{
CONS_Printf("Cannot use gamepad #%d/(%s), it doesn't exist\n",joyindex,fname);
for (i = 0; i < num_joy; i++)
CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
I_ShutdownJoystick();
return -1;
}
}
else
{
JoyReset(&JoyInfo);
//I_ShutdownJoystick();
//joy_open(fname);
}
if (joyindex <= 0)
return -1;
num_joy = SDL_NumJoysticks();
if (joyindex <= 0 || num_joy == 0 || JoyInfo.oldjoy == joyindex)
if (num_joy == 0)
{
// I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname);
if (num_joy != 0)
{
CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy);
for (i = 0; i < num_joy; i++)
CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
}
else
CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
if (joyindex <= 0 || num_joy == 0) return 0;
CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
return -1;
}
JoyInfo.dev = SDL_JoystickOpen(joyindex-1);
newdev = SDL_JoystickOpen(joyindex-1);
// Handle the edge case where the device <-> joystick index assignment can change due to hotplugging
// This indexing is SDL's responsibility and there's not much we can do about it.
//
// Example:
// 1. Plug Controller A -> Index 0 opened
// 2. Plug Controller B -> Index 1 opened
// 3. Unplug Controller A -> Index 0 closed, Index 1 active
// 4. Unplug Controller B -> Index 0 inactive, Index 1 closed
// 5. Plug Controller B -> Index 0 opened
// 6. Plug Controller A -> Index 0 REPLACED, opened as Controller A; Index 1 is now Controller B
if (JoyInfo.dev)
{
if (JoyInfo.dev == newdev // same device, nothing to do
|| (newdev == NULL && SDL_JoystickGetAttached(JoyInfo.dev))) // we failed, but already have a working device
return JoyInfo.axises;
// Else, we're changing devices, so send neutral joy events
CONS_Debug(DBG_GAMELOGIC, "Joystick1 device is changing; resetting events...\n");
I_ShutdownJoystick();
}
JoyInfo.dev = newdev;
if (JoyInfo.dev == NULL)
{
CONS_Printf(M_GetText("Couldn't open joystick: %s\n"), SDL_GetError());
I_ShutdownJoystick();
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick1: Couldn't open device - %s\n"), SDL_GetError());
return -1;
}
else
{
CONS_Printf(M_GetText("Joystick: %s\n"), SDL_JoystickName(JoyInfo.dev));
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick1: %s\n"), SDL_JoystickName(JoyInfo.dev));
JoyInfo.axises = SDL_JoystickNumAxes(JoyInfo.dev);
if (JoyInfo.axises > JOYAXISSET*2)
JoyInfo.axises = JOYAXISSET*2;
/* if (joyaxes<2)
/* if (joyaxes<2)
{
I_OutputMsg("Not enought axes?\n");
I_ShutdownJoystick();
return 0;
}*/
@ -1126,7 +1129,7 @@ static UINT64 lastjoy2hats = 0;
\return void
*/
static void I_ShutdownJoystick2(void)
void I_ShutdownJoystick2(void)
{
INT32 i;
event_t event;
@ -1160,14 +1163,8 @@ static void I_ShutdownJoystick2(void)
joystick2_started = 0;
JoyReset(&JoyInfo2);
if (!joystick_started && !joystick2_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
if (cv_usejoystick2.value == 0)
{
DEBFILE("I_Joystick2: SDL's Joystick system has been shutdown\n");
}
}
// don't shut down the subsystem here, because hotplugging
}
void I_GetJoystick2Events(void)
@ -1310,72 +1307,66 @@ void I_GetJoystick2Events(void)
*/
static int joy_open2(const char *fname)
static int joy_open2(int joyindex)
{
int joyindex = atoi(fname);
SDL_Joystick *newdev = NULL;
int num_joy = 0;
int i;
if (joystick_started == 0 && joystick2_started == 0)
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
{
CONS_Printf(M_GetText("Couldn't initialize gamepad: %s\n"), SDL_GetError());
return -1;
}
else
num_joy = SDL_NumJoysticks();
CONS_Printf(M_GetText("Joystick subsystem not started\n"));
return -1;
}
if (num_joy < joyindex)
{
CONS_Printf("Cannot use gamepad #%d/(%s), it doesn't exist\n",joyindex,fname);
for (i = 0; i < num_joy; i++)
CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
I_ShutdownJoystick2();
return -1;
}
}
else
{
JoyReset(&JoyInfo2);
//I_ShutdownJoystick();
//joy_open(fname);
}
if (joyindex <= 0)
return -1;
num_joy = SDL_NumJoysticks();
if (joyindex <= 0 || num_joy == 0 || JoyInfo2.oldjoy == joyindex)
if (num_joy == 0)
{
// I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname);
if (num_joy != 0)
{
CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy);
for (i = 0; i < num_joy; i++)
CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
}
else
CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
if (joyindex <= 0 || num_joy == 0) return 0;
CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
return -1;
}
JoyInfo2.dev = SDL_JoystickOpen(joyindex-1);
newdev = SDL_JoystickOpen(joyindex-1);
if (!JoyInfo2.dev)
// Handle the edge case where the device <-> joystick index assignment can change due to hotplugging
// This indexing is SDL's responsibility and there's not much we can do about it.
//
// Example:
// 1. Plug Controller A -> Index 0 opened
// 2. Plug Controller B -> Index 1 opened
// 3. Unplug Controller A -> Index 0 closed, Index 1 active
// 4. Unplug Controller B -> Index 0 inactive, Index 1 closed
// 5. Plug Controller B -> Index 0 opened
// 6. Plug Controller A -> Index 0 REPLACED, opened as Controller A; Index 1 is now Controller B
if (JoyInfo2.dev)
{
CONS_Printf(M_GetText("Couldn't open joystick2: %s\n"), SDL_GetError());
if (JoyInfo2.dev == newdev // same device, nothing to do
|| (newdev == NULL && SDL_JoystickGetAttached(JoyInfo2.dev))) // we failed, but already have a working device
return JoyInfo.axises;
// Else, we're changing devices, so send neutral joy events
CONS_Debug(DBG_GAMELOGIC, "Joystick2 device is changing; resetting events...\n");
I_ShutdownJoystick2();
}
JoyInfo2.dev = newdev;
if (JoyInfo2.dev == NULL)
{
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick2: couldn't open device - %s\n"), SDL_GetError());
return -1;
}
else
{
CONS_Printf(M_GetText("Joystick2: %s\n"), SDL_JoystickName(JoyInfo2.dev));
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick2: %s\n"), SDL_JoystickName(JoyInfo2.dev));
JoyInfo2.axises = SDL_JoystickNumAxes(JoyInfo2.dev);
if (JoyInfo2.axises > JOYAXISSET*2)
JoyInfo2.axises = JOYAXISSET*2;
/* if (joyaxes < 2)
/* if (joyaxes<2)
{
I_OutputMsg("Not enought axes?\n");
I_ShutdownJoystick2();
return 0;
}*/
@ -1400,7 +1391,11 @@ static int joy_open2(const char *fname)
//
void I_InitJoystick(void)
{
I_ShutdownJoystick();
SDL_Joystick *newjoy = NULL;
//I_ShutdownJoystick();
if (M_CheckParm("-nojoy"))
return;
if (M_CheckParm("-noxinput"))
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
@ -1408,21 +1403,48 @@ void I_InitJoystick(void)
if (M_CheckParm("-nohidapi"))
SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE);
if (!strcmp(cv_usejoystick.string, "0") || M_CheckParm("-nojoy"))
return;
if (joy_open(cv_usejoystick.string) != -1)
JoyInfo.oldjoy = atoi(cv_usejoystick.string);
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{
CONS_Printf("I_InitJoystick()...\n");
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
{
CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
return;
}
}
if (cv_usejoystick.value)
newjoy = SDL_JoystickOpen(cv_usejoystick.value-1);
if (newjoy && JoyInfo2.dev == newjoy) // don't override an active device
cv_usejoystick.value = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
else if (newjoy && joy_open(cv_usejoystick.value) != -1)
{
// SDL's device indexes are unstable, so cv_usejoystick may not match
// the actual device index. So let's cheat a bit and find the device's current index.
JoyInfo.oldjoy = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
joystick_started = 1;
}
else
{
if (JoyInfo.oldjoy)
I_ShutdownJoystick();
cv_usejoystick.value = 0;
return;
joystick_started = 0;
}
joystick_started = 1;
if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy)
SDL_JoystickClose(newjoy);
}
void I_InitJoystick2(void)
{
I_ShutdownJoystick2();
SDL_Joystick *newjoy = NULL;
//I_ShutdownJoystick2();
if (M_CheckParm("-nojoy"))
return;
if (M_CheckParm("-noxinput"))
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
@ -1430,64 +1452,77 @@ void I_InitJoystick2(void)
if (M_CheckParm("-nohidapi"))
SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE);
if (!strcmp(cv_usejoystick2.string, "0") || M_CheckParm("-nojoy"))
return;
if (joy_open2(cv_usejoystick2.string) != -1)
JoyInfo2.oldjoy = atoi(cv_usejoystick2.string);
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{
CONS_Printf("I_InitJoystick2()...\n");
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
{
CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
return;
}
}
if (cv_usejoystick2.value)
newjoy = SDL_JoystickOpen(cv_usejoystick2.value-1);
if (newjoy && JoyInfo.dev == newjoy) // don't override an active device
cv_usejoystick2.value = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
else if (newjoy && joy_open2(cv_usejoystick2.value) != -1)
{
// SDL's device indexes are unstable, so cv_usejoystick may not match
// the actual device index. So let's cheat a bit and find the device's current index.
JoyInfo2.oldjoy = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
joystick2_started = 1;
}
else
{
if (JoyInfo2.oldjoy)
I_ShutdownJoystick2();
cv_usejoystick2.value = 0;
return;
joystick2_started = 0;
}
joystick2_started = 1;
if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy)
SDL_JoystickClose(newjoy);
}
static void I_ShutdownInput(void)
{
// Yes, the name is misleading: these send neutral events to
// clean up the unplugged joystick's input
// Note these methods are internal to this file, not called elsewhere.
I_ShutdownJoystick();
I_ShutdownJoystick2();
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{
JoyReset(&JoyInfo);
JoyReset(&JoyInfo2);
CONS_Printf("Shutting down joy system\n");
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
I_OutputMsg("I_Joystick: SDL's Joystick system has been shutdown\n");
}
}
INT32 I_NumJoys(void)
{
INT32 numjoy = 0;
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1)
numjoy = SDL_NumJoysticks();
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
}
else
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
numjoy = SDL_NumJoysticks();
return numjoy;
}
static char joyname[255]; // MAX_PATH; joystick name is straight from the driver
static char joyname[255]; // joystick name is straight from the driver
const char *I_GetJoyName(INT32 joyindex)
{
const char *tempname = NULL;
joyname[0] = 0;
joyindex--; //SDL's Joystick System starts at 0, not 1
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1)
{
tempname = SDL_JoystickNameForIndex(joyindex);
if (tempname)
strncpy(joyname, tempname, 254);
}
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
}
else
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{
tempname = SDL_JoystickNameForIndex(joyindex);
if (tempname)
strncpy(joyname, tempname, 254);
strncpy(joyname, tempname, 255);
}
return joyname;
}

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
@ -886,6 +886,136 @@ void I_GetEvent(void)
case SDL_JOYBUTTONDOWN:
Impl_HandleJoystickButtonEvent(evt.jbutton, evt.type);
break;
case SDL_JOYDEVICEADDED:
{
SDL_Joystick *newjoy = SDL_JoystickOpen(evt.jdevice.which);
CONS_Debug(DBG_GAMELOGIC, "Joystick device index %d added\n", evt.jdevice.which + 1);
// Because SDL's device index is unstable, we're going to cheat here a bit:
// For the first joystick setting that is NOT active:
// 1. Set cv_usejoystickX.value to the new device index (this does not change what is written to config.cfg)
// 2. Set OTHERS' cv_usejoystickX.value to THEIR new device index, because it likely changed
// * If device doesn't exist, switch cv_usejoystick back to default value (.string)
// * BUT: If that default index is being occupied, use ANOTHER cv_usejoystick's default value!
if (newjoy && (!JoyInfo.dev || !SDL_JoystickGetAttached(JoyInfo.dev))
&& JoyInfo2.dev != newjoy) // don't override a currently active device
{
cv_usejoystick.value = evt.jdevice.which + 1;
if (JoyInfo2.dev)
cv_usejoystick2.value = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
else if (atoi(cv_usejoystick2.string) != JoyInfo.oldjoy
&& atoi(cv_usejoystick2.string) != cv_usejoystick.value)
cv_usejoystick2.value = atoi(cv_usejoystick2.string);
else if (atoi(cv_usejoystick.string) != JoyInfo.oldjoy
&& atoi(cv_usejoystick.string) != cv_usejoystick.value)
cv_usejoystick2.value = atoi(cv_usejoystick.string);
else // we tried...
cv_usejoystick2.value = 0;
}
else if (newjoy && (!JoyInfo2.dev || !SDL_JoystickGetAttached(JoyInfo2.dev))
&& JoyInfo.dev != newjoy) // don't override a currently active device
{
cv_usejoystick2.value = evt.jdevice.which + 1;
if (JoyInfo.dev)
cv_usejoystick.value = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
else if (atoi(cv_usejoystick.string) != JoyInfo2.oldjoy
&& atoi(cv_usejoystick.string) != cv_usejoystick2.value)
cv_usejoystick.value = atoi(cv_usejoystick.string);
else if (atoi(cv_usejoystick2.string) != JoyInfo2.oldjoy
&& atoi(cv_usejoystick2.string) != cv_usejoystick2.value)
cv_usejoystick.value = atoi(cv_usejoystick2.string);
else // we tried...
cv_usejoystick.value = 0;
}
// Was cv_usejoystick disabled in settings?
if (!strcmp(cv_usejoystick.string, "0") || !cv_usejoystick.value)
cv_usejoystick.value = 0;
else if (atoi(cv_usejoystick.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
&& cv_usejoystick.value) // update the cvar ONLY if a device exists
CV_SetValue(&cv_usejoystick, cv_usejoystick.value);
if (!strcmp(cv_usejoystick2.string, "0") || !cv_usejoystick2.value)
cv_usejoystick2.value = 0;
else if (atoi(cv_usejoystick2.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
&& cv_usejoystick2.value) // update the cvar ONLY if a device exists
CV_SetValue(&cv_usejoystick2, cv_usejoystick2.value);
// Update all joysticks' init states
// This is a little wasteful since cv_usejoystick already calls this, but
// we need to do this in case CV_SetValue did nothing because the string was already same.
// if the device is already active, this should do nothing, effectively.
I_InitJoystick();
I_InitJoystick2();
CONS_Debug(DBG_GAMELOGIC, "Joystick1 device index: %d\n", JoyInfo.oldjoy);
CONS_Debug(DBG_GAMELOGIC, "Joystick2 device index: %d\n", JoyInfo2.oldjoy);
// update the menu
if (currentMenu == &OP_JoystickSetDef)
M_SetupJoystickMenu(0);
if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy)
SDL_JoystickClose(newjoy);
}
break;
case SDL_JOYDEVICEREMOVED:
if (JoyInfo.dev && !SDL_JoystickGetAttached(JoyInfo.dev))
{
CONS_Debug(DBG_GAMELOGIC, "Joystick1 removed, device index: %d\n", JoyInfo.oldjoy);
I_ShutdownJoystick();
}
if (JoyInfo2.dev && !SDL_JoystickGetAttached(JoyInfo2.dev))
{
CONS_Debug(DBG_GAMELOGIC, "Joystick2 removed, device index: %d\n", JoyInfo2.oldjoy);
I_ShutdownJoystick2();
}
// Update the device indexes, because they likely changed
// * If device doesn't exist, switch cv_usejoystick back to default value (.string)
// * BUT: If that default index is being occupied, use ANOTHER cv_usejoystick's default value!
if (JoyInfo.dev)
cv_usejoystick.value = JoyInfo.oldjoy = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
else if (atoi(cv_usejoystick.string) != JoyInfo2.oldjoy)
cv_usejoystick.value = atoi(cv_usejoystick.string);
else if (atoi(cv_usejoystick2.string) != JoyInfo2.oldjoy)
cv_usejoystick.value = atoi(cv_usejoystick2.string);
else // we tried...
cv_usejoystick.value = 0;
if (JoyInfo2.dev)
cv_usejoystick2.value = JoyInfo2.oldjoy = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
else if (atoi(cv_usejoystick2.string) != JoyInfo.oldjoy)
cv_usejoystick2.value = atoi(cv_usejoystick2.string);
else if (atoi(cv_usejoystick.string) != JoyInfo.oldjoy)
cv_usejoystick2.value = atoi(cv_usejoystick.string);
else // we tried...
cv_usejoystick2.value = 0;
// Was cv_usejoystick disabled in settings?
if (!strcmp(cv_usejoystick.string, "0"))
cv_usejoystick.value = 0;
else if (atoi(cv_usejoystick.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
&& cv_usejoystick.value) // update the cvar ONLY if a device exists
CV_SetValue(&cv_usejoystick, cv_usejoystick.value);
if (!strcmp(cv_usejoystick2.string, "0"))
cv_usejoystick2.value = 0;
else if (atoi(cv_usejoystick2.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
&& cv_usejoystick2.value) // update the cvar ONLY if a device exists
CV_SetValue(&cv_usejoystick2, cv_usejoystick2.value);
CONS_Debug(DBG_GAMELOGIC, "Joystick1 device index: %d\n", JoyInfo.oldjoy);
CONS_Debug(DBG_GAMELOGIC, "Joystick2 device index: %d\n", JoyInfo2.oldjoy);
// update the menu
if (currentMenu == &OP_JoystickSetDef)
M_SetupJoystickMenu(0);
break;
case SDL_QUIT:
I_Quit();
M_QuitResponse('y');
@ -1499,7 +1629,6 @@ void I_StartupGraphics(void)
HWD.pfnFinishUpdate = NULL;
HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL);
HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL);
HWD.pfnRenderSkyDome = hwSym("RenderSkyDome",NULL);
HWD.pfnSetBlend = hwSym("SetBlend",NULL);
HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL);
HWD.pfnSetTexture = hwSym("SetTexture",NULL);

Binary file not shown.

View File

@ -31,6 +31,9 @@ extern SDL_bool framebuffer;
#define SDL2STUB() CONS_Printf("SDL2: stubbed: %s:%d\n", __func__, __LINE__)
#endif
// So m_menu knows whether to store cv_usejoystick value or string
#define JOYSTICK_HOTPLUG
/** \brief The JoyInfo_s struct
info about joystick
@ -67,6 +70,13 @@ extern SDLJoyInfo_t JoyInfo;
*/
extern SDLJoyInfo_t JoyInfo2;
// So we can call this from i_video event loop
void I_ShutdownJoystick(void);
void I_ShutdownJoystick2(void);
// Cheat to get the device index for a joystick handle
INT32 I_GetJoystickDeviceIndex(SDL_Joystick *dev);
void I_GetConsoleEvents(void);
void SDLforceUngrabMouse(void);

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"},
@ -195,6 +212,8 @@ sfxinfo_t S_sfx[NUMSFX] =
{"boingf", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bouncing"},
{"corkp", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork fired"},
{"corkh", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork hit"},
{"alart", false, 200, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Caught red handed!"},
{"vwre", false, 200, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Clone fighter!"},
{"bowl", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bowling"},
{"chuchu", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Train horn"},
{"bsnipe", false, 200, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Home-run smash"},
@ -290,6 +309,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
@ -334,7 +486,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3k5b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Menu beep"},
{"s3k5c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Electric spark"},
{"s3k5d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Heavy hit"},
{"s3k5e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing laser"},
{"s3k5e", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Releasing charge"},
{"s3k5f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crusher stomp"},
{"s3k60", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Accelerating"},
{"s3k61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drilling"},
@ -459,8 +611,8 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3kcal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"}, // ditto
{"s3kcbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"},
{"s3kcbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, // ditto
{"s3kccs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"},
{"s3kccl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"}, // ditto
{"s3kccs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bursting"},
{"s3kccl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bursting"}, // ditto
{"s3kcds", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"},
{"s3kcdl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, // ditto
{"s3kces", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wind tunnel"},
@ -492,6 +644,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

@ -261,6 +261,8 @@ typedef enum
sfx_boingf,
sfx_corkp,
sfx_corkh,
sfx_alart,
sfx_vwre,
sfx_bowl,
sfx_chuchu,
sfx_bsnipe,
@ -356,6 +358,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 +693,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)
{
@ -2072,7 +2047,7 @@ static void ST_drawTextHUD(void)
donef12 = true;
}
}
else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text.
else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) // Death overrides spectator text.
{
INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE;
@ -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

@ -112,7 +112,6 @@ static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NUL
// console variables in development
consvar_t cv_grmd2 = {"gr_md2", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
// local copy of the palette for V_GetColor()
@ -1046,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);
@ -1065,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
@ -1457,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
// ==========================================================================
@ -1480,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)
@ -1515,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)
@ -1522,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
@ -1619,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)
@ -1634,66 +1833,18 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist,
if ((handle = W_OpenWadFile(&filename, false)) == NULL)
return -1;
// 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"))
if (stricmp(&filename[strlen(filename) - 4], ".pk3") == 0)
goodfile = W_VerifyPK3(handle, checklist, status);
else
{
// 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))
// 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
)
{
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

@ -102,7 +102,6 @@ static loadfunc_t hwdFuncTable[] = {
{"FinishUpdate@4", &hwdriver.pfnFinishUpdate},
{"Draw2DLine@12", &hwdriver.pfnDraw2DLine},
{"DrawPolygon@16", &hwdriver.pfnDrawPolygon},
{"RenderSkyDome@16", &hwdriver.pfnRenderDome},
{"SetBlend@4", &hwdriver.pfnSetBlend},
{"ClearBuffer@12", &hwdriver.pfnClearBuffer},
{"SetTexture@4", &hwdriver.pfnSetTexture},
@ -134,7 +133,6 @@ static loadfunc_t hwdFuncTable[] = {
{"FinishUpdate", &hwdriver.pfnFinishUpdate},
{"Draw2DLine", &hwdriver.pfnDraw2DLine},
{"DrawPolygon", &hwdriver.pfnDrawPolygon},
{"RenderSkyDome", &hwdriver.pfnRenderDome},
{"SetBlend", &hwdriver.pfnSetBlend},
{"ClearBuffer", &hwdriver.pfnClearBuffer},
{"SetTexture", &hwdriver.pfnSetTexture},

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);
}
}
}