mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'master' into terrain-lump
This commit is contained in:
commit
0cd3efc76d
48 changed files with 2376 additions and 1052 deletions
|
|
@ -112,3 +112,4 @@ k_botsearch.c
|
|||
k_grandprix.c
|
||||
k_hud.c
|
||||
k_terrain.c
|
||||
k_brightmap.c
|
||||
|
|
|
|||
|
|
@ -795,10 +795,14 @@ static boolean CL_SendJoin(void)
|
|||
sizeof netbuffer->u.clientcfg.application);
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
CleanupPlayerName(g_localplayers[i], cv_playername[i].zstring);
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
// the MAXPLAYERS addition is necessary to communicate that g_localplayers is not yet safe to reference
|
||||
CleanupPlayerName(MAXPLAYERS+i, cv_playername[i].zstring);
|
||||
strncpy(netbuffer->u.clientcfg.names[i], cv_playername[i].zstring, MAXPLAYERNAME);
|
||||
}
|
||||
// privacy shield for the local players not joining this session
|
||||
for (; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
strncpy(netbuffer->u.clientcfg.names[i], va("Player %c", 'A' + i), MAXPLAYERNAME);
|
||||
|
||||
return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak));
|
||||
}
|
||||
|
|
@ -1334,7 +1338,7 @@ static void CL_ReloadReceivedSavegame(void)
|
|||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
LUA_InvalidatePlayer(&players[i]);
|
||||
sprintf(player_names[i], "Player %d", i + 1);
|
||||
sprintf(player_names[i], "Player %c", 'A' + i);
|
||||
}
|
||||
|
||||
CL_LoadReceivedSavegame(true);
|
||||
|
|
@ -2401,7 +2405,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
|
|||
doomcom->numslots--;
|
||||
|
||||
// Reset the name
|
||||
sprintf(player_names[playernum], "Player %d", playernum+1);
|
||||
sprintf(player_names[playernum], "Player %c", 'A' + playernum);
|
||||
|
||||
player_name_changes[playernum] = 0;
|
||||
|
||||
|
|
@ -3213,7 +3217,7 @@ void SV_ResetServer(void)
|
|||
playeringame[i] = false;
|
||||
playernode[i] = UINT8_MAX;
|
||||
memset(playeraddress[i], 0, sizeof(*playeraddress));
|
||||
sprintf(player_names[i], "Player %d", i + 1);
|
||||
sprintf(player_names[i], "Player %c", 'A' + i);
|
||||
adminplayers[i] = -1; // Populate the entire adminplayers array with -1.
|
||||
K_ClearClientPowerLevels();
|
||||
splitscreen_invitations[i] = -1;
|
||||
|
|
@ -3412,7 +3416,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
|
||||
P_ForceLocalAngle(newplayer, newplayer->angleturn);
|
||||
|
||||
D_SendPlayerConfig();
|
||||
D_SendPlayerConfig(splitscreenplayer);
|
||||
addedtogame = true;
|
||||
|
||||
if (rejoined)
|
||||
|
|
@ -3558,14 +3562,13 @@ static void Got_AddBot(UINT8 **p, INT32 playernum)
|
|||
LUAh_PlayerJoin(newplayernum);
|
||||
}
|
||||
|
||||
static boolean SV_AddWaitingPlayers(const char *name, const char *name2, const char *name3, const char *name4)
|
||||
static boolean SV_AddWaitingPlayers(SINT8 node, const char *name, const char *name2, const char *name3, const char *name4)
|
||||
{
|
||||
INT32 node, n, newplayer = false;
|
||||
INT32 n, newplayernum;
|
||||
UINT8 buf[4 + MAXPLAYERNAME];
|
||||
UINT8 *buf_p = buf;
|
||||
INT32 newplayernum;
|
||||
boolean newplayer = false;
|
||||
|
||||
for (node = 0; node < MAXNETNODES; node++)
|
||||
{
|
||||
// splitscreen can allow 2+ players in one node
|
||||
for (; nodewaiting[node] > 0; nodewaiting[node]--)
|
||||
|
|
@ -3684,6 +3687,7 @@ boolean SV_SpawnServer(void)
|
|||
I_Error("What do you think you're doing?");
|
||||
return false;
|
||||
#else
|
||||
boolean result = false;
|
||||
if (demo.playback)
|
||||
G_StopDemo(); // reset engine parameter
|
||||
if (metalplayback)
|
||||
|
|
@ -3710,7 +3714,14 @@ boolean SV_SpawnServer(void)
|
|||
else doomcom->numslots = 1;
|
||||
}
|
||||
|
||||
return SV_AddWaitingPlayers(cv_playername[0].zstring, cv_playername[1].zstring, cv_playername[2].zstring, cv_playername[3].zstring);
|
||||
// strictly speaking, i'm not convinced the following is necessary
|
||||
// but I'm not confident enough to remove it entirely in case it breaks something
|
||||
{
|
||||
SINT8 node = 0;
|
||||
for (; node < MAXNETNODES; node++)
|
||||
result |= SV_AddWaitingPlayers(node, cv_playername[0].zstring, cv_playername[1].zstring, cv_playername[2].zstring, cv_playername[3].zstring);
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -3882,7 +3893,7 @@ static void HandleConnect(SINT8 node)
|
|||
SV_SendSaveGame(node, false); // send a complete game state
|
||||
DEBFILE("send savegame\n");
|
||||
}
|
||||
SV_AddWaitingPlayers(names[0], names[1], names[2], names[3]);
|
||||
SV_AddWaitingPlayers(node, names[0], names[1], names[2], names[3]);
|
||||
joindelay += cv_joindelay.value * TICRATE;
|
||||
player_joining = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1417,6 +1417,9 @@ void D_SRB2Main(void)
|
|||
// setup loading screen
|
||||
SCR_Startup();
|
||||
|
||||
// Do this in background; lots of number crunching
|
||||
R_InitTranslucencyTables();
|
||||
|
||||
CON_SetLoadingProgress(LOADED_ISTARTUPGRAPHICS);
|
||||
|
||||
CONS_Printf("HU_Init()...\n");
|
||||
|
|
|
|||
|
|
@ -222,8 +222,6 @@ static void Command_KartGiveItem_f(void);
|
|||
// CLIENT VARIABLES
|
||||
// =========================================================================
|
||||
|
||||
void SendWeaponPref(UINT8 n);
|
||||
|
||||
static CV_PossibleValue_t usemouse_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Force"}, {0, NULL}};
|
||||
|
||||
#ifdef LJOYSTICK
|
||||
|
|
@ -1116,6 +1114,7 @@ boolean EnsurePlayerNameIsGood(char *name, INT32 playernum)
|
|||
* is restored to what it was before.
|
||||
*
|
||||
* We assume that if playernum is in ::g_localplayers
|
||||
* (unless clientjoin is true, a necessary evil)
|
||||
* the console variable ::cv_playername[n] is
|
||||
* already set to newname. However, the player name table is assumed to
|
||||
* contain the old name.
|
||||
|
|
@ -1134,6 +1133,10 @@ void CleanupPlayerName(INT32 playernum, const char *newname)
|
|||
char *tmpname = NULL;
|
||||
INT32 i;
|
||||
boolean namefailed = true;
|
||||
boolean clientjoin = !!(playernum >= MAXPLAYERS);
|
||||
|
||||
if (clientjoin)
|
||||
playernum -= MAXPLAYERS;
|
||||
|
||||
buf = Z_StrDup(newname);
|
||||
|
||||
|
|
@ -1191,17 +1194,20 @@ void CleanupPlayerName(INT32 playernum, const char *newname)
|
|||
}
|
||||
|
||||
// no stealing another player's name
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (!clientjoin)
|
||||
{
|
||||
if (i != playernum && playeringame[i]
|
||||
&& strcasecmp(tmpname, player_names[i]) == 0)
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
break;
|
||||
if (i != playernum && playeringame[i]
|
||||
&& strcasecmp(tmpname, player_names[i]) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i < MAXPLAYERS)
|
||||
break;
|
||||
if (i < MAXPLAYERS)
|
||||
break;
|
||||
}
|
||||
|
||||
// name is okay then
|
||||
namefailed = false;
|
||||
|
|
@ -1212,18 +1218,23 @@ void CleanupPlayerName(INT32 playernum, const char *newname)
|
|||
|
||||
// set consvars whether namefailed or not, because even if it succeeded,
|
||||
// spaces may have been removed
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
if (clientjoin)
|
||||
CV_StealthSet(&cv_playername[playernum], tmpname);
|
||||
else
|
||||
{
|
||||
if (playernum == g_localplayers[i])
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
CV_StealthSet(&cv_playername[i], tmpname);
|
||||
break;
|
||||
if (playernum == g_localplayers[i])
|
||||
{
|
||||
CV_StealthSet(&cv_playername[i], tmpname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i > splitscreen)
|
||||
{
|
||||
I_Assert(((void)"CleanupPlayerName used on non-local player", 0));
|
||||
if (i > splitscreen)
|
||||
{
|
||||
I_Assert(((void)"CleanupPlayerName used on non-local player", 0));
|
||||
}
|
||||
}
|
||||
|
||||
Z_Free(buf);
|
||||
|
|
@ -1819,33 +1830,28 @@ static void Got_LeaveParty(UINT8 **cp,INT32 playernum)
|
|||
}
|
||||
}
|
||||
|
||||
void D_SendPlayerConfig(void)
|
||||
void D_SendPlayerConfig(UINT8 n)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT8 buf[4];
|
||||
UINT8 *p = buf;
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
SendNameAndColor(n);
|
||||
SendWeaponPref(n);
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
UINT8 buf[4];
|
||||
UINT8 *p = buf;
|
||||
|
||||
SendNameAndColor(i);
|
||||
SendWeaponPref(i);
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
// Send it over
|
||||
WRITEUINT16(p, vspowerlevel[PWRLV_RACE]);
|
||||
WRITEUINT16(p, vspowerlevel[PWRLV_BATTLE]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Splitscreen players have invalid powerlevel
|
||||
WRITEUINT16(p, 0);
|
||||
WRITEUINT16(p, 0);
|
||||
}
|
||||
|
||||
SendNetXCmdForPlayer(i, XD_POWERLEVEL, buf, p-buf);
|
||||
// Send it over
|
||||
WRITEUINT16(p, vspowerlevel[PWRLV_RACE]);
|
||||
WRITEUINT16(p, vspowerlevel[PWRLV_BATTLE]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Splitscreen players have invalid powerlevel
|
||||
WRITEUINT16(p, 0);
|
||||
WRITEUINT16(p, 0);
|
||||
}
|
||||
|
||||
SendNetXCmdForPlayer(n, XD_POWERLEVEL, buf, p-buf);
|
||||
}
|
||||
|
||||
// Only works for displayplayer, sorry!
|
||||
|
|
|
|||
|
|
@ -207,7 +207,8 @@ void D_RegisterServerCommands(void);
|
|||
void D_RegisterClientCommands(void);
|
||||
void CleanupPlayerName(INT32 playernum, const char *newname);
|
||||
boolean EnsurePlayerNameIsGood(char *name, INT32 playernum);
|
||||
void D_SendPlayerConfig(void);
|
||||
void SendWeaponPref(UINT8 n);
|
||||
void D_SendPlayerConfig(UINT8 n);
|
||||
void Command_ExitGame_f(void);
|
||||
void Command_Retry_f(void);
|
||||
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
|
||||
|
|
|
|||
|
|
@ -161,10 +161,16 @@ UINT8 *PutFileNeeded(UINT16 firstfile)
|
|||
char wadfilename[MAX_WADPATH] = "";
|
||||
UINT8 filestatus;
|
||||
|
||||
for (i = mainwads+1; i < numwadfiles; i++) //mainwads+1, otherwise we start on the first mainwad
|
||||
#ifdef DEVELOP
|
||||
i = 0;
|
||||
#else
|
||||
i = mainwads + 1;
|
||||
#endif
|
||||
|
||||
for (; i < numwadfiles; i++) //mainwads+1, otherwise we start on the first mainwad
|
||||
{
|
||||
// If it has only music/sound lumps, don't put it in the list
|
||||
if (!wadfiles[i]->important)
|
||||
if (i > mainwads && !wadfiles[i]->important)
|
||||
continue;
|
||||
|
||||
if (firstfile)
|
||||
|
|
@ -276,11 +282,16 @@ boolean CL_CheckDownloadable(void)
|
|||
}
|
||||
|
||||
// Downloading locally disabled
|
||||
#if 0
|
||||
if (!dlstatus && M_CheckParm("-nodownload"))
|
||||
dlstatus = 3;
|
||||
|
||||
if (!dlstatus)
|
||||
return true;
|
||||
#else
|
||||
if (!dlstatus)
|
||||
dlstatus = 3;
|
||||
#endif
|
||||
|
||||
// not downloadable, put reason in console
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n"));
|
||||
|
|
@ -489,7 +500,12 @@ INT32 CL_CheckFiles(void)
|
|||
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
|
||||
|
||||
// Check in already loaded files
|
||||
for (j = mainwads+1; wadfiles[j]; j++)
|
||||
#ifdef DEVELOP
|
||||
j = 0;
|
||||
#else
|
||||
j = mainwads + 1;
|
||||
#endif
|
||||
for (; wadfiles[j]; j++)
|
||||
{
|
||||
nameonly(strcpy(wadfilename, wadfiles[j]->filename));
|
||||
if (!stricmp(wadfilename, fileneeded[i].filename) &&
|
||||
|
|
|
|||
|
|
@ -3476,6 +3476,21 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
"S_RANDOMITEM12",
|
||||
"S_DEADRANDOMITEM",
|
||||
|
||||
// Sphere Box (for Battle)
|
||||
"S_SPHEREBOX1",
|
||||
"S_SPHEREBOX2",
|
||||
"S_SPHEREBOX3",
|
||||
"S_SPHEREBOX4",
|
||||
"S_SPHEREBOX5",
|
||||
"S_SPHEREBOX6",
|
||||
"S_SPHEREBOX7",
|
||||
"S_SPHEREBOX8",
|
||||
"S_SPHEREBOX9",
|
||||
"S_SPHEREBOX10",
|
||||
"S_SPHEREBOX11",
|
||||
"S_SPHEREBOX12",
|
||||
"S_DEADSPHEREBOX",
|
||||
|
||||
// Random Item Pop
|
||||
"S_RANDOMITEMPOP1",
|
||||
"S_RANDOMITEMPOP2",
|
||||
|
|
|
|||
|
|
@ -2793,6 +2793,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
demoflags = READUINT8(demo_p);
|
||||
gametype = READUINT8(demo_p);
|
||||
G_SetGametype(gametype);
|
||||
|
||||
if (demo.title) // Titledemos should always play and ought to always be compatible with whatever wadlist is running.
|
||||
G_SkipDemoExtraFiles(&demo_p);
|
||||
|
|
|
|||
|
|
@ -346,7 +346,6 @@ static void kickstartaccel_OnChange(void);
|
|||
static void kickstartaccel2_OnChange(void);
|
||||
static void kickstartaccel3_OnChange(void);
|
||||
static void kickstartaccel4_OnChange(void);
|
||||
void SendWeaponPref(UINT8 n);
|
||||
|
||||
static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"},
|
||||
{1, "X-Axis"}, {2, "Y-Axis"}, {-1, "X-Axis-"}, {-2, "Y-Axis-"},
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ typedef struct
|
|||
UINT8 splitscreen;
|
||||
boolean flip; // screenflip
|
||||
boolean shearing; // 14042019
|
||||
angle_t viewaiming; // 17052019
|
||||
float viewaiming; // 17052019
|
||||
boolean roll;
|
||||
FLOAT rollangle; // done to not override USE_FTRANSFORM_ANGLEZ
|
||||
FLOAT centerx, centery;
|
||||
|
|
|
|||
42
src/info.c
42
src/info.c
|
|
@ -526,6 +526,7 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
|
||||
//SRB2kart Sprites (sort later)
|
||||
"RNDM", // Random Item Box
|
||||
"SBOX", // Sphere Box (for Battle)
|
||||
"RPOP", // Random Item Box Pop
|
||||
"SGNS", // Signpost sparkle
|
||||
"FAST", // Speed boost trail
|
||||
|
|
@ -4061,6 +4062,20 @@ state_t states[NUMSTATES] =
|
|||
{SPR_RNDM, 22|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM1}, // S_RANDOMITEM12
|
||||
{SPR_NULL, 0, 0, {A_ItemPop}, 0, 0, S_NULL}, // S_DEADRANDOMITEM
|
||||
|
||||
{SPR_SBOX, FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX2}, // S_SPHEREBOX1
|
||||
{SPR_SBOX, 2|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX3}, // S_SPHEREBOX2
|
||||
{SPR_SBOX, 4|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX4}, // S_SPHEREBOX3
|
||||
{SPR_SBOX, 6|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX5}, // S_SPHEREBOX4
|
||||
{SPR_SBOX, 8|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX6}, // S_SPHEREBOX5
|
||||
{SPR_SBOX, 10|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX7}, // S_SPHEREBOX6
|
||||
{SPR_SBOX, 12|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX8}, // S_SPHEREBOX7
|
||||
{SPR_SBOX, 14|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX9}, // S_SPHEREBOX8
|
||||
{SPR_SBOX, 16|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX10}, // S_SPHEREBOX9
|
||||
{SPR_SBOX, 18|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX11}, // S_SPHEREBOX10
|
||||
{SPR_SBOX, 20|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX12}, // S_SPHEREBOX11
|
||||
{SPR_SBOX, 22|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX1}, // S_SPHEREBOX12
|
||||
{SPR_NULL, 0, 0, {A_ItemPop}, 1, 0, S_NULL}, // S_DEADSPHEREBOX
|
||||
|
||||
{SPR_RPOP, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_RANDOMITEMPOP2}, // S_RANDOMITEMPOP1
|
||||
{SPR_RPOP, FF_FULLBRIGHT|1, 5, {NULL}, 0, 0, S_RANDOMITEMPOP3}, // S_RANDOMITEMPOP2
|
||||
{SPR_RPOP, FF_FULLBRIGHT|2, 5, {NULL}, 0, 0, S_RANDOMITEMPOP4}, // S_RANDOMITEMPOP3
|
||||
|
|
@ -23017,6 +23032,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_SPHEREBOX
|
||||
-1, // doomednum
|
||||
S_SPHEREBOX1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_DEADSPHEREBOX, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_kc2e, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
48*FRACUNIT, // radius
|
||||
48*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
MT_RANDOMITEMPOP, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_RANDOMITEMPOP
|
||||
-1, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
|
|
|
|||
17
src/info.h
17
src/info.h
|
|
@ -1070,6 +1070,7 @@ typedef enum sprite
|
|||
|
||||
// SRB2Kart
|
||||
SPR_RNDM, // Random Item Box
|
||||
SPR_SBOX, // Sphere Box (for Battle)
|
||||
SPR_RPOP, // Random Item Box Pop
|
||||
SPR_SGNS, // Signpost sparkle
|
||||
SPR_FAST, // Speed boost trail
|
||||
|
|
@ -4453,6 +4454,21 @@ typedef enum state
|
|||
S_RANDOMITEM12,
|
||||
S_DEADRANDOMITEM,
|
||||
|
||||
// Sphere Box (for Battle)
|
||||
S_SPHEREBOX1,
|
||||
S_SPHEREBOX2,
|
||||
S_SPHEREBOX3,
|
||||
S_SPHEREBOX4,
|
||||
S_SPHEREBOX5,
|
||||
S_SPHEREBOX6,
|
||||
S_SPHEREBOX7,
|
||||
S_SPHEREBOX8,
|
||||
S_SPHEREBOX9,
|
||||
S_SPHEREBOX10,
|
||||
S_SPHEREBOX11,
|
||||
S_SPHEREBOX12,
|
||||
S_DEADSPHEREBOX,
|
||||
|
||||
// Random Item Pop
|
||||
S_RANDOMITEMPOP1,
|
||||
S_RANDOMITEMPOP2,
|
||||
|
|
@ -6465,6 +6481,7 @@ typedef enum mobj_type
|
|||
|
||||
// SRB2kart
|
||||
MT_RANDOMITEM,
|
||||
MT_SPHEREBOX,
|
||||
MT_RANDOMITEMPOP,
|
||||
MT_FLOATINGITEM,
|
||||
MT_ITEMCAPSULE,
|
||||
|
|
|
|||
|
|
@ -229,6 +229,28 @@ mobj_t *K_SpawnChaosEmerald(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT
|
|||
return emerald;
|
||||
}
|
||||
|
||||
mobj_t *K_SpawnSphereBox(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 amount)
|
||||
{
|
||||
mobj_t *drop = P_SpawnMobj(x, y, z, MT_SPHEREBOX);
|
||||
|
||||
(void)amount;
|
||||
|
||||
drop->angle = angle;
|
||||
P_Thrust(drop,
|
||||
FixedAngle(P_RandomFixed() * 180) + angle,
|
||||
P_RandomRange(4, 12) * mapobjectscale);
|
||||
|
||||
drop->momz = flip * 12 * mapobjectscale;
|
||||
if (drop->eflags & MFE_UNDERWATER)
|
||||
drop->momz = (117 * drop->momz) / 200;
|
||||
|
||||
drop->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
||||
|
||||
drop->extravalue1 = amount;
|
||||
|
||||
return drop;
|
||||
}
|
||||
|
||||
void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType)
|
||||
{
|
||||
UINT8 i;
|
||||
|
|
@ -359,6 +381,12 @@ void K_RunPaperItemSpawners(void)
|
|||
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
|
||||
0, 0
|
||||
);
|
||||
|
||||
K_SpawnSphereBox(
|
||||
battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip),
|
||||
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
|
||||
10
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -441,6 +469,14 @@ void K_RunPaperItemSpawners(void)
|
|||
firstUnspawnedEmerald
|
||||
);
|
||||
}
|
||||
else if (P_RandomChance(FRACUNIT/3))
|
||||
{
|
||||
drop = K_SpawnSphereBox(
|
||||
spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip),
|
||||
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
|
||||
10
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
drop = K_CreatePaperItem(
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount);
|
|||
void K_CheckBumpers(void);
|
||||
void K_CheckEmeralds(player_t *player);
|
||||
mobj_t *K_SpawnChaosEmerald(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT32 emeraldType);
|
||||
mobj_t *K_SpawnSphereBox(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 amount);
|
||||
void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType);
|
||||
UINT8 K_NumEmeralds(player_t *player);
|
||||
void K_RunPaperItemSpawners(void);
|
||||
|
|
|
|||
287
src/k_bot.c
287
src/k_bot.c
|
|
@ -273,16 +273,94 @@ boolean K_PlayerUsesBotMovement(player_t *player)
|
|||
--------------------------------------------------*/
|
||||
boolean K_BotCanTakeCut(player_t *player)
|
||||
{
|
||||
if (!K_ApplyOffroad(player)
|
||||
if (
|
||||
#if 1
|
||||
K_TripwirePass(player) == true
|
||||
#else
|
||||
K_ApplyOffroad(player) == false
|
||||
#endif
|
||||
|| player->itemtype == KITEM_SNEAKER
|
||||
|| player->itemtype == KITEM_ROCKETSNEAKER
|
||||
|| player->itemtype == KITEM_INVINCIBILITY
|
||||
|| player->itemtype == KITEM_HYUDORO)
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static line_t *K_FindBotController(mobj_t *mo)
|
||||
|
||||
Finds if any bot controller linedefs are tagged to the bot's sector.
|
||||
|
||||
Input Arguments:-
|
||||
mo - The bot player's mobj.
|
||||
|
||||
Return:-
|
||||
Linedef of the bot controller. NULL if it doesn't exist.
|
||||
--------------------------------------------------*/
|
||||
static line_t *K_FindBotController(mobj_t *mo)
|
||||
{
|
||||
msecnode_t *node;
|
||||
ffloor_t *rover;
|
||||
INT16 lineNum = -1;
|
||||
mtag_t tag;
|
||||
|
||||
I_Assert(mo != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mo));
|
||||
|
||||
for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (!node->m_sector)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tag = Tag_FGet(&node->m_sector->tags);
|
||||
lineNum = P_FindSpecialLineFromTag(2004, tag, -1); // todo: needs to not use P_FindSpecialLineFromTag
|
||||
|
||||
if (lineNum != -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
sector_t *rs = NULL;
|
||||
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mo->z > *rover->topheight || mo->z + mo->height < *rover->bottomheight)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
rs = §ors[rover->secnum];
|
||||
tag = Tag_FGet(&rs->tags);
|
||||
lineNum = P_FindSpecialLineFromTag(2004, tag, -1);
|
||||
|
||||
if (lineNum != -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lineNum != -1)
|
||||
{
|
||||
return &lines[lineNum];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static UINT32 K_BotRubberbandDistance(player_t *player)
|
||||
|
||||
|
|
@ -346,6 +424,7 @@ fixed_t K_BotRubberband(player_t *player)
|
|||
fixed_t rubberband = FRACUNIT;
|
||||
fixed_t max, min;
|
||||
player_t *firstplace = NULL;
|
||||
line_t *botController = NULL;
|
||||
UINT8 i;
|
||||
|
||||
if (player->exiting)
|
||||
|
|
@ -354,6 +433,17 @@ fixed_t K_BotRubberband(player_t *player)
|
|||
return FRACUNIT;
|
||||
}
|
||||
|
||||
botController = K_FindBotController(player->mo);
|
||||
|
||||
if (botController != NULL)
|
||||
{
|
||||
// No Climb Flag: Disable rubberbanding
|
||||
if (botController->flags & ML_NOCLIMB)
|
||||
{
|
||||
return FRACUNIT;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
|
|
@ -430,8 +520,8 @@ fixed_t K_BotTopSpeedRubberband(player_t *player)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Max at +10% for level 9 bots
|
||||
rubberband = FRACUNIT + ((rubberband - FRACUNIT) / 10);
|
||||
// Max at +20% for level 9 bots
|
||||
rubberband = FRACUNIT + ((rubberband - FRACUNIT) / 5);
|
||||
}
|
||||
|
||||
// Only allow you to go faster than your regular top speed if you're facing the right direction
|
||||
|
|
@ -488,6 +578,14 @@ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict)
|
|||
return frict;
|
||||
}
|
||||
|
||||
if (player->tiregrease > 0)
|
||||
{
|
||||
// This isn't great -- it means rubberbanding will slow down when they hit a spring
|
||||
// But it's better than the opposite where they accelerate into hyperspace :V
|
||||
// (would appreciate an actual fix though ... could try being additive instead of multiplicative)
|
||||
return frict;
|
||||
}
|
||||
|
||||
origFrict = FixedDiv(ORIG_FRICTION, FRACUNIT + (rubberband / 2));
|
||||
|
||||
if (frict == ORIG_FRICTION)
|
||||
|
|
@ -567,14 +665,11 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
const INT16 handling = K_GetKartTurnValue(player, KART_FULLTURN); // Reduce prediction based on how fast you can turn
|
||||
const INT16 normal = KART_FULLTURN; // "Standard" handling to compare to
|
||||
|
||||
const fixed_t distreduce = K_BotReducePrediction(player);
|
||||
const fixed_t radreduce = min(distreduce + FRACUNIT/4, FRACUNIT);
|
||||
|
||||
const tic_t futuresight = (TICRATE * normal) / max(1, handling); // How far ahead into the future to try and predict
|
||||
const fixed_t speed = max(P_AproxDistance(player->mo->momx, player->mo->momy), K_GetKartSpeed(player, false) / 4);
|
||||
const fixed_t speed = P_AproxDistance(player->mo->momx, player->mo->momy);
|
||||
|
||||
const INT32 startDist = (768 * mapobjectscale) / FRACUNIT;
|
||||
const INT32 distance = ((FixedMul(speed, distreduce) / FRACUNIT) * futuresight) + startDist;
|
||||
const INT32 distance = ((speed / FRACUNIT) * futuresight) + startDist;
|
||||
|
||||
botprediction_t *predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL);
|
||||
waypoint_t *wp = player->nextwaypoint;
|
||||
|
|
@ -583,6 +678,9 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
fixed_t smallestradius = INT32_MAX;
|
||||
angle_t angletonext = ANGLE_MAX;
|
||||
|
||||
// Halves radius when encountering a wall on your way to your destination.
|
||||
fixed_t radreduce = FRACUNIT;
|
||||
|
||||
size_t nwp;
|
||||
size_t i;
|
||||
|
||||
|
|
@ -595,7 +693,7 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
{
|
||||
predict->x = wp->mobj->x;
|
||||
predict->y = wp->mobj->y;
|
||||
predict->radius = FixedMul(wp->mobj->radius, radreduce);
|
||||
predict->radius = wp->mobj->radius;
|
||||
return predict;
|
||||
}
|
||||
|
||||
|
|
@ -635,12 +733,12 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
|
||||
for (i = 0; i < wp->numnextwaypoints; i++)
|
||||
{
|
||||
if (!K_GetWaypointIsEnabled(wp->nextwaypoints[i]))
|
||||
if (K_GetWaypointIsEnabled(wp->nextwaypoints[i]) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (K_GetWaypointIsShortcut(wp->nextwaypoints[i]) && !K_BotCanTakeCut(player))
|
||||
if (K_GetWaypointIsShortcut(wp->nextwaypoints[i]) == true && K_BotCanTakeCut(player) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -673,6 +771,13 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
|
||||
disttonext = (INT32)wp->nextwaypointdistances[nwp];
|
||||
|
||||
if (P_TraceBotTraversal(player->mo, wp->nextwaypoints[nwp]->mobj) == false)
|
||||
{
|
||||
// If we can't get a direct path to this waypoint, we don't want to check much further...
|
||||
disttonext *= 2;
|
||||
radreduce = FRACUNIT/2;
|
||||
}
|
||||
|
||||
if (disttonext > distanceleft)
|
||||
{
|
||||
break;
|
||||
|
|
@ -761,7 +866,7 @@ static UINT8 K_TrySpindash(player_t *player)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (speedDiff < (3 * baseAccel / 4))
|
||||
if (speedDiff < (baseAccel / 4))
|
||||
{
|
||||
if (player->botvars.spindashconfirm < BOTSPINDASHCONFIRM)
|
||||
{
|
||||
|
|
@ -797,70 +902,6 @@ static UINT8 K_TrySpindash(player_t *player)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static INT16 K_FindBotController(mobj_t *mo)
|
||||
|
||||
Finds if any bot controller linedefs are tagged to the bot's sector.
|
||||
|
||||
Input Arguments:-
|
||||
mo - The bot player's mobj.
|
||||
|
||||
Return:-
|
||||
Line number of the bot controller. -1 if it doesn't exist.
|
||||
--------------------------------------------------*/
|
||||
static INT16 K_FindBotController(mobj_t *mo)
|
||||
{
|
||||
msecnode_t *node;
|
||||
ffloor_t *rover;
|
||||
INT16 lineNum = -1;
|
||||
mtag_t tag;
|
||||
|
||||
I_Assert(mo != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mo));
|
||||
|
||||
for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (!node->m_sector)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tag = Tag_FGet(&node->m_sector->tags);
|
||||
lineNum = P_FindSpecialLineFromTag(2004, tag, -1); // todo: needs to not use P_FindSpecialLineFromTag
|
||||
|
||||
if (lineNum != -1)
|
||||
{
|
||||
return lineNum;
|
||||
}
|
||||
|
||||
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
sector_t *rs = NULL;
|
||||
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mo->z > *rover->topheight || mo->z + mo->height < *rover->bottomheight)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
rs = §ors[rover->secnum];
|
||||
tag = Tag_FGet(&rs->tags);
|
||||
lineNum = P_FindSpecialLineFromTag(2004, tag, -1);
|
||||
|
||||
if (lineNum != -1)
|
||||
{
|
||||
return lineNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
|
||||
|
||||
|
|
@ -925,6 +966,50 @@ static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_BotTrick(player_t *player, ticcmd_t *cmd, line_t *botController)
|
||||
|
||||
Determines inputs for trick panels.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to generate the ticcmd for.
|
||||
cmd - The player's ticcmd to modify.
|
||||
botController - Linedef for the bot controller.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
static void K_BotTrick(player_t *player, ticcmd_t *cmd, line_t *botController)
|
||||
{
|
||||
// Trick panel state -- do nothing until a controller line is found, in which case do a trick.
|
||||
if (botController == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->trickpanel == 1)
|
||||
{
|
||||
INT32 type = (sides[botController->sidenum[0]].rowoffset / FRACUNIT);
|
||||
|
||||
// Y Offset: Trick type
|
||||
switch (type)
|
||||
{
|
||||
case 1:
|
||||
cmd->turning = KART_FULLTURN;
|
||||
break;
|
||||
case 2:
|
||||
cmd->turning = -KART_FULLTURN;
|
||||
break;
|
||||
case 3:
|
||||
cmd->buttons |= BT_FORWARD;
|
||||
break;
|
||||
case 4:
|
||||
cmd->buttons |= BT_BACKWARD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||
|
||||
|
|
@ -936,7 +1021,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
boolean trySpindash = true;
|
||||
UINT8 spindash = 0;
|
||||
INT32 turnamt = 0;
|
||||
INT16 botController = -1;
|
||||
line_t *botController = NULL;
|
||||
|
||||
// Can't build a ticcmd if we aren't spawned...
|
||||
if (!player->mo)
|
||||
|
|
@ -959,7 +1044,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
}
|
||||
|
||||
// Complete override of all ticcmd functionality
|
||||
if (LUAh_BotTiccmd(player, cmd))
|
||||
if (LUAh_BotTiccmd(player, cmd) == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -968,30 +1053,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
if (player->trickpanel != 0)
|
||||
{
|
||||
// Trick panel state -- do nothing until a controller line is found, in which case do a trick.
|
||||
|
||||
if (player->trickpanel == 1 && botController != -1)
|
||||
{
|
||||
line_t *controllerLine = &lines[botController];
|
||||
INT32 type = (sides[controllerLine->sidenum[0]].rowoffset / FRACUNIT);
|
||||
|
||||
// Y Offset: Trick type
|
||||
switch (type)
|
||||
{
|
||||
case 1:
|
||||
cmd->turning = KART_FULLTURN;
|
||||
break;
|
||||
case 2:
|
||||
cmd->turning = -KART_FULLTURN;
|
||||
break;
|
||||
case 3:
|
||||
cmd->buttons |= BT_FORWARD;
|
||||
break;
|
||||
case 4:
|
||||
cmd->buttons |= BT_BACKWARD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
K_BotTrick(player, cmd, botController);
|
||||
|
||||
// Don't do anything else.
|
||||
return;
|
||||
|
|
@ -1000,20 +1062,19 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
if ((player->nextwaypoint != NULL
|
||||
&& player->nextwaypoint->mobj != NULL
|
||||
&& !P_MobjWasRemoved(player->nextwaypoint->mobj))
|
||||
|| (botController != -1))
|
||||
|| (botController != NULL))
|
||||
{
|
||||
// Handle steering towards waypoints!
|
||||
SINT8 turnsign = 0;
|
||||
angle_t destangle, moveangle, angle;
|
||||
INT16 anglediff;
|
||||
|
||||
if (botController != -1)
|
||||
if (botController != NULL && (botController->flags & ML_EFFECT1))
|
||||
{
|
||||
const fixed_t dist = (player->mo->radius * 4);
|
||||
line_t *controllerLine = &lines[botController];
|
||||
|
||||
// X Offset: Movement direction
|
||||
destangle = FixedAngle(sides[controllerLine->sidenum[0]].textureoffset);
|
||||
destangle = FixedAngle(sides[botController->sidenum[0]].textureoffset);
|
||||
|
||||
// Overwritten prediction
|
||||
predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL);
|
||||
|
|
@ -1112,18 +1173,6 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
// Don't turn at all
|
||||
turnamt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make minor adjustments
|
||||
turnamt /= 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (anglediff > 60)
|
||||
{
|
||||
// Actually, don't go too fast...
|
||||
cmd->forwardmove /= 2;
|
||||
cmd->buttons |= BT_BRAKE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
src/k_bot.h
20
src/k_bot.h
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "k_waypoint.h"
|
||||
#include "d_player.h"
|
||||
#include "r_defs.h"
|
||||
|
||||
// Maximum value of botvars.difficulty
|
||||
#define MAXBOTDIFFICULTY 9
|
||||
|
|
@ -185,19 +186,22 @@ UINT8 K_EggboxStealth(fixed_t x, fixed_t y);
|
|||
|
||||
|
||||
/*--------------------------------------------------
|
||||
fixed_t K_BotReducePrediction(player_t *player);
|
||||
boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y)
|
||||
|
||||
Finds walls nearby the specified player, to create a multiplier
|
||||
to pull bot predictions back by.
|
||||
Tells us if a bot will play more careful around
|
||||
this sector. Checks FOFs in the sector, as well.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to compare.
|
||||
player - Player to check against.
|
||||
sec - Sector to check against.
|
||||
x - Linedef cross X position, for slopes
|
||||
y - Linedef cross Y position, for slopes
|
||||
|
||||
Return:-
|
||||
Multiplier in fixed point scale.
|
||||
true if avoiding this sector, false otherwise.
|
||||
--------------------------------------------------*/
|
||||
|
||||
fixed_t K_BotReducePrediction(player_t *player);
|
||||
boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
@ -219,8 +223,8 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
/*--------------------------------------------------
|
||||
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd);
|
||||
|
||||
Gives a multiplier for a bot's rubberbanding. Meant to be used for top speed,
|
||||
acceleration, and handling.
|
||||
Creates a bot's ticcmd, looking at its surroundings to
|
||||
try and figure out what it should do.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to generate the ticcmd for.
|
||||
|
|
|
|||
265
src/k_botitem.c
265
src/k_botitem.c
|
|
@ -86,7 +86,7 @@ static boolean K_BotUseItemNearPlayer(player_t *player, ticcmd_t *cmd, fixed_t r
|
|||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static boolean K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t radius)
|
||||
static player_t *K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t radius)
|
||||
|
||||
Looks for players around a specified x/y coordinate.
|
||||
|
||||
|
|
@ -97,9 +97,9 @@ static boolean K_BotUseItemNearPlayer(player_t *player, ticcmd_t *cmd, fixed_t r
|
|||
radius - The radius to look for players in.
|
||||
|
||||
Return:-
|
||||
true if a player was found around the coordinate, otherwise false.
|
||||
The player we found, NULL if nothing was found.
|
||||
--------------------------------------------------*/
|
||||
static boolean K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t radius)
|
||||
static player_t *K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t radius)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
|
|
@ -129,15 +129,15 @@ static boolean K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t
|
|||
|
||||
if (dist <= radius)
|
||||
{
|
||||
return true;
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static boolean K_PlayerPredictThrow(player_t *player, UINT8 extra)
|
||||
static player_t *K_PlayerPredictThrow(player_t *player, UINT8 extra)
|
||||
|
||||
Looks for players around the predicted coordinates of their thrown item.
|
||||
|
||||
|
|
@ -146,9 +146,9 @@ static boolean K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t
|
|||
extra - Extra throwing distance, for aim forward on mines.
|
||||
|
||||
Return:-
|
||||
true if a player was found around the coordinate, otherwise false.
|
||||
The player we're trying to throw at, NULL if none was found.
|
||||
--------------------------------------------------*/
|
||||
static boolean K_PlayerPredictThrow(player_t *player, UINT8 extra)
|
||||
static player_t *K_PlayerPredictThrow(player_t *player, UINT8 extra)
|
||||
{
|
||||
const fixed_t dist = (30 + (extra * 10)) * player->mo->scale;
|
||||
const UINT32 airtime = FixedDiv(dist + player->mo->momz, gravity);
|
||||
|
|
@ -159,7 +159,7 @@ static boolean K_PlayerPredictThrow(player_t *player, UINT8 extra)
|
|||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static boolean K_PlayerInCone(player_t *player, UINT16 cone, boolean flip)
|
||||
static player_t *K_PlayerInCone(player_t *player, UINT16 cone, boolean flip)
|
||||
|
||||
Looks for players in the .
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ static boolean K_PlayerPredictThrow(player_t *player, UINT8 extra)
|
|||
Return:-
|
||||
true if a player was found in the cone, otherwise false.
|
||||
--------------------------------------------------*/
|
||||
static boolean K_PlayerInCone(player_t *player, fixed_t radius, UINT16 cone, boolean flip)
|
||||
static player_t *K_PlayerInCone(player_t *player, fixed_t radius, UINT16 cone, boolean flip)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
|
|
@ -222,22 +222,96 @@ static boolean K_PlayerInCone(player_t *player, fixed_t radius, UINT16 cone, boo
|
|||
{
|
||||
if (ad >= 180-cone)
|
||||
{
|
||||
return true;
|
||||
return target;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ad <= cone)
|
||||
{
|
||||
return true;
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static boolean K_RivalBotAggression(player_t *bot, player_t *target)
|
||||
|
||||
Returns if a bot is a rival & wants to be aggressive to a player.
|
||||
|
||||
Input Arguments:-
|
||||
bot - Bot to check.
|
||||
target - Who the bot wants to attack.
|
||||
|
||||
Return:-
|
||||
false if not the rival. false if the target is another bot. Otherwise, true.
|
||||
--------------------------------------------------*/
|
||||
static boolean K_RivalBotAggression(player_t *bot, player_t *target)
|
||||
{
|
||||
if (bot == NULL || target == NULL)
|
||||
{
|
||||
// Invalid.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bot->bot == false)
|
||||
{
|
||||
// lol
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bot->botvars.rival == false)
|
||||
{
|
||||
// Not the rival, we aren't self-aware.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target->bot == false)
|
||||
{
|
||||
// This bot knows that the real threat is the player.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calling them your friends is misleading, but you'll at least spare them.
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_ItemConfirmForTarget(player_t *bot, player_t *target, UINT16 amount)
|
||||
|
||||
Handles updating item confirm values for offense items.
|
||||
|
||||
Input Arguments:-
|
||||
bot - Bot to check.
|
||||
target - Who the bot wants to attack.
|
||||
amount - Amount to increase item confirm time by.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
static void K_ItemConfirmForTarget(player_t *bot, player_t *target, UINT16 amount)
|
||||
{
|
||||
if (bot == NULL || target == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (K_RivalBotAggression(bot, target) == true)
|
||||
{
|
||||
// Double the rate when you're aggressive.
|
||||
bot->botvars.itemconfirm += amount << 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do as normal.
|
||||
bot->botvars.itemconfirm += amount;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static boolean K_BotGenericPressItem(player_t *player, ticcmd_t *cmd, SINT8 dir)
|
||||
|
||||
|
|
@ -316,21 +390,21 @@ static boolean K_BotRevealsGenericTrap(player_t *player, INT16 turnamt, boolean
|
|||
}
|
||||
|
||||
// Check the predicted throws.
|
||||
if (K_PlayerPredictThrow(player, 0))
|
||||
if (K_PlayerPredictThrow(player, 0) != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mine)
|
||||
{
|
||||
if (K_PlayerPredictThrow(player, 1))
|
||||
if (K_PlayerPredictThrow(player, 1) != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check your behind.
|
||||
if (K_PlayerInCone(player, player->mo->radius * 16, 10, true))
|
||||
if (K_PlayerInCone(player, player->mo->radius * 16, 10, true) != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -447,7 +521,6 @@ static void K_BotItemRocketSneaker(player_t *player, ticcmd_t *cmd)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||
|
||||
|
|
@ -464,9 +537,17 @@ static void K_BotItemRocketSneaker(player_t *player, ticcmd_t *cmd)
|
|||
static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||
{
|
||||
SINT8 throwdir = -1;
|
||||
player_t *target = NULL;
|
||||
|
||||
player->botvars.itemconfirm++;
|
||||
|
||||
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
|
||||
if (target != NULL)
|
||||
{
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||
throwdir = -1;
|
||||
}
|
||||
|
||||
if (abs(turnamt) >= KART_FULLTURN/2)
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty / 2;
|
||||
|
|
@ -474,19 +555,15 @@ static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (K_PlayerPredictThrow(player, 0))
|
||||
target = K_PlayerPredictThrow(player, 0);
|
||||
|
||||
if (target != NULL)
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty * 2;
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty * 2);
|
||||
throwdir = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (K_PlayerInCone(player, player->mo->radius * 16, 10, true))
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty;
|
||||
throwdir = -1;
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE)
|
||||
{
|
||||
K_BotGenericPressItem(player, cmd, throwdir);
|
||||
|
|
@ -509,12 +586,14 @@ static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
|||
static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||
{
|
||||
SINT8 throwdir = 0;
|
||||
player_t *target = NULL;
|
||||
|
||||
player->botvars.itemconfirm++;
|
||||
|
||||
if (K_PlayerInCone(player, player->mo->radius * 16, 10, true))
|
||||
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
|
||||
if (target != NULL)
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty;
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||
throwdir = -1;
|
||||
}
|
||||
|
||||
|
|
@ -525,27 +604,63 @@ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (K_PlayerPredictThrow(player, 0))
|
||||
target = K_PlayerPredictThrow(player, 0);
|
||||
if (target != NULL)
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty * 2;
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty * 2);
|
||||
throwdir = 0;
|
||||
}
|
||||
|
||||
if (K_PlayerPredictThrow(player, 1))
|
||||
target = K_PlayerPredictThrow(player, 1);
|
||||
if (target != NULL)
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty * 2;
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty * 2);
|
||||
throwdir = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE)
|
||||
{
|
||||
K_BotGenericPressItem(player, cmd, throwdir);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||
|
||||
Item usage for landmine tossing.
|
||||
|
||||
Input Arguments:-
|
||||
player - Bot to do this for.
|
||||
cmd - Bot's ticcmd to edit.
|
||||
turnamt - How hard they currently are turning.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||
{
|
||||
player_t *target = NULL;
|
||||
|
||||
player->botvars.itemconfirm++;
|
||||
|
||||
if (abs(turnamt) >= KART_FULLTURN/2)
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty / 2;
|
||||
}
|
||||
|
||||
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
|
||||
if (target != NULL)
|
||||
{
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 2*TICRATE)
|
||||
{
|
||||
K_BotGenericPressItem(player, cmd, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_BotItemEggman(player_t *player, ticcmd_t *cmd)
|
||||
|
||||
|
|
@ -562,18 +677,21 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd)
|
|||
{
|
||||
const UINT8 stealth = K_EggboxStealth(player->mo->x, player->mo->y);
|
||||
SINT8 throwdir = -1;
|
||||
player_t *target = NULL;
|
||||
|
||||
player->botvars.itemconfirm++;
|
||||
|
||||
if (K_PlayerPredictThrow(player, 0))
|
||||
target = K_PlayerPredictThrow(player, 0);
|
||||
if (target != NULL)
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty / 2;
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty / 2);
|
||||
throwdir = 1;
|
||||
}
|
||||
|
||||
if (K_PlayerInCone(player, player->mo->radius * 16, 10, true))
|
||||
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
|
||||
if (target != NULL)
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty;
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||
throwdir = -1;
|
||||
}
|
||||
|
||||
|
|
@ -603,6 +721,7 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd)
|
|||
static boolean K_BotRevealsEggbox(player_t *player)
|
||||
{
|
||||
const UINT8 stealth = K_EggboxStealth(player->mo->x, player->mo->y);
|
||||
player_t *target = NULL;
|
||||
|
||||
// This is a stealthy spot for an eggbox, lets reveal it!
|
||||
if (stealth > 1)
|
||||
|
|
@ -611,13 +730,15 @@ static boolean K_BotRevealsEggbox(player_t *player)
|
|||
}
|
||||
|
||||
// Check the predicted throws.
|
||||
if (K_PlayerPredictThrow(player, 0))
|
||||
target = K_PlayerPredictThrow(player, 0);
|
||||
if (target != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check your behind.
|
||||
if (K_PlayerInCone(player, player->mo->radius * 16, 10, true))
|
||||
target = K_PlayerInCone(player, player->mo->radius * 16, 10, true);
|
||||
if (target != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -644,7 +765,7 @@ static void K_BotItemEggmanShield(player_t *player, ticcmd_t *cmd)
|
|||
return;
|
||||
}
|
||||
|
||||
if (K_BotRevealsEggbox(player) || (player->botvars.itemconfirm++ > 20*TICRATE))
|
||||
if (K_BotRevealsEggbox(player) == true || (player->botvars.itemconfirm++ > 20*TICRATE))
|
||||
{
|
||||
K_BotGenericPressItem(player, cmd, 0);
|
||||
}
|
||||
|
|
@ -666,8 +787,9 @@ static void K_BotItemEggmanExplosion(player_t *player, ticcmd_t *cmd)
|
|||
{
|
||||
if (player->position == 1)
|
||||
{
|
||||
// Hey, we aren't gonna find anyone up here...
|
||||
// why don't we slow down a bit? :)
|
||||
cmd->forwardmove /= 2;
|
||||
cmd->buttons |= BT_BRAKE;
|
||||
}
|
||||
|
||||
K_BotUseItemNearPlayer(player, cmd, 128*player->mo->scale);
|
||||
|
|
@ -690,23 +812,32 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd)
|
|||
const fixed_t topspeed = K_GetKartSpeed(player, false);
|
||||
fixed_t radius = (player->mo->radius * 32);
|
||||
SINT8 throwdir = -1;
|
||||
UINT8 snipeMul = 2;
|
||||
player_t *target = NULL;
|
||||
|
||||
if (player->speed > topspeed)
|
||||
{
|
||||
radius = FixedMul(radius, FixedDiv(player->speed, topspeed));
|
||||
snipeMul = 3; // Confirm faster when you'll throw it with a bunch of extra speed!!
|
||||
}
|
||||
|
||||
player->botvars.itemconfirm++;
|
||||
|
||||
if (K_PlayerInCone(player, radius, 10, false))
|
||||
target = K_PlayerInCone(player, radius, 10, false);
|
||||
if (target != NULL)
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty * 2;
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty * snipeMul);
|
||||
throwdir = 1;
|
||||
}
|
||||
else if (K_PlayerInCone(player, radius, 10, true))
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty;
|
||||
throwdir = -1;
|
||||
target = K_PlayerInCone(player, radius, 10, true);
|
||||
|
||||
if (target != NULL)
|
||||
{
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||
throwdir = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 5*TICRATE)
|
||||
|
|
@ -732,24 +863,54 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd)
|
|||
const fixed_t topspeed = K_GetKartSpeed(player, false);
|
||||
fixed_t radius = (player->mo->radius * 32);
|
||||
SINT8 throwdir = 1;
|
||||
UINT8 snipeMul = 2;
|
||||
INT32 lastTarg = player->lastjawztarget;
|
||||
player_t *target = NULL;
|
||||
|
||||
if (player->speed > topspeed)
|
||||
{
|
||||
radius = FixedMul(radius, FixedDiv(player->speed, topspeed));
|
||||
snipeMul = 3; // Confirm faster when you'll throw it with a bunch of extra speed!!
|
||||
}
|
||||
|
||||
player->botvars.itemconfirm++;
|
||||
|
||||
if (K_PlayerInCone(player, radius, 10, true))
|
||||
target = K_PlayerInCone(player, radius, 10, true);
|
||||
if (target != NULL)
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty;
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
|
||||
throwdir = -1;
|
||||
}
|
||||
|
||||
if (player->lastjawztarget != -1)
|
||||
if (lastTarg != -1
|
||||
&& playeringame[lastTarg] == true
|
||||
&& players[lastTarg].spectator == false
|
||||
&& players[lastTarg].mo != NULL
|
||||
&& P_MobjWasRemoved(players[lastTarg].mo) == false)
|
||||
{
|
||||
player->botvars.itemconfirm += player->botvars.difficulty * 2;
|
||||
throwdir = 1;
|
||||
mobj_t *targMo = players[lastTarg].mo;
|
||||
mobj_t *mobj = NULL, *next = NULL;
|
||||
boolean targettedAlready = false;
|
||||
|
||||
target = &players[lastTarg];
|
||||
|
||||
// Make sure no other Jawz are targetting this player.
|
||||
for (mobj = kitemcap; mobj; mobj = next)
|
||||
{
|
||||
next = mobj->itnext;
|
||||
|
||||
if (mobj->type == MT_JAWZ && mobj->target == targMo)
|
||||
{
|
||||
targettedAlready = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (targettedAlready == false)
|
||||
{
|
||||
K_ItemConfirmForTarget(player, target, player->botvars.difficulty * snipeMul);
|
||||
throwdir = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (player->botvars.itemconfirm > 5*TICRATE)
|
||||
|
|
@ -772,7 +933,7 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd)
|
|||
--------------------------------------------------*/
|
||||
static void K_BotItemThunder(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
if (!K_BotUseItemNearPlayer(player, cmd, 192*player->mo->scale))
|
||||
if (K_BotUseItemNearPlayer(player, cmd, 192*player->mo->scale) == false)
|
||||
{
|
||||
if (player->botvars.itemconfirm > 10*TICRATE)
|
||||
{
|
||||
|
|
@ -1036,7 +1197,6 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
|||
K_BotItemSneaker(player, cmd);
|
||||
break;
|
||||
case KITEM_BANANA:
|
||||
case KITEM_LANDMINE:
|
||||
if (!(player->pflags & PF_ITEMOUT))
|
||||
{
|
||||
K_BotItemGenericTrapShield(player, cmd, turnamt, false);
|
||||
|
|
@ -1081,6 +1241,9 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
|||
K_BotItemMine(player, cmd, turnamt);
|
||||
}
|
||||
break;
|
||||
case KITEM_LANDMINE:
|
||||
K_BotItemLandmine(player, cmd, turnamt);
|
||||
break;
|
||||
case KITEM_THUNDERSHIELD:
|
||||
K_BotItemThunder(player, cmd);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ UINT8 K_EggboxStealth(fixed_t x, fixed_t y)
|
|||
}
|
||||
}
|
||||
|
||||
return (globalsmuggle.randomitems * globalsmuggle.eggboxes);
|
||||
return (globalsmuggle.randomitems * (globalsmuggle.eggboxes + 1));
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
@ -162,21 +162,11 @@ static boolean K_BotHatesThisSectorsSpecial(player_t *player, sector_t *sec)
|
|||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y)
|
||||
boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y)
|
||||
|
||||
Tells us if a bot will play more careful around
|
||||
this sector. Checks FOFs in the sector, as well.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to check against.
|
||||
sec - Sector to check against.
|
||||
x - Linedef cross X position, for slopes
|
||||
y - Linedef cross Y position, for slopes
|
||||
|
||||
Return:-
|
||||
true if avoiding this sector, false otherwise.
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
static boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y)
|
||||
boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y)
|
||||
{
|
||||
const boolean flip = (player->mo->eflags & MFE_VERTICALFLIP);
|
||||
INT32 specialflag = 0;
|
||||
|
|
@ -257,171 +247,6 @@ static boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x,
|
|||
return K_BotHatesThisSectorsSpecial(player, bestsector);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static boolean K_FindBlockingWalls(line_t *line)
|
||||
|
||||
Blockmap search function.
|
||||
Reels the bot prediction back in based on solid walls
|
||||
or other obstacles surrounding the bot.
|
||||
|
||||
Input Arguments:-
|
||||
line - Linedef passed in from iteration.
|
||||
|
||||
Return:-
|
||||
true continues searching, false ends the search early.
|
||||
--------------------------------------------------*/
|
||||
static boolean K_FindBlockingWalls(line_t *line)
|
||||
{
|
||||
// Condensed version of PIT_CheckLine
|
||||
const fixed_t maxstepmove = FixedMul(MAXSTEPMOVE, mapobjectscale);
|
||||
fixed_t maxstep = maxstepmove;
|
||||
fixed_t linedist = INT32_MAX;
|
||||
INT32 lineside = 0;
|
||||
vertex_t pos;
|
||||
|
||||
if (!globalsmuggle.botmo || P_MobjWasRemoved(globalsmuggle.botmo) || !globalsmuggle.botmo->player)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (line->polyobj && !(line->polyobj->flags & POF_SOLID))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tmbbox[BOXRIGHT] <= line->bbox[BOXLEFT] || tmbbox[BOXLEFT] >= line->bbox[BOXRIGHT]
|
||||
|| tmbbox[BOXTOP] <= line->bbox[BOXBOTTOM] || tmbbox[BOXBOTTOM] >= line->bbox[BOXTOP])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (P_BoxOnLineSide(tmbbox, line) != -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
lineside = P_PointOnLineSide(globalsmuggle.botmo->x, globalsmuggle.botmo->y, line);
|
||||
|
||||
// one sided line
|
||||
if (!line->backsector)
|
||||
{
|
||||
if (lineside)
|
||||
{
|
||||
// don't hit the back side
|
||||
return true;
|
||||
}
|
||||
|
||||
goto blocked;
|
||||
}
|
||||
|
||||
if ((line->flags & ML_IMPASSABLE) || (line->flags & ML_BLOCKPLAYERS))
|
||||
{
|
||||
goto blocked;
|
||||
}
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
P_LineOpening(line, globalsmuggle.botmo);
|
||||
|
||||
if (globalsmuggle.botmo->player->waterskip)
|
||||
maxstep += maxstepmove;
|
||||
|
||||
if (P_MobjTouchingSectorSpecial(globalsmuggle.botmo, 1, 13, false))
|
||||
maxstep <<= 1;
|
||||
else if (P_MobjTouchingSectorSpecial(globalsmuggle.botmo, 1, 12, false))
|
||||
maxstep = 0;
|
||||
|
||||
if ((openrange < globalsmuggle.botmo->height) // doesn't fit
|
||||
|| (opentop - globalsmuggle.botmo->z < globalsmuggle.botmo->height) // mobj is too high
|
||||
|| (openbottom - globalsmuggle.botmo->z > maxstep)) // too big a step up
|
||||
{
|
||||
goto blocked;
|
||||
}
|
||||
|
||||
// Treat damage sectors like walls
|
||||
P_ClosestPointOnLine(globalsmuggle.botmo->x, globalsmuggle.botmo->y, line, &pos);
|
||||
|
||||
if (lineside)
|
||||
{
|
||||
if (K_BotHatesThisSector(globalsmuggle.botmo->player, line->frontsector, pos.x, pos.y))
|
||||
goto blocked;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (K_BotHatesThisSector(globalsmuggle.botmo->player, line->backsector, pos.x, pos.y))
|
||||
goto blocked;
|
||||
}
|
||||
|
||||
// We weren't blocked!
|
||||
return true;
|
||||
|
||||
blocked:
|
||||
linedist = K_DistanceOfLineFromPoint(line->v1->x, line->v1->y, line->v2->x, line->v2->y, globalsmuggle.botmo->x, globalsmuggle.botmo->y);
|
||||
linedist -= (globalsmuggle.botmo->radius * 8); // Maintain a reasonable distance away from it
|
||||
|
||||
if (linedist > globalsmuggle.distancetocheck)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (linedist <= 0)
|
||||
{
|
||||
globalsmuggle.closestlinedist = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (linedist < globalsmuggle.closestlinedist)
|
||||
{
|
||||
globalsmuggle.closestlinedist = linedist;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
fixed_t K_BotReducePrediction(player_t *player)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
fixed_t K_BotReducePrediction(player_t *player)
|
||||
{
|
||||
INT32 xl, xh, yl, yh, bx, by;
|
||||
|
||||
globalsmuggle.botmo = player->mo;
|
||||
globalsmuggle.distancetocheck = (player->mo->radius * 32);
|
||||
globalsmuggle.closestlinedist = INT32_MAX;
|
||||
|
||||
tmx = player->mo->x;
|
||||
tmy = player->mo->y;
|
||||
|
||||
xl = (unsigned)(tmx - globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(tmx + globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(tmy - globalsmuggle.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(tmy + globalsmuggle.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
|
||||
BMBOUNDFIX(xl, xh, yl, yh);
|
||||
|
||||
tmbbox[BOXTOP] = tmy + globalsmuggle.distancetocheck;
|
||||
tmbbox[BOXBOTTOM] = tmy - globalsmuggle.distancetocheck;
|
||||
tmbbox[BOXRIGHT] = tmx + globalsmuggle.distancetocheck;
|
||||
tmbbox[BOXLEFT] = tmx - globalsmuggle.distancetocheck;
|
||||
|
||||
// Check for lines that the bot might collide with
|
||||
for (bx = xl; bx <= xh; bx++)
|
||||
{
|
||||
for (by = yl; by <= yh; by++)
|
||||
{
|
||||
P_BlockLinesIterator(bx, by, K_FindBlockingWalls);
|
||||
}
|
||||
}
|
||||
|
||||
if (globalsmuggle.closestlinedist == INT32_MAX)
|
||||
{
|
||||
return FRACUNIT;
|
||||
}
|
||||
|
||||
return (FRACUNIT/2) + (FixedDiv(globalsmuggle.closestlinedist, globalsmuggle.distancetocheck) / 2);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_AddAttackObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
||||
|
||||
|
|
|
|||
256
src/k_brightmap.c
Normal file
256
src/k_brightmap.c
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2021 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2021 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_brightmap.c
|
||||
/// \brief Brightmap texture loading.
|
||||
|
||||
#include "k_brightmap.h"
|
||||
|
||||
#include "doomdata.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomtype.h"
|
||||
#include "fastcmp.h"
|
||||
#include "r_textures.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
static brightmapStorage_t *brightmapStorage = NULL;
|
||||
static size_t maxBrightmapStorage = 0;
|
||||
|
||||
/*--------------------------------------------------
|
||||
static brightmapStorage_t *K_NewBrightmap(void)
|
||||
|
||||
Increases the size of maxBrightmapStorage by 1.
|
||||
|
||||
Input Arguments:-
|
||||
None
|
||||
|
||||
Return:-
|
||||
The new brightmap storage struct.
|
||||
--------------------------------------------------*/
|
||||
static brightmapStorage_t *K_NewBrightmap(void)
|
||||
{
|
||||
maxBrightmapStorage++;
|
||||
brightmapStorage = (brightmapStorage_t *)Z_Realloc(brightmapStorage, sizeof(brightmapStorage_t) * (maxBrightmapStorage + 1), PU_STATIC, NULL);
|
||||
return &brightmapStorage[ maxBrightmapStorage - 1 ];
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static brightmapStorage_t *K_GetBrightmapStorageByIndex(size_t checkIndex)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
static brightmapStorage_t *K_GetBrightmapStorageByIndex(size_t checkIndex)
|
||||
{
|
||||
if (checkIndex >= maxBrightmapStorage)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &brightmapStorage[checkIndex];
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkName)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkName)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (maxBrightmapStorage == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < maxBrightmapStorage; i++)
|
||||
{
|
||||
brightmapStorage_t *bms = &brightmapStorage[i];
|
||||
|
||||
if (stricmp(checkName, bms->textureName) == 0)
|
||||
{
|
||||
// Name matches.
|
||||
return bms;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size)
|
||||
|
||||
Parses inputted lump data as a BRIGHT lump.
|
||||
|
||||
Input Arguments:-
|
||||
data - Pointer to lump data.
|
||||
size - The length of the lump data.
|
||||
|
||||
Return:-
|
||||
false if any errors occured, otherwise true.
|
||||
--------------------------------------------------*/
|
||||
static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size)
|
||||
{
|
||||
char *tkn = M_GetToken((char *)data);
|
||||
size_t pos = 0;
|
||||
|
||||
while (tkn && (pos = M_GetTokenPos()) < size)
|
||||
{
|
||||
boolean valid = true;
|
||||
|
||||
if (stricmp(tkn, "texture") == 0)
|
||||
{
|
||||
Z_Free(tkn);
|
||||
tkn = M_GetToken(NULL);
|
||||
pos = M_GetTokenPos();
|
||||
|
||||
if (tkn && pos < size)
|
||||
{
|
||||
brightmapStorage_t *bms = K_GetBrightmapStorageByTextureName(tkn);
|
||||
|
||||
if (bms == NULL)
|
||||
{
|
||||
bms = K_NewBrightmap();
|
||||
strncpy(bms->textureName, tkn, 9);
|
||||
}
|
||||
|
||||
Z_Free(tkn);
|
||||
tkn = M_GetToken(NULL);
|
||||
pos = M_GetTokenPos();
|
||||
|
||||
if (tkn && pos < size)
|
||||
{
|
||||
strncpy(bms->brightmapName, tkn, 9);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "No brightmap for brightmap definition.\n");
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "No texture for brightmap definition.\n");
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
// todo: SPRITE brightmaps?!
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Unknown keyword '%s' found in BRIGHT lump.\n", tkn);
|
||||
valid = false;
|
||||
}
|
||||
|
||||
Z_Free(tkn);
|
||||
|
||||
if (valid == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
tkn = M_GetToken(NULL);
|
||||
}
|
||||
|
||||
Z_Free(tkn);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_InitBrightmaps(void)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void K_InitBrightmaps(void)
|
||||
{
|
||||
INT32 wadNum;
|
||||
size_t i;
|
||||
|
||||
I_Assert(brightmapStorage == NULL);
|
||||
maxBrightmapStorage = 0;
|
||||
|
||||
for (wadNum = 0; wadNum < numwadfiles; wadNum++)
|
||||
{
|
||||
UINT16 lumpNum;
|
||||
|
||||
// Find BRIGHT lump in the WAD
|
||||
lumpNum = W_CheckNumForNamePwad("BRIGHT", wadNum, 0);
|
||||
|
||||
while (lumpNum != INT16_MAX)
|
||||
{
|
||||
UINT8 *data;
|
||||
data = (UINT8 *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC);
|
||||
|
||||
// If that didn't exist, we have nothing to do here.
|
||||
if (data == NULL)
|
||||
{
|
||||
lumpNum = W_CheckNumForNamePwad("BRIGHT", (UINT16)wadNum, lumpNum + 1);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
lumpinfo_t *lump_p = &wadfiles[wadNum]->lumpinfo[lumpNum];
|
||||
size_t size = W_LumpLengthPwad(wadNum, lumpNum);
|
||||
|
||||
size_t nameLength = strlen(wadfiles[wadNum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
|
||||
char *name = malloc(nameLength + 1);
|
||||
|
||||
sprintf(name, "%s|%s", wadfiles[wadNum]->filename, lump_p->fullname);
|
||||
name[nameLength] = '\0';
|
||||
|
||||
size = W_LumpLengthPwad(wadNum, lumpNum);
|
||||
|
||||
CONS_Printf(M_GetText("Loading BRIGHT from %s\n"), name);
|
||||
K_BRIGHTLumpParser(data, size);
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
lumpNum = W_CheckNumForNamePwad("BRIGHT", (UINT16)wadNum, lumpNum + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (maxBrightmapStorage == 0)
|
||||
{
|
||||
// No brightmaps were defined.
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < maxBrightmapStorage; i++)
|
||||
{
|
||||
brightmapStorage_t *bms = K_GetBrightmapStorageByIndex(i);
|
||||
INT32 texNum, bmNum;
|
||||
|
||||
if (bms == NULL)
|
||||
{
|
||||
// Shouldn't happen.
|
||||
break;
|
||||
}
|
||||
|
||||
texNum = R_CheckTextureNumForName(bms->textureName);
|
||||
if (texNum != -1)
|
||||
{
|
||||
bmNum = R_CheckTextureNumForName(bms->brightmapName);
|
||||
if (bmNum == -1)
|
||||
{
|
||||
texturebrightmaps[texNum] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
texturebrightmaps[texNum] = bmNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R_ClearTextureNumCache(false);
|
||||
|
||||
// Clear brightmapStorage now that we're done with it.
|
||||
Z_Free(brightmapStorage);
|
||||
brightmapStorage = NULL;
|
||||
}
|
||||
38
src/k_brightmap.h
Normal file
38
src/k_brightmap.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2021 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2021 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_brightmap.h
|
||||
/// \brief Brightmap texture loading.
|
||||
|
||||
#ifndef __K_BRIGHTMAP_H__
|
||||
#define __K_BRIGHTMAP_H__
|
||||
|
||||
#include "doomdata.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomtype.h"
|
||||
|
||||
typedef struct brightmapStorage_s
|
||||
{
|
||||
// Brightmap storage struct.
|
||||
// Stores data for brightmap definitions,
|
||||
// before putting them into texturebrightmaps.
|
||||
|
||||
char textureName[9]; // The texture's name.
|
||||
char brightmapName[9]; // The brightmap's name.
|
||||
} brightmapStorage_t;
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_InitBrightmaps(void);
|
||||
|
||||
Finds all BRIGHT lumps and processes them.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_InitBrightmaps(void);
|
||||
|
||||
#endif // __K_BRIGHTMAP_H__
|
||||
|
|
@ -2694,7 +2694,7 @@ boolean K_ApplyOffroad(player_t *player)
|
|||
|
||||
boolean K_SlopeResistance(player_t *player)
|
||||
{
|
||||
if (player->invincibilitytimer || player->sneakertimer || player->tiregrease)
|
||||
if (player->invincibilitytimer || player->sneakertimer || player->tiregrease || player->flamedash)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -8646,8 +8646,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
boolean HOLDING_ITEM = (player->pflags & (PF_ITEMOUT|PF_EGGMANOUT));
|
||||
boolean NO_HYUDORO = (player->stealingtimer == 0);
|
||||
|
||||
player->pflags &= ~PF_HITFINISHLINE;
|
||||
|
||||
if (!player->exiting)
|
||||
{
|
||||
if (player->oldposition < player->position) // But first, if you lost a place,
|
||||
|
|
|
|||
|
|
@ -13254,6 +13254,8 @@ void A_ChangeHeight(mobj_t *actor)
|
|||
|
||||
void A_ItemPop(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
|
||||
mobj_t *remains;
|
||||
mobjtype_t explode;
|
||||
|
||||
|
|
@ -13308,7 +13310,9 @@ void A_ItemPop(mobj_t *actor)
|
|||
if (actor->info->deathsound)
|
||||
S_StartSound(remains, actor->info->deathsound);
|
||||
|
||||
if (!((gametyperules & GTR_BUMPERS) && actor->target->player->bumpers <= 0))
|
||||
if (locvar1 == 1)
|
||||
P_GivePlayerSpheres(actor->target->player, actor->extravalue1);
|
||||
else if (locvar1 == 0)
|
||||
actor->target->player->itemroulette = 1;
|
||||
|
||||
remains->flags2 &= ~MF2_AMBUSH;
|
||||
|
|
@ -14143,7 +14147,6 @@ void A_LandMineExplode(mobj_t *actor)
|
|||
INT32 colour = SKINCOLOR_KETCHUP; // we spell words properly here
|
||||
INT32 i;
|
||||
mobj_t *smoldering;
|
||||
mobj_t *dust;
|
||||
|
||||
if (LUA_CallAction(A_LANDMINEEXPLODE, actor))
|
||||
return;
|
||||
|
|
@ -14161,18 +14164,6 @@ void A_LandMineExplode(mobj_t *actor)
|
|||
P_SetScale(smoldering, actor->scale);
|
||||
smoldering->tics = TICRATE*3;
|
||||
|
||||
// Spawn a ring:
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
dust = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMOKE);
|
||||
P_SetMobjState(dust, S_OPAQUESMOKE1);
|
||||
dust->angle = (ANGLE_180/16) * i;
|
||||
P_SetScale(dust, actor->scale);
|
||||
dust->destscale = actor->scale*4;
|
||||
dust->scalespeed = actor->scale/4;
|
||||
P_InstaThrust(dust, dust->angle, FixedMul(20*FRACUNIT, actor->scale));
|
||||
}
|
||||
|
||||
actor->fuse = actor->tics; // disappear when this state ends.
|
||||
|
||||
// spawn a few physics explosions
|
||||
|
|
|
|||
|
|
@ -268,12 +268,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (!P_CanPickupItem(player, 1))
|
||||
return;
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
special->momx = special->momy = special->momz = 0;
|
||||
P_SetTarget(&special->target, toucher);
|
||||
P_KillMobj(special, toucher, toucher, DMG_NORMAL);
|
||||
break;
|
||||
case MT_SPHEREBOX:
|
||||
if (player->bumpers <= 0)
|
||||
return;
|
||||
|
||||
P_SetTarget(&special->target, toucher);
|
||||
P_KillMobj(special, toucher, toucher, DMG_NORMAL);
|
||||
break;
|
||||
|
|
@ -510,16 +512,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (!(P_CanPickupItem(player, 0)))
|
||||
return;
|
||||
|
||||
// Reached the cap, don't waste 'em!
|
||||
if (player->spheres >= 40)
|
||||
return;
|
||||
|
||||
// Not alive
|
||||
if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= 0))
|
||||
return;
|
||||
|
||||
special->momx = special->momy = special->momz = 0;
|
||||
player->spheres++;
|
||||
P_GivePlayerSpheres(player, 1);
|
||||
break;
|
||||
|
||||
// Secret emblem thingy
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ void P_RestoreMusic(player_t *player);
|
|||
boolean P_EndingMusic(player_t *player);
|
||||
mobj_t *P_SpawnGhostMobj(mobj_t *mobj);
|
||||
INT32 P_GivePlayerRings(player_t *player, INT32 num_rings);
|
||||
void P_GivePlayerSpheres(player_t *player, INT32 num_spheres);
|
||||
INT32 P_GivePlayerSpheres(player_t *player, INT32 num_spheres);
|
||||
void P_GivePlayerLives(player_t *player, INT32 numlives);
|
||||
UINT8 P_GetNextEmerald(void);
|
||||
void P_GiveEmerald(boolean spawnObj);
|
||||
|
|
@ -405,6 +405,8 @@ boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing);
|
|||
boolean P_IsLineTripWire(const line_t *ld);
|
||||
boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y);
|
||||
boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam);
|
||||
fixed_t P_BaseStepUp(void);
|
||||
fixed_t P_GetThingStepUp(mobj_t *thing);
|
||||
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);
|
||||
boolean P_Move(mobj_t *actor, fixed_t speed);
|
||||
boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
|
||||
|
|
@ -414,6 +416,7 @@ void P_BouncePlayerMove(mobj_t *mo);
|
|||
void P_BounceMove(mobj_t *mo);
|
||||
boolean P_CheckSight(mobj_t *t1, mobj_t *t2);
|
||||
boolean P_TraceBlockingLines(mobj_t *t1, mobj_t *t2);
|
||||
boolean P_TraceBotTraversal(mobj_t *t1, mobj_t *t2);
|
||||
void P_CheckHoopPosition(mobj_t *hoopthing, fixed_t x, fixed_t y, fixed_t z, fixed_t radius);
|
||||
|
||||
boolean P_CheckSector(sector_t *sector, boolean crunch);
|
||||
|
|
|
|||
56
src/p_map.c
56
src/p_map.c
|
|
@ -2456,6 +2456,42 @@ static boolean P_WaterStepUp(mobj_t *thing)
|
|||
P_WaterRunning(thing);
|
||||
}
|
||||
|
||||
fixed_t P_BaseStepUp(void)
|
||||
{
|
||||
return FixedMul(MAXSTEPMOVE, mapobjectscale);
|
||||
}
|
||||
|
||||
fixed_t P_GetThingStepUp(mobj_t *thing)
|
||||
{
|
||||
const fixed_t maxstepmove = P_BaseStepUp();
|
||||
fixed_t maxstep = maxstepmove;
|
||||
|
||||
if (thing->type == MT_SKIM)
|
||||
{
|
||||
// Skim special (not needed for kart?)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (P_WaterStepUp(thing) == true)
|
||||
{
|
||||
// Add some extra stepmove when waterskipping
|
||||
maxstep += maxstepmove;
|
||||
}
|
||||
|
||||
if (P_MobjTouchingSectorSpecial(thing, 1, 13, false))
|
||||
{
|
||||
// If using type Section1:13, double the maxstep.
|
||||
maxstep <<= 1;
|
||||
}
|
||||
else if (P_MobjTouchingSectorSpecial(thing, 1, 12, false))
|
||||
{
|
||||
// If using type Section1:12, no maxstep. For short walls, like Egg Zeppelin
|
||||
maxstep = 0;
|
||||
}
|
||||
|
||||
return maxstep;
|
||||
}
|
||||
|
||||
//
|
||||
// P_TryMove
|
||||
// Attempt to move to a new position.
|
||||
|
|
@ -2517,21 +2553,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
if (!(thing->flags & MF_NOCLIP))
|
||||
{
|
||||
//All things are affected by their scale.
|
||||
const fixed_t maxstepmove = FixedMul(MAXSTEPMOVE, mapobjectscale);
|
||||
fixed_t maxstep = maxstepmove;
|
||||
|
||||
if (thing->player && P_WaterStepUp(thing))
|
||||
maxstep += maxstepmove; // Add some extra stepmove when waterskipping
|
||||
|
||||
// If using type Section1:13, double the maxstep.
|
||||
if (P_MobjTouchingSectorSpecial(thing, 1, 13, false))
|
||||
maxstep <<= 1;
|
||||
// If using type Section1:12, no maxstep. For short walls, like Egg Zeppelin
|
||||
else if (P_MobjTouchingSectorSpecial(thing, 1, 12, false))
|
||||
maxstep = 0;
|
||||
|
||||
if (thing->type == MT_SKIM)
|
||||
maxstep = 0;
|
||||
fixed_t maxstep = P_GetThingStepUp(thing);
|
||||
|
||||
if (tmceilingz - tmfloorz < thing->height)
|
||||
{
|
||||
|
|
@ -2786,7 +2808,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
|
||||
if (!(thing->flags & MF_NOCLIP))
|
||||
{
|
||||
const fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale);
|
||||
const fixed_t maxstep = P_BaseStepUp();
|
||||
|
||||
if (tmceilingz - tmfloorz < thing->height)
|
||||
return false; // doesn't fit
|
||||
|
|
@ -3248,7 +3270,7 @@ static boolean PTR_LineIsBlocking(line_t *li)
|
|||
if (opentop - slidemo->z < slidemo->height)
|
||||
return true; // mobj is too high
|
||||
|
||||
if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, mapobjectscale))
|
||||
if (openbottom - slidemo->z > P_GetThingStepUp(slidemo))
|
||||
return true; // too big a step up
|
||||
|
||||
return false;
|
||||
|
|
|
|||
121
src/p_mobj.c
121
src/p_mobj.c
|
|
@ -3112,9 +3112,13 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
}
|
||||
|
||||
// The rest of this code only executes on a water state change.
|
||||
if (waterwasnotset || !!(mobj->eflags & MFE_UNDERWATER) == wasinwater)
|
||||
{
|
||||
if (!!(mobj->eflags & MFE_UNDERWATER) == wasinwater)
|
||||
return;
|
||||
|
||||
if (p && !p->waterskip &&
|
||||
p->curshield != KSHIELD_BUBBLE && wasinwater)
|
||||
{
|
||||
S_StartSound(mobj, sfx_s3k38);
|
||||
}
|
||||
|
||||
if ((p) // Players
|
||||
|
|
@ -3146,6 +3150,62 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
diff = -diff;
|
||||
}
|
||||
|
||||
// Time to spawn the bubbles!
|
||||
{
|
||||
INT32 i;
|
||||
INT32 bubblecount;
|
||||
UINT8 prandom[4];
|
||||
mobj_t *bubble;
|
||||
mobjtype_t bubbletype;
|
||||
|
||||
if (mobj->eflags & MFE_GOOWATER || wasingoo)
|
||||
S_StartSound(mobj, sfx_ghit);
|
||||
else if (mobj->eflags & MFE_TOUCHLAVA)
|
||||
S_StartSound(mobj, sfx_splash);
|
||||
else
|
||||
S_StartSound(mobj, sfx_splish); // And make a sound!
|
||||
|
||||
bubblecount = FixedDiv(abs(mobj->momz), mobj->scale)>>(FRACBITS-1);
|
||||
// Max bubble count
|
||||
if (bubblecount > 128)
|
||||
bubblecount = 128;
|
||||
|
||||
// Create tons of bubbles
|
||||
for (i = 0; i < bubblecount; i++)
|
||||
{
|
||||
// P_RandomByte()s are called individually to allow consistency
|
||||
// across various compilers, since the order of function calls
|
||||
// in C is not part of the ANSI specification.
|
||||
prandom[0] = P_RandomByte();
|
||||
prandom[1] = P_RandomByte();
|
||||
prandom[2] = P_RandomByte();
|
||||
prandom[3] = P_RandomByte();
|
||||
|
||||
bubbletype = MT_SMALLBUBBLE;
|
||||
if (!(prandom[0] & 0x3)) // medium bubble chance up to 64 from 32
|
||||
bubbletype = MT_MEDIUMBUBBLE;
|
||||
|
||||
bubble = P_SpawnMobj(
|
||||
mobj->x + FixedMul((prandom[1]<<(FRACBITS-3)) * (prandom[0]&0x80 ? 1 : -1), mobj->scale),
|
||||
mobj->y + FixedMul((prandom[2]<<(FRACBITS-3)) * (prandom[0]&0x40 ? 1 : -1), mobj->scale),
|
||||
mobj->z + FixedMul((prandom[3]<<(FRACBITS-2)), mobj->scale), bubbletype);
|
||||
|
||||
if (bubble)
|
||||
{
|
||||
if (P_MobjFlip(mobj)*mobj->momz < 0)
|
||||
bubble->momz = mobj->momz >> 4;
|
||||
else
|
||||
bubble->momz = 0;
|
||||
|
||||
bubble->destscale = mobj->scale;
|
||||
P_SetScale(bubble, mobj->scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (waterwasnotset)
|
||||
return;
|
||||
|
||||
// Check to make sure you didn't just cross into a sector to jump out of
|
||||
// that has shallower water than the block you were originally in.
|
||||
if (diff <= (height >> 1))
|
||||
|
|
@ -3247,59 +3307,6 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
P_SetScale(splish, mobj->scale);
|
||||
}
|
||||
}
|
||||
|
||||
// Time to spawn the bubbles!
|
||||
{
|
||||
INT32 i;
|
||||
INT32 bubblecount;
|
||||
UINT8 prandom[4];
|
||||
mobj_t *bubble;
|
||||
mobjtype_t bubbletype;
|
||||
|
||||
if (mobj->eflags & MFE_GOOWATER || wasingoo)
|
||||
S_StartSound(mobj, sfx_ghit);
|
||||
else if (mobj->eflags & MFE_TOUCHLAVA)
|
||||
S_StartSound(mobj, sfx_splash);
|
||||
else
|
||||
S_StartSound(mobj, sfx_splish); // And make a sound!
|
||||
|
||||
bubblecount = FixedDiv(abs(mobj->momz), mobj->scale) >> (FRACBITS-1);
|
||||
// Max bubble count
|
||||
if (bubblecount > 128)
|
||||
bubblecount = 128;
|
||||
|
||||
// Create tons of bubbles
|
||||
for (i = 0; i < bubblecount; i++)
|
||||
{
|
||||
// P_RandomByte()s are called individually to allow consistency
|
||||
// across various compilers, since the order of function calls
|
||||
// in C is not part of the ANSI specification.
|
||||
prandom[0] = P_RandomByte();
|
||||
prandom[1] = P_RandomByte();
|
||||
prandom[2] = P_RandomByte();
|
||||
prandom[3] = P_RandomByte();
|
||||
|
||||
bubbletype = MT_SMALLBUBBLE;
|
||||
if (!(prandom[0] & 0x3)) // medium bubble chance up to 64 from 32
|
||||
bubbletype = MT_MEDIUMBUBBLE;
|
||||
|
||||
bubble = P_SpawnMobj(
|
||||
mobj->x + FixedMul((prandom[1]<<(FRACBITS-3)) * (prandom[0]&0x80 ? 1 : -1), mobj->scale),
|
||||
mobj->y + FixedMul((prandom[2]<<(FRACBITS-3)) * (prandom[0]&0x40 ? 1 : -1), mobj->scale),
|
||||
mobj->z + FixedMul((prandom[3]<<(FRACBITS-2)), mobj->scale), bubbletype);
|
||||
|
||||
if (bubble)
|
||||
{
|
||||
if (P_MobjFlip(mobj)*mobj->momz < 0)
|
||||
bubble->momz = mobj->momz >> 4;
|
||||
else
|
||||
bubble->momz = 0;
|
||||
|
||||
bubble->destscale = mobj->scale;
|
||||
P_SetScale(bubble, mobj->scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4191,7 +4198,7 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest)
|
|||
|
||||
player = &players[actor->lastlook];
|
||||
|
||||
if (player->bot || player->spectator)
|
||||
if (player->spectator)
|
||||
continue; // ignore notarget
|
||||
|
||||
if (!player->mo || P_MobjWasRemoved(player->mo))
|
||||
|
|
@ -8693,6 +8700,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
}
|
||||
break;
|
||||
case MT_RANDOMITEM:
|
||||
case MT_SPHEREBOX:
|
||||
if (gametype == GT_BATTLE && mobj->threshold == 70)
|
||||
{
|
||||
mobj->color = K_RainbowColor(leveltime);
|
||||
|
|
@ -9473,6 +9481,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
|
|||
thing->shadowscale = 12*FRACUNIT/5;
|
||||
break;
|
||||
case MT_RANDOMITEM:
|
||||
case MT_SPHEREBOX:
|
||||
thing->shadowscale = FRACUNIT/2;
|
||||
thing->whiteshadow = false;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@
|
|||
#include "k_bot.h"
|
||||
#include "k_grandprix.h"
|
||||
#include "k_terrain.h" // TRF_TRIPWIRE
|
||||
#include "k_brightmap.h"
|
||||
|
||||
// Replay names have time
|
||||
#if !defined (UNDER_CE)
|
||||
|
|
@ -4455,6 +4456,9 @@ boolean P_AddWadFile(const char *wadfilename)
|
|||
// Reload ANIMDEFS
|
||||
P_InitPicAnims();
|
||||
|
||||
// Reload BRIGHT
|
||||
K_InitBrightmaps();
|
||||
|
||||
// Flush and reload HUD graphics
|
||||
ST_UnloadGraphics();
|
||||
HU_LoadGraphics();
|
||||
|
|
|
|||
194
src/p_sight.c
194
src/p_sight.c
|
|
@ -18,6 +18,9 @@
|
|||
#include "r_main.h"
|
||||
#include "r_state.h"
|
||||
|
||||
#include "k_bot.h" // K_BotHatesThisSector
|
||||
#include "k_kart.h" // K_TripwirePass
|
||||
|
||||
//
|
||||
// P_CheckSight
|
||||
//
|
||||
|
|
@ -572,7 +575,7 @@ static boolean P_CrossBlockingSubsector(size_t num, register traceblocking_t *tb
|
|||
|
||||
if (P_IsLineBlocking(line, tb->compareThing) == true)
|
||||
{
|
||||
// This line will block us
|
||||
// This line will always block us
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -656,3 +659,192 @@ boolean P_TraceBlockingLines(mobj_t *t1, mobj_t *t2)
|
|||
// the head node is the last node output
|
||||
return P_CrossBSPNodeBlocking((INT32)numnodes - 1, &tb);
|
||||
}
|
||||
|
||||
//
|
||||
// ANOTHER version, this time for bot traversal.
|
||||
// (TODO: since we have so many versions of this function, the differences
|
||||
// should maybe just be a function var that gets called?)
|
||||
//
|
||||
|
||||
static boolean P_CrossBotTraversalSubsector(size_t num, register traceblocking_t *tb)
|
||||
{
|
||||
seg_t *seg;
|
||||
INT32 count;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (num >= numsubsectors)
|
||||
I_Error("P_CrossBotTraversalSubsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
|
||||
#endif
|
||||
|
||||
// haleyjd 02/23/06: this assignment should be after the above check
|
||||
seg = segs + subsectors[num].firstline;
|
||||
|
||||
for (count = subsectors[num].numlines; --count >= 0; seg++) // check lines
|
||||
{
|
||||
line_t *line = seg->linedef;
|
||||
divline_t divl;
|
||||
const vertex_t *v1,*v2;
|
||||
fixed_t maxstep = INT32_MAX;
|
||||
|
||||
if (seg->glseg)
|
||||
continue;
|
||||
|
||||
// already checked other side?
|
||||
if (line->validcount == validcount)
|
||||
continue;
|
||||
|
||||
line->validcount = validcount;
|
||||
|
||||
// OPTIMIZE: killough 4/20/98: Added quick bounding-box rejection test
|
||||
if (line->bbox[BOXLEFT ] > tb->bbox[BOXRIGHT ] ||
|
||||
line->bbox[BOXRIGHT ] < tb->bbox[BOXLEFT ] ||
|
||||
line->bbox[BOXBOTTOM] > tb->bbox[BOXTOP ] ||
|
||||
line->bbox[BOXTOP] < tb->bbox[BOXBOTTOM])
|
||||
continue;
|
||||
|
||||
v1 = line->v1;
|
||||
v2 = line->v2;
|
||||
|
||||
// line isn't crossed?
|
||||
if (P_DivlineSide(v1->x, v1->y, &tb->strace) ==
|
||||
P_DivlineSide(v2->x, v2->y, &tb->strace))
|
||||
continue;
|
||||
|
||||
// stop because it is not two sided anyway
|
||||
if (!(line->flags & ML_TWOSIDED))
|
||||
return false;
|
||||
|
||||
divl.dx = v2->x - (divl.x = v1->x);
|
||||
divl.dy = v2->y - (divl.y = v1->y);
|
||||
|
||||
// line isn't crossed?
|
||||
if (P_DivlineSide(tb->strace.x, tb->strace.y, &divl) ==
|
||||
P_DivlineSide(tb->t2x, tb->t2y, &divl))
|
||||
continue;
|
||||
|
||||
if (P_IsLineBlocking(line, tb->compareThing) == true)
|
||||
{
|
||||
// This line will always block us
|
||||
return false;
|
||||
}
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
P_LineOpening(line, tb->compareThing);
|
||||
maxstep = P_GetThingStepUp(tb->compareThing);
|
||||
|
||||
if ((openrange < tb->compareThing->height) // doesn't fit
|
||||
|| (opentop - tb->compareThing->z < tb->compareThing->height) // mobj is too high
|
||||
|| (openbottom - tb->compareThing->z > maxstep)) // too big a step up
|
||||
{
|
||||
// This line situationally blocks us
|
||||
return false;
|
||||
}
|
||||
|
||||
// Treat damage sectors like walls
|
||||
if (tb->compareThing->player != NULL)
|
||||
{
|
||||
boolean alreadyHates = K_BotHatesThisSector(tb->compareThing->player, tb->compareThing->subsector->sector, tb->compareThing->x, tb->compareThing->y);
|
||||
|
||||
if (alreadyHates == false)
|
||||
{
|
||||
INT32 lineside = 0;
|
||||
vertex_t pos;
|
||||
|
||||
P_ClosestPointOnLine(tb->compareThing->x, tb->compareThing->y, line, &pos);
|
||||
lineside = P_PointOnLineSide(tb->compareThing->x, tb->compareThing->y, line);
|
||||
|
||||
if (K_BotHatesThisSector(tb->compareThing->player, ((lineside == 1) ? line->frontsector : line->backsector), pos.x, pos.y))
|
||||
{
|
||||
// This line does not block us, but we don't want to be in it.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (P_IsLineTripWire(line) == true && K_TripwirePass(tb->compareThing->player) == false)
|
||||
{
|
||||
// Can't go through trip wire.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// passed the subsector ok
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean P_CrossBSPNodeBotTraversal(INT32 bspnum, register traceblocking_t *tb)
|
||||
{
|
||||
while (!(bspnum & NF_SUBSECTOR))
|
||||
{
|
||||
register node_t *bsp = nodes + bspnum;
|
||||
INT32 side = P_DivlineSide(tb->strace.x,tb->strace.y,(divline_t *)bsp)&1;
|
||||
if (side == P_DivlineSide(tb->t2x, tb->t2y, (divline_t *) bsp))
|
||||
bspnum = bsp->children[side]; // doesn't touch the other side
|
||||
else // the partition plane is crossed here
|
||||
{
|
||||
if (!P_CrossBSPNodeBotTraversal(bsp->children[side], tb))
|
||||
return false; // cross the starting side
|
||||
else
|
||||
bspnum = bsp->children[side^1]; // cross the ending side
|
||||
}
|
||||
}
|
||||
|
||||
return P_CrossBotTraversalSubsector((bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR), tb);
|
||||
}
|
||||
|
||||
boolean P_TraceBotTraversal(mobj_t *t1, mobj_t *t2)
|
||||
{
|
||||
const sector_t *s1, *s2;
|
||||
size_t pnum;
|
||||
traceblocking_t tb;
|
||||
|
||||
// First check for trivial rejection.
|
||||
if (!t1 || !t2)
|
||||
return false;
|
||||
|
||||
I_Assert(!P_MobjWasRemoved(t1));
|
||||
I_Assert(!P_MobjWasRemoved(t2));
|
||||
|
||||
if (!t1->subsector || !t2->subsector
|
||||
|| !t1->subsector->sector || !t2->subsector->sector)
|
||||
return false;
|
||||
|
||||
s1 = t1->subsector->sector;
|
||||
s2 = t2->subsector->sector;
|
||||
pnum = (s1-sectors)*numsectors + (s2-sectors);
|
||||
|
||||
if (rejectmatrix != NULL)
|
||||
{
|
||||
// Check in REJECT table.
|
||||
if (rejectmatrix[pnum>>3] & (1 << (pnum&7))) // can't possibly be connected
|
||||
return false;
|
||||
}
|
||||
|
||||
// killough 11/98: shortcut for melee situations
|
||||
// same subsector? obviously visible
|
||||
// haleyjd 02/23/06: can't do this if there are polyobjects in the subsec
|
||||
if (!t1->subsector->polyList &&
|
||||
t1->subsector == t2->subsector)
|
||||
return true;
|
||||
|
||||
validcount++;
|
||||
|
||||
tb.strace.dx = (tb.t2x = t2->x) - (tb.strace.x = t1->x);
|
||||
tb.strace.dy = (tb.t2y = t2->y) - (tb.strace.y = t1->y);
|
||||
|
||||
if (t1->x > t2->x)
|
||||
tb.bbox[BOXRIGHT] = t1->x, tb.bbox[BOXLEFT] = t2->x;
|
||||
else
|
||||
tb.bbox[BOXRIGHT] = t2->x, tb.bbox[BOXLEFT] = t1->x;
|
||||
|
||||
if (t1->y > t2->y)
|
||||
tb.bbox[BOXTOP] = t1->y, tb.bbox[BOXBOTTOM] = t2->y;
|
||||
else
|
||||
tb.bbox[BOXTOP] = t2->y, tb.bbox[BOXBOTTOM] = t1->y;
|
||||
|
||||
tb.compareThing = t1;
|
||||
|
||||
// the head node is the last node output
|
||||
return P_CrossBSPNodeBotTraversal((INT32)numnodes - 1, &tb);
|
||||
}
|
||||
|
||||
|
|
|
|||
44
src/p_user.c
44
src/p_user.c
|
|
@ -500,6 +500,26 @@ INT32 P_GivePlayerRings(player_t *player, INT32 num_rings)
|
|||
return num_rings;
|
||||
}
|
||||
|
||||
INT32 P_GivePlayerSpheres(player_t *player, INT32 num_spheres)
|
||||
{
|
||||
num_spheres += player->spheres;
|
||||
|
||||
// Not alive
|
||||
if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= 0))
|
||||
return 0;
|
||||
|
||||
if (num_spheres > 40) // Reached the cap, don't waste 'em!
|
||||
num_spheres = 40;
|
||||
else if (num_spheres < 0)
|
||||
num_spheres = 0;
|
||||
|
||||
num_spheres -= player->spheres;
|
||||
|
||||
player->spheres += num_spheres;
|
||||
|
||||
return num_spheres;
|
||||
}
|
||||
|
||||
//
|
||||
// P_GivePlayerLives
|
||||
//
|
||||
|
|
@ -2500,6 +2520,8 @@ static void P_ConsiderAllGone(void)
|
|||
//
|
||||
static void P_DeathThink(player_t *player)
|
||||
{
|
||||
boolean playerGone = false;
|
||||
|
||||
player->deltaviewheight = 0;
|
||||
|
||||
if (player->deadtimer < INT32_MAX)
|
||||
|
|
@ -2520,7 +2542,19 @@ static void P_DeathThink(player_t *player)
|
|||
|
||||
K_KartPlayerHUDUpdate(player);
|
||||
|
||||
if (player->lives > 0 && !(player->pflags & PF_NOCONTEST) && player->deadtimer > TICRATE)
|
||||
if (player->pflags & PF_NOCONTEST)
|
||||
{
|
||||
playerGone = true;
|
||||
}
|
||||
else if (player->bot == false)
|
||||
{
|
||||
if (G_GametypeUsesLives() == true && player->lives == 0)
|
||||
{
|
||||
playerGone = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (playerGone == false && player->deadtimer > TICRATE)
|
||||
{
|
||||
player->playerstate = PST_REBORN;
|
||||
}
|
||||
|
|
@ -4220,9 +4254,6 @@ void P_PlayerThink(player_t *player)
|
|||
ticcmd_t *cmd;
|
||||
const size_t playeri = (size_t)(player - players);
|
||||
|
||||
player->old_drawangle = player->drawangle;
|
||||
player->old_viewrollangle = player->viewrollangle;
|
||||
|
||||
#ifdef PARANOIA
|
||||
if (!player->mo)
|
||||
I_Error("p_playerthink: players[%s].mo == NULL", sizeu1(playeri));
|
||||
|
|
@ -4235,6 +4266,11 @@ void P_PlayerThink(player_t *player)
|
|||
player->playerstate = PST_DEAD;
|
||||
}
|
||||
|
||||
player->old_drawangle = player->drawangle;
|
||||
player->old_viewrollangle = player->viewrollangle;
|
||||
|
||||
player->pflags &= ~PF_HITFINISHLINE;
|
||||
|
||||
if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj))
|
||||
{
|
||||
P_SetTarget(&player->awayviewmobj, NULL); // remove awayviewmobj asap if invalid
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@
|
|||
#include "byteptr.h"
|
||||
#include "dehacked.h"
|
||||
|
||||
// DRRR
|
||||
#include "k_brightmap.h"
|
||||
|
||||
//
|
||||
// Graphics.
|
||||
// SRB2 graphics for walls and sprites
|
||||
|
|
@ -1175,6 +1178,9 @@ void R_InitTextureData(void)
|
|||
|
||||
CONS_Printf("P_InitPicAnims()...\n");
|
||||
P_InitPicAnims();
|
||||
|
||||
CONS_Printf("K_InitBrightmaps()...\n");
|
||||
K_InitBrightmaps();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
44
src/r_draw.c
44
src/r_draw.c
|
|
@ -26,6 +26,7 @@
|
|||
#include "z_zone.h"
|
||||
#include "console.h" // Until buffering gets finished
|
||||
#include "k_color.h" // SRB2kart
|
||||
#include "i_threads.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
|
@ -71,12 +72,14 @@ UINT8 *topleft;
|
|||
// =========================================================================
|
||||
|
||||
lighttable_t *dc_colormap;
|
||||
lighttable_t *dc_fullbright;
|
||||
INT32 dc_x = 0, dc_yl = 0, dc_yh = 0;
|
||||
|
||||
fixed_t dc_iscale, dc_texturemid;
|
||||
UINT8 dc_hires; // under MSVC boolean is a byte, while on other systems, it a bit,
|
||||
// soo lets make it a byte on all system for the ASM code
|
||||
UINT8 *dc_source;
|
||||
UINT8 *dc_brightmap;
|
||||
|
||||
// -----------------------
|
||||
// translucency stuff here
|
||||
|
|
@ -108,6 +111,7 @@ INT32 dc_numlights = 0, dc_maxlights, dc_texheight;
|
|||
|
||||
INT32 ds_y, ds_x1, ds_x2;
|
||||
lighttable_t *ds_colormap;
|
||||
lighttable_t *ds_fullbright;
|
||||
lighttable_t *ds_translation; // Lactozilla: Sprite splat drawer
|
||||
|
||||
fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
|
||||
|
|
@ -117,6 +121,7 @@ UINT16 ds_flatwidth, ds_flatheight;
|
|||
boolean ds_powersoftwo;
|
||||
|
||||
UINT8 *ds_source; // points to the start of a flat
|
||||
UINT8 *ds_brightmap; // start of brightmap flat
|
||||
UINT8 *ds_transmap; // one of the translucency tables
|
||||
|
||||
// Vectors for Software's tilted slope drawers
|
||||
|
|
@ -192,6 +197,29 @@ CV_PossibleValue_t Followercolor_cons_t[MAXSKINCOLORS+3]; // +3 to account for "
|
|||
|
||||
#define TRANSTAB_AMTMUL10 (255.0f / 10.0f)
|
||||
|
||||
static void R_AllocateBlendTables(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < NUMBLENDMAPS; i++)
|
||||
{
|
||||
if (i == blendtab_modulate)
|
||||
continue;
|
||||
blendtables[i] = Z_MallocAlign((NUMTRANSTABLES + 1) * 0x10000, PU_STATIC, NULL, 16);
|
||||
}
|
||||
|
||||
// Modulation blending only requires a single table
|
||||
blendtables[blendtab_modulate] = Z_MallocAlign(0x10000, PU_STATIC, NULL, 16);
|
||||
}
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
static void R_GenerateBlendTables_Thread(void *userdata)
|
||||
{
|
||||
(void)userdata;
|
||||
R_GenerateBlendTables();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \brief Initializes the translucency tables used by the Software renderer.
|
||||
*/
|
||||
void R_InitTranslucencyTables(void)
|
||||
|
|
@ -212,20 +240,20 @@ void R_InitTranslucencyTables(void)
|
|||
W_ReadLump(W_GetNumForName("TRANS80"), transtables+0x70000);
|
||||
W_ReadLump(W_GetNumForName("TRANS90"), transtables+0x80000);
|
||||
|
||||
R_AllocateBlendTables();
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
I_spawn_thread("blend-tables",
|
||||
R_GenerateBlendTables_Thread, NULL);
|
||||
#else
|
||||
R_GenerateBlendTables();
|
||||
#endif
|
||||
}
|
||||
|
||||
void R_GenerateBlendTables(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < NUMBLENDMAPS; i++)
|
||||
{
|
||||
if (i == blendtab_modulate)
|
||||
continue;
|
||||
blendtables[i] = Z_MallocAlign((NUMTRANSTABLES + 1) * 0x10000, PU_STATIC, NULL, 16);
|
||||
}
|
||||
|
||||
for (i = 0; i <= 9; i++)
|
||||
{
|
||||
const size_t offs = (0x10000 * i);
|
||||
|
|
@ -236,8 +264,6 @@ void R_GenerateBlendTables(void)
|
|||
R_GenerateTranslucencyTable(blendtables[blendtab_reversesubtract] + offs, AST_REVERSESUBTRACT, alpha);
|
||||
}
|
||||
|
||||
// Modulation blending only requires a single table
|
||||
blendtables[blendtab_modulate] = Z_MallocAlign(0x10000, PU_STATIC, NULL, 16);
|
||||
R_GenerateTranslucencyTable(blendtables[blendtab_modulate], AST_MODULATE, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,11 +32,13 @@ extern UINT8 *topleft;
|
|||
// -------------------------
|
||||
|
||||
extern lighttable_t *dc_colormap;
|
||||
extern lighttable_t *dc_fullbright;
|
||||
extern INT32 dc_x, dc_yl, dc_yh;
|
||||
extern fixed_t dc_iscale, dc_texturemid;
|
||||
extern UINT8 dc_hires;
|
||||
|
||||
extern UINT8 *dc_source; // first pixel in a column
|
||||
extern UINT8 *dc_brightmap; // brightmap texture column, can be NULL
|
||||
|
||||
// translucency stuff here
|
||||
extern UINT8 *dc_transmap;
|
||||
|
|
@ -57,6 +59,7 @@ extern INT32 dc_texheight;
|
|||
|
||||
extern INT32 ds_y, ds_x1, ds_x2;
|
||||
extern lighttable_t *ds_colormap;
|
||||
extern lighttable_t *ds_fullbright;
|
||||
extern lighttable_t *ds_translation;
|
||||
|
||||
extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
|
||||
|
|
@ -66,6 +69,7 @@ extern UINT16 ds_flatwidth, ds_flatheight;
|
|||
extern boolean ds_powersoftwo;
|
||||
|
||||
extern UINT8 *ds_source;
|
||||
extern UINT8 *ds_brightmap;
|
||||
extern UINT8 *ds_transmap;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -167,6 +171,7 @@ void R_DrawViewBorder(void);
|
|||
#endif
|
||||
|
||||
#define TRANSPARENTPIXEL 255
|
||||
#define BRIGHTPIXEL 0
|
||||
|
||||
// -----------------
|
||||
// 8bpp DRAWING CODE
|
||||
|
|
|
|||
1129
src/r_draw8.c
1129
src/r_draw8.c
File diff suppressed because it is too large
Load diff
|
|
@ -149,10 +149,6 @@ static void ChaseCam_OnChange(void);
|
|||
static void ChaseCam2_OnChange(void);
|
||||
static void ChaseCam3_OnChange(void);
|
||||
static void ChaseCam4_OnChange(void);
|
||||
void SendWeaponPref(void);
|
||||
void SendWeaponPref2(void);
|
||||
void SendWeaponPref3(void);
|
||||
void SendWeaponPref4(void);
|
||||
|
||||
consvar_t cv_tailspickup = CVAR_INIT ("tailspickup", "On", CV_NETVAR|CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||
consvar_t cv_chasecam[MAXSPLITSCREENPLAYERS] = {
|
||||
|
|
@ -1141,7 +1137,7 @@ void R_Init(void)
|
|||
R_InitLightTables();
|
||||
|
||||
//I_OutputMsg("\nR_InitTranslucencyTables\n");
|
||||
R_InitTranslucencyTables();
|
||||
//R_InitTranslucencyTables();
|
||||
|
||||
R_InitDrawNodes();
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ typedef struct
|
|||
} spriteinfo_t;
|
||||
|
||||
// Portable Network Graphics
|
||||
#define PNG_HEADER_SIZE (8)
|
||||
boolean Picture_IsLumpPNG(const UINT8 *d, size_t s);
|
||||
#define Picture_ThrowPNGError(lumpname, wadfilename) I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .png - please convert to either Doom or Flat (raw) image format.", lumpname, wadfilename); // Fears Of LJ Sonic
|
||||
|
||||
|
|
|
|||
|
|
@ -235,7 +235,9 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
|
|||
}
|
||||
|
||||
if (currentplane->slope)
|
||||
{
|
||||
ds_colormap = colormaps;
|
||||
}
|
||||
else
|
||||
{
|
||||
pindex = distance >> LIGHTZSHIFT;
|
||||
|
|
@ -244,8 +246,13 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
|
|||
ds_colormap = planezlight[pindex];
|
||||
}
|
||||
|
||||
ds_fullbright = colormaps;
|
||||
|
||||
if (encoremap && !currentplane->noencore)
|
||||
{
|
||||
ds_colormap += COLORMAP_REMAPOFFSET;
|
||||
ds_fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
|
||||
if (currentplane->extra_colormap)
|
||||
ds_colormap = currentplane->extra_colormap->colormap + (ds_colormap - colormaps);
|
||||
|
|
@ -641,7 +648,7 @@ static void R_DrawSkyPlane(visplane_t *pl)
|
|||
|
||||
// Reset column drawer function (note: couldn't we just call walldrawerfunc directly?)
|
||||
// (that is, unless we'll need to switch drawers in future for some reason)
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
R_SetColumnFunc(BASEDRAWFUNC, false);
|
||||
|
||||
// use correct aspect ratio scale
|
||||
dc_iscale = skyscale[viewssnum];
|
||||
|
|
@ -651,8 +658,12 @@ static void R_DrawSkyPlane(visplane_t *pl)
|
|||
// Because of this hack, sky is not affected
|
||||
// by sector colormaps (INVUL inverse mapping is not implemented in SRB2 so is irrelevant).
|
||||
dc_colormap = colormaps;
|
||||
dc_fullbright = colormaps;
|
||||
if (encoremap)
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
dc_texturemid = skytexturemid;
|
||||
dc_texheight = textureheight[skytexture]
|
||||
>>FRACBITS;
|
||||
|
|
@ -669,6 +680,7 @@ static void R_DrawSkyPlane(visplane_t *pl)
|
|||
dc_source =
|
||||
R_GetColumn(texturetranslation[skytexture],
|
||||
-angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
|
||||
dc_brightmap = NULL;
|
||||
colfunc();
|
||||
}
|
||||
}
|
||||
|
|
@ -808,7 +820,8 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
}
|
||||
|
||||
planeripple.active = false;
|
||||
spanfunc = spanfuncs[BASEDRAWFUNC];
|
||||
ds_brightmap = NULL;
|
||||
R_SetSpanFunc(BASEDRAWFUNC, false, false);
|
||||
|
||||
if (pl->polyobj)
|
||||
{
|
||||
|
|
@ -965,6 +978,17 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
|
||||
}
|
||||
|
||||
if (type == LEVELFLAT_TEXTURE)
|
||||
{
|
||||
// Get the span's brightmap.
|
||||
// FLATS not supported, SORRY!!
|
||||
INT32 bmNum = R_GetTextureBrightmap(levelflat->u.texture.num);
|
||||
if (bmNum != 0)
|
||||
{
|
||||
ds_brightmap = (UINT8 *)R_GenerateTextureAsFlat(bmNum);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pl->slope // Don't mess with angle on slopes! We'll handle this ourselves later
|
||||
&& viewangle != pl->viewangle+pl->plangle)
|
||||
{
|
||||
|
|
@ -1080,15 +1104,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
planezlight = zlight[light];
|
||||
|
||||
// Use the correct span drawer depending on the powers-of-twoness
|
||||
if (!ds_powersoftwo)
|
||||
{
|
||||
if (spanfuncs_npo2[spanfunctype])
|
||||
spanfunc = spanfuncs_npo2[spanfunctype];
|
||||
else
|
||||
spanfunc = spanfuncs[spanfunctype];
|
||||
}
|
||||
else
|
||||
spanfunc = spanfuncs[spanfunctype];
|
||||
R_SetSpanFunc(spanfunctype, !ds_powersoftwo, ds_brightmap != NULL);
|
||||
|
||||
// set the maximum value for unsigned
|
||||
pl->top[pl->maxx+1] = 0xffff;
|
||||
|
|
|
|||
143
src/r_segs.c
143
src/r_segs.c
|
|
@ -36,6 +36,7 @@ static boolean markceiling;
|
|||
|
||||
static boolean maskedtexture;
|
||||
static INT32 toptexture, bottomtexture, midtexture;
|
||||
static INT32 topbrightmap, bottombrightmap, midbrightmap;
|
||||
static INT32 numthicksides, numbackffloors;
|
||||
|
||||
angle_t rw_normalangle;
|
||||
|
|
@ -83,7 +84,7 @@ static fixed_t *maskedtextureheight = NULL;
|
|||
// multi-patch textures. They are not normally needed as multi-patch
|
||||
// textures don't have holes in it. At least not for now.
|
||||
|
||||
static void R_Render2sidedMultiPatchColumn(column_t *column)
|
||||
static void R_Render2sidedMultiPatchColumn(column_t *column, column_t *brightmap)
|
||||
{
|
||||
INT32 topscreen, bottomscreen;
|
||||
|
||||
|
|
@ -93,6 +94,8 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
|
|||
dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
|
||||
dc_yh = (bottomscreen-1)>>FRACBITS;
|
||||
|
||||
dc_brightmap = NULL;
|
||||
|
||||
if (windowtop != INT32_MAX && windowbottom != INT32_MAX)
|
||||
{
|
||||
dc_yl = ((windowtop + FRACUNIT)>>FRACBITS);
|
||||
|
|
@ -110,10 +113,14 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
|
|||
if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0)
|
||||
{
|
||||
dc_source = (UINT8 *)column + 3;
|
||||
if (brightmap != NULL)
|
||||
{
|
||||
dc_brightmap = (UINT8 *)brightmap + 3;
|
||||
}
|
||||
|
||||
if (colfunc == colfuncs[BASEDRAWFUNC])
|
||||
if (R_CheckColumnFunc(BASEDRAWFUNC) == true)
|
||||
(colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])();
|
||||
else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
|
||||
else if (R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == true)
|
||||
(colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])();
|
||||
else
|
||||
colfunc();
|
||||
|
|
@ -132,12 +139,12 @@ transnum_t R_GetLinedefTransTable(line_t *ldef)
|
|||
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
||||
{
|
||||
size_t pindex;
|
||||
column_t *col;
|
||||
INT32 lightnum, texnum, i;
|
||||
column_t *col, *bmCol = NULL;
|
||||
INT32 lightnum, texnum, bmnum, i;
|
||||
fixed_t height, realbot;
|
||||
lightlist_t *light;
|
||||
r_lightlist_t *rlight;
|
||||
void (*colfunc_2s)(column_t *);
|
||||
void (*colfunc_2s)(column_t *, column_t *);
|
||||
line_t *ldef;
|
||||
sector_t *front, *back;
|
||||
INT32 times, repeats;
|
||||
|
|
@ -155,6 +162,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
frontsector = curline->frontsector;
|
||||
backsector = curline->backsector;
|
||||
texnum = R_GetTextureNum(curline->sidedef->midtexture);
|
||||
bmnum = R_GetTextureBrightmap(texnum);
|
||||
windowbottom = windowtop = sprbotscreen = INT32_MAX;
|
||||
|
||||
ldef = curline->linedef;
|
||||
|
|
@ -188,16 +196,18 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
if (transtable != NUMTRANSMAPS && (blendmode || transtable))
|
||||
{
|
||||
dc_transmap = R_GetBlendTable(blendmode, transtable);
|
||||
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
|
||||
R_SetColumnFunc(COLDRAWFUNC_FUZZY, bmnum != 0);
|
||||
}
|
||||
else if (ldef->special == 909)
|
||||
{
|
||||
colfunc = colfuncs[COLDRAWFUNC_FOG];
|
||||
R_SetColumnFunc(COLDRAWFUNC_FOG, bmnum != 0);
|
||||
windowtop = frontsector->ceilingheight;
|
||||
windowbottom = frontsector->floorheight;
|
||||
}
|
||||
else
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
{
|
||||
R_SetColumnFunc(BASEDRAWFUNC, bmnum != 0);
|
||||
}
|
||||
|
||||
if (curline->polyseg && curline->polyseg->translucency > 0)
|
||||
{
|
||||
|
|
@ -205,7 +215,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
return;
|
||||
|
||||
dc_transmap = R_GetTranslucencyTable(curline->polyseg->translucency);
|
||||
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
|
||||
R_SetColumnFunc(COLDRAWFUNC_FUZZY, bmnum != 0);
|
||||
}
|
||||
|
||||
range = max(ds->x2-ds->x1, 1);
|
||||
|
|
@ -215,6 +225,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
// Texture must be cached before setting colfunc_2s,
|
||||
// otherwise texture[texnum]->holes may be false when it shouldn't be
|
||||
R_CheckTextureCache(texnum);
|
||||
if (bmnum) { R_CheckTextureCache(bmnum); }
|
||||
|
||||
// handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
|
||||
// are not stored per-column with post info in SRB2
|
||||
if (textures[texnum]->holes)
|
||||
|
|
@ -265,7 +277,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
rlight->extra_colormap = *light->extra_colormap;
|
||||
rlight->flags = light->flags;
|
||||
|
||||
if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY])
|
||||
if ((R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == false)
|
||||
|| (rlight->flags & FF_FOG)
|
||||
|| (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
|
|
@ -282,13 +294,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY])
|
||||
if ((R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == false)
|
||||
|| (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
|
||||
if (colfunc == colfuncs[COLDRAWFUNC_FOG]
|
||||
if ((R_CheckColumnFunc(COLDRAWFUNC_FOG) == true)
|
||||
|| (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
;
|
||||
else
|
||||
|
|
@ -400,6 +412,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
|
||||
// draw the texture
|
||||
col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3);
|
||||
if (bmnum) { bmCol = (column_t *)((UINT8 *)R_GetColumn(bmnum, maskedtexturecol[dc_x]) - 3); }
|
||||
|
||||
for (i = 0; i < dc_numlights; i++)
|
||||
{
|
||||
|
|
@ -431,8 +444,12 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
if (height <= windowtop)
|
||||
{
|
||||
dc_colormap = rlight->rcolormap;
|
||||
dc_fullbright = colormaps;
|
||||
if (encoremap && !(ldef->flags & ML_TFERLINE))
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -440,7 +457,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
if (windowbottom >= realbot)
|
||||
{
|
||||
windowbottom = realbot;
|
||||
colfunc_2s(col);
|
||||
colfunc_2s(col, bmCol);
|
||||
for (i++; i < dc_numlights; i++)
|
||||
{
|
||||
rlight = &dc_lightlist[i];
|
||||
|
|
@ -449,15 +466,19 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
|
||||
continue;
|
||||
}
|
||||
colfunc_2s(col);
|
||||
colfunc_2s(col, bmCol);
|
||||
windowtop = windowbottom + 1;
|
||||
dc_colormap = rlight->rcolormap;
|
||||
dc_fullbright = colormaps;
|
||||
if (encoremap && !(ldef->flags & ML_TFERLINE))
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
}
|
||||
windowbottom = realbot;
|
||||
if (windowtop < windowbottom)
|
||||
colfunc_2s(col);
|
||||
colfunc_2s(col, bmCol);
|
||||
|
||||
spryscale += rw_scalestep;
|
||||
continue;
|
||||
|
|
@ -470,8 +491,12 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
pindex = MAXLIGHTSCALE - 1;
|
||||
|
||||
dc_colormap = walllights[pindex];
|
||||
dc_fullbright = colormaps;
|
||||
if (encoremap && !(ldef->flags & ML_TFERLINE))
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
|
||||
if (frontsector->extra_colormap)
|
||||
dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
|
||||
|
|
@ -481,6 +506,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
|
||||
// draw the texture
|
||||
col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3);
|
||||
if (bmnum) { bmCol = (column_t *)((UINT8 *)R_GetColumn(bmnum, maskedtexturecol[dc_x]) - 3); }
|
||||
|
||||
#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red
|
||||
if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES))
|
||||
|
|
@ -535,19 +561,20 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
colfunc_2s(col);
|
||||
colfunc_2s(col, bmCol);
|
||||
}
|
||||
spryscale += rw_scalestep;
|
||||
}
|
||||
}
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
|
||||
R_SetColumnFunc(BASEDRAWFUNC, false);
|
||||
}
|
||||
|
||||
// Loop through R_DrawMaskedColumn calls
|
||||
static void R_DrawRepeatMaskedColumn(column_t *col)
|
||||
static void R_DrawRepeatMaskedColumn(column_t *col, column_t *bm)
|
||||
{
|
||||
while (sprtopscreen < sprbotscreen) {
|
||||
R_DrawMaskedColumn(col);
|
||||
R_DrawMaskedColumn(col, bm);
|
||||
if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow
|
||||
sprtopscreen = INT32_MAX;
|
||||
else
|
||||
|
|
@ -555,10 +582,10 @@ static void R_DrawRepeatMaskedColumn(column_t *col)
|
|||
}
|
||||
}
|
||||
|
||||
static void R_DrawRepeatFlippedMaskedColumn(column_t *col)
|
||||
static void R_DrawRepeatFlippedMaskedColumn(column_t *col, column_t *bm)
|
||||
{
|
||||
do {
|
||||
R_DrawFlippedMaskedColumn(col);
|
||||
R_DrawFlippedMaskedColumn(col, bm);
|
||||
sprtopscreen += dc_texheight*spryscale;
|
||||
} while (sprtopscreen < sprbotscreen);
|
||||
}
|
||||
|
|
@ -582,9 +609,9 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor)
|
|||
void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||
{
|
||||
size_t pindex;
|
||||
column_t * col;
|
||||
column_t * col, *bmCol = NULL;
|
||||
INT32 lightnum;
|
||||
INT32 texnum;
|
||||
INT32 texnum, bmnum;
|
||||
sector_t tempsec;
|
||||
INT32 templight;
|
||||
INT32 i, p;
|
||||
|
|
@ -605,7 +632,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
fixed_t left_top, left_bottom; // needed here for slope skewing
|
||||
pslope_t *skewslope = NULL;
|
||||
|
||||
void (*colfunc_2s) (column_t *);
|
||||
void (*colfunc_2s) (column_t *, column_t *);
|
||||
|
||||
// Calculate light table.
|
||||
// Use different light tables
|
||||
|
|
@ -616,14 +643,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
backsector = pfloor->target;
|
||||
frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector;
|
||||
texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture);
|
||||
bmnum = R_GetTextureBrightmap(texnum);
|
||||
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
R_SetColumnFunc(BASEDRAWFUNC, bmnum != 0);
|
||||
|
||||
if (pfloor->master->flags & ML_TFERLINE)
|
||||
{
|
||||
size_t linenum = curline->linedef-backsector->lines[0];
|
||||
newline = pfloor->master->frontsector->lines[0] + linenum;
|
||||
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture);
|
||||
bmnum = R_GetTextureBrightmap(texnum);
|
||||
}
|
||||
|
||||
if (pfloor->flags & FF_TRANSLUCENT)
|
||||
|
|
@ -641,10 +670,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
}
|
||||
|
||||
if (fuzzy)
|
||||
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
|
||||
{
|
||||
R_SetColumnFunc(COLDRAWFUNC_FUZZY, bmnum != 0);
|
||||
}
|
||||
}
|
||||
else if (pfloor->flags & FF_FOG)
|
||||
colfunc = colfuncs[COLDRAWFUNC_FOG];
|
||||
{
|
||||
R_SetColumnFunc(COLDRAWFUNC_FOG, bmnum != 0);
|
||||
}
|
||||
|
||||
range = max(ds->x2-ds->x1, 1);
|
||||
//SoM: Moved these up here so they are available for my lightlist calculations
|
||||
|
|
@ -752,7 +785,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
else if (pfloor->flags & FF_FOG)
|
||||
lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
|
||||
else if (R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == true)
|
||||
lightnum = LIGHTLEVELS-1;
|
||||
else
|
||||
lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
|
||||
|
|
@ -833,6 +866,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
// Texture must be cached before setting colfunc_2s,
|
||||
// otherwise texture[texnum]->holes may be false when it shouldn't be
|
||||
R_CheckTextureCache(texnum);
|
||||
if (bmnum) { R_CheckTextureCache(bmnum); }
|
||||
|
||||
//faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
|
||||
// are not stored per-column with post info anymore in Doom Legacy
|
||||
if (textures[texnum]->holes)
|
||||
|
|
@ -916,6 +951,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
|
||||
// Get data for the column
|
||||
col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
|
||||
if (bmnum) { bmCol = (column_t *)((UINT8 *)R_GetColumn(bmnum, maskedtexturecol[dc_x]) - 3); }
|
||||
|
||||
// SoM: New code does not rely on R_DrawColumnShadowed_8 which
|
||||
// will (hopefully) put less strain on the stack.
|
||||
|
|
@ -998,8 +1034,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
if (lighteffect)
|
||||
{
|
||||
dc_colormap = rlight->rcolormap;
|
||||
dc_fullbright = colormaps;
|
||||
if (encoremap && !(curline->linedef->flags & ML_TFERLINE))
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
}
|
||||
if (solid && windowtop < bheight)
|
||||
windowtop = bheight;
|
||||
|
|
@ -1011,7 +1051,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
{
|
||||
windowbottom = sprbotscreen;
|
||||
// draw the texture
|
||||
colfunc_2s (col);
|
||||
colfunc_2s (col, bmCol);
|
||||
for (i++; i < dc_numlights; i++)
|
||||
{
|
||||
rlight = &dc_lightlist[i];
|
||||
|
|
@ -1022,7 +1062,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
continue;
|
||||
}
|
||||
// draw the texture
|
||||
colfunc_2s (col);
|
||||
colfunc_2s (col, bmCol);
|
||||
if (solid)
|
||||
windowtop = bheight;
|
||||
else
|
||||
|
|
@ -1030,14 +1070,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
if (lighteffect)
|
||||
{
|
||||
dc_colormap = rlight->rcolormap;
|
||||
dc_fullbright = colormaps;
|
||||
if (encoremap && !(curline->linedef->flags & ML_TFERLINE))
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
}
|
||||
}
|
||||
windowbottom = sprbotscreen;
|
||||
// draw the texture, if there is any space left
|
||||
if (windowtop < windowbottom)
|
||||
colfunc_2s (col);
|
||||
colfunc_2s (col, bmCol);
|
||||
|
||||
spryscale += rw_scalestep;
|
||||
continue;
|
||||
|
|
@ -1050,9 +1094,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
pindex = MAXLIGHTSCALE - 1;
|
||||
|
||||
dc_colormap = walllights[pindex];
|
||||
dc_fullbright = colormaps;
|
||||
|
||||
if (encoremap && !(curline->linedef->flags & ML_TFERLINE))
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
|
||||
if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap)
|
||||
dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
|
||||
|
|
@ -1060,11 +1108,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
|
||||
|
||||
// draw the texture
|
||||
colfunc_2s (col);
|
||||
colfunc_2s (col, bmCol);
|
||||
spryscale += rw_scalestep;
|
||||
}
|
||||
}
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
|
||||
R_SetColumnFunc(BASEDRAWFUNC, false);
|
||||
|
||||
#undef CLAMPMAX
|
||||
#undef CLAMPMIN
|
||||
|
|
@ -1311,8 +1360,12 @@ static void R_RenderSegLoop (void)
|
|||
pindex = MAXLIGHTSCALE-1;
|
||||
|
||||
dc_colormap = walllights[pindex];
|
||||
dc_fullbright = colormaps;
|
||||
if (encoremap && !(curline->linedef->flags & ML_TFERLINE))
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
dc_x = rw_x;
|
||||
dc_iscale = 0xffffffffu / (unsigned)rw_scale;
|
||||
|
||||
|
|
@ -1350,7 +1403,7 @@ static void R_RenderSegLoop (void)
|
|||
else
|
||||
dc_lightlist[i].rcolormap = xwalllights[pindex];
|
||||
|
||||
colfunc = colfuncs[COLDRAWFUNC_SHADOWED];
|
||||
R_SetColumnFunc(COLDRAWFUNC_SHADOWED, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1366,8 +1419,11 @@ static void R_RenderSegLoop (void)
|
|||
dc_yh = yh;
|
||||
dc_texturemid = rw_midtexturemid;
|
||||
dc_source = R_GetColumn(midtexture,texturecolumn);
|
||||
dc_brightmap = (midbrightmap ? R_GetColumn(midbrightmap, texturecolumn) : NULL);
|
||||
dc_texheight = textureheight[midtexture]>>FRACBITS;
|
||||
|
||||
R_SetColumnFunc(colfunctype, dc_brightmap != NULL);
|
||||
|
||||
//profile stuff ---------------------------------------------------------
|
||||
#ifdef TIMING
|
||||
ProfZeroTimer();
|
||||
|
|
@ -1427,7 +1483,9 @@ static void R_RenderSegLoop (void)
|
|||
dc_yh = mid;
|
||||
dc_texturemid = rw_toptexturemid;
|
||||
dc_source = R_GetColumn(toptexture,texturecolumn);
|
||||
dc_brightmap = (topbrightmap ? R_GetColumn(topbrightmap, texturecolumn) : NULL);
|
||||
dc_texheight = textureheight[toptexture]>>FRACBITS;
|
||||
R_SetColumnFunc(colfunctype, dc_brightmap != NULL);
|
||||
colfunc();
|
||||
ceilingclip[rw_x] = (INT16)mid;
|
||||
}
|
||||
|
|
@ -1462,9 +1520,10 @@ static void R_RenderSegLoop (void)
|
|||
dc_yl = mid;
|
||||
dc_yh = yh;
|
||||
dc_texturemid = rw_bottomtexturemid;
|
||||
dc_source = R_GetColumn(bottomtexture,
|
||||
texturecolumn);
|
||||
dc_source = R_GetColumn(bottomtexture,texturecolumn);
|
||||
dc_brightmap = (bottombrightmap ? R_GetColumn(bottombrightmap, texturecolumn) : NULL);
|
||||
dc_texheight = textureheight[bottomtexture]>>FRACBITS;
|
||||
R_SetColumnFunc(colfunctype, dc_brightmap != NULL);
|
||||
colfunc();
|
||||
floorclip[rw_x] = (INT16)mid;
|
||||
}
|
||||
|
|
@ -1558,7 +1617,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
memset(&segleft, 0x00, sizeof(segleft));
|
||||
memset(&segright, 0x00, sizeof(segright));
|
||||
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
R_SetColumnFunc(BASEDRAWFUNC, false);
|
||||
|
||||
if (ds_p == drawsegs+maxdrawsegs)
|
||||
{
|
||||
|
|
@ -1738,6 +1797,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
worldbottomslope -= viewz;
|
||||
|
||||
midtexture = toptexture = bottomtexture = maskedtexture = 0;
|
||||
midbrightmap = topbrightmap = bottombrightmap = 0;
|
||||
ds_p->maskedtexturecol = NULL;
|
||||
ds_p->numthicksides = numthicksides = 0;
|
||||
ds_p->thicksidecol = NULL;
|
||||
|
|
@ -1785,6 +1845,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
fixed_t texheight;
|
||||
// single sided line
|
||||
midtexture = R_GetTextureNum(sidedef->midtexture);
|
||||
midbrightmap = R_GetTextureBrightmap(midtexture);
|
||||
texheight = textureheight[midtexture];
|
||||
// a single sided line is terminal, so it must mark ends
|
||||
markfloor = markceiling = true;
|
||||
|
|
@ -2021,11 +2082,14 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
|
||||
if (!toptexture) //Second side has no texture, use the first side's instead.
|
||||
toptexture = R_GetTextureNum(sidedef->toptexture);
|
||||
|
||||
topbrightmap = R_GetTextureBrightmap(toptexture);
|
||||
texheight = textureheight[toptexture];
|
||||
}
|
||||
else
|
||||
{
|
||||
toptexture = R_GetTextureNum(sidedef->toptexture);
|
||||
topbrightmap = R_GetTextureBrightmap(toptexture);
|
||||
texheight = textureheight[toptexture];
|
||||
}
|
||||
if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
|
||||
|
|
@ -2052,6 +2116,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
{
|
||||
// bottom texture
|
||||
bottomtexture = R_GetTextureNum(sidedef->bottomtexture);
|
||||
bottombrightmap = R_GetTextureBrightmap(bottomtexture);
|
||||
|
||||
if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
|
||||
if (linedef->flags & ML_DONTPEGBOTTOM)
|
||||
|
|
@ -2772,7 +2837,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
rw_bsilheight = &(ds_p->bsilheight);
|
||||
|
||||
R_RenderSegLoop();
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
R_SetColumnFunc(BASEDRAWFUNC, false);
|
||||
|
||||
if (portalline) // if curline is a portal, set portalrender for drawseg
|
||||
ds_p->portalpass = portalrender+1;
|
||||
|
|
|
|||
|
|
@ -311,11 +311,6 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
|||
}
|
||||
|
||||
player->skincolor = newcolor = skin->prefcolor;
|
||||
if (player->bot && botingame)
|
||||
{
|
||||
botskin = (UINT8)(skinnum + 1);
|
||||
botcolor = skin->prefcolor;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -444,6 +444,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
}
|
||||
|
||||
ds_colormap = vis->colormap;
|
||||
ds_fullbright = colormaps;
|
||||
ds_translation = R_GetSpriteTranslation(vis);
|
||||
if (ds_translation == NULL)
|
||||
ds_translation = colormaps;
|
||||
|
|
@ -468,10 +469,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
else
|
||||
ds_transmap = NULL;
|
||||
|
||||
if (ds_powersoftwo)
|
||||
spanfunc = spanfuncs[spanfunctype];
|
||||
else
|
||||
spanfunc = spanfuncs_npo2[spanfunctype];
|
||||
R_SetSpanFunc(spanfunctype, !ds_powersoftwo, false);
|
||||
|
||||
if (maxy >= vid.height)
|
||||
maxy = vid.height-1;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ extern extracolormap_t *extra_colormaps;
|
|||
// for global animation
|
||||
extern INT32 *texturetranslation;
|
||||
|
||||
// for brightmaps
|
||||
extern INT32 *texturebrightmaps;
|
||||
|
||||
// Sprites
|
||||
extern size_t numspritelumps, max_spritelumps;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ INT32 *texturewidth;
|
|||
fixed_t *textureheight; // needed for texture pegging
|
||||
|
||||
INT32 *texturetranslation;
|
||||
INT32 *texturebrightmaps;
|
||||
|
||||
// Painfully simple texture id cacheing to make maps load faster. :3
|
||||
static struct {
|
||||
|
|
@ -500,6 +501,20 @@ INT32 R_GetTextureNum(INT32 texnum)
|
|||
return texturetranslation[texnum];
|
||||
}
|
||||
|
||||
//
|
||||
// R_GetTextureBrightmap
|
||||
//
|
||||
// Returns the actual texture id that we should use.
|
||||
// This can either be the texture's brightmap,
|
||||
// or 0 if not valid.
|
||||
//
|
||||
INT32 R_GetTextureBrightmap(INT32 texnum)
|
||||
{
|
||||
if (texnum < 0 || texnum >= numtextures)
|
||||
return 0;
|
||||
return texturebrightmaps[texnum];
|
||||
}
|
||||
|
||||
//
|
||||
// R_CheckTextureCache
|
||||
//
|
||||
|
|
@ -725,6 +740,7 @@ Rloadflats (INT32 i, INT32 w)
|
|||
UINT16 texstart, texend;
|
||||
texture_t *texture;
|
||||
texpatch_t *patch;
|
||||
UINT8 header[PNG_HEADER_SIZE];
|
||||
|
||||
// Yes
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
|
|
@ -743,7 +759,6 @@ Rloadflats (INT32 i, INT32 w)
|
|||
// Work through each lump between the markers in the WAD.
|
||||
for (j = 0; j < (texend - texstart); j++)
|
||||
{
|
||||
UINT8 *flatlump;
|
||||
UINT16 wadnum = (UINT16)w;
|
||||
lumpnum_t lumpnum = texstart + j;
|
||||
size_t lumplength;
|
||||
|
|
@ -755,7 +770,7 @@ Rloadflats (INT32 i, INT32 w)
|
|||
continue; // If it is then SKIP IT
|
||||
}
|
||||
|
||||
flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
W_ReadLumpHeaderPwad(wadnum, lumpnum, header, sizeof header, 0);
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
|
||||
switch (lumplength)
|
||||
|
|
@ -790,12 +805,14 @@ Rloadflats (INT32 i, INT32 w)
|
|||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)flatlump, lumplength))
|
||||
if (Picture_IsLumpPNG(header, lumplength))
|
||||
{
|
||||
UINT8 *flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
INT32 width, height;
|
||||
Picture_PNGDimensions((UINT8 *)flatlump, &width, &height, NULL, NULL, lumplength);
|
||||
texture->width = (INT16)width;
|
||||
texture->height = (INT16)height;
|
||||
Z_Free(flatlump);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
|
@ -814,8 +831,6 @@ Rloadflats (INT32 i, INT32 w)
|
|||
patch->lump = texstart + j;
|
||||
patch->flip = 0;
|
||||
|
||||
Z_Unlock(flatlump);
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
|
|
@ -835,8 +850,8 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
UINT16 j;
|
||||
UINT16 texstart, texend, texturesLumpPos;
|
||||
texture_t *texture;
|
||||
softwarepatch_t *patchlump;
|
||||
texpatch_t *patch;
|
||||
softwarepatch_t patchlump;
|
||||
|
||||
// Get the lump numbers for the markers in the WAD, if they exist.
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
|
|
@ -876,7 +891,7 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
continue; // If it is then SKIP IT
|
||||
}
|
||||
|
||||
patchlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
W_ReadLumpHeaderPwad(wadnum, lumpnum, &patchlump, PNG_HEADER_SIZE, 0);
|
||||
#ifndef NO_PNG_LUMPS
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
#endif
|
||||
|
|
@ -888,18 +903,20 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)patchlump, lumplength))
|
||||
if (Picture_IsLumpPNG((UINT8 *)&patchlump, lumplength))
|
||||
{
|
||||
UINT8 *png = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
INT32 width, height;
|
||||
Picture_PNGDimensions((UINT8 *)patchlump, &width, &height, NULL, NULL, lumplength);
|
||||
Picture_PNGDimensions(png, &width, &height, NULL, NULL, lumplength);
|
||||
texture->width = (INT16)width;
|
||||
texture->height = (INT16)height;
|
||||
Z_Free(png);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
texture->width = SHORT(patchlump->width);
|
||||
texture->height = SHORT(patchlump->height);
|
||||
texture->width = SHORT(patchlump.width);
|
||||
texture->height = SHORT(patchlump.height);
|
||||
}
|
||||
|
||||
texture->type = TEXTURETYPE_SINGLEPATCH;
|
||||
|
|
@ -915,8 +932,6 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
patch->lump = texstart + j;
|
||||
patch->flip = 0;
|
||||
|
||||
Z_Unlock(patchlump);
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
|
|
@ -944,6 +959,7 @@ void R_LoadTextures(void)
|
|||
Z_Free(textures[i]);
|
||||
Z_Free(texturecache[i]);
|
||||
}
|
||||
Z_Free(texturebrightmaps);
|
||||
Z_Free(texturetranslation);
|
||||
Z_Free(textures);
|
||||
}
|
||||
|
|
@ -1044,9 +1060,14 @@ void R_LoadTextures(void)
|
|||
textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4));
|
||||
// Create translation table for global animation.
|
||||
texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL);
|
||||
// Create brightmap texture table.
|
||||
texturebrightmaps = Z_Malloc((numtextures + 1) * sizeof(*texturebrightmaps), PU_STATIC, NULL);
|
||||
|
||||
for (i = 0; i < numtextures; i++)
|
||||
{
|
||||
texturetranslation[i] = i;
|
||||
texturebrightmaps[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0, w = 0; w < numwadfiles; w++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ void R_FlushTextureCache(void);
|
|||
UINT8 *R_GenerateTexture(size_t texnum);
|
||||
UINT8 *R_GenerateTextureAsFlat(size_t texnum);
|
||||
INT32 R_GetTextureNum(INT32 texnum);
|
||||
INT32 R_GetTextureBrightmap(INT32 texnum);
|
||||
void R_CheckTextureCache(INT32 tex);
|
||||
void R_ClearTextureNumCache(boolean btell);
|
||||
|
||||
|
|
|
|||
|
|
@ -286,16 +286,18 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
|
|||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
{
|
||||
softwarepatch_t *png = W_CacheLumpNumPwad(wadnum, l, PU_STATIC);
|
||||
UINT8 header[PNG_HEADER_SIZE];
|
||||
size_t len = W_LumpLengthPwad(wadnum, l);
|
||||
|
||||
if (Picture_IsLumpPNG((UINT8 *)png, len))
|
||||
W_ReadLumpHeaderPwad(wadnum, l, header, sizeof header, 0);
|
||||
|
||||
if (Picture_IsLumpPNG(header, len))
|
||||
{
|
||||
UINT8 *png = W_CacheLumpNumPwad(wadnum, l, PU_STATIC);
|
||||
Picture_PNGDimensions((UINT8 *)png, &width, &height, &topoffset, &leftoffset, len);
|
||||
isPNG = true;
|
||||
Z_Free(png);
|
||||
}
|
||||
|
||||
Z_Free(png);
|
||||
}
|
||||
|
||||
if (!isPNG)
|
||||
|
|
@ -602,7 +604,7 @@ INT16 *mceilingclip;
|
|||
fixed_t spryscale = 0, sprtopscreen = 0, sprbotscreen = 0;
|
||||
fixed_t windowtop = 0, windowbottom = 0;
|
||||
|
||||
void R_DrawMaskedColumn(column_t *column)
|
||||
void R_DrawMaskedColumn(column_t *column, column_t *brightmap)
|
||||
{
|
||||
INT32 topscreen;
|
||||
INT32 bottomscreen;
|
||||
|
|
@ -611,6 +613,9 @@ void R_DrawMaskedColumn(column_t *column)
|
|||
|
||||
basetexturemid = dc_texturemid;
|
||||
|
||||
R_SetColumnFunc(colfunctype, brightmap != NULL);
|
||||
dc_brightmap = NULL;
|
||||
|
||||
for (; column->topdelta != 0xff ;)
|
||||
{
|
||||
// calculate unclipped screen coordinates
|
||||
|
|
@ -645,6 +650,11 @@ void R_DrawMaskedColumn(column_t *column)
|
|||
if (dc_yl <= dc_yh && dc_yh > 0)
|
||||
{
|
||||
dc_source = (UINT8 *)column + 3;
|
||||
if (brightmap != NULL)
|
||||
{
|
||||
dc_brightmap = (UINT8 *)brightmap + 3;
|
||||
}
|
||||
|
||||
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||
|
||||
// Drawn by R_DrawColumn.
|
||||
|
|
@ -659,6 +669,10 @@ void R_DrawMaskedColumn(column_t *column)
|
|||
#endif
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
if (brightmap != NULL)
|
||||
{
|
||||
brightmap = (column_t *)((UINT8 *)brightmap + brightmap->length + 4);
|
||||
}
|
||||
}
|
||||
|
||||
dc_texturemid = basetexturemid;
|
||||
|
|
@ -666,7 +680,7 @@ void R_DrawMaskedColumn(column_t *column)
|
|||
|
||||
INT32 lengthcol; // column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height
|
||||
|
||||
void R_DrawFlippedMaskedColumn(column_t *column)
|
||||
void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap)
|
||||
{
|
||||
INT32 topscreen;
|
||||
INT32 bottomscreen;
|
||||
|
|
@ -674,6 +688,9 @@ void R_DrawFlippedMaskedColumn(column_t *column)
|
|||
INT32 topdelta, prevdelta = -1;
|
||||
UINT8 *d,*s;
|
||||
|
||||
R_SetColumnFunc(colfunctype, brightmap != NULL);
|
||||
dc_brightmap = NULL;
|
||||
|
||||
for (; column->topdelta != 0xff ;)
|
||||
{
|
||||
// calculate unclipped screen coordinates
|
||||
|
|
@ -712,6 +729,14 @@ void R_DrawFlippedMaskedColumn(column_t *column)
|
|||
dc_source = ZZ_Alloc(column->length);
|
||||
for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s)
|
||||
*d++ = *s;
|
||||
|
||||
if (brightmap != NULL)
|
||||
{
|
||||
dc_brightmap = ZZ_Alloc(brightmap->length);
|
||||
for (s = (UINT8 *)brightmap+2+brightmap->length, d = dc_brightmap; d < dc_brightmap+brightmap->length; --s)
|
||||
*d++ = *s;
|
||||
}
|
||||
|
||||
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||
|
||||
// Still drawn by R_DrawColumn.
|
||||
|
|
@ -724,6 +749,10 @@ void R_DrawFlippedMaskedColumn(column_t *column)
|
|||
Z_Free(dc_source);
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
if (brightmap != NULL)
|
||||
{
|
||||
brightmap = (column_t *)((UINT8 *)brightmap + brightmap->length + 4);
|
||||
}
|
||||
}
|
||||
|
||||
dc_texturemid = basetexturemid;
|
||||
|
|
@ -779,7 +808,7 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
|
|||
static void R_DrawVisSprite(vissprite_t *vis)
|
||||
{
|
||||
column_t *column;
|
||||
void (*localcolfunc)(column_t *);
|
||||
void (*localcolfunc)(column_t *, column_t *);
|
||||
INT32 texturecolumn;
|
||||
INT32 pwidth;
|
||||
fixed_t frac;
|
||||
|
|
@ -803,26 +832,27 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto
|
||||
}
|
||||
|
||||
colfunc = colfuncs[BASEDRAWFUNC]; // hack: this isn't resetting properly somewhere.
|
||||
R_SetColumnFunc(BASEDRAWFUNC, false); // hack: this isn't resetting properly somewhere.
|
||||
dc_colormap = vis->colormap;
|
||||
dc_fullbright = colormaps;
|
||||
dc_translation = R_GetSpriteTranslation(vis);
|
||||
|
||||
if (R_SpriteIsFlashing(vis)) // Bosses "flash"
|
||||
colfunc = colfuncs[COLDRAWFUNC_TRANS]; // translate certain pixels to white
|
||||
R_SetColumnFunc(COLDRAWFUNC_TRANS, false); // translate certain pixels to white
|
||||
else if (vis->mobj->color && vis->transmap) // Color mapping
|
||||
{
|
||||
colfunc = colfuncs[COLDRAWFUNC_TRANSTRANS];
|
||||
R_SetColumnFunc(COLDRAWFUNC_TRANSTRANS, false);
|
||||
dc_transmap = vis->transmap;
|
||||
}
|
||||
else if (vis->transmap)
|
||||
{
|
||||
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
|
||||
R_SetColumnFunc(COLDRAWFUNC_FUZZY, false);
|
||||
dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table
|
||||
}
|
||||
else if (vis->mobj->color) // translate green skin to another color
|
||||
colfunc = colfuncs[COLDRAWFUNC_TRANS];
|
||||
R_SetColumnFunc(COLDRAWFUNC_TRANS, false);
|
||||
else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome.
|
||||
colfunc = colfuncs[COLDRAWFUNC_TRANS];
|
||||
R_SetColumnFunc(COLDRAWFUNC_TRANS, false);
|
||||
|
||||
if (vis->extra_colormap && !(vis->renderflags & RF_NOCOLORMAPS))
|
||||
{
|
||||
|
|
@ -834,8 +864,13 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
if (!dc_colormap)
|
||||
dc_colormap = colormaps;
|
||||
|
||||
dc_fullbright = colormaps;
|
||||
|
||||
if (encoremap && !vis->mobj->color && !(vis->mobj->flags & MF_DONTENCOREMAP))
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
|
||||
dc_texturemid = vis->texturemid;
|
||||
dc_texheight = 0;
|
||||
|
|
@ -908,7 +943,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
|
||||
|
||||
localcolfunc (column);
|
||||
localcolfunc (column, NULL);
|
||||
}
|
||||
}
|
||||
else if (vis->cut & SC_SHEAR)
|
||||
|
|
@ -930,7 +965,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
#endif
|
||||
|
||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||
localcolfunc (column);
|
||||
localcolfunc (column, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -950,11 +985,11 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
#else
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS]));
|
||||
#endif
|
||||
localcolfunc (column);
|
||||
localcolfunc (column, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
R_SetColumnFunc(BASEDRAWFUNC, false);
|
||||
dc_hires = 0;
|
||||
|
||||
vis->x1 = x1;
|
||||
|
|
@ -984,13 +1019,17 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
|||
|
||||
if (vis->transmap)
|
||||
{
|
||||
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
|
||||
R_SetColumnFunc(COLDRAWFUNC_FUZZY, false);
|
||||
dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table
|
||||
}
|
||||
|
||||
dc_colormap = colormaps;
|
||||
dc_fullbright = colormaps;
|
||||
if (encoremap)
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
|
||||
dc_iscale = FixedDiv(FRACUNIT, vis->scale);
|
||||
dc_texturemid = vis->texturemid;
|
||||
|
|
@ -1019,10 +1058,10 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
|||
#else
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS]));
|
||||
#endif
|
||||
R_DrawMaskedColumn(column);
|
||||
R_DrawMaskedColumn(column, NULL);
|
||||
}
|
||||
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
R_SetColumnFunc(BASEDRAWFUNC, false);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ extern fixed_t windowtop;
|
|||
extern fixed_t windowbottom;
|
||||
extern INT32 lengthcol;
|
||||
|
||||
void R_DrawMaskedColumn(column_t *column);
|
||||
void R_DrawFlippedMaskedColumn(column_t *column);
|
||||
void R_DrawMaskedColumn(column_t *column, column_t *brightmap);
|
||||
void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap);
|
||||
|
||||
// ----------------
|
||||
// SPRITE RENDERING
|
||||
|
|
|
|||
92
src/screen.c
92
src/screen.c
|
|
@ -49,10 +49,17 @@
|
|||
// --------------------------------------------
|
||||
void (*colfunc)(void);
|
||||
void (*colfuncs[COLDRAWFUNC_MAX])(void);
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
void (*colfuncs_asm[COLDRAWFUNC_MAX])(void);
|
||||
#endif
|
||||
int colfunctype;
|
||||
|
||||
void (*spanfunc)(void);
|
||||
void (*spanfuncs[SPANDRAWFUNC_MAX])(void);
|
||||
void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void);
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
void (*spanfuncs_asm[SPANDRAWFUNC_MAX])(void);
|
||||
#endif
|
||||
|
||||
// ------------------
|
||||
// global video state
|
||||
|
|
@ -118,9 +125,6 @@ void SCR_SetDrawFuncs(void)
|
|||
colfuncs[BASEDRAWFUNC] = R_DrawColumn_8;
|
||||
spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8;
|
||||
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
spanfunc = spanfuncs[BASEDRAWFUNC];
|
||||
|
||||
colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8;
|
||||
colfuncs[COLDRAWFUNC_TRANS] = R_DrawTranslatedColumn_8;
|
||||
colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8;
|
||||
|
|
@ -160,26 +164,29 @@ void SCR_SetDrawFuncs(void)
|
|||
spanfuncs_npo2[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedTranslucentWaterSpan_NPO2_8;
|
||||
spanfuncs_npo2[SPANDRAWFUNC_FOG] = NULL; // Not needed
|
||||
|
||||
#ifdef RUSEASM
|
||||
#if (defined(RUSEASM) && defined(USE_COL_SPAN_ASM))
|
||||
if (R_ASM)
|
||||
{
|
||||
if (R_MMX)
|
||||
{
|
||||
colfuncs[BASEDRAWFUNC] = R_DrawColumn_8_MMX;
|
||||
//colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM;
|
||||
//colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM;
|
||||
colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_MMX;
|
||||
spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8_MMX;
|
||||
colfuncs_asm[BASEDRAWFUNC] = R_DrawColumn_8_MMX;
|
||||
//colfuncs_asm[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM;
|
||||
//colfuncs_asm[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM;
|
||||
colfuncs_asm[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_MMX;
|
||||
spanfuncs_asm[BASEDRAWFUNC] = R_DrawSpan_8_MMX;
|
||||
}
|
||||
else
|
||||
{
|
||||
colfuncs[BASEDRAWFUNC] = R_DrawColumn_8_ASM;
|
||||
//colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM;
|
||||
//colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM;
|
||||
colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_ASM;
|
||||
colfuncs_asm[BASEDRAWFUNC] = R_DrawColumn_8_ASM;
|
||||
//colfuncs_asm[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM;
|
||||
//colfuncs_asm[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM;
|
||||
colfuncs_asm[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_ASM;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
R_SetColumnFunc(BASEDRAWFUNC, false);
|
||||
R_SetSpanFunc(BASEDRAWFUNC, false, false);
|
||||
}
|
||||
/* else if (vid.bpp > 1)
|
||||
{
|
||||
|
|
@ -201,6 +208,65 @@ void SCR_SetDrawFuncs(void)
|
|||
*/
|
||||
}
|
||||
|
||||
void R_SetColumnFunc(size_t id, boolean brightmapped)
|
||||
{
|
||||
I_Assert(id < COLDRAWFUNC_MAX);
|
||||
|
||||
colfunctype = id;
|
||||
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
if (colfuncs_asm[id] != NULL && brightmapped == false)
|
||||
{
|
||||
colfunc = colfuncs_asm[id];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
colfunc = colfuncs[id];
|
||||
}
|
||||
}
|
||||
|
||||
void R_SetSpanFunc(size_t id, boolean npo2, boolean brightmapped)
|
||||
{
|
||||
I_Assert(id < COLDRAWFUNC_MAX);
|
||||
|
||||
if (spanfuncs_npo2[id] != NULL && npo2 == true)
|
||||
{
|
||||
spanfunc = spanfuncs_npo2[id];
|
||||
}
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
else if (spanfuncs_asm[id] != NULL && brightmapped == false)
|
||||
{
|
||||
spanfunc = spanfuncs_asm[id];
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
spanfunc = spanfuncs[id];
|
||||
}
|
||||
}
|
||||
|
||||
boolean R_CheckColumnFunc(size_t id)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (colfunc == NULL)
|
||||
{
|
||||
// Shouldn't happen.
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < COLDRAWFUNC_MAX; i++)
|
||||
{
|
||||
if (colfunc == colfuncs[id] || colfunc == colfuncs_asm[id])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SCR_SetMode(void)
|
||||
{
|
||||
if (dedicated)
|
||||
|
|
|
|||
16
src/screen.h
16
src/screen.h
|
|
@ -116,6 +116,8 @@ extern vmode_t specialmodes[NUMSPECIALMODES];
|
|||
// color mode dependent drawer function pointers
|
||||
// ---------------------------------------------
|
||||
|
||||
#define USE_COL_SPAN_ASM 0
|
||||
|
||||
#define BASEDRAWFUNC 0
|
||||
|
||||
enum
|
||||
|
|
@ -135,6 +137,10 @@ enum
|
|||
|
||||
extern void (*colfunc)(void);
|
||||
extern void (*colfuncs[COLDRAWFUNC_MAX])(void);
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
extern void (*colfuncs_asm[COLDRAWFUNC_MAX])(void);
|
||||
#endif
|
||||
extern int colfunctype;
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -163,6 +169,9 @@ enum
|
|||
extern void (*spanfunc)(void);
|
||||
extern void (*spanfuncs[SPANDRAWFUNC_MAX])(void);
|
||||
extern void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void);
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
extern void (*spanfuncs_asm[SPANDRAWFUNC_MAX])(void);
|
||||
#endif
|
||||
|
||||
// -----
|
||||
// CPUID
|
||||
|
|
@ -205,6 +214,13 @@ void SCR_SetMode(void);
|
|||
// Set drawer functions for Software
|
||||
void SCR_SetDrawFuncs(void);
|
||||
|
||||
// Set current column / span drawers
|
||||
void R_SetColumnFunc(size_t id, boolean brightmapped);
|
||||
void R_SetSpanFunc(size_t id, boolean npo2, boolean brightmapped);
|
||||
|
||||
// Compare current column drawer
|
||||
boolean R_CheckColumnFunc(size_t id);
|
||||
|
||||
// Recalc screen size dependent stuff
|
||||
void SCR_Recalc(void);
|
||||
|
||||
|
|
|
|||
13
src/w_wad.c
13
src/w_wad.c
|
|
@ -1484,10 +1484,10 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
int zErr; // Helper var.
|
||||
z_stream strm;
|
||||
unsigned long rawSize = l->disksize;
|
||||
unsigned long decSize = l->size;
|
||||
unsigned long decSize = size;
|
||||
|
||||
rawData = Z_Malloc(rawSize, PU_STATIC, NULL);
|
||||
decData = Z_Malloc(decSize, PU_STATIC, NULL);
|
||||
decData = dest;
|
||||
|
||||
if (fread(rawData, 1, rawSize, handle) < rawSize)
|
||||
I_Error("wad %d, lump %d: cannot read compressed data", wad, lump);
|
||||
|
|
@ -1505,12 +1505,8 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
zErr = inflateInit2(&strm, -15);
|
||||
if (zErr == Z_OK)
|
||||
{
|
||||
zErr = inflate(&strm, Z_FINISH);
|
||||
if (zErr == Z_STREAM_END)
|
||||
{
|
||||
M_Memcpy(dest, decData, size);
|
||||
}
|
||||
else
|
||||
zErr = inflate(&strm, Z_SYNC_FLUSH);
|
||||
if (zErr != Z_OK && zErr != Z_STREAM_END)
|
||||
{
|
||||
size = 0;
|
||||
zerr(zErr);
|
||||
|
|
@ -1524,7 +1520,6 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
}
|
||||
|
||||
Z_Free(rawData);
|
||||
Z_Free(decData);
|
||||
|
||||
#ifdef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)dest, size))
|
||||
|
|
|
|||
|
|
@ -1459,7 +1459,7 @@ static void Y_VoteStops(SINT8 pick, SINT8 level)
|
|||
if (gametype != votelevels[level][1])
|
||||
{
|
||||
INT16 lastgametype = gametype;
|
||||
gametype = votelevels[level][1];
|
||||
G_SetGametype(votelevels[level][1]);
|
||||
D_GameTypeChanged(lastgametype);
|
||||
forceresetplayers = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue