mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-25 05:41:42 +00:00
Merge branch 'next' into 'extra-textures'
# Conflicts: # src/p_maputl.c # src/r_segs.c
This commit is contained in:
commit
419cfe8007
41 changed files with 1087 additions and 285 deletions
|
@ -387,7 +387,8 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bot AI isn't programmed in analog.
|
// Bot AI isn't programmed in analog.
|
||||||
CV_SetValue(&cv_analog[1], false);
|
if (!dedicated)
|
||||||
|
CV_SetValue(&cv_analog[1], false);
|
||||||
|
|
||||||
// Let Lua scripts build ticcmds
|
// Let Lua scripts build ticcmds
|
||||||
if (LUA_HookTiccmd(player, cmd, HOOK(BotTiccmd)))
|
if (LUA_HookTiccmd(player, cmd, HOOK(BotTiccmd)))
|
||||||
|
|
|
@ -1992,7 +1992,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
|
||||||
if (var->flags & CV_NETVAR)
|
if (var->flags & CV_NETVAR)
|
||||||
{
|
{
|
||||||
// send the value of the variable
|
// send the value of the variable
|
||||||
UINT8 buf[128];
|
UINT8 buf[512];
|
||||||
UINT8 *p = buf;
|
UINT8 *p = buf;
|
||||||
|
|
||||||
// Loading from a config in a netgame? Set revert value.
|
// Loading from a config in a netgame? Set revert value.
|
||||||
|
|
|
@ -1728,12 +1728,12 @@ static void CON_DrawBackpic(void)
|
||||||
|
|
||||||
// Get the lumpnum for CONSBACK, STARTUP (Only during game startup) or fallback into MISSING.
|
// Get the lumpnum for CONSBACK, STARTUP (Only during game startup) or fallback into MISSING.
|
||||||
if (con_startup)
|
if (con_startup)
|
||||||
piclump = W_CheckNumForName("STARTUP");
|
piclump = W_CheckNumForPatchName("STARTUP");
|
||||||
else
|
else
|
||||||
piclump = W_CheckNumForName("CONSBACK");
|
piclump = W_CheckNumForPatchName("CONSBACK");
|
||||||
|
|
||||||
if (piclump == LUMPERROR)
|
if (piclump == LUMPERROR)
|
||||||
piclump = W_GetNumForName("MISSING");
|
piclump = W_GetNumForPatchName("MISSING");
|
||||||
|
|
||||||
// Cache the patch.
|
// Cache the patch.
|
||||||
con_backpic = W_CachePatchNum(piclump, PU_PATCH);
|
con_backpic = W_CachePatchNum(piclump, PU_PATCH);
|
||||||
|
|
18
src/d_main.c
18
src/d_main.c
|
@ -758,9 +758,9 @@ void D_SRB2Loop(void)
|
||||||
/* Smells like a hack... Don't fade Sonic's ass into the title screen. */
|
/* Smells like a hack... Don't fade Sonic's ass into the title screen. */
|
||||||
if (gamestate != GS_TITLESCREEN)
|
if (gamestate != GS_TITLESCREEN)
|
||||||
{
|
{
|
||||||
gstartuplumpnum = W_CheckNumForName("STARTUP");
|
gstartuplumpnum = W_CheckNumForPatchName("STARTUP");
|
||||||
if (gstartuplumpnum == LUMPERROR)
|
if (gstartuplumpnum == LUMPERROR)
|
||||||
gstartuplumpnum = W_GetNumForName("MISSING");
|
gstartuplumpnum = W_GetNumForPatchName("MISSING");
|
||||||
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(gstartuplumpnum, PU_PATCH));
|
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(gstartuplumpnum, PU_PATCH));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -983,7 +983,7 @@ void D_StartTitle(void)
|
||||||
emeralds = 0;
|
emeralds = 0;
|
||||||
memset(&luabanks, 0, sizeof(luabanks));
|
memset(&luabanks, 0, sizeof(luabanks));
|
||||||
lastmaploaded = 0;
|
lastmaploaded = 0;
|
||||||
pickedchar = R_SkinAvailable(cv_defaultskin.string);
|
pickedchar = R_SkinAvailable(cv_skin.string);
|
||||||
|
|
||||||
// In case someone exits out at the same time they start a time attack run,
|
// In case someone exits out at the same time they start a time attack run,
|
||||||
// reset modeattacking
|
// reset modeattacking
|
||||||
|
@ -1842,17 +1842,21 @@ static boolean check_top_dir(const char **path, const char *top)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmp_strlen_desc(const void *a, const void *b)
|
static int cmp_strlen_desc(const void *A, const void *B)
|
||||||
{
|
{
|
||||||
return ((int)strlen(*(const char*const*)b) - (int)strlen(*(const char*const*)a));
|
const char *pA = A;
|
||||||
|
const char *pB = B;
|
||||||
|
size_t As = strlen(pA);
|
||||||
|
size_t Bs = strlen(pB);
|
||||||
|
return ((int)Bs - (int)As);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean D_IsPathAllowed(const char *path)
|
boolean D_IsPathAllowed(const char *path)
|
||||||
{
|
{
|
||||||
const char *paths[] = {
|
char *paths[] = {
|
||||||
srb2home,
|
srb2home,
|
||||||
srb2path,
|
srb2path,
|
||||||
cv_addons_folder.string
|
cv_addons_folder.zstring
|
||||||
};
|
};
|
||||||
|
|
||||||
const size_t n_paths = sizeof paths / sizeof *paths;
|
const size_t n_paths = sizeof paths / sizeof *paths;
|
||||||
|
|
|
@ -1433,9 +1433,15 @@ static const char *locateWad(void)
|
||||||
|
|
||||||
#ifndef NOHOME
|
#ifndef NOHOME
|
||||||
// find in $HOME
|
// find in $HOME
|
||||||
I_OutputMsg(",HOME");
|
I_OutputMsg(",HOME/" DEFAULTDIR);
|
||||||
if ((envstr = I_GetEnv("HOME")) != NULL)
|
if ((envstr = I_GetEnv("HOME")) != NULL)
|
||||||
|
{
|
||||||
|
char *tmp = malloc(strlen(envstr) + sizeof(DEFAULTDIR));
|
||||||
|
strcpy(tmp, envstr);
|
||||||
|
strcat(tmp, DEFAULTDIR);
|
||||||
SEARCHWAD(envstr);
|
SEARCHWAD(envstr);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// search paths
|
// search paths
|
||||||
|
|
|
@ -5805,6 +5805,10 @@ struct int_const_s const INT_CONST[] = {
|
||||||
{"MB_SCROLLUP",MB_SCROLLUP},
|
{"MB_SCROLLUP",MB_SCROLLUP},
|
||||||
{"MB_SCROLLDOWN",MB_SCROLLDOWN},
|
{"MB_SCROLLDOWN",MB_SCROLLDOWN},
|
||||||
|
|
||||||
|
// screen.h constants
|
||||||
|
{"BASEVIDWIDTH",BASEVIDWIDTH},
|
||||||
|
{"BASEVIDHEIGHT",BASEVIDHEIGHT},
|
||||||
|
|
||||||
{NULL,0}
|
{NULL,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2336,7 +2336,7 @@ void F_SkyScroll(const char *patchname)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOADTTGFX(arr, name, maxf) \
|
#define LOADTTGFX(arr, name, maxf) \
|
||||||
lumpnum = W_CheckNumForName(name); \
|
lumpnum = W_CheckNumForPatchName(name); \
|
||||||
if (lumpnum != LUMPERROR) \
|
if (lumpnum != LUMPERROR) \
|
||||||
{ \
|
{ \
|
||||||
arr[0] = W_CachePatchName(name, PU_PATCH_LOWPRIORITY); \
|
arr[0] = W_CachePatchName(name, PU_PATCH_LOWPRIORITY); \
|
||||||
|
@ -2350,7 +2350,7 @@ else if (strlen(name) <= 6) \
|
||||||
{ \
|
{ \
|
||||||
sprintf(&lumpname[cnt], "%.2hu", (UINT16)(i+1)); \
|
sprintf(&lumpname[cnt], "%.2hu", (UINT16)(i+1)); \
|
||||||
lumpname[8] = 0; \
|
lumpname[8] = 0; \
|
||||||
lumpnum = W_CheckNumForName(lumpname); \
|
lumpnum = W_CheckNumForPatchName(lumpname); \
|
||||||
if (lumpnum != LUMPERROR) \
|
if (lumpnum != LUMPERROR) \
|
||||||
arr[i] = W_CachePatchName(lumpname, PU_PATCH_LOWPRIORITY); \
|
arr[i] = W_CachePatchName(lumpname, PU_PATCH_LOWPRIORITY); \
|
||||||
else \
|
else \
|
||||||
|
@ -4116,7 +4116,7 @@ static void F_GetPageTextGeometry(UINT8 *pagelines, boolean *rightside, INT32 *b
|
||||||
// reuse:
|
// reuse:
|
||||||
// cutnum -> promptnum
|
// cutnum -> promptnum
|
||||||
// scenenum -> pagenum
|
// scenenum -> pagenum
|
||||||
lumpnum_t iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname);
|
lumpnum_t iconlump = W_CheckNumForPatchName(textprompts[cutnum]->page[scenenum].iconname);
|
||||||
|
|
||||||
*pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4;
|
*pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4;
|
||||||
*rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside);
|
*rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside);
|
||||||
|
@ -4508,7 +4508,7 @@ void F_TextPromptDrawer(void)
|
||||||
if (!promptactive)
|
if (!promptactive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname);
|
iconlump = W_CheckNumForPatchName(textprompts[cutnum]->page[scenenum].iconname);
|
||||||
F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr);
|
F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr);
|
||||||
|
|
||||||
// Draw gfx first
|
// Draw gfx first
|
||||||
|
|
|
@ -699,6 +699,15 @@ static void initdirpath(char *dirpath, size_t *dirpathindex, int depthleft)
|
||||||
dirpathindex[depthleft]--;
|
dirpathindex[depthleft]--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//sortdir by name?
|
||||||
|
static int lumpnamecompare(const void *A, const void *B)
|
||||||
|
{
|
||||||
|
const lumpinfo_t *pA = A;
|
||||||
|
const lumpinfo_t *pB = B;
|
||||||
|
return strcmp((pA->fullname), (pB->fullname));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders)
|
lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders)
|
||||||
{
|
{
|
||||||
DIR **dirhandle;
|
DIR **dirhandle;
|
||||||
|
@ -889,6 +898,9 @@ lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders)
|
||||||
free(dirpathindex);
|
free(dirpathindex);
|
||||||
free(dirhandle);
|
free(dirhandle);
|
||||||
|
|
||||||
|
//sort files and directories
|
||||||
|
qsort (lumpinfo, numlumps, sizeof(lumpinfo_t), lumpnamecompare);
|
||||||
|
|
||||||
(*nlmp) = numlumps;
|
(*nlmp) = numlumps;
|
||||||
return lumpinfo;
|
return lumpinfo;
|
||||||
}
|
}
|
||||||
|
|
18
src/g_demo.c
18
src/g_demo.c
|
@ -67,6 +67,8 @@ static UINT8 *metalbuffer = NULL;
|
||||||
static UINT8 *metal_p;
|
static UINT8 *metal_p;
|
||||||
static UINT16 metalversion;
|
static UINT16 metalversion;
|
||||||
|
|
||||||
|
consvar_t cv_resyncdemo = CVAR_INIT("resyncdemo", "On", 0, CV_OnOff, NULL);
|
||||||
|
|
||||||
// extra data stuff (events registered this frame while recording)
|
// extra data stuff (events registered this frame while recording)
|
||||||
static struct {
|
static struct {
|
||||||
UINT8 flags; // EZT flags
|
UINT8 flags; // EZT flags
|
||||||
|
@ -549,6 +551,9 @@ void G_ConsGhostTic(void)
|
||||||
|
|
||||||
testmo = players[0].mo;
|
testmo = players[0].mo;
|
||||||
|
|
||||||
|
if (P_MobjWasRemoved(testmo))
|
||||||
|
return; // No valid mobj exists, probably because of unexpected quit
|
||||||
|
|
||||||
// Grab ghost data.
|
// Grab ghost data.
|
||||||
ziptic = READUINT8(demo_p);
|
ziptic = READUINT8(demo_p);
|
||||||
if (ziptic & GZT_XYZ)
|
if (ziptic & GZT_XYZ)
|
||||||
|
@ -664,11 +669,14 @@ void G_ConsGhostTic(void)
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
|
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
|
||||||
demosynced = false;
|
demosynced = false;
|
||||||
|
|
||||||
P_UnsetThingPosition(testmo);
|
if (cv_resyncdemo.value)
|
||||||
testmo->x = oldghost.x;
|
{
|
||||||
testmo->y = oldghost.y;
|
P_UnsetThingPosition(testmo);
|
||||||
P_SetThingPosition(testmo);
|
testmo->x = oldghost.x;
|
||||||
testmo->z = oldghost.z;
|
testmo->y = oldghost.y;
|
||||||
|
P_SetThingPosition(testmo);
|
||||||
|
testmo->z = oldghost.z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*demo_p == DEMOMARKER)
|
if (*demo_p == DEMOMARKER)
|
||||||
|
|
|
@ -35,6 +35,7 @@ typedef enum
|
||||||
} demo_file_override_e;
|
} demo_file_override_e;
|
||||||
|
|
||||||
extern demo_file_override_e demofileoverride;
|
extern demo_file_override_e demofileoverride;
|
||||||
|
extern consvar_t cv_resyncdemo;
|
||||||
|
|
||||||
// Quit after playing a demo from cmdline.
|
// Quit after playing a demo from cmdline.
|
||||||
extern boolean singledemo;
|
extern boolean singledemo;
|
||||||
|
|
30
src/g_game.c
30
src/g_game.c
|
@ -1363,11 +1363,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL);
|
axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL);
|
||||||
if (PLAYERINPUTDOWN(ssplayer, GC_FIRENORMAL) || (usejoystick && axis > 0))
|
if (PLAYERINPUTDOWN(ssplayer, GC_FIRENORMAL) || (usejoystick && axis > 0))
|
||||||
cmd->buttons |= BT_FIRENORMAL;
|
cmd->buttons |= BT_FIRENORMAL;
|
||||||
|
|
||||||
// Toss flag button
|
// Toss flag button
|
||||||
if (PLAYERINPUTDOWN(ssplayer, GC_TOSSFLAG))
|
if (PLAYERINPUTDOWN(ssplayer, GC_TOSSFLAG))
|
||||||
cmd->buttons |= BT_TOSSFLAG;
|
cmd->buttons |= BT_TOSSFLAG;
|
||||||
|
|
||||||
// Shield button
|
// Shield button
|
||||||
axis = PlayerJoyAxis(ssplayer, JA_SHIELD);
|
axis = PlayerJoyAxis(ssplayer, JA_SHIELD);
|
||||||
if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD) || (usejoystick && axis > 0))
|
if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD) || (usejoystick && axis > 0))
|
||||||
|
@ -1386,6 +1386,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
if (PLAYERINPUTDOWN(ssplayer, GC_SPIN) || (usejoystick && axis > 0))
|
if (PLAYERINPUTDOWN(ssplayer, GC_SPIN) || (usejoystick && axis > 0))
|
||||||
cmd->buttons |= BT_SPIN;
|
cmd->buttons |= BT_SPIN;
|
||||||
|
|
||||||
|
if (gamestate != GS_LEVEL) // not in a level, don't build anything else
|
||||||
|
{
|
||||||
|
cmd->angleturn = ticcmd_oldangleturn[forplayer];
|
||||||
|
cmd->aiming = G_ClipAimingPitch(myaiming);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Centerview can be a toggle in simple mode!
|
// Centerview can be a toggle in simple mode!
|
||||||
{
|
{
|
||||||
static boolean last_centerviewdown[2], centerviewhold[2]; // detect taps for toggle behavior
|
static boolean last_centerviewdown[2], centerviewhold[2]; // detect taps for toggle behavior
|
||||||
|
@ -1420,7 +1427,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
|
|
||||||
ticcmd_centerviewdown[forplayer] = true;
|
ticcmd_centerviewdown[forplayer] = true;
|
||||||
}
|
}
|
||||||
else if (ticcmd_centerviewdown[forplayer])
|
else if (ticcmd_centerviewdown[forplayer] || (leveltime < 5))
|
||||||
{
|
{
|
||||||
if (controlstyle == CS_SIMPLE)
|
if (controlstyle == CS_SIMPLE)
|
||||||
{
|
{
|
||||||
|
@ -1435,6 +1442,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
P_MobjWasRemoved(ticcmd_ztargetfocus[forplayer]) ||
|
P_MobjWasRemoved(ticcmd_ztargetfocus[forplayer]) ||
|
||||||
|
(leveltime < 5) ||
|
||||||
|
(player->playerstate != PST_LIVE) ||
|
||||||
|
player->exiting ||
|
||||||
!ticcmd_ztargetfocus[forplayer]->health ||
|
!ticcmd_ztargetfocus[forplayer]->health ||
|
||||||
(ticcmd_ztargetfocus[forplayer]->type == MT_EGGMOBILE3 && !ticcmd_ztargetfocus[forplayer]->movecount) // Sea Egg is moving around underground and shouldn't be tracked
|
(ticcmd_ztargetfocus[forplayer]->type == MT_EGGMOBILE3 && !ticcmd_ztargetfocus[forplayer]->movecount) // Sea Egg is moving around underground and shouldn't be tracked
|
||||||
)
|
)
|
||||||
|
@ -1466,7 +1476,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]);
|
P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]);
|
||||||
newtarget->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating
|
newtarget->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating
|
||||||
|
|
||||||
if (player->mo && P_AproxDistance(
|
if (player->mo && R_PointToDist2(0, 0,
|
||||||
player->mo->x - ticcmd_ztargetfocus[forplayer]->x,
|
player->mo->x - ticcmd_ztargetfocus[forplayer]->x,
|
||||||
player->mo->y - ticcmd_ztargetfocus[forplayer]->y
|
player->mo->y - ticcmd_ztargetfocus[forplayer]->y
|
||||||
) > 50*player->mo->scale)
|
) > 50*player->mo->scale)
|
||||||
|
@ -1714,7 +1724,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
// At this point, cmd doesn't contain the final angle yet,
|
// At this point, cmd doesn't contain the final angle yet,
|
||||||
// So we need to temporarily transform it so Lua scripters
|
// So we need to temporarily transform it so Lua scripters
|
||||||
// don't need to handle it differently than in other hooks.
|
// don't need to handle it differently than in other hooks.
|
||||||
if (addedtogame && gamestate == GS_LEVEL)
|
if (addedtogame)
|
||||||
{
|
{
|
||||||
INT16 extra = ticcmd_oldangleturn[forplayer] - player->oldrelangleturn;
|
INT16 extra = ticcmd_oldangleturn[forplayer] - player->oldrelangleturn;
|
||||||
INT16 origangle = cmd->angleturn;
|
INT16 origangle = cmd->angleturn;
|
||||||
|
@ -4018,7 +4028,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent)
|
||||||
INT32 i;
|
INT32 i;
|
||||||
INT16 newmapnum;
|
INT16 newmapnum;
|
||||||
boolean spec = G_IsSpecialStage(gamemap);
|
boolean spec = G_IsSpecialStage(gamemap);
|
||||||
|
|
||||||
// go to next level
|
// go to next level
|
||||||
// newmapnum is 0-based, unlike gamemap
|
// newmapnum is 0-based, unlike gamemap
|
||||||
if (nextmapoverride != 0)
|
if (nextmapoverride != 0)
|
||||||
|
@ -4122,7 +4132,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent)
|
||||||
|
|
||||||
if (spec && (!gottoken || ignoretokens) && !nextmapoverride)
|
if (spec && (!gottoken || ignoretokens) && !nextmapoverride)
|
||||||
newmapnum = lastmap; // Exiting from a special stage? Go back to the game. Tails 08-11-2001
|
newmapnum = lastmap; // Exiting from a special stage? Go back to the game. Tails 08-11-2001
|
||||||
|
|
||||||
if (!(gametyperules & GTR_CAMPAIGN))
|
if (!(gametyperules & GTR_CAMPAIGN))
|
||||||
{
|
{
|
||||||
if (cv_advancemap.value == 0) // Stay on same map.
|
if (cv_advancemap.value == 0) // Stay on same map.
|
||||||
|
@ -4130,7 +4140,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent)
|
||||||
else if (cv_advancemap.value == 2) // Go to random map.
|
else if (cv_advancemap.value == 2) // Go to random map.
|
||||||
newmapnum = RandMap(G_TOLFlag(gametype_to_use), prevmap);
|
newmapnum = RandMap(G_TOLFlag(gametype_to_use), prevmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newmapnum;
|
return newmapnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4140,7 +4150,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent)
|
||||||
static void G_DoCompleted(void)
|
static void G_DoCompleted(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
tokenlist = 0; // Reset the list
|
tokenlist = 0; // Reset the list
|
||||||
|
|
||||||
if (modeattacking && pausedelay)
|
if (modeattacking && pausedelay)
|
||||||
|
@ -4168,7 +4178,7 @@ static void G_DoCompleted(void)
|
||||||
//Get and set prevmap/nextmap
|
//Get and set prevmap/nextmap
|
||||||
prevmap = (INT16)(gamemap-1);
|
prevmap = (INT16)(gamemap-1);
|
||||||
nextmap = G_GetNextMap(false, false);
|
nextmap = G_GetNextMap(false, false);
|
||||||
|
|
||||||
automapactive = false;
|
automapactive = false;
|
||||||
|
|
||||||
// We are committed to this map now.
|
// We are committed to this map now.
|
||||||
|
|
|
@ -2294,14 +2294,14 @@ static void HWR_ProcessSeg(void)
|
||||||
if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
|
if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
side_t *side = R_GetFFloorSide(gl_curline, rover);
|
side_t *side = R_GetFFloorSide(gl_curline->linedef, rover, gl_backsector);
|
||||||
|
|
||||||
boolean do_texture_skew;
|
boolean do_texture_skew;
|
||||||
boolean dont_peg_bottom;
|
boolean dont_peg_bottom;
|
||||||
|
|
||||||
if (rover->master->flags & ML_TFERLINE)
|
if (rover->master->flags & ML_TFERLINE)
|
||||||
{
|
{
|
||||||
line_t *newline = R_GetFFloorLine(gl_curline, rover);
|
line_t *newline = R_GetFFloorLine(gl_curline->linedef, rover, gl_backsector);
|
||||||
do_texture_skew = newline->flags & ML_SKEWTD;
|
do_texture_skew = newline->flags & ML_SKEWTD;
|
||||||
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
|
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
|
||||||
}
|
}
|
||||||
|
@ -2459,14 +2459,14 @@ static void HWR_ProcessSeg(void)
|
||||||
if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
|
if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
side_t *side = R_GetFFloorSide(gl_curline, rover);
|
side_t *side = R_GetFFloorSide(gl_curline->linedef, rover, gl_backsector);
|
||||||
|
|
||||||
boolean do_texture_skew;
|
boolean do_texture_skew;
|
||||||
boolean dont_peg_bottom;
|
boolean dont_peg_bottom;
|
||||||
|
|
||||||
if (rover->master->flags & ML_TFERLINE)
|
if (rover->master->flags & ML_TFERLINE)
|
||||||
{
|
{
|
||||||
line_t *newline = R_GetFFloorLine(gl_curline, rover);
|
line_t *newline = R_GetFFloorLine(gl_curline->linedef, rover, gl_backsector);
|
||||||
do_texture_skew = newline->flags & ML_SKEWTD;
|
do_texture_skew = newline->flags & ML_SKEWTD;
|
||||||
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
|
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
|
||||||
}
|
}
|
||||||
|
@ -6000,7 +6000,9 @@ static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean
|
||||||
if (cv_glshearing.value == 1 || (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox)))
|
if (cv_glshearing.value == 1 || (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox)))
|
||||||
{
|
{
|
||||||
fixed_t fixedaiming = AIMINGTODY(aimingangle);
|
fixed_t fixedaiming = AIMINGTODY(aimingangle);
|
||||||
trans->viewaiming = FIXED_TO_FLOAT(fixedaiming);
|
trans->viewaiming = FIXED_TO_FLOAT(fixedaiming) * ((float)vid.width / vid.height) / ((float)BASEVIDWIDTH / BASEVIDHEIGHT);
|
||||||
|
if (splitscreen)
|
||||||
|
trans->viewaiming *= 2.125; // splitscreen adjusts fov with 0.8, so compensate (but only halfway, since splitscreen means only half the screen is used)
|
||||||
trans->shearing = true;
|
trans->shearing = true;
|
||||||
gl_aimingangle = 0;
|
gl_aimingangle = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1093,19 +1093,19 @@ static modelspr2frames_t *HWR_GetModelSprite2Frames(md2_t *md2, UINT16 spr2)
|
||||||
return &md2->model->superspr2frames[spr2];
|
return &md2->model->superspr2frames[spr2];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (md2->model->spr2frames)
|
if (md2->model->spr2frames[spr2].numframes)
|
||||||
return &md2->model->spr2frames[spr2];
|
return &md2->model->spr2frames[spr2];
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static modelspr2frames_t *HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT16 spr2, player_t *player)
|
static UINT16 HWR_GetModelSprite2Num(md2_t *md2, skin_t *skin, UINT16 spr2, player_t *player)
|
||||||
{
|
{
|
||||||
UINT16 super = 0;
|
UINT16 super = 0;
|
||||||
UINT8 i = 0;
|
UINT8 i = 0;
|
||||||
|
|
||||||
if (!md2 || !md2->model || !skin)
|
if (!md2 || !md2->model || !skin)
|
||||||
return HWR_GetModelSprite2Frames(md2, 0);
|
return 0;
|
||||||
|
|
||||||
while (!HWR_GetModelSprite2Frames(md2, spr2)
|
while (!HWR_GetModelSprite2Frames(md2, spr2)
|
||||||
&& spr2 != SPR2_STND
|
&& spr2 != SPR2_STND
|
||||||
|
@ -1145,7 +1145,7 @@ static modelspr2frames_t *HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT16 s
|
||||||
if (i >= 32) // probably an infinite loop...
|
if (i >= 32) // probably an infinite loop...
|
||||||
spr2 = 0;
|
spr2 = 0;
|
||||||
|
|
||||||
return HWR_GetModelSprite2Frames(md2, spr2);
|
return spr2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust texture coords of model to fit into a patch's max_s and max_t
|
// Adjust texture coords of model to fit into a patch's max_s and max_t
|
||||||
|
@ -1269,6 +1269,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
||||||
const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(spr->mobj));
|
const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(spr->mobj));
|
||||||
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj));
|
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj));
|
||||||
spritedef_t *sprdef;
|
spritedef_t *sprdef;
|
||||||
|
UINT16 spr2 = 0;
|
||||||
spriteframe_t *sprframe;
|
spriteframe_t *sprframe;
|
||||||
INT32 mod;
|
INT32 mod;
|
||||||
interpmobjstate_t interp;
|
interpmobjstate_t interp;
|
||||||
|
@ -1438,13 +1439,17 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
||||||
|
|
||||||
frame = (spr->mobj->frame & FF_FRAMEMASK);
|
frame = (spr->mobj->frame & FF_FRAMEMASK);
|
||||||
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
||||||
spr2frames = HWR_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player);
|
{
|
||||||
|
spr2 = HWR_GetModelSprite2Num(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player);
|
||||||
|
spr2frames = HWR_GetModelSprite2Frames(md2, spr2);
|
||||||
|
}
|
||||||
if (spr2frames)
|
if (spr2frames)
|
||||||
{
|
{
|
||||||
|
spritedef_t *defaultdef = P_GetSkinSpritedef(spr->mobj->skin, spr2);
|
||||||
mod = spr2frames->numframes;
|
mod = spr2frames->numframes;
|
||||||
#ifndef DONTHIDEDIFFANIMLENGTH // by default, different anim length is masked by the mod
|
#ifndef DONTHIDEDIFFANIMLENGTH // by default, different anim length is masked by the mod
|
||||||
if (mod > (INT32)sprdef->numframes)
|
if (mod > (INT32)defaultdef->numframes)
|
||||||
mod = sprdef->numframes;
|
mod = defaultdef->numframes;
|
||||||
#endif
|
#endif
|
||||||
if (!mod)
|
if (!mod)
|
||||||
mod = 1;
|
mod = 1;
|
||||||
|
|
|
@ -272,7 +272,7 @@ void HU_LoadFontCharacters(fontdef_t *font, const char *prefix)
|
||||||
for (i = 0; i < FONTSIZE; i++, j++)
|
for (i = 0; i < FONTSIZE; i++, j++)
|
||||||
{
|
{
|
||||||
sprintf(buffer, "%.5s%.3d", prefix, j);
|
sprintf(buffer, "%.5s%.3d", prefix, j);
|
||||||
if (W_CheckNumForName(buffer) == LUMPERROR)
|
if (W_CheckNumForPatchName(buffer) == LUMPERROR)
|
||||||
font->chars[i] = NULL;
|
font->chars[i] = NULL;
|
||||||
else
|
else
|
||||||
font->chars[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
font->chars[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||||
|
@ -2015,13 +2015,13 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
||||||
greycheck = greycheckdef;
|
greycheck = greycheckdef;
|
||||||
supercheck = supercheckdef;
|
supercheck = supercheckdef;
|
||||||
|
|
||||||
if (tab[i].color == skincolor_redteam) //red
|
if (players[tab[i].num].ctfteam == 1) //red
|
||||||
{
|
{
|
||||||
redplayers++;
|
redplayers++;
|
||||||
x = 14 + (BASEVIDWIDTH/2);
|
x = 14 + (BASEVIDWIDTH/2);
|
||||||
y = (redplayers * 9) + 20;
|
y = (redplayers * 9) + 20;
|
||||||
}
|
}
|
||||||
else if (tab[i].color == skincolor_blueteam) //blue
|
else if (players[tab[i].num].ctfteam == 2) //blue
|
||||||
{
|
{
|
||||||
blueplayers++;
|
blueplayers++;
|
||||||
x = 14;
|
x = 14;
|
||||||
|
@ -2103,7 +2103,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
||||||
if (players[tab[i].num].spectator)
|
if (players[tab[i].num].spectator)
|
||||||
continue; //ignore them.
|
continue; //ignore them.
|
||||||
|
|
||||||
if (tab[i].color == skincolor_redteam) //red
|
if (players[tab[i].num].ctfteam == 1) //red
|
||||||
{
|
{
|
||||||
if (redplayers++ > 8)
|
if (redplayers++ > 8)
|
||||||
{
|
{
|
||||||
|
@ -2111,7 +2111,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
||||||
break; // don't make more loops than we need to.
|
break; // don't make more loops than we need to.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tab[i].color == skincolor_blueteam) //blue
|
else if (players[tab[i].num].ctfteam == 2) //blue
|
||||||
{
|
{
|
||||||
if (blueplayers++ > 8)
|
if (blueplayers++ > 8)
|
||||||
{
|
{
|
||||||
|
@ -2142,14 +2142,14 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
||||||
if (players[tab[i].num].spectator)
|
if (players[tab[i].num].spectator)
|
||||||
continue; //ignore them.
|
continue; //ignore them.
|
||||||
|
|
||||||
if (tab[i].color == skincolor_redteam) //red
|
if (players[tab[i].num].ctfteam == 1) //red
|
||||||
{
|
{
|
||||||
if (redplayers++ > 8)
|
if (redplayers++ > 8)
|
||||||
continue;
|
continue;
|
||||||
x = 32 + (BASEVIDWIDTH/2);
|
x = 32 + (BASEVIDWIDTH/2);
|
||||||
y = (redplayers * 16) + 16;
|
y = (redplayers * 16) + 16;
|
||||||
}
|
}
|
||||||
else if (tab[i].color == skincolor_blueteam) //blue
|
else if (players[tab[i].num].ctfteam == 2) //blue
|
||||||
{
|
{
|
||||||
if (blueplayers++ > 8)
|
if (blueplayers++ > 8)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -346,6 +346,18 @@ static int lib_reserveLuabanks(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lib_tofixed(lua_State *L)
|
||||||
|
{
|
||||||
|
const char *arg = luaL_checkstring(L, 1);
|
||||||
|
char *end;
|
||||||
|
float f = strtof(arg, &end);
|
||||||
|
if (*end != '\0')
|
||||||
|
lua_pushnil(L);
|
||||||
|
else
|
||||||
|
lua_pushnumber(L, FLOAT_TO_FIXED(f));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// M_MENU
|
// M_MENU
|
||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
|
@ -642,7 +654,7 @@ static int lib_pSpawnMobj(lua_State *L)
|
||||||
NOHUD
|
NOHUD
|
||||||
INLEVEL
|
INLEVEL
|
||||||
NOSPAWNNULL
|
NOSPAWNNULL
|
||||||
LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ);
|
LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type, NULL), META_MOBJ);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4334,6 +4346,7 @@ static luaL_Reg lib[] = {
|
||||||
{"userdataMetatable", lib_userdataMetatable},
|
{"userdataMetatable", lib_userdataMetatable},
|
||||||
{"IsPlayerAdmin", lib_isPlayerAdmin},
|
{"IsPlayerAdmin", lib_isPlayerAdmin},
|
||||||
{"reserveLuabanks", lib_reserveLuabanks},
|
{"reserveLuabanks", lib_reserveLuabanks},
|
||||||
|
{"tofixed", lib_tofixed},
|
||||||
|
|
||||||
// m_menu
|
// m_menu
|
||||||
{"M_MoveColorAfter",lib_pMoveColorAfter},
|
{"M_MoveColorAfter",lib_pMoveColorAfter},
|
||||||
|
|
|
@ -180,7 +180,8 @@ static const char *CopyString(huddrawlist_h list, const char* str)
|
||||||
const char *old_offset = list->strbuf;
|
const char *old_offset = list->strbuf;
|
||||||
size_t i;
|
size_t i;
|
||||||
if (list->strbuf_capacity == 0) list->strbuf_capacity = 256;
|
if (list->strbuf_capacity == 0) list->strbuf_capacity = 256;
|
||||||
else list->strbuf_capacity *= 2;
|
while (list->strbuf_capacity <= list->strbuf_len + lenstr + 1)
|
||||||
|
list->strbuf_capacity *= 2;
|
||||||
list->strbuf = (char*) Z_Realloc(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL);
|
list->strbuf = (char*) Z_Realloc(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL);
|
||||||
|
|
||||||
// align the string pointers to make sure old pointers don't point towards invalid addresses
|
// align the string pointers to make sure old pointers don't point towards invalid addresses
|
||||||
|
|
|
@ -242,17 +242,12 @@ static int lib_getSpriteInfo(lua_State *L)
|
||||||
UINT32 i = NUMSPRITES;
|
UINT32 i = NUMSPRITES;
|
||||||
lua_remove(L, 1);
|
lua_remove(L, 1);
|
||||||
|
|
||||||
if (lua_isstring(L, 1))
|
if (lua_type(L, 1) == LUA_TSTRING)
|
||||||
{
|
{
|
||||||
const char *name = lua_tostring(L, 1);
|
const char *name = lua_tostring(L, 1);
|
||||||
INT32 spr = R_GetSpriteNumByName(name);
|
INT32 spr = R_GetSpriteNumByName(name);
|
||||||
if (spr == NUMSPRITES)
|
if (spr == NUMSPRITES)
|
||||||
{
|
return luaL_error(L, "unknown sprite name %s", name);
|
||||||
char *check;
|
|
||||||
i = strtol(name, &check, 10);
|
|
||||||
if (check == name || *check != '\0')
|
|
||||||
return luaL_error(L, "unknown sprite name %s", name);
|
|
||||||
}
|
|
||||||
i = spr;
|
i = spr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1740,7 +1735,7 @@ static int lib_setSkinColor(lua_State *L)
|
||||||
else if (i == 6 || (str && fastcmp(str,"accessible"))) {
|
else if (i == 6 || (str && fastcmp(str,"accessible"))) {
|
||||||
boolean v = lua_toboolean(L, 3);
|
boolean v = lua_toboolean(L, 3);
|
||||||
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
|
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
|
||||||
CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum);
|
CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.\n", cnum);
|
||||||
else
|
else
|
||||||
info->accessible = v;
|
info->accessible = v;
|
||||||
}
|
}
|
||||||
|
@ -1835,7 +1830,7 @@ static int skincolor_set(lua_State *L)
|
||||||
else if (fastcmp(field,"accessible")) {
|
else if (fastcmp(field,"accessible")) {
|
||||||
boolean v = lua_toboolean(L, 3);
|
boolean v = lua_toboolean(L, 3);
|
||||||
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
|
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
|
||||||
CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum);
|
CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.\n", cnum);
|
||||||
else
|
else
|
||||||
info->accessible = v;
|
info->accessible = v;
|
||||||
} else
|
} else
|
||||||
|
|
45
src/m_menu.c
45
src/m_menu.c
|
@ -263,7 +263,7 @@ static void M_ConfirmTeamScramble(INT32 choice);
|
||||||
static void M_ConfirmTeamChange(INT32 choice);
|
static void M_ConfirmTeamChange(INT32 choice);
|
||||||
static void M_SecretsMenu(INT32 choice);
|
static void M_SecretsMenu(INT32 choice);
|
||||||
static void M_SetupChoosePlayer(INT32 choice);
|
static void M_SetupChoosePlayer(INT32 choice);
|
||||||
static UINT16 M_SetupChoosePlayerDirect(INT32 choice);
|
static INT32 M_SetupChoosePlayerDirect(INT32 choice);
|
||||||
static void M_QuitSRB2(INT32 choice);
|
static void M_QuitSRB2(INT32 choice);
|
||||||
menu_t SP_MainDef, OP_MainDef;
|
menu_t SP_MainDef, OP_MainDef;
|
||||||
menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef;
|
menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef;
|
||||||
|
@ -3674,7 +3674,7 @@ void M_StartControlPanel(void)
|
||||||
{
|
{
|
||||||
// Devmode unlocks Pandora's Box in the pause menu
|
// Devmode unlocks Pandora's Box in the pause menu
|
||||||
boolean pandora = ((M_SecretUnlocked(SECRET_PANDORA, serverGamedata) || cv_debug || devparm) && !marathonmode);
|
boolean pandora = ((M_SecretUnlocked(SECRET_PANDORA, serverGamedata) || cv_debug || devparm) && !marathonmode);
|
||||||
|
|
||||||
if (gamestate != GS_LEVEL || ultimatemode) // intermission, so gray out stuff.
|
if (gamestate != GS_LEVEL || ultimatemode) // intermission, so gray out stuff.
|
||||||
{
|
{
|
||||||
SPauseMenu[spause_pandora].status = (pandora) ? (IT_GRAYEDOUT) : (IT_DISABLED);
|
SPauseMenu[spause_pandora].status = (pandora) ? (IT_GRAYEDOUT) : (IT_DISABLED);
|
||||||
|
@ -4030,11 +4030,11 @@ static void M_DrawThermo(INT32 x, INT32 y, consvar_t *cv)
|
||||||
lumpnum_t leftlump, rightlump, centerlump[2], cursorlump;
|
lumpnum_t leftlump, rightlump, centerlump[2], cursorlump;
|
||||||
patch_t *p;
|
patch_t *p;
|
||||||
|
|
||||||
leftlump = W_GetNumForName("M_THERML");
|
leftlump = W_GetNumForPatchName("M_THERML");
|
||||||
rightlump = W_GetNumForName("M_THERMR");
|
rightlump = W_GetNumForPatchName("M_THERMR");
|
||||||
centerlump[0] = W_GetNumForName("M_THERMM");
|
centerlump[0] = W_GetNumForPatchName("M_THERMM");
|
||||||
centerlump[1] = W_GetNumForName("M_THERMM");
|
centerlump[1] = W_GetNumForPatchName("M_THERMM");
|
||||||
cursorlump = W_GetNumForName("M_THERMO");
|
cursorlump = W_GetNumForPatchName("M_THERMO");
|
||||||
|
|
||||||
V_DrawScaledPatch(xx, y, 0, p = W_CachePatchNum(leftlump,PU_PATCH));
|
V_DrawScaledPatch(xx, y, 0, p = W_CachePatchNum(leftlump,PU_PATCH));
|
||||||
xx += p->width - p->leftoffset;
|
xx += p->width - p->leftoffset;
|
||||||
|
@ -4156,7 +4156,7 @@ static void M_DrawStaticBox(fixed_t x, fixed_t y, INT32 flags, fixed_t w, fixed_
|
||||||
temp = (gametic % temp) * h*2*FRACUNIT; // Which frame to draw
|
temp = (gametic % temp) * h*2*FRACUNIT; // Which frame to draw
|
||||||
|
|
||||||
V_DrawCroppedPatch(x*FRACUNIT, y*FRACUNIT, (w*FRACUNIT) / 160, (h*FRACUNIT) / 100, flags, patch, NULL, 0, temp, w*2*FRACUNIT, h*2*FRACUNIT);
|
V_DrawCroppedPatch(x*FRACUNIT, y*FRACUNIT, (w*FRACUNIT) / 160, (h*FRACUNIT) / 100, flags, patch, NULL, 0, temp, w*2*FRACUNIT, h*2*FRACUNIT);
|
||||||
|
|
||||||
W_UnlockCachedPatch(patch);
|
W_UnlockCachedPatch(patch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -7000,7 +7000,10 @@ static void M_LevelSelectWarp(INT32 choice)
|
||||||
if (currentMenu == &SP_LevelSelectDef || currentMenu == &SP_PauseLevelSelectDef)
|
if (currentMenu == &SP_LevelSelectDef || currentMenu == &SP_PauseLevelSelectDef)
|
||||||
{
|
{
|
||||||
if (cursaveslot > 0) // do we have a save slot to load?
|
if (cursaveslot > 0) // do we have a save slot to load?
|
||||||
|
{
|
||||||
|
CV_StealthSet(&cv_skin, DEFAULTSKIN); // already handled by loadgame so we don't want this
|
||||||
G_LoadGame((UINT32)cursaveslot, startmap); // reload from SP save data: this is needed to keep score/lives/continues from reverting to defaults
|
G_LoadGame((UINT32)cursaveslot, startmap); // reload from SP save data: this is needed to keep score/lives/continues from reverting to defaults
|
||||||
|
}
|
||||||
else // no save slot, start new game but keep the current skin
|
else // no save slot, start new game but keep the current skin
|
||||||
{
|
{
|
||||||
M_ClearMenus(true);
|
M_ClearMenus(true);
|
||||||
|
@ -8649,9 +8652,14 @@ static void M_LoadSelect(INT32 choice)
|
||||||
M_NewGame();
|
M_NewGame();
|
||||||
}
|
}
|
||||||
else if (savegameinfo[saveSlotSelected-1].gamemap & 8192) // Completed
|
else if (savegameinfo[saveSlotSelected-1].gamemap & 8192) // Completed
|
||||||
|
{
|
||||||
M_LoadGameLevelSelect(0);
|
M_LoadGameLevelSelect(0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
CV_StealthSet(&cv_skin, DEFAULTSKIN); // already handled by loadgame so we don't want this
|
||||||
G_LoadGame((UINT32)saveSlotSelected, 0);
|
G_LoadGame((UINT32)saveSlotSelected, 0);
|
||||||
|
}
|
||||||
|
|
||||||
cursaveslot = saveSlotSelected;
|
cursaveslot = saveSlotSelected;
|
||||||
}
|
}
|
||||||
|
@ -9072,7 +9080,7 @@ static void M_CacheCharacterSelectEntry(INT32 i, INT32 skinnum)
|
||||||
description[i].namepic = W_CachePatchName(description[i].nametag, PU_PATCH);
|
description[i].namepic = W_CachePatchName(description[i].nametag, PU_PATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT16 M_SetupChoosePlayerDirect(INT32 choice)
|
static INT32 M_SetupChoosePlayerDirect(INT32 choice)
|
||||||
{
|
{
|
||||||
INT32 skinnum, botskinnum;
|
INT32 skinnum, botskinnum;
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
|
@ -9161,7 +9169,7 @@ static UINT16 M_SetupChoosePlayerDirect(INT32 choice)
|
||||||
|
|
||||||
static void M_SetupChoosePlayer(INT32 choice)
|
static void M_SetupChoosePlayer(INT32 choice)
|
||||||
{
|
{
|
||||||
UINT16 skinset = M_SetupChoosePlayerDirect(choice);
|
INT32 skinset = M_SetupChoosePlayerDirect(choice);
|
||||||
if (skinset != MAXCHARACTERSLOTS)
|
if (skinset != MAXCHARACTERSLOTS)
|
||||||
{
|
{
|
||||||
M_ChoosePlayer(skinset);
|
M_ChoosePlayer(skinset);
|
||||||
|
@ -9510,6 +9518,8 @@ static void M_ChoosePlayer(INT32 choice)
|
||||||
//lastmapsaved = 0;
|
//lastmapsaved = 0;
|
||||||
gamecomplete = 0;
|
gamecomplete = 0;
|
||||||
|
|
||||||
|
CV_StealthSet(&cv_skin, skins[skinnum]->name);
|
||||||
|
|
||||||
G_DeferedInitNew(ultmode, G_BuildMapName(startmap), skinnum, false, fromlevelselect);
|
G_DeferedInitNew(ultmode, G_BuildMapName(startmap), skinnum, false, fromlevelselect);
|
||||||
COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this
|
COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this
|
||||||
|
|
||||||
|
@ -10186,7 +10196,7 @@ void M_DrawNightsAttackMenu(void)
|
||||||
skinnumber = 0; //Default to Sonic
|
skinnumber = 0; //Default to Sonic
|
||||||
else
|
else
|
||||||
skinnumber = (cv_chooseskin.value-1);
|
skinnumber = (cv_chooseskin.value-1);
|
||||||
|
|
||||||
spritedef_t *sprdef = &skins[skinnumber]->sprites[SPR2_NFLY]; //Make our patch the selected character's NFLY sprite
|
spritedef_t *sprdef = &skins[skinnumber]->sprites[SPR2_NFLY]; //Make our patch the selected character's NFLY sprite
|
||||||
spritetimer = FixedInt(ntsatkdrawtimer/2) % skins[skinnumber]->sprites[SPR2_NFLY].numframes; //Make the sprite timer cycle though all the frames at 2 tics per frame
|
spritetimer = FixedInt(ntsatkdrawtimer/2) % skins[skinnumber]->sprites[SPR2_NFLY].numframes; //Make the sprite timer cycle though all the frames at 2 tics per frame
|
||||||
spriteframe_t *sprframe = &sprdef->spriteframes[spritetimer]; //Our animation frame is equal to the number on the timer
|
spriteframe_t *sprframe = &sprdef->spriteframes[spritetimer]; //Our animation frame is equal to the number on the timer
|
||||||
|
@ -10199,11 +10209,14 @@ void M_DrawNightsAttackMenu(void)
|
||||||
color = skins[skinnumber]->supercolor+4;
|
color = skins[skinnumber]->supercolor+4;
|
||||||
else //If you don't go super in NiGHTS or at all, use prefcolor
|
else //If you don't go super in NiGHTS or at all, use prefcolor
|
||||||
color = skins[skinnumber]->prefcolor;
|
color = skins[skinnumber]->prefcolor;
|
||||||
|
|
||||||
angle_t fa = (FixedAngle(((FixedInt(ntsatkdrawtimer * 4)) % 360)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK;
|
angle_t fa = (FixedAngle(((FixedInt(ntsatkdrawtimer * 4)) % 360)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK;
|
||||||
|
fixed_t scale = skins[skinnumber]->highresscale;
|
||||||
|
if (skins[skinnumber]->shieldscale)
|
||||||
|
scale = FixedDiv(scale, skins[skinnumber]->shieldscale);
|
||||||
|
|
||||||
V_DrawFixedPatch(270<<FRACBITS, (186<<FRACBITS) - 8*FINESINE(fa),
|
V_DrawFixedPatch(270<<FRACBITS, (186<<FRACBITS) - 8*FINESINE(fa),
|
||||||
FixedDiv(skins[skinnumber]->highresscale, skins[skinnumber]->shieldscale),
|
scale,
|
||||||
(sprframe->flip & 1<<6) ? V_FLIP : 0,
|
(sprframe->flip & 1<<6) ? V_FLIP : 0,
|
||||||
natksprite,
|
natksprite,
|
||||||
R_GetTranslationColormap(TC_BLINK, color, GTC_CACHE));
|
R_GetTranslationColormap(TC_BLINK, color, GTC_CACHE));
|
||||||
|
@ -12290,7 +12303,9 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||||
if (multi_frame >= sprdef->numframes)
|
if (multi_frame >= sprdef->numframes)
|
||||||
multi_frame = 0;
|
multi_frame = 0;
|
||||||
|
|
||||||
scale = FixedDiv(skins[setupm_fakeskin]->highresscale, skins[setupm_fakeskin]->shieldscale);
|
scale = skins[setupm_fakeskin]->highresscale;
|
||||||
|
if (skins[setupm_fakeskin]->shieldscale)
|
||||||
|
scale = FixedDiv(scale, skins[setupm_fakeskin]->shieldscale);
|
||||||
|
|
||||||
#define chary (y+64)
|
#define chary (y+64)
|
||||||
|
|
||||||
|
@ -12323,7 +12338,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||||
V_DrawFixedPatch(
|
V_DrawFixedPatch(
|
||||||
x<<FRACBITS,
|
x<<FRACBITS,
|
||||||
chary<<FRACBITS,
|
chary<<FRACBITS,
|
||||||
FixedDiv(skins[setupm_fakeskin]->highresscale, skins[setupm_fakeskin]->shieldscale),
|
scale,
|
||||||
flags, patch, colormap);
|
flags, patch, colormap);
|
||||||
|
|
||||||
goto colordraw;
|
goto colordraw;
|
||||||
|
|
|
@ -691,6 +691,7 @@ void D_RegisterClientCommands(void)
|
||||||
COM_AddCommand("timedemo", Command_Timedemo_f, 0);
|
COM_AddCommand("timedemo", Command_Timedemo_f, 0);
|
||||||
COM_AddCommand("stopdemo", Command_Stopdemo_f, COM_LUA);
|
COM_AddCommand("stopdemo", Command_Stopdemo_f, COM_LUA);
|
||||||
COM_AddCommand("playintro", Command_Playintro_f, COM_LUA);
|
COM_AddCommand("playintro", Command_Playintro_f, COM_LUA);
|
||||||
|
CV_RegisterVar(&cv_resyncdemo);
|
||||||
|
|
||||||
COM_AddCommand("resetcamera", Command_ResetCamera_f, COM_LUA);
|
COM_AddCommand("resetcamera", Command_ResetCamera_f, COM_LUA);
|
||||||
|
|
||||||
|
@ -1308,7 +1309,7 @@ static void SendNameAndColor(void)
|
||||||
|
|
||||||
SetColorLocal(consoleplayer, cv_playercolor.value);
|
SetColorLocal(consoleplayer, cv_playercolor.value);
|
||||||
|
|
||||||
if (splitscreen)
|
if (splitscreen || (!pickedchar && stricmp(cv_skin.string, skins[consoleplayer]->name) != 0))
|
||||||
SetSkinLocal(consoleplayer, R_SkinAvailable(cv_skin.string));
|
SetSkinLocal(consoleplayer, R_SkinAvailable(cv_skin.string));
|
||||||
else
|
else
|
||||||
SetSkinLocal(consoleplayer, pickedchar);
|
SetSkinLocal(consoleplayer, pickedchar);
|
||||||
|
@ -4608,7 +4609,7 @@ static void Command_ExitLevel_f(void)
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow exiting without cheating if at least one player beat the level
|
// Allow exiting without cheating if at least one player beat the level
|
||||||
// Consistent with just setting playersforexit to one
|
// Consistent with just setting playersforexit to one
|
||||||
if (splitscreen || multiplayer)
|
if (splitscreen || multiplayer)
|
||||||
|
@ -4622,7 +4623,7 @@ static void Command_ExitLevel_f(void)
|
||||||
continue;
|
continue;
|
||||||
if (players[i].lives <= 0)
|
if (players[i].lives <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((players[i].pflags & PF_FINISHED) || players[i].exiting)
|
if ((players[i].pflags & PF_FINISHED) || players[i].exiting)
|
||||||
{
|
{
|
||||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||||
|
@ -4630,7 +4631,7 @@ static void Command_ExitLevel_f(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only consider it a cheat if we're not allowed to go to the next map
|
// Only consider it a cheat if we're not allowed to go to the next map
|
||||||
if (M_CampaignWarpIsCheat(gametype, G_GetNextMap(true, true) + 1, serverGamedata))
|
if (M_CampaignWarpIsCheat(gametype, G_GetNextMap(true, true) + 1, serverGamedata))
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Cheats must be enabled to force exit to a locked level!\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("Cheats must be enabled to force exit to a locked level!\n"));
|
||||||
|
@ -4769,7 +4770,7 @@ static void Command_Cheats_f(void)
|
||||||
G_SetUsedCheats(false);
|
G_SetUsedCheats(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usedCheats)
|
if (usedCheats)
|
||||||
CONS_Printf(M_GetText("Cheats are enabled, the game cannot be saved.\n"));
|
CONS_Printf(M_GetText("Cheats are enabled, the game cannot be saved.\n"));
|
||||||
else
|
else
|
||||||
|
@ -4941,6 +4942,8 @@ static boolean Skin2_CanChange(const char *valstr)
|
||||||
*/
|
*/
|
||||||
static void Skin_OnChange(void)
|
static void Skin_OnChange(void)
|
||||||
{
|
{
|
||||||
|
pickedchar = R_SkinAvailable(cv_skin.string);
|
||||||
|
|
||||||
if (!Playing())
|
if (!Playing())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -486,20 +486,23 @@ int
|
||||||
HMS_unlist (void)
|
HMS_unlist (void)
|
||||||
{
|
{
|
||||||
struct HMS_buffer *hms;
|
struct HMS_buffer *hms;
|
||||||
int ok;
|
int ok = 0;
|
||||||
|
|
||||||
hms = HMS_connect(PROTO_V4, "servers/%s/unlist", hms_server_token);
|
if (hms_server_token)
|
||||||
|
{
|
||||||
|
hms = HMS_connect(PROTO_V4, "servers/%s/unlist", hms_server_token);
|
||||||
|
|
||||||
if (! hms)
|
if (! hms)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
curl_easy_setopt(hms->curl, CURLOPT_POST, 1);
|
curl_easy_setopt(hms->curl, CURLOPT_POST, 1);
|
||||||
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDSIZE, 0);
|
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDSIZE, 0);
|
||||||
|
|
||||||
ok = HMS_do(hms);
|
ok = HMS_do(hms);
|
||||||
HMS_end(hms);
|
HMS_end(hms);
|
||||||
|
|
||||||
free(hms_server_token);
|
free(hms_server_token);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NO_IPV6
|
#ifndef NO_IPV6
|
||||||
if (hms_server_token_ipv6 && hms_allow_ipv6)
|
if (hms_server_token_ipv6 && hms_allow_ipv6)
|
||||||
|
@ -526,18 +529,13 @@ int
|
||||||
HMS_update (void)
|
HMS_update (void)
|
||||||
{
|
{
|
||||||
struct HMS_buffer *hms;
|
struct HMS_buffer *hms;
|
||||||
int ok;
|
int ok = 0;
|
||||||
|
|
||||||
char post[256];
|
char post[256];
|
||||||
|
|
||||||
char *title;
|
char *title;
|
||||||
|
|
||||||
hms = HMS_connect(PROTO_V4, "servers/%s/update", hms_server_token);
|
title = curl_easy_escape(NULL, cv_servername.string, 0);
|
||||||
|
|
||||||
if (! hms)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
title = curl_easy_escape(hms->curl, cv_servername.string, 0);
|
|
||||||
|
|
||||||
snprintf(post, sizeof post,
|
snprintf(post, sizeof post,
|
||||||
"title=%s",
|
"title=%s",
|
||||||
|
@ -546,10 +544,18 @@ HMS_update (void)
|
||||||
|
|
||||||
curl_free(title);
|
curl_free(title);
|
||||||
|
|
||||||
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
|
if (hms_server_token)
|
||||||
|
{
|
||||||
|
hms = HMS_connect(PROTO_V4, "servers/%s/update", hms_server_token);
|
||||||
|
|
||||||
ok = HMS_do(hms);
|
if (! hms)
|
||||||
HMS_end(hms);
|
return 0;
|
||||||
|
|
||||||
|
curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
|
||||||
|
|
||||||
|
ok = HMS_do(hms);
|
||||||
|
HMS_end(hms);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NO_IPV6
|
#ifndef NO_IPV6
|
||||||
if (hms_server_token_ipv6 && hms_allow_ipv6)
|
if (hms_server_token_ipv6 && hms_allow_ipv6)
|
||||||
|
|
|
@ -50,6 +50,8 @@ static void Command_Listserv_f(void);
|
||||||
|
|
||||||
#endif/*MASTERSERVER*/
|
#endif/*MASTERSERVER*/
|
||||||
|
|
||||||
|
static boolean ServerName_CanChange (const char*);
|
||||||
|
|
||||||
static void Update_parameters (void);
|
static void Update_parameters (void);
|
||||||
|
|
||||||
static void MasterServer_OnChange(void);
|
static void MasterServer_OnChange(void);
|
||||||
|
@ -61,7 +63,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ds.ms.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange);
|
consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ds.ms.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange);
|
||||||
consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters);
|
consvar_t cv_servername = CVAR_INIT_WITH_CALLBACKS ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters, ServerName_CanChange);
|
||||||
|
|
||||||
consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters);
|
consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters);
|
||||||
|
|
||||||
|
@ -497,6 +499,15 @@ Set_api (const char *api)
|
||||||
|
|
||||||
#endif/*MASTERSERVER*/
|
#endif/*MASTERSERVER*/
|
||||||
|
|
||||||
|
static boolean ServerName_CanChange(const char* newvalue)
|
||||||
|
{
|
||||||
|
if (strlen(newvalue) < MAXSERVERNAME)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CONS_Alert(CONS_NOTICE, "The server name must be shorter than %d characters\n", MAXSERVERNAME);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Update_parameters (void)
|
Update_parameters (void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4865,7 +4865,7 @@ void A_AttractChase(mobj_t *actor)
|
||||||
else
|
else
|
||||||
actor->flags2 &= ~MF2_DONTDRAW;
|
actor->flags2 &= ~MF2_DONTDRAW;
|
||||||
|
|
||||||
// Turn flingrings back into regular rings if attracted.
|
// Turn rings into flingrings if shield is lost or out of range
|
||||||
if (actor->tracer && actor->tracer->player
|
if (actor->tracer && actor->tracer->player
|
||||||
&& !(actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC) && actor->info->reactiontime && actor->type != (mobjtype_t)actor->info->reactiontime)
|
&& !(actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC) && actor->info->reactiontime && actor->type != (mobjtype_t)actor->info->reactiontime)
|
||||||
{
|
{
|
||||||
|
@ -4897,8 +4897,9 @@ void A_AttractChase(mobj_t *actor)
|
||||||
// If a FlingRing gets attracted by a shield, change it into a normal ring.
|
// If a FlingRing gets attracted by a shield, change it into a normal ring.
|
||||||
if (actor->type == (mobjtype_t)actor->info->reactiontime)
|
if (actor->type == (mobjtype_t)actor->info->reactiontime)
|
||||||
{
|
{
|
||||||
P_SpawnMobj(actor->x, actor->y, actor->z, actor->info->painchance);
|
actor->type = mobjinfo[actor->type].painchance; // Become the regular version of the fling object.
|
||||||
P_RemoveMobj(actor);
|
actor->flags = mobjinfo[actor->type].flags; // Reset actor flags.
|
||||||
|
P_SetMobjState(actor, actor->info->spawnstate); // Go to regular object's spawn state.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14857,12 +14858,18 @@ void A_RolloutRock(mobj_t *actor)
|
||||||
|
|
||||||
if (!actor->tracer || P_MobjWasRemoved(actor->tracer) || !actor->tracer->health)
|
if (!actor->tracer || P_MobjWasRemoved(actor->tracer) || !actor->tracer->health)
|
||||||
actor->flags |= MF_PUSHABLE;
|
actor->flags |= MF_PUSHABLE;
|
||||||
|
else if (actor->tracer->eflags & MFE_VERTICALFLIP)
|
||||||
|
{
|
||||||
|
actor->flags2 |= MF2_OBJECTFLIP;
|
||||||
|
actor->eflags |= MFE_VERTICALFLIP;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
actor->flags2 = (actor->flags2 & ~MF2_OBJECTFLIP) | (actor->tracer->flags2 & MF2_OBJECTFLIP);
|
actor->flags2 &= ~MF2_OBJECTFLIP;
|
||||||
actor->eflags = (actor->eflags & ~MFE_VERTICALFLIP) | (actor->tracer->eflags & MFE_VERTICALFLIP);
|
actor->eflags &= ~MFE_VERTICALFLIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
actor->friction = FRACUNIT; // turns out riding on solids sucks, so let's just make it easier on ourselves
|
actor->friction = FRACUNIT; // turns out riding on solids sucks, so let's just make it easier on ourselves
|
||||||
|
|
||||||
if (actor->eflags & MFE_JUSTHITFLOOR)
|
if (actor->eflags & MFE_JUSTHITFLOOR)
|
||||||
|
|
|
@ -389,7 +389,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||||
{
|
{
|
||||||
INT32 pflags;
|
INT32 pflags;
|
||||||
UINT8 secondjump;
|
UINT8 secondjump;
|
||||||
boolean washoming;
|
|
||||||
|
|
||||||
if (spring->flags & MF_ENEMY) // Spring shells
|
if (spring->flags & MF_ENEMY) // Spring shells
|
||||||
P_SetTarget(&spring->target, object);
|
P_SetTarget(&spring->target, object);
|
||||||
|
@ -421,7 +420,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||||
{
|
{
|
||||||
boolean wasSpindashing = object->player->dashspeed > 0 && (object->player->charability2 == CA2_SPINDASH);
|
boolean wasSpindashing = object->player->dashspeed > 0 && (object->player->charability2 == CA2_SPINDASH);
|
||||||
|
|
||||||
pflags = object->player->pflags & (PF_STARTJUMP | PF_JUMPED | PF_NOJUMPDAMAGE | PF_SPINNING | PF_THOKKED | PF_BOUNCING); // I still need these.
|
pflags = object->player->pflags & (PF_STARTJUMP | PF_JUMPED | PF_NOJUMPDAMAGE | PF_SPINNING | PF_BOUNCING); // I still need these.
|
||||||
|
|
||||||
if (wasSpindashing) // Ensure we're in the rolling state, and not spindash.
|
if (wasSpindashing) // Ensure we're in the rolling state, and not spindash.
|
||||||
P_SetMobjState(object, S_PLAY_ROLL);
|
P_SetMobjState(object, S_PLAY_ROLL);
|
||||||
|
@ -433,7 +432,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
secondjump = object->player->secondjump;
|
secondjump = object->player->secondjump;
|
||||||
washoming = object->player->homing;
|
|
||||||
P_ResetPlayer(object->player);
|
P_ResetPlayer(object->player);
|
||||||
|
|
||||||
if (spring->info->painchance == 1) // For all those ancient, SOC'd abilities.
|
if (spring->info->painchance == 1) // For all those ancient, SOC'd abilities.
|
||||||
|
@ -445,8 +443,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||||
{
|
{
|
||||||
object->player->pflags |= (pflags &~ PF_STARTJUMP);
|
object->player->pflags |= (pflags &~ PF_STARTJUMP);
|
||||||
object->player->secondjump = secondjump;
|
object->player->secondjump = secondjump;
|
||||||
if (washoming)
|
|
||||||
object->player->pflags &= ~PF_THOKKED;
|
|
||||||
}
|
}
|
||||||
else if (!vertispeed)
|
else if (!vertispeed)
|
||||||
{
|
{
|
||||||
|
@ -1027,7 +1023,6 @@ static unsigned PIT_DoCheckThing(mobj_t *thing)
|
||||||
if ((thing->flags & MF_PUSHABLE) // not carrying a player
|
if ((thing->flags & MF_PUSHABLE) // not carrying a player
|
||||||
&& (tmthing->player->powers[pw_carry] == CR_NONE) // player is not already riding something
|
&& (tmthing->player->powers[pw_carry] == CR_NONE) // player is not already riding something
|
||||||
&& !(tmthing->player->powers[pw_ignorelatch] & (1<<15))
|
&& !(tmthing->player->powers[pw_ignorelatch] & (1<<15))
|
||||||
&& ((tmthing->eflags & MFE_VERTICALFLIP) == (thing->eflags & MFE_VERTICALFLIP))
|
|
||||||
&& (P_MobjFlip(tmthing)*tmthing->momz <= 0)
|
&& (P_MobjFlip(tmthing)*tmthing->momz <= 0)
|
||||||
&& ((!(tmthing->eflags & MFE_VERTICALFLIP) && abs(thing->z + thing->height - tmthing->z) < (thing->height>>2))
|
&& ((!(tmthing->eflags & MFE_VERTICALFLIP) && abs(thing->z + thing->height - tmthing->z) < (thing->height>>2))
|
||||||
|| (tmthing->eflags & MFE_VERTICALFLIP && abs(tmthing->z + tmthing->height - thing->z) < (thing->height>>2))))
|
|| (tmthing->eflags & MFE_VERTICALFLIP && abs(tmthing->z + tmthing->height - thing->z) < (thing->height>>2))))
|
||||||
|
@ -1041,6 +1036,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing)
|
||||||
P_SetTarget(&tmthing->tracer, thing);
|
P_SetTarget(&tmthing->tracer, thing);
|
||||||
if (!P_IsObjectOnGround(thing))
|
if (!P_IsObjectOnGround(thing))
|
||||||
thing->momz += tmthing->momz;
|
thing->momz += tmthing->momz;
|
||||||
|
|
||||||
return CHECKTHING_COLLIDE;
|
return CHECKTHING_COLLIDE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -501,35 +501,51 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||||
boolean wrapmidtex = linedef->flags & ML_WRAPMIDTEX || side->flags & SIDEFLAG_WRAP_MIDTEX;
|
boolean wrapmidtex = linedef->flags & ML_WRAPMIDTEX || side->flags & SIDEFLAG_WRAP_MIDTEX;
|
||||||
|
|
||||||
if (texnum) {
|
if (texnum) {
|
||||||
|
fixed_t scaley = abs(side->scaley_mid);
|
||||||
|
fixed_t offsetvalue = FixedDiv(side->rowoffset + side->offsety_mid, scaley);
|
||||||
|
fixed_t midopentop, midopenbottom;
|
||||||
|
|
||||||
|
if (linedef->flags & ML_NOSKEW)
|
||||||
|
{
|
||||||
|
// Use the sector's actual heights if the midtexture is not skewed
|
||||||
|
midopentop = min(front->ceilingheight, back->ceilingheight);
|
||||||
|
midopenbottom = max(front->floorheight, back->floorheight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
midopentop = opentop;
|
||||||
|
midopenbottom = openbottom;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the midtexture's height
|
// Get the midtexture's height
|
||||||
texheight = textures[texnum]->height << FRACBITS;
|
texheight = FixedDiv(textureheight[texnum], scaley);
|
||||||
|
|
||||||
// Set texbottom and textop to the Z coordinates of the texture's boundaries
|
// Set texbottom and textop to the Z coordinates of the texture's boundaries
|
||||||
#if 0
|
#if 0
|
||||||
// don't remove this code unless solid midtextures
|
// don't remove this code unless solid midtextures
|
||||||
// on non-solid polyobjects should NEVER happen in the future
|
// on non-solid polyobjects should NEVER happen in the future
|
||||||
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) {
|
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) {
|
||||||
if (wrapmidtex && !side->repeatcnt) { // "infinite" repeat
|
if (linedef->flags & ML_WRAPMIDTEX && !side->repeatcnt) { // "infinite" repeat
|
||||||
texbottom = back->floorheight + side->rowoffset + side->offsety_mid;
|
texbottom = back->floorheight + offsetvalue;
|
||||||
textop = back->ceilingheight + side->rowoffset + side->offsety_mid;
|
textop = back->ceilingheight + offsetvalue;
|
||||||
} else if (linedef->flags & ML_MIDTEX) {
|
} else if (linedef->flags & ML_MIDTEX) {
|
||||||
texbottom = back->floorheight + side->rowoffset + side->offsety_mid;
|
texbottom = back->floorheight + offsetvalue;
|
||||||
textop = texbottom + texheight*(side->repeatcnt+1);
|
textop = texbottom + texheight*(side->repeatcnt+1);
|
||||||
} else {
|
} else {
|
||||||
textop = back->ceilingheight + side->rowoffset + side->offsety_mid;
|
textop = back->ceilingheight + offsetvalue;
|
||||||
texbottom = textop - texheight*(side->repeatcnt+1);
|
texbottom = textop - texheight*(side->repeatcnt+1);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (wrapmidtex && !side->repeatcnt) { // "infinite" repeat
|
if (linedef->flags & ML_WRAPMIDTEX && !side->repeatcnt) { // "infinite" repeat
|
||||||
texbottom = openbottom + side->rowoffset + side->offsety_mid;
|
texbottom = midopenbottom + offsetvalue;
|
||||||
textop = opentop + side->rowoffset + side->offsety_mid;
|
textop = midopentop + offsetvalue;
|
||||||
} else if (linedef->flags & ML_MIDPEG) {
|
} else if (linedef->flags & ML_MIDPEG) {
|
||||||
texbottom = openbottom + side->rowoffset + side->offsety_mid;
|
texbottom = midopenbottom + offsetvalue;
|
||||||
textop = texbottom + texheight*(side->repeatcnt+1);
|
textop = texbottom + texheight*(side->repeatcnt+1);
|
||||||
} else {
|
} else {
|
||||||
textop = opentop + side->rowoffset + side->offsety_mid;
|
textop = midopentop + offsetvalue;
|
||||||
texbottom = textop - texheight*(side->repeatcnt+1);
|
texbottom = textop - texheight*(side->repeatcnt+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -540,11 +556,21 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||||
delta2 = abs(thingtop - texmid);
|
delta2 = abs(thingtop - texmid);
|
||||||
|
|
||||||
if (delta1 > delta2) { // Below
|
if (delta1 > delta2) { // Below
|
||||||
if (opentop > texbottom)
|
if (opentop > texbottom) {
|
||||||
opentop = texbottom;
|
opentop = texbottom;
|
||||||
|
if (linedef->flags & ML_NOSKEW)
|
||||||
|
opentopslope = NULL; // Object is not actually on a slope
|
||||||
|
else
|
||||||
|
opentopslope = linedef->midtexslope;
|
||||||
|
}
|
||||||
} else { // Above
|
} else { // Above
|
||||||
if (openbottom < textop)
|
if (openbottom < textop) {
|
||||||
openbottom = textop;
|
openbottom = textop;
|
||||||
|
if (linedef->flags & ML_NOSKEW)
|
||||||
|
openbottomslope = NULL; // Object is not actually on a slope
|
||||||
|
else
|
||||||
|
openbottomslope = linedef->midtexslope;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
24
src/p_mobj.c
24
src/p_mobj.c
|
@ -1385,6 +1385,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
||||||
case MT_WATERDROP:
|
case MT_WATERDROP:
|
||||||
case MT_CYBRAKDEMON:
|
case MT_CYBRAKDEMON:
|
||||||
gravityadd >>= 1;
|
gravityadd >>= 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6661,8 +6662,21 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
|
||||||
thing->flags |= MF_NOCLIPHEIGHT;
|
thing->flags |= MF_NOCLIPHEIGHT;
|
||||||
thing->eflags = (thing->eflags & ~MFE_VERTICALFLIP)|(thing->target->eflags & MFE_VERTICALFLIP);
|
thing->eflags = (thing->eflags & ~MFE_VERTICALFLIP)|(thing->target->eflags & MFE_VERTICALFLIP);
|
||||||
|
|
||||||
P_SetScale(thing, FixedMul(thing->target->scale, thing->target->player->shieldscale), true);
|
//Set the shield's scale based on shieldscale, hide it if we're too small!
|
||||||
thing->old_scale = FixedMul(thing->target->old_scale, thing->target->player->shieldscale);
|
fixed_t scale = FixedMul(thing->target->scale, thing->target->player->shieldscale);
|
||||||
|
if (scale < 1) {
|
||||||
|
P_SetScale(thing, thing->target->scale, true);
|
||||||
|
thing->old_scale = thing->target->old_scale;
|
||||||
|
|
||||||
|
thing->flags2 |= (MF2_DONTDRAW|MF2_JUSTATTACKED); //Hide and indicate we're hidden
|
||||||
|
} else {
|
||||||
|
P_SetScale(thing, scale, true);
|
||||||
|
thing->old_scale = FixedMul(thing->target->old_scale, thing->target->player->shieldscale);
|
||||||
|
|
||||||
|
//Only unhide if we were hidden by the above code
|
||||||
|
if (thing->flags2 & MF2_JUSTATTACKED)
|
||||||
|
thing->flags2 &= ~(MF2_DONTDRAW|MF2_JUSTATTACKED);
|
||||||
|
}
|
||||||
|
|
||||||
#define NewMH(mobj) mobj->height // Ugly mobj-height and player-height defines, for the sake of prettier code
|
#define NewMH(mobj) mobj->height // Ugly mobj-height and player-height defines, for the sake of prettier code
|
||||||
#define NewPH(player) P_GetPlayerHeight(player)
|
#define NewPH(player) P_GetPlayerHeight(player)
|
||||||
|
@ -10746,7 +10760,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
|
||||||
// when spawning MT_PLAYER, set mobj->player before calling MobjSpawn hook to prevent P_RemoveMobj from succeeding on player mobj.
|
// when spawning MT_PLAYER, set mobj->player before calling MobjSpawn hook to prevent P_RemoveMobj from succeeding on player mobj.
|
||||||
va_start(args, type);
|
va_start(args, type);
|
||||||
mobj->player = va_arg(args, player_t *);
|
mobj->player = va_arg(args, player_t *);
|
||||||
mobj->player->mo = mobj;
|
if (mobj->player)
|
||||||
|
mobj->player->mo = mobj;
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14288,7 +14303,8 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
|
||||||
yofs = FixedMul(yofs, mobj->scale);
|
yofs = FixedMul(yofs, mobj->scale);
|
||||||
zofs = FixedMul(zofs, mobj->scale);
|
zofs = FixedMul(zofs, mobj->scale);
|
||||||
|
|
||||||
newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type);
|
newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type, NULL);
|
||||||
|
|
||||||
if (!newmobj)
|
if (!newmobj)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -831,13 +831,15 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
|
||||||
|
|
||||||
static void P_SpawnEmeraldHunt(void)
|
static void P_SpawnEmeraldHunt(void)
|
||||||
{
|
{
|
||||||
INT32 emer[3], num[MAXHUNTEMERALDS], i, randomkey;
|
INT32 emer[3], num[MAXHUNTEMERALDS], i, amount, randomkey;
|
||||||
fixed_t x, y, z;
|
fixed_t x, y, z;
|
||||||
|
|
||||||
for (i = 0; i < numhuntemeralds; i++)
|
for (i = 0; i < numhuntemeralds; i++)
|
||||||
num[i] = i;
|
num[i] = i;
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
amount = min(numhuntemeralds, 3);
|
||||||
|
|
||||||
|
for (i = 0; i < amount; i++)
|
||||||
{
|
{
|
||||||
// generate random index, shuffle afterwards
|
// generate random index, shuffle afterwards
|
||||||
randomkey = P_RandomKey(numhuntemeralds--);
|
randomkey = P_RandomKey(numhuntemeralds--);
|
||||||
|
@ -1113,6 +1115,8 @@ static void P_InitializeLinedef(line_t *ld)
|
||||||
ld->callcount = 0;
|
ld->callcount = 0;
|
||||||
ld->secportal = UINT32_MAX;
|
ld->secportal = UINT32_MAX;
|
||||||
|
|
||||||
|
ld->midtexslope = NULL;
|
||||||
|
|
||||||
// cph 2006/09/30 - fix sidedef errors right away.
|
// cph 2006/09/30 - fix sidedef errors right away.
|
||||||
// cph 2002/07/20 - these errors are fatal if not fixed, so apply them
|
// cph 2002/07/20 - these errors are fatal if not fixed, so apply them
|
||||||
for (j = 0; j < 2; j++)
|
for (j = 0; j < 2; j++)
|
||||||
|
@ -1569,11 +1573,41 @@ static void P_LoadThings(UINT8 *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stores positions for relevant map data spread through a TEXTMAP.
|
// Stores positions for relevant map data spread through a TEXTMAP.
|
||||||
UINT32 mapthingsPos[UINT16_MAX];
|
typedef struct textmap_block_s
|
||||||
UINT32 linesPos[UINT16_MAX];
|
{
|
||||||
UINT32 sidesPos[UINT16_MAX];
|
UINT32 *pos;
|
||||||
UINT32 vertexesPos[UINT16_MAX];
|
size_t capacity;
|
||||||
UINT32 sectorsPos[UINT16_MAX];
|
} textmap_block_t;
|
||||||
|
|
||||||
|
static textmap_block_t mapthingBlocks;
|
||||||
|
static textmap_block_t linedefBlocks;
|
||||||
|
static textmap_block_t sidedefBlocks;
|
||||||
|
static textmap_block_t vertexBlocks;
|
||||||
|
static textmap_block_t sectorBlocks;
|
||||||
|
|
||||||
|
static void TextmapStorePos(textmap_block_t *blocks, size_t *count)
|
||||||
|
{
|
||||||
|
size_t locCount = (*count) + 1;
|
||||||
|
|
||||||
|
if (blocks->pos == NULL)
|
||||||
|
{
|
||||||
|
// Initial capacity (half of the former one.)
|
||||||
|
blocks->capacity = UINT16_MAX / 2;
|
||||||
|
|
||||||
|
Z_Calloc(sizeof(blocks->pos) * blocks->capacity, PU_LEVEL, &blocks->pos);
|
||||||
|
}
|
||||||
|
else if (locCount >= blocks->capacity)
|
||||||
|
{
|
||||||
|
// If we hit the list's capacity, make space for 1024 more blocks
|
||||||
|
blocks->capacity += 1024;
|
||||||
|
|
||||||
|
Z_Realloc(blocks->pos, sizeof(blocks->pos) * blocks->capacity, PU_LEVEL, &blocks->pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks->pos[locCount - 1] = M_TokenizerGetEndPos();
|
||||||
|
|
||||||
|
(*count) = locCount;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine total amount of map data in TEXTMAP.
|
// Determine total amount of map data in TEXTMAP.
|
||||||
static boolean TextmapCount(size_t size)
|
static boolean TextmapCount(size_t size)
|
||||||
|
@ -1617,15 +1651,15 @@ static boolean TextmapCount(size_t size)
|
||||||
brackets++;
|
brackets++;
|
||||||
// Check for valid fields.
|
// Check for valid fields.
|
||||||
else if (fastcmp(tkn, "thing"))
|
else if (fastcmp(tkn, "thing"))
|
||||||
mapthingsPos[nummapthings++] = M_TokenizerGetEndPos();
|
TextmapStorePos(&mapthingBlocks, &nummapthings);
|
||||||
else if (fastcmp(tkn, "linedef"))
|
else if (fastcmp(tkn, "linedef"))
|
||||||
linesPos[numlines++] = M_TokenizerGetEndPos();
|
TextmapStorePos(&linedefBlocks, &numlines);
|
||||||
else if (fastcmp(tkn, "sidedef"))
|
else if (fastcmp(tkn, "sidedef"))
|
||||||
sidesPos[numsides++] = M_TokenizerGetEndPos();
|
TextmapStorePos(&sidedefBlocks, &numsides);
|
||||||
else if (fastcmp(tkn, "vertex"))
|
else if (fastcmp(tkn, "vertex"))
|
||||||
vertexesPos[numvertexes++] = M_TokenizerGetEndPos();
|
TextmapStorePos(&vertexBlocks, &numvertexes);
|
||||||
else if (fastcmp(tkn, "sector"))
|
else if (fastcmp(tkn, "sector"))
|
||||||
sectorsPos[numsectors++] = M_TokenizerGetEndPos();
|
TextmapStorePos(§orBlocks, &numsectors);
|
||||||
else
|
else
|
||||||
CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn);
|
CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn);
|
||||||
}
|
}
|
||||||
|
@ -3076,7 +3110,7 @@ static void P_LoadTextmap(void)
|
||||||
vt->floorzset = vt->ceilingzset = false;
|
vt->floorzset = vt->ceilingzset = false;
|
||||||
vt->floorz = vt->ceilingz = 0;
|
vt->floorz = vt->ceilingz = 0;
|
||||||
|
|
||||||
TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter);
|
TextmapParse(vertexBlocks.pos[i], i, ParseTextmapVertexParameter);
|
||||||
|
|
||||||
if (vt->x == INT32_MAX)
|
if (vt->x == INT32_MAX)
|
||||||
I_Error("P_LoadTextmap: vertex %s has no x value set!\n", sizeu1(i));
|
I_Error("P_LoadTextmap: vertex %s has no x value set!\n", sizeu1(i));
|
||||||
|
@ -3133,7 +3167,7 @@ static void P_LoadTextmap(void)
|
||||||
textmap_planefloor.defined = 0;
|
textmap_planefloor.defined = 0;
|
||||||
textmap_planeceiling.defined = 0;
|
textmap_planeceiling.defined = 0;
|
||||||
|
|
||||||
TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter);
|
TextmapParse(sectorBlocks.pos[i], i, ParseTextmapSectorParameter);
|
||||||
|
|
||||||
P_InitializeSector(sc);
|
P_InitializeSector(sc);
|
||||||
if (textmap_colormap.used)
|
if (textmap_colormap.used)
|
||||||
|
@ -3182,7 +3216,7 @@ static void P_LoadTextmap(void)
|
||||||
ld->sidenum[0] = NO_SIDEDEF;
|
ld->sidenum[0] = NO_SIDEDEF;
|
||||||
ld->sidenum[1] = NO_SIDEDEF;
|
ld->sidenum[1] = NO_SIDEDEF;
|
||||||
|
|
||||||
TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter);
|
TextmapParse(linedefBlocks.pos[i], i, ParseTextmapLinedefParameter);
|
||||||
|
|
||||||
if (!ld->v1)
|
if (!ld->v1)
|
||||||
I_Error("P_LoadTextmap: linedef %s has no v1 value set!\n", sizeu1(i));
|
I_Error("P_LoadTextmap: linedef %s has no v1 value set!\n", sizeu1(i));
|
||||||
|
@ -3212,7 +3246,7 @@ static void P_LoadTextmap(void)
|
||||||
|
|
||||||
P_InitSideEdges(sd);
|
P_InitSideEdges(sd);
|
||||||
|
|
||||||
TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter);
|
TextmapParse(sidedefBlocks.pos[i], i, ParseTextmapSidedefParameter);
|
||||||
|
|
||||||
if (!sd->sector)
|
if (!sd->sector)
|
||||||
I_Error("P_LoadTextmap: sidedef %s has no sector value set!\n", sizeu1(i));
|
I_Error("P_LoadTextmap: sidedef %s has no sector value set!\n", sizeu1(i));
|
||||||
|
@ -3236,7 +3270,7 @@ static void P_LoadTextmap(void)
|
||||||
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
|
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
|
||||||
mt->mobj = NULL;
|
mt->mobj = NULL;
|
||||||
|
|
||||||
TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter);
|
TextmapParse(mapthingBlocks.pos[i], i, ParseTextmapThingParameter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
133
src/p_slopes.c
133
src/p_slopes.c
|
@ -28,6 +28,8 @@
|
||||||
pslope_t *slopelist = NULL;
|
pslope_t *slopelist = NULL;
|
||||||
UINT16 slopecount = 0;
|
UINT16 slopecount = 0;
|
||||||
|
|
||||||
|
static void P_UpdateMidtextureSlopesForSector(sector_t *sector);
|
||||||
|
|
||||||
// Calculate line normal
|
// Calculate line normal
|
||||||
void P_CalculateSlopeNormal(pslope_t *slope)
|
void P_CalculateSlopeNormal(pslope_t *slope)
|
||||||
{
|
{
|
||||||
|
@ -212,6 +214,9 @@ void T_DynamicSlopeLine (dynlineplanethink_t* th)
|
||||||
slope->zangle = R_PointToAngle2(0, 0, th->extent, -zdelta);
|
slope->zangle = R_PointToAngle2(0, 0, th->extent, -zdelta);
|
||||||
slope->moved = true;
|
slope->moved = true;
|
||||||
P_CalculateSlopeNormal(slope);
|
P_CalculateSlopeNormal(slope);
|
||||||
|
P_UpdateMidtextureSlopesForSector(srcline->frontsector);
|
||||||
|
if (srcline->backsector)
|
||||||
|
P_UpdateMidtextureSlopesForSector(srcline->backsector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,6 +237,12 @@ void T_DynamicSlopeVert (dynvertexplanethink_t* th)
|
||||||
}
|
}
|
||||||
|
|
||||||
ReconfigureViaVertexes(th->slope, th->vex[0], th->vex[1], th->vex[2]);
|
ReconfigureViaVertexes(th->slope, th->vex[0], th->vex[1], th->vex[2]);
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (th->secs[i])
|
||||||
|
P_UpdateMidtextureSlopesForSector(th->secs[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void P_AddDynLineSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent)
|
static inline void P_AddDynLineSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent)
|
||||||
|
@ -758,6 +769,111 @@ pslope_t *P_MakeSlopeViaEquationConstants(const double a, const double b, const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static pslope_t *P_GetReferenceSlopeForMidtexture(line_t *line)
|
||||||
|
{
|
||||||
|
if (line->flags & ML_MIDPEG)
|
||||||
|
{
|
||||||
|
// Line has ML_MIDPEG, so use the floor slope
|
||||||
|
fixed_t frontheight = P_GetSectorFloorZAt(line->frontsector, line->v1->x, line->v1->y);
|
||||||
|
fixed_t backheight = P_GetSectorFloorZAt(line->backsector, line->v1->x, line->v1->y);
|
||||||
|
|
||||||
|
if (frontheight > backheight)
|
||||||
|
{
|
||||||
|
return line->frontsector->f_slope;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return line->backsector->f_slope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Line does not have ML_MIDPEG, so use the ceiling slope
|
||||||
|
fixed_t frontheight = P_GetSectorCeilingZAt(line->frontsector, line->v1->x, line->v1->y);
|
||||||
|
fixed_t backheight = P_GetSectorCeilingZAt(line->backsector, line->v1->x, line->v1->y);
|
||||||
|
|
||||||
|
if (frontheight < backheight)
|
||||||
|
{
|
||||||
|
return line->frontsector->c_slope;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return line->backsector->c_slope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates a slope for a solid midtexture based on the slope of the sector it's in.
|
||||||
|
static void P_UpdateSolidMidtextureSlope(line_t *line, pslope_t *ref)
|
||||||
|
{
|
||||||
|
pslope_t *slope = line->midtexslope;
|
||||||
|
|
||||||
|
if (ref == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Set origin
|
||||||
|
vector3_t origin;
|
||||||
|
origin.x = line->v1->x;
|
||||||
|
origin.y = line->v1->y;
|
||||||
|
origin.z = P_GetSlopeZAt(ref, origin.x, origin.y);
|
||||||
|
FV3_Copy(&slope->o, &origin);
|
||||||
|
|
||||||
|
// Get where the line ends
|
||||||
|
vector3_t point;
|
||||||
|
point.x = line->v2->x;
|
||||||
|
point.y = line->v2->y;
|
||||||
|
point.z = P_GetSlopeZAt(ref, point.x, point.y);
|
||||||
|
|
||||||
|
// Get length of the line
|
||||||
|
fixed_t extent = R_PointToDist2(0, 0, line->dx, line->dy);
|
||||||
|
|
||||||
|
// Precalculate variables
|
||||||
|
slope->zdelta = FixedDiv(origin.z - point.z, extent);
|
||||||
|
slope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
|
||||||
|
slope->xydirection = line->angle;
|
||||||
|
|
||||||
|
// Precalculate the direction
|
||||||
|
vector2_t dir;
|
||||||
|
dir.x = FixedMul(FINECOSINE(slope->zangle >> ANGLETOFINESHIFT), FINECOSINE((slope->xydirection+ANGLE_180) >> ANGLETOFINESHIFT));
|
||||||
|
dir.y = FixedMul(FINECOSINE(slope->zangle >> ANGLETOFINESHIFT), FINESINE((slope->xydirection+ANGLE_180) >> ANGLETOFINESHIFT));
|
||||||
|
FV2_Copy(&slope->d, &dir);
|
||||||
|
|
||||||
|
P_CalculateSlopeNormal(slope);
|
||||||
|
|
||||||
|
// Calling P_CalculateSlopeVectors is not necessary.
|
||||||
|
slope->moved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Goes through every line in the sector and updates the midtexture slope if it is present
|
||||||
|
static void P_UpdateMidtextureSlopesForSector(sector_t *sector)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < sector->linecount; i++)
|
||||||
|
{
|
||||||
|
if (sector->lines[i]->midtexslope != NULL)
|
||||||
|
P_UpdateSolidMidtextureSlope(sector->lines[i], P_GetReferenceSlopeForMidtexture(sector->lines[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a solid midtexture slope for the line if possible
|
||||||
|
static void P_CreateSolidMidtextureSlope(line_t *line)
|
||||||
|
{
|
||||||
|
if (line->backsector == NULL) // Ignore single-sided lines (of course)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((line->flags & ML_MIDSOLID) == 0) // Ignore if the midtexture is not solid
|
||||||
|
return;
|
||||||
|
|
||||||
|
pslope_t *ref = P_GetReferenceSlopeForMidtexture(line);
|
||||||
|
if (ref)
|
||||||
|
{
|
||||||
|
line->midtexslope = Slope_Add(ref->flags & SL_NOPHYSICS);
|
||||||
|
|
||||||
|
P_UpdateSolidMidtextureSlope(line, ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Initializes and reads the slopes from the map data.
|
/// Initializes and reads the slopes from the map data.
|
||||||
void P_SpawnSlopes(const boolean fromsave) {
|
void P_SpawnSlopes(const boolean fromsave) {
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -785,14 +901,21 @@ void P_SpawnSlopes(const boolean fromsave) {
|
||||||
|
|
||||||
/// Copies slopes from tagged sectors via line specials.
|
/// Copies slopes from tagged sectors via line specials.
|
||||||
/// \note Doesn't actually copy, but instead they share the same pointers.
|
/// \note Doesn't actually copy, but instead they share the same pointers.
|
||||||
|
// Also, creates midtexture slopes.
|
||||||
for (i = 0; i < numlines; i++)
|
for (i = 0; i < numlines; i++)
|
||||||
switch (lines[i].special)
|
{
|
||||||
|
line_t *line = &lines[i];
|
||||||
|
|
||||||
|
switch (line->special)
|
||||||
{
|
{
|
||||||
case 720:
|
case 720:
|
||||||
P_CopySectorSlope(&lines[i]);
|
P_CopySectorSlope(line);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
P_CreateSolidMidtextureSlope(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes slopes.
|
/// Initializes slopes.
|
||||||
|
@ -810,10 +933,10 @@ void P_InitSlopes(void)
|
||||||
// Returns the height of the sloped plane at (x, y) as a fixed_t
|
// Returns the height of the sloped plane at (x, y) as a fixed_t
|
||||||
fixed_t P_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y)
|
fixed_t P_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y)
|
||||||
{
|
{
|
||||||
fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) +
|
fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) / 2 +
|
||||||
FixedMul(y - slope->o.y, slope->d.y);
|
FixedMul(y - slope->o.y, slope->d.y) / 2;
|
||||||
|
|
||||||
return slope->o.z + FixedMul(dist, slope->zdelta);
|
return slope->o.z + FixedMul(dist, slope->zdelta) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like P_GetSlopeZAt but falls back to z if slope is NULL
|
// Like P_GetSlopeZAt but falls back to z if slope is NULL
|
||||||
|
|
29
src/p_user.c
29
src/p_user.c
|
@ -915,7 +915,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
||||||
player->textvar = NTV_BONUSTIMEEND; // Score and grades
|
player->textvar = NTV_BONUSTIMEEND; // Score and grades
|
||||||
player->finishedspheres = (INT16)(player->spheres);
|
player->finishedspheres = (INT16)(player->spheres);
|
||||||
player->finishedrings = (INT16)(player->rings);
|
player->finishedrings = (INT16)(player->rings);
|
||||||
|
|
||||||
// Add score to temp leaderboards
|
// Add score to temp leaderboards
|
||||||
player->lastmaretime = leveltime - player->marebegunat;
|
player->lastmaretime = leveltime - player->marebegunat;
|
||||||
G_AddTempNightsRecords(player, player->marescore, player->lastmaretime, (UINT8)(oldmare + 1));
|
G_AddTempNightsRecords(player, player->marescore, player->lastmaretime, (UINT8)(oldmare + 1));
|
||||||
|
@ -1089,6 +1089,13 @@ void P_ResetPlayer(player_t *player)
|
||||||
if (player->mo->tracer && !P_MobjWasRemoved(player->mo->tracer))
|
if (player->mo->tracer && !P_MobjWasRemoved(player->mo->tracer))
|
||||||
{
|
{
|
||||||
player->mo->tracer->flags |= MF_PUSHABLE;
|
player->mo->tracer->flags |= MF_PUSHABLE;
|
||||||
|
|
||||||
|
// goose the mom a little bit to trigger gravity to process for a tic
|
||||||
|
if (player->mo->tracer->eflags & MFE_VERTICALFLIP)
|
||||||
|
player->mo->tracer->momz -= 1;
|
||||||
|
else
|
||||||
|
player->mo->tracer->momz += 1;
|
||||||
|
|
||||||
P_SetTarget(&player->mo->tracer->tracer, NULL);
|
P_SetTarget(&player->mo->tracer->tracer, NULL);
|
||||||
}
|
}
|
||||||
P_SetTarget(&player->mo->tracer, NULL);
|
P_SetTarget(&player->mo->tracer, NULL);
|
||||||
|
@ -2372,7 +2379,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
||||||
if (dorollstuff)
|
if (dorollstuff)
|
||||||
{
|
{
|
||||||
if ((player->charability2 == CA2_SPINDASH) && !((player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_THOKKED) && !(player->charability == CA_THOK && player->secondjump)
|
if ((player->charability2 == CA2_SPINDASH) && !((player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_THOKKED) && !(player->charability == CA_THOK && player->secondjump)
|
||||||
&& (player->cmd.buttons & BT_SPIN) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale)))
|
&& (player->cmd.buttons & BT_SPIN) && (FixedHypot(player->mo->momx, player->mo->momy) >= (5*player->mo->scale)))
|
||||||
player->pflags = (player->pflags|PF_SPINNING) & ~PF_THOKKED;
|
player->pflags = (player->pflags|PF_SPINNING) & ~PF_THOKKED;
|
||||||
else if (!(player->pflags & PF_STARTDASH))
|
else if (!(player->pflags & PF_STARTDASH))
|
||||||
player->pflags &= ~PF_SPINNING;
|
player->pflags &= ~PF_SPINNING;
|
||||||
|
@ -4546,6 +4553,13 @@ void P_DoJump(player_t *player, boolean soundandstate, boolean allowflip)
|
||||||
player->mo->momz += player->mo->tracer->momz;
|
player->mo->momz += player->mo->tracer->momz;
|
||||||
if (!P_IsObjectOnGround(player->mo->tracer))
|
if (!P_IsObjectOnGround(player->mo->tracer))
|
||||||
P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true);
|
P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true);
|
||||||
|
|
||||||
|
// goose the mom a little bit to trigger gravity to process for a tic
|
||||||
|
if (player->mo->tracer->eflags & MFE_VERTICALFLIP)
|
||||||
|
player->mo->tracer->momz -= 1;
|
||||||
|
else
|
||||||
|
player->mo->tracer->momz += 1;
|
||||||
|
|
||||||
player->mo->tracer->flags |= MF_PUSHABLE;
|
player->mo->tracer->flags |= MF_PUSHABLE;
|
||||||
P_SetTarget(&player->mo->tracer->tracer, NULL);
|
P_SetTarget(&player->mo->tracer->tracer, NULL);
|
||||||
}
|
}
|
||||||
|
@ -4721,7 +4735,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
|
||||||
// Revving
|
// Revving
|
||||||
else if ((cmd->buttons & BT_SPIN) && (player->pflags & PF_STARTDASH))
|
else if ((cmd->buttons & BT_SPIN) && (player->pflags & PF_STARTDASH))
|
||||||
{
|
{
|
||||||
if (player->speed > 5*player->mo->scale)
|
if (player->speed >= 5*player->mo->scale)
|
||||||
{
|
{
|
||||||
player->pflags &= ~PF_STARTDASH;
|
player->pflags &= ~PF_STARTDASH;
|
||||||
P_SetMobjState(player->mo, S_PLAY_ROLL);
|
P_SetMobjState(player->mo, S_PLAY_ROLL);
|
||||||
|
@ -4761,9 +4775,8 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
|
||||||
if (!player->spectator)
|
if (!player->spectator)
|
||||||
S_StartSound(player->mo, sfx_spin);
|
S_StartSound(player->mo, sfx_spin);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
// Catapult the player from a spindash rev!
|
// Catapult the player from a spindash rev!
|
||||||
if (onground && !(player->pflags & PF_SPINDOWN) && (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING))
|
else if (onground && !(player->pflags & PF_SPINDOWN) && (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING))
|
||||||
{
|
{
|
||||||
player->pflags &= ~PF_STARTDASH;
|
player->pflags &= ~PF_STARTDASH;
|
||||||
if (player->powers[pw_carry] == CR_BRAKGOOP)
|
if (player->powers[pw_carry] == CR_BRAKGOOP)
|
||||||
|
@ -8766,7 +8779,7 @@ void P_MovePlayer(player_t *player)
|
||||||
if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER)
|
if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER)
|
||||||
&& player->panim == PA_IDLE && !(player->powers[pw_carry]))
|
&& player->panim == PA_IDLE && !(player->powers[pw_carry]))
|
||||||
P_DoTeeter(player);
|
P_DoTeeter(player);
|
||||||
|
|
||||||
// Toss a flag
|
// Toss a flag
|
||||||
if (G_GametypeHasTeams() && (cmd->buttons & BT_TOSSFLAG) && !(player->powers[pw_super]) && !(player->tossdelay))
|
if (G_GametypeHasTeams() && (cmd->buttons & BT_TOSSFLAG) && !(player->powers[pw_super]) && !(player->tossdelay))
|
||||||
{
|
{
|
||||||
|
@ -12129,6 +12142,10 @@ void P_PlayerThink(player_t *player)
|
||||||
case CR_DUSTDEVIL:
|
case CR_DUSTDEVIL:
|
||||||
player->drawangle += ANG20;
|
player->drawangle += ANG20;
|
||||||
break;
|
break;
|
||||||
|
case CR_FAN:
|
||||||
|
if (player->pflags & PF_ANALOGMODE) // Don't impact drawangle in any special way when on a fan
|
||||||
|
player->drawangle = player->mo->angle;
|
||||||
|
break;
|
||||||
/* -- in case we wanted to have the camera freely movable during zoom tubes
|
/* -- in case we wanted to have the camera freely movable during zoom tubes
|
||||||
case CR_ZOOMTUBE:*/
|
case CR_ZOOMTUBE:*/
|
||||||
case CR_ROPEHANG:
|
case CR_ROPEHANG:
|
||||||
|
|
|
@ -626,6 +626,8 @@ typedef struct line_s
|
||||||
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
|
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
|
||||||
|
|
||||||
UINT32 secportal; // transferred sector portal
|
UINT32 secportal; // transferred sector portal
|
||||||
|
|
||||||
|
struct pslope_s *midtexslope;
|
||||||
} line_t;
|
} line_t;
|
||||||
|
|
||||||
// Don't make available to Lua or I will find where you live
|
// Don't make available to Lua or I will find where you live
|
||||||
|
|
|
@ -74,7 +74,7 @@ UINT8 *dc_transmap; // one of the translucency tables
|
||||||
UINT8 *dc_translation;
|
UINT8 *dc_translation;
|
||||||
|
|
||||||
struct r_lightlist_s *dc_lightlist = NULL;
|
struct r_lightlist_s *dc_lightlist = NULL;
|
||||||
INT32 dc_numlights = 0, dc_maxlights, dc_texheight;
|
INT32 dc_numlights = 0, dc_maxlights, dc_texheight, dc_postlength;
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// SPAN DRAWING CODE STUFF
|
// SPAN DRAWING CODE STUFF
|
||||||
|
|
|
@ -41,8 +41,7 @@ extern UINT8 *dc_translation;
|
||||||
extern struct r_lightlist_s *dc_lightlist;
|
extern struct r_lightlist_s *dc_lightlist;
|
||||||
extern INT32 dc_numlights, dc_maxlights;
|
extern INT32 dc_numlights, dc_maxlights;
|
||||||
|
|
||||||
//Fix TUTIFRUTI
|
extern INT32 dc_texheight, dc_postlength;
|
||||||
extern INT32 dc_texheight;
|
|
||||||
|
|
||||||
// -----------------------
|
// -----------------------
|
||||||
// SPAN DRAWING CODE STUFF
|
// SPAN DRAWING CODE STUFF
|
||||||
|
@ -154,8 +153,10 @@ void R_VideoErase(size_t ofs, INT32 count);
|
||||||
// -----------------
|
// -----------------
|
||||||
|
|
||||||
void R_DrawColumn_8(void);
|
void R_DrawColumn_8(void);
|
||||||
|
void R_DrawColumnClamped_8(void);
|
||||||
void R_DrawShadeColumn_8(void);
|
void R_DrawShadeColumn_8(void);
|
||||||
void R_DrawTranslucentColumn_8(void);
|
void R_DrawTranslucentColumn_8(void);
|
||||||
|
void R_DrawTranslucentColumnClamped_8(void);
|
||||||
void R_DrawDropShadowColumn_8(void);
|
void R_DrawDropShadowColumn_8(void);
|
||||||
void R_DrawTranslatedColumn_8(void);
|
void R_DrawTranslatedColumn_8(void);
|
||||||
void R_DrawTranslatedTranslucentColumn_8(void);
|
void R_DrawTranslatedTranslucentColumn_8(void);
|
||||||
|
|
176
src/r_draw8.c
176
src/r_draw8.c
|
@ -100,6 +100,98 @@ void R_DrawColumn_8(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief The R_DrawColumnClamped_8 function
|
||||||
|
Same as R_DrawColumn_8, but prevents artifacts from showing up (caused by fixed-point imprecisions)
|
||||||
|
*/
|
||||||
|
void R_DrawColumnClamped_8(void)
|
||||||
|
{
|
||||||
|
INT32 count;
|
||||||
|
UINT8 *dest;
|
||||||
|
fixed_t frac;
|
||||||
|
fixed_t fracstep;
|
||||||
|
|
||||||
|
count = dc_yh - dc_yl;
|
||||||
|
|
||||||
|
if (count < 0) // Zero length, column does not exceed a pixel.
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef RANGECHECK
|
||||||
|
if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Framebuffer destination address.
|
||||||
|
dest = &topleft[dc_yl*vid.width + dc_x];
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
// Determine scaling, which is the only mapping to be done.
|
||||||
|
fracstep = dc_iscale;
|
||||||
|
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
|
||||||
|
|
||||||
|
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
|
||||||
|
// This is as fast as it gets.
|
||||||
|
{
|
||||||
|
const UINT8 *source = dc_source;
|
||||||
|
const lighttable_t *colormap = dc_colormap;
|
||||||
|
INT32 heightmask = dc_texheight-1;
|
||||||
|
INT32 idx;
|
||||||
|
if (dc_texheight & heightmask) // not a power of 2 -- killough
|
||||||
|
{
|
||||||
|
heightmask++;
|
||||||
|
heightmask <<= FRACBITS;
|
||||||
|
|
||||||
|
if (frac < 0)
|
||||||
|
while ((frac += heightmask) < 0);
|
||||||
|
else
|
||||||
|
while (frac >= heightmask)
|
||||||
|
frac -= heightmask;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Re-map color indices from wall texture column
|
||||||
|
// using a lighting/special effects LUT.
|
||||||
|
// heightmask is the Tutti-Frutti fix
|
||||||
|
idx = frac>>FRACBITS;
|
||||||
|
if (idx >= 0 && idx < dc_postlength)
|
||||||
|
*dest = colormap[source[idx]];
|
||||||
|
dest += vid.width;
|
||||||
|
|
||||||
|
// Avoid overflow.
|
||||||
|
if (fracstep > 0x7FFFFFFF - frac)
|
||||||
|
frac += fracstep - heightmask;
|
||||||
|
else
|
||||||
|
frac += fracstep;
|
||||||
|
|
||||||
|
while (frac >= heightmask)
|
||||||
|
frac -= heightmask;
|
||||||
|
} while (--count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while ((count -= 2) >= 0) // texture height is a power of 2
|
||||||
|
{
|
||||||
|
idx = (frac>>FRACBITS) & heightmask;
|
||||||
|
if (idx >= 0 && idx < dc_postlength)
|
||||||
|
*dest = colormap[source[idx]];
|
||||||
|
dest += vid.width;
|
||||||
|
frac += fracstep;
|
||||||
|
idx = (frac>>FRACBITS) & heightmask;
|
||||||
|
if (idx >= 0 && idx < dc_postlength)
|
||||||
|
*dest = colormap[source[idx]];
|
||||||
|
dest += vid.width;
|
||||||
|
frac += fracstep;
|
||||||
|
}
|
||||||
|
if (count & 1)
|
||||||
|
{
|
||||||
|
idx = (frac>>FRACBITS) & heightmask;
|
||||||
|
if (idx >= 0 && idx < dc_postlength)
|
||||||
|
*dest = colormap[source[idx]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** \brief The R_DrawShadeColumn_8 function
|
/** \brief The R_DrawShadeColumn_8 function
|
||||||
Experiment to make software go faster. Taken from the Boom source
|
Experiment to make software go faster. Taken from the Boom source
|
||||||
*/
|
*/
|
||||||
|
@ -212,6 +304,90 @@ void R_DrawTranslucentColumn_8(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief The R_DrawTranslucentColumnClamped_8 function
|
||||||
|
Same as R_DrawTranslucentColumn_8, but prevents artifacts from showing up (caused by fixed-point imprecisions)
|
||||||
|
*/
|
||||||
|
void R_DrawTranslucentColumnClamped_8(void)
|
||||||
|
{
|
||||||
|
INT32 count;
|
||||||
|
UINT8 *dest;
|
||||||
|
fixed_t frac, fracstep;
|
||||||
|
|
||||||
|
count = dc_yh - dc_yl + 1;
|
||||||
|
|
||||||
|
if (count <= 0) // Zero length, column does not exceed a pixel.
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef RANGECHECK
|
||||||
|
if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
|
||||||
|
I_Error("R_DrawTranslucentColumnClamped_8: %d to %d at %d", dc_yl, dc_yh, dc_x);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dest = &topleft[dc_yl*vid.width + dc_x];
|
||||||
|
|
||||||
|
// Looks familiar.
|
||||||
|
fracstep = dc_iscale;
|
||||||
|
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
|
||||||
|
|
||||||
|
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
|
||||||
|
// This is as fast as it gets.
|
||||||
|
{
|
||||||
|
const UINT8 *source = dc_source;
|
||||||
|
const UINT8 *transmap = dc_transmap;
|
||||||
|
const lighttable_t *colormap = dc_colormap;
|
||||||
|
INT32 heightmask = dc_texheight - 1;
|
||||||
|
INT32 idx;
|
||||||
|
if (dc_texheight & heightmask)
|
||||||
|
{
|
||||||
|
heightmask++;
|
||||||
|
heightmask <<= FRACBITS;
|
||||||
|
|
||||||
|
if (frac < 0)
|
||||||
|
while ((frac += heightmask) < 0)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
while (frac >= heightmask)
|
||||||
|
frac -= heightmask;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Re-map color indices from wall texture column
|
||||||
|
// using a lighting/special effects LUT.
|
||||||
|
// heightmask is the Tutti-Frutti fix
|
||||||
|
idx = frac>>FRACBITS;
|
||||||
|
if (idx >= 0 && idx < dc_postlength)
|
||||||
|
*dest = *(transmap + (colormap[source[idx]]<<8) + (*dest));
|
||||||
|
dest += vid.width;
|
||||||
|
if ((frac += fracstep) >= heightmask)
|
||||||
|
frac -= heightmask;
|
||||||
|
}
|
||||||
|
while (--count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while ((count -= 2) >= 0) // texture height is a power of 2
|
||||||
|
{
|
||||||
|
idx = (frac>>FRACBITS)&heightmask;
|
||||||
|
if (idx >= 0 && idx < dc_postlength)
|
||||||
|
*dest = *(transmap + (colormap[source[idx]]<<8) + (*dest));
|
||||||
|
dest += vid.width;
|
||||||
|
frac += fracstep;
|
||||||
|
idx = (frac>>FRACBITS)&heightmask;
|
||||||
|
if (idx >= 0 && idx < dc_postlength)
|
||||||
|
*dest = *(transmap + (colormap[source[idx]]<<8) + (*dest));
|
||||||
|
dest += vid.width;
|
||||||
|
frac += fracstep;
|
||||||
|
}
|
||||||
|
if (count & 1)
|
||||||
|
{
|
||||||
|
idx = (frac>>FRACBITS)&heightmask;
|
||||||
|
if (idx >= 0 && idx < dc_postlength)
|
||||||
|
*dest = *(transmap + (colormap[source[idx]]<<8) + (*dest));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Hack: A cut-down copy of R_DrawTranslucentColumn_8 that does not read texture
|
// Hack: A cut-down copy of R_DrawTranslucentColumn_8 that does not read texture
|
||||||
// data since something about calculating the texture reading address for drop shadows is broken.
|
// data since something about calculating the texture reading address for drop shadows is broken.
|
||||||
// dc_texturemid and dc_iscale get wrong values for drop shadows, however those are not strictly
|
// dc_texturemid and dc_iscale get wrong values for drop shadows, however those are not strictly
|
||||||
|
|
|
@ -390,22 +390,22 @@ fixed_t R_PointToDist(fixed_t x, fixed_t y)
|
||||||
return R_PointToDist2(viewx, viewy, x, y);
|
return R_PointToDist2(viewx, viewy, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
line_t *R_GetFFloorLine(const seg_t *seg, const ffloor_t *pfloor)
|
line_t *R_GetFFloorLine(const line_t *line, const ffloor_t *pfloor, const sector_t *sector)
|
||||||
{
|
{
|
||||||
if (pfloor->master->flags & ML_TFERLINE)
|
if (pfloor->master->flags & ML_TFERLINE)
|
||||||
{
|
{
|
||||||
size_t linenum = seg->linedef - pfloor->target->lines[0];
|
size_t linenum = min((size_t)(line - sector->lines[0]), pfloor->master->frontsector->linecount);
|
||||||
return pfloor->master->frontsector->lines[0] + linenum;
|
return pfloor->master->frontsector->lines[0] + linenum;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return pfloor->master;
|
return pfloor->master;
|
||||||
}
|
}
|
||||||
|
|
||||||
side_t *R_GetFFloorSide(const seg_t *seg, const ffloor_t *pfloor)
|
side_t *R_GetFFloorSide(const line_t *line, const ffloor_t *pfloor, const sector_t *sector)
|
||||||
{
|
{
|
||||||
if (pfloor->master->flags & ML_TFERLINE)
|
if (pfloor->master->flags & ML_TFERLINE)
|
||||||
{
|
{
|
||||||
line_t *newline = R_GetFFloorLine(seg, pfloor);
|
line_t *newline = R_GetFFloorLine(line, pfloor, sector);
|
||||||
return &sides[newline->sidenum[0]];
|
return &sides[newline->sidenum[0]];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -86,8 +86,8 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y);
|
||||||
|
|
||||||
boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph);
|
boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph);
|
||||||
|
|
||||||
line_t *R_GetFFloorLine(const seg_t *seg, const ffloor_t *pfloor);
|
line_t *R_GetFFloorLine(const line_t *line, const ffloor_t *pfloor, const sector_t *sector);
|
||||||
side_t *R_GetFFloorSide(const seg_t *seg, const ffloor_t *pfloor);
|
side_t *R_GetFFloorSide(const line_t *line, const ffloor_t *pfloor, const sector_t *sector);
|
||||||
|
|
||||||
// Render stats
|
// Render stats
|
||||||
|
|
||||||
|
|
147
src/r_segs.c
147
src/r_segs.c
|
@ -888,26 +888,75 @@ static void R_RenderExtraTexture(unsigned which, INT32 x1, INT32 x2, INT32 repea
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop through R_DrawMaskedColumn calls
|
// Loop through R_DrawMaskedColumn calls
|
||||||
|
static fixed_t repeatscroll = 0;
|
||||||
|
|
||||||
static void R_DrawRepeatMaskedColumn(column_t *col, unsigned lengthcol)
|
static void R_DrawRepeatMaskedColumn(column_t *col, unsigned lengthcol)
|
||||||
{
|
{
|
||||||
while (sprtopscreen < sprbotscreen) {
|
fixed_t topscreen = sprtopscreen;
|
||||||
R_DrawMaskedColumn(col, lengthcol);
|
fixed_t bottomscreen = sprbotscreen;
|
||||||
if ((INT64)sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow
|
|
||||||
sprtopscreen = INT32_MAX;
|
fixed_t texheight = dc_texheight*spryscale;
|
||||||
else
|
|
||||||
sprtopscreen += dc_texheight*spryscale;
|
fixed_t scroll = -repeatscroll;
|
||||||
|
if (scroll < 0)
|
||||||
|
{
|
||||||
|
scroll = -FixedMul((abs(scroll) % (dc_texheight*FRACUNIT)), spryscale);
|
||||||
|
bottomscreen += texheight; // Draw an extra time
|
||||||
}
|
}
|
||||||
|
else if (scroll)
|
||||||
|
{
|
||||||
|
scroll = FixedMul(scroll % (dc_texheight*FRACUNIT), spryscale);
|
||||||
|
topscreen -= texheight; // Draw an extra time
|
||||||
|
}
|
||||||
|
|
||||||
|
while (topscreen < bottomscreen)
|
||||||
|
{
|
||||||
|
sprtopscreen = topscreen + scroll;
|
||||||
|
|
||||||
|
R_DrawMaskedColumn(col, lengthcol);
|
||||||
|
|
||||||
|
if ((INT64)sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow
|
||||||
|
break;
|
||||||
|
|
||||||
|
topscreen += texheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprtopscreen = sprbotscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void R_DrawRepeatFlippedMaskedColumn(column_t *col, unsigned lengthcol)
|
static void R_DrawRepeatFlippedMaskedColumn(column_t *col, unsigned lengthcol)
|
||||||
{
|
{
|
||||||
while (sprtopscreen < sprbotscreen) {
|
fixed_t topscreen = sprtopscreen;
|
||||||
R_DrawFlippedMaskedColumn(col, lengthcol);
|
fixed_t bottomscreen = sprbotscreen;
|
||||||
if ((INT64)sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow
|
|
||||||
sprtopscreen = INT32_MAX;
|
fixed_t texheight = dc_texheight*spryscale;
|
||||||
else
|
|
||||||
sprtopscreen += dc_texheight*spryscale;
|
fixed_t scroll = -repeatscroll;
|
||||||
|
if (scroll < 0)
|
||||||
|
{
|
||||||
|
scroll = -FixedMul((abs(scroll) % (dc_texheight*FRACUNIT)), spryscale);
|
||||||
|
bottomscreen += texheight; // Draw an extra time
|
||||||
}
|
}
|
||||||
|
else if (scroll)
|
||||||
|
{
|
||||||
|
scroll = FixedMul(scroll % (dc_texheight*FRACUNIT), spryscale);
|
||||||
|
topscreen -= texheight; // Draw an extra time
|
||||||
|
}
|
||||||
|
|
||||||
|
while (topscreen < bottomscreen)
|
||||||
|
{
|
||||||
|
sprtopscreen = topscreen + scroll;
|
||||||
|
sprbotscreen = bottomscreen + scroll;
|
||||||
|
|
||||||
|
R_DrawFlippedMaskedColumn(col, lengthcol);
|
||||||
|
|
||||||
|
if ((INT64)sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow
|
||||||
|
break;
|
||||||
|
|
||||||
|
topscreen += texheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprtopscreen = sprbotscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if a fake floor is translucent.
|
// Returns true if a fake floor is translucent.
|
||||||
|
@ -943,7 +992,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
sector_t tempsec;
|
sector_t tempsec;
|
||||||
INT32 templight;
|
INT32 templight;
|
||||||
INT32 i, p;
|
INT32 i, p;
|
||||||
fixed_t offsetvalue;
|
|
||||||
lightlist_t *light;
|
lightlist_t *light;
|
||||||
r_lightlist_t *rlight;
|
r_lightlist_t *rlight;
|
||||||
INT32 range;
|
INT32 range;
|
||||||
|
@ -963,6 +1011,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
INT32 blendlevel = 0;
|
INT32 blendlevel = 0;
|
||||||
UINT8 vertflip;
|
UINT8 vertflip;
|
||||||
unsigned lengthcol;
|
unsigned lengthcol;
|
||||||
|
boolean fog = false;
|
||||||
|
boolean fuzzy = false;
|
||||||
|
|
||||||
void (*colfunc_2s) (column_t *, unsigned);
|
void (*colfunc_2s) (column_t *, unsigned);
|
||||||
|
|
||||||
|
@ -974,13 +1024,11 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
curline = ds->curline;
|
curline = ds->curline;
|
||||||
backsector = NULL;
|
backsector = NULL;
|
||||||
frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector;
|
frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector;
|
||||||
sidedef = R_GetFFloorSide(curline, pfloor);
|
sidedef = R_GetFFloorSide(curline->linedef, pfloor, pfloor->target);
|
||||||
|
|
||||||
colfunc = colfuncs[BASEDRAWFUNC];
|
|
||||||
|
|
||||||
if (pfloor->master->flags & ML_TFERLINE)
|
if (pfloor->master->flags & ML_TFERLINE)
|
||||||
{
|
{
|
||||||
line_t *newline = R_GetFFloorLine(curline, pfloor);
|
line_t *newline = R_GetFFloorLine(curline->linedef, pfloor, pfloor->target);
|
||||||
do_texture_skew = newline->flags & ML_SKEWTD;
|
do_texture_skew = newline->flags & ML_SKEWTD;
|
||||||
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
|
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
|
||||||
}
|
}
|
||||||
|
@ -997,6 +1045,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
|
|
||||||
if (pfloor->fofflags & FOF_TRANSLUCENT)
|
if (pfloor->fofflags & FOF_TRANSLUCENT)
|
||||||
{
|
{
|
||||||
|
fuzzy = true;
|
||||||
|
|
||||||
// Hacked up support for alpha value in software mode Tails 09-24-2002
|
// Hacked up support for alpha value in software mode Tails 09-24-2002
|
||||||
// ...unhacked by toaster 04-01-2021, re-hacked a little by sphere 19-11-2021
|
// ...unhacked by toaster 04-01-2021, re-hacked a little by sphere 19-11-2021
|
||||||
blendlevel = (10*((256+12) - pfloor->alpha))/255;
|
blendlevel = (10*((256+12) - pfloor->alpha))/255;
|
||||||
|
@ -1015,17 +1065,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
else if (blendlevel > 0)
|
else if (blendlevel > 0)
|
||||||
dc_transmap = R_GetTranslucencyTable(blendlevel);
|
dc_transmap = R_GetTranslucencyTable(blendlevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc_transmap)
|
|
||||||
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
|
|
||||||
}
|
}
|
||||||
else if (pfloor->fofflags & FOF_FOG)
|
else if (pfloor->fofflags & FOF_FOG)
|
||||||
|
{
|
||||||
colfunc = colfuncs[COLDRAWFUNC_FOG];
|
colfunc = colfuncs[COLDRAWFUNC_FOG];
|
||||||
|
fog = true;
|
||||||
|
}
|
||||||
|
|
||||||
range = max(ds->x2-ds->x1, 1);
|
range = max(ds->x2-ds->x1, 1);
|
||||||
//SoM: Moved these up here so they are available for my lightlist calculations
|
|
||||||
rw_scalestep = ds->scalestep;
|
|
||||||
spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
|
|
||||||
|
|
||||||
dc_numlights = 0;
|
dc_numlights = 0;
|
||||||
if (frontsector->numlights)
|
if (frontsector->numlights)
|
||||||
|
@ -1128,9 +1175,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
// Get correct light level!
|
// Get correct light level!
|
||||||
if ((frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
if ((frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||||
else if (pfloor->fofflags & FOF_FOG)
|
else if (fog)
|
||||||
lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
|
lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||||
else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
|
else if (fuzzy)
|
||||||
lightnum = LIGHTLEVELS-1;
|
lightnum = LIGHTLEVELS-1;
|
||||||
else
|
else
|
||||||
lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
|
lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
|
||||||
|
@ -1158,6 +1205,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
vertflip = !vertflip;
|
vertflip = !vertflip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SoM: Moved these up here so they are available for my lightlist calculations
|
||||||
|
// Lactozilla: Moved them back down
|
||||||
|
// This uses floating point math now, because the fixed-point imprecisions
|
||||||
|
// become more severe the bigger the texture is scaled.
|
||||||
|
double dwall_scaley = FixedToDouble(wall_scaley);
|
||||||
|
double scalestep = FixedToDouble(ds->scalestep) / dwall_scaley;
|
||||||
|
double yscale = (FixedToDouble(ds->scale1) + (x1 - ds->x1)*scalestep) / dwall_scaley;
|
||||||
|
|
||||||
thicksidecol = ffloortexturecolumn;
|
thicksidecol = ffloortexturecolumn;
|
||||||
|
|
||||||
wall_offsetx = ds->offsetx + sidedef->offsetx_mid;
|
wall_offsetx = ds->offsetx + sidedef->offsetx_mid;
|
||||||
|
@ -1189,7 +1244,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
else
|
else
|
||||||
dc_texturemid = FixedMul(*pfloor->topheight - viewz, wall_scaley);
|
dc_texturemid = FixedMul(*pfloor->topheight - viewz, wall_scaley);
|
||||||
|
|
||||||
offsetvalue = sidedef->rowoffset + sidedef->offsety_mid;
|
repeatscroll = sidedef->rowoffset + sidedef->offsety_mid;
|
||||||
|
|
||||||
if (dont_peg_bottom)
|
if (dont_peg_bottom)
|
||||||
{
|
{
|
||||||
|
@ -1199,7 +1254,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
dc_texturemid = FixedMul(left_bottom, wall_scaley);
|
dc_texturemid = FixedMul(left_bottom, wall_scaley);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
offsetvalue -= FixedMul(*pfloor->topheight - *pfloor->bottomheight, wall_scaley);
|
repeatscroll -= FixedMul(*pfloor->topheight - *pfloor->bottomheight, wall_scaley);
|
||||||
}
|
}
|
||||||
|
|
||||||
lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y);
|
lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y);
|
||||||
|
@ -1207,7 +1262,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
if (skewslope)
|
if (skewslope)
|
||||||
ffloortextureslide = FixedMul(R_GetSlopeTextureSlide(skewslope, lineangle), wall_scaley);
|
ffloortextureslide = FixedMul(R_GetSlopeTextureSlide(skewslope, lineangle), wall_scaley);
|
||||||
|
|
||||||
dc_texturemid += offsetvalue;
|
dc_texturemid += repeatscroll;
|
||||||
|
|
||||||
// Texture must be cached
|
// Texture must be cached
|
||||||
R_CheckTextureCache(texnum);
|
R_CheckTextureCache(texnum);
|
||||||
|
@ -1296,15 +1351,41 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
rlight->botheight += rlight->botheightstep;
|
rlight->botheight += rlight->botheightstep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spryscale += rw_scalestep;
|
yscale += scalestep;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley);
|
|
||||||
|
|
||||||
// Get data for the column
|
// Get data for the column
|
||||||
col = R_GetColumn(texnum, ((thicksidecol[dc_x] + wall_offsetx) >> FRACBITS));
|
col = R_GetColumn(texnum, ((thicksidecol[dc_x] + wall_offsetx) >> FRACBITS));
|
||||||
|
|
||||||
|
spryscale = DoubleToFixed(yscale);
|
||||||
|
|
||||||
|
// Eh. I tried fixing the scaling artifacts but it still wasn't perfect.
|
||||||
|
// So this checks if the column has gaps in it or not, and if it does, uses a version of the column drawers
|
||||||
|
// that prevents the artifacts from being visible.
|
||||||
|
// Note that if rendering fog then none of this matters because there's no texture mapping to be done
|
||||||
|
if (!fog)
|
||||||
|
{
|
||||||
|
dc_iscale = 0xffffffffu / (unsigned)spryscale;
|
||||||
|
|
||||||
|
// Column has a single post and it matches the texture height, use regular column drawers
|
||||||
|
if (col->num_posts == 1 && col->posts[0].topdelta == 0 && col->posts[0].length == (unsigned)dc_texheight)
|
||||||
|
{
|
||||||
|
if (fuzzy)
|
||||||
|
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
|
||||||
|
else
|
||||||
|
colfunc = colfuncs[BASEDRAWFUNC];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Otherwise use column drawers with extra checks
|
||||||
|
if (fuzzy)
|
||||||
|
colfunc = R_DrawTranslucentColumnClamped_8;
|
||||||
|
else
|
||||||
|
colfunc = R_DrawColumnClamped_8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SoM: New code does not rely on R_DrawColumnShadowed_8 which
|
// SoM: New code does not rely on R_DrawColumnShadowed_8 which
|
||||||
// will (hopefully) put less strain on the stack.
|
// will (hopefully) put less strain on the stack.
|
||||||
if (dc_numlights)
|
if (dc_numlights)
|
||||||
|
@ -1419,7 +1500,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
if (windowtop < windowbottom)
|
if (windowtop < windowbottom)
|
||||||
colfunc_2s (col, lengthcol);
|
colfunc_2s (col, lengthcol);
|
||||||
|
|
||||||
spryscale += rw_scalestep;
|
yscale += scalestep;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1438,7 +1519,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
|
|
||||||
// draw the texture
|
// draw the texture
|
||||||
colfunc_2s (col, lengthcol);
|
colfunc_2s (col, lengthcol);
|
||||||
spryscale += rw_scalestep;
|
yscale += scalestep;
|
||||||
}
|
}
|
||||||
colfunc = colfuncs[BASEDRAWFUNC];
|
colfunc = colfuncs[BASEDRAWFUNC];
|
||||||
|
|
||||||
|
|
|
@ -839,8 +839,10 @@ void R_DrawMaskedColumn(column_t *column, unsigned lengthcol)
|
||||||
{
|
{
|
||||||
post_t *post = &column->posts[i];
|
post_t *post = &column->posts[i];
|
||||||
|
|
||||||
|
dc_postlength = post->length;
|
||||||
|
|
||||||
INT32 topscreen = sprtopscreen + spryscale*post->topdelta;
|
INT32 topscreen = sprtopscreen + spryscale*post->topdelta;
|
||||||
INT32 bottomscreen = topscreen + spryscale*post->length;
|
INT32 bottomscreen = topscreen + spryscale*dc_postlength;
|
||||||
|
|
||||||
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
|
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
|
||||||
dc_yh = (bottomscreen-1)>>FRACBITS;
|
dc_yh = (bottomscreen-1)>>FRACBITS;
|
||||||
|
@ -909,10 +911,12 @@ void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol)
|
||||||
if (!post->length)
|
if (!post->length)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
topdelta = lengthcol-post->length-post->topdelta;
|
dc_postlength = post->length;
|
||||||
|
|
||||||
|
topdelta = lengthcol-dc_postlength-post->topdelta;
|
||||||
topscreen = sprtopscreen + spryscale*topdelta;
|
topscreen = sprtopscreen + spryscale*topdelta;
|
||||||
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*post->length
|
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*dc_postlength
|
||||||
: sprbotscreen + spryscale*post->length;
|
: sprbotscreen + spryscale*dc_postlength;
|
||||||
|
|
||||||
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
|
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
|
||||||
dc_yh = (bottomscreen-1)>>FRACBITS;
|
dc_yh = (bottomscreen-1)>>FRACBITS;
|
||||||
|
@ -1774,6 +1778,10 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
}
|
}
|
||||||
|
|
||||||
this_scale = interp.scale;
|
this_scale = interp.scale;
|
||||||
|
|
||||||
|
if (this_scale < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
radius = interp.radius; // For drop shadows
|
radius = interp.radius; // For drop shadows
|
||||||
height = interp.height; // Ditto
|
height = interp.height; // Ditto
|
||||||
|
|
||||||
|
|
|
@ -271,75 +271,86 @@ SDL_bool framebuffer = SDL_FALSE;
|
||||||
UINT8 keyboard_started = false;
|
UINT8 keyboard_started = false;
|
||||||
|
|
||||||
#ifdef UNIXBACKTRACE
|
#ifdef UNIXBACKTRACE
|
||||||
#define STDERR_WRITE(string) if (fd != -1) I_OutputMsg("%s", string)
|
|
||||||
#define CRASHLOG_WRITE(string) if (fd != -1) junk = write(fd, string, strlen(string))
|
static void bt_write_file(int fd, const char *string) {
|
||||||
#define CRASHLOG_STDERR_WRITE(string) \
|
ssize_t written = 0;
|
||||||
if (fd != -1)\
|
ssize_t sourcelen = strlen(string);
|
||||||
junk = write(fd, string, strlen(string));\
|
|
||||||
I_OutputMsg("%s", string)
|
while (fd != -1 && (written != -1 && errno != EINTR) && written < sourcelen)
|
||||||
|
written = write(fd, string, sourcelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bt_write_stderr(const char *string) {
|
||||||
|
bt_write_file(STDERR_FILENO, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bt_write_all(int fd, const char *string) {
|
||||||
|
bt_write_file(fd, string);
|
||||||
|
bt_write_file(STDERR_FILENO, string);
|
||||||
|
}
|
||||||
|
|
||||||
static void write_backtrace(INT32 signal)
|
static void write_backtrace(INT32 signal)
|
||||||
{
|
{
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
#ifndef NOEXECINFO
|
|
||||||
size_t size;
|
|
||||||
#endif
|
|
||||||
time_t rawtime;
|
time_t rawtime;
|
||||||
struct tm timeinfo;
|
struct tm timeinfo;
|
||||||
ssize_t junk;
|
|
||||||
|
|
||||||
enum { BT_SIZE = 1024, STR_SIZE = 32 };
|
enum { BT_SIZE = 1024, STR_SIZE = 32 };
|
||||||
#ifndef NOEXECINFO
|
#ifndef NOEXECINFO
|
||||||
void *array[BT_SIZE];
|
void *funcptrs[BT_SIZE];
|
||||||
|
size_t bt_size;
|
||||||
#endif
|
#endif
|
||||||
char timestr[STR_SIZE];
|
char timestr[STR_SIZE];
|
||||||
|
|
||||||
const char *error = "An error occurred within SRB2! Send this stack trace to someone who can help!\n";
|
const char *filename = va("%s" PATHSEP "%s", srb2home, "crash-log.txt");
|
||||||
const char *error2 = "(Or find crash-log.txt in your SRB2 directory.)\n"; // Shown only to stderr.
|
|
||||||
|
|
||||||
fd = open(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), O_CREAT|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR);
|
fd = open(filename, O_CREAT|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR);
|
||||||
|
|
||||||
if (fd == -1)
|
if (fd == -1) // File handle error
|
||||||
I_OutputMsg("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n");
|
bt_write_stderr("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n");
|
||||||
|
|
||||||
// Get the current time as a string.
|
// Get the current time as a string.
|
||||||
time(&rawtime);
|
time(&rawtime);
|
||||||
localtime_r(&rawtime, &timeinfo);
|
localtime_r(&rawtime, &timeinfo);
|
||||||
strftime(timestr, STR_SIZE, "%a, %d %b %Y %T %z", &timeinfo);
|
strftime(timestr, STR_SIZE, "%a, %d %b %Y %T %z", &timeinfo);
|
||||||
|
|
||||||
CRASHLOG_WRITE("------------------------\n"); // Nice looking seperator
|
bt_write_file(fd, "------------------------\n"); // Nice looking seperator
|
||||||
|
|
||||||
CRASHLOG_STDERR_WRITE("\n"); // Newline to look nice for both outputs.
|
bt_write_all(fd, "\n"); // Newline to look nice for both outputs.
|
||||||
CRASHLOG_STDERR_WRITE(error); // "Oops, SRB2 crashed" message
|
bt_write_all(fd, "An error occurred within SRB2! Send this stack trace to someone who can help!\n");
|
||||||
STDERR_WRITE(error2); // Tell the user where the crash log is.
|
|
||||||
|
if (fd != -1) // If the crash log exists,
|
||||||
|
bt_write_stderr("(Or find crash-log.txt in your SRB2 directory.)\n"); // tell the user where the crash log is.
|
||||||
|
|
||||||
// Tell the log when we crashed.
|
// Tell the log when we crashed.
|
||||||
CRASHLOG_WRITE("Time of crash: ");
|
bt_write_file(fd, "Time of crash: ");
|
||||||
CRASHLOG_WRITE(timestr);
|
bt_write_file(fd, timestr);
|
||||||
CRASHLOG_WRITE("\n");
|
bt_write_file(fd, "\n");
|
||||||
|
|
||||||
// Give the crash log the cause and a nice 'Backtrace:' thing
|
// Give the crash log the cause and a nice 'Backtrace:' thing
|
||||||
// The signal is given to the user when the parent process sees we crashed.
|
// The signal is given to the user when the parent process sees we crashed.
|
||||||
CRASHLOG_WRITE("Cause: ");
|
bt_write_file(fd, "Cause: ");
|
||||||
CRASHLOG_WRITE(strsignal(signal));
|
bt_write_file(fd, strsignal(signal));
|
||||||
CRASHLOG_WRITE("\n"); // Newline for the signal name
|
bt_write_file(fd, "\n"); // Newline for the signal name
|
||||||
|
|
||||||
#ifndef NOEXECINFO
|
#ifdef NOEXECINFO
|
||||||
CRASHLOG_STDERR_WRITE("\nBacktrace:\n");
|
bt_write_all(fd, "\nNo Backtrace support\n");
|
||||||
|
#else
|
||||||
|
bt_write_all(fd, "\nBacktrace:\n");
|
||||||
|
|
||||||
// Flood the output and log with the backtrace
|
// Flood the output and log with the backtrace
|
||||||
size = backtrace(array, BT_SIZE);
|
bt_size = backtrace(funcptrs, BT_SIZE);
|
||||||
backtrace_symbols_fd(array, size, fd);
|
backtrace_symbols_fd(funcptrs, bt_size, fd);
|
||||||
backtrace_symbols_fd(array, size, STDERR_FILENO);
|
backtrace_symbols_fd(funcptrs, bt_size, STDERR_FILENO);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :)
|
bt_write_file(fd, "\n"); // Write another newline to the log so it looks nice :)
|
||||||
(void)junk;
|
if (fd != -1) {
|
||||||
close(fd);
|
fsync(fd); // reaaaaally make sure we got that data written.
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#undef STDERR_WRITE
|
|
||||||
#undef CRASHLOG_WRITE
|
|
||||||
#undef CRASHLOG_STDERR_WRITE
|
|
||||||
#endif // UNIXBACKTRACE
|
#endif // UNIXBACKTRACE
|
||||||
|
|
||||||
static void I_ReportSignal(int num, int coredumped)
|
static void I_ReportSignal(int num, int coredumped)
|
||||||
|
@ -2976,7 +2987,7 @@ static void pathonly(char *s)
|
||||||
*/
|
*/
|
||||||
static const char *searchWad(const char *searchDir)
|
static const char *searchWad(const char *searchDir)
|
||||||
{
|
{
|
||||||
static char tempsw[256] = "";
|
static char tempsw[MAX_WADPATH] = "";
|
||||||
filestatus_t fstemp;
|
filestatus_t fstemp;
|
||||||
|
|
||||||
strcpy(tempsw, WADKEYWORD1);
|
strcpy(tempsw, WADKEYWORD1);
|
||||||
|
@ -3039,9 +3050,15 @@ static const char *locateWad(void)
|
||||||
|
|
||||||
#ifndef NOHOME
|
#ifndef NOHOME
|
||||||
// find in $HOME
|
// find in $HOME
|
||||||
I_OutputMsg(",HOME");
|
I_OutputMsg(",HOME/" DEFAULTDIR);
|
||||||
if ((envstr = I_GetEnv("HOME")) != NULL)
|
if ((envstr = I_GetEnv("HOME")) != NULL)
|
||||||
|
{
|
||||||
|
char *tmp = malloc(strlen(envstr) + sizeof(DEFAULTDIR));
|
||||||
|
strcpy(tmp, envstr);
|
||||||
|
strcat(tmp, DEFAULTDIR);
|
||||||
SEARCHWAD(envstr);
|
SEARCHWAD(envstr);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// search paths
|
// search paths
|
||||||
|
|
|
@ -382,6 +382,8 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
|
||||||
|
|
||||||
static boolean ShouldIgnoreMouse(void)
|
static boolean ShouldIgnoreMouse(void)
|
||||||
{
|
{
|
||||||
|
if (cv_alwaysgrabmouse.value)
|
||||||
|
return false;
|
||||||
if (menuactive)
|
if (menuactive)
|
||||||
return !M_MouseNeeded();
|
return !M_MouseNeeded();
|
||||||
if (paused || con_destlines || chat_on)
|
if (paused || con_destlines || chat_on)
|
||||||
|
|
|
@ -1269,19 +1269,19 @@ tic_t lt_exitticker = 0, lt_endtime = 0;
|
||||||
//
|
//
|
||||||
static void ST_cacheLevelTitle(void)
|
static void ST_cacheLevelTitle(void)
|
||||||
{
|
{
|
||||||
#define SETPATCH(default, warning, custom, idx) \
|
#define SETPATCH(def, warning, custom, idx) \
|
||||||
{ \
|
{ \
|
||||||
lumpnum_t patlumpnum = LUMPERROR; \
|
lumpnum_t patlumpnum = LUMPERROR; \
|
||||||
if (mapheaderinfo[gamemap-1]->custom[0] != '\0') \
|
if (mapheaderinfo[gamemap-1]->custom[0] != '\0') \
|
||||||
{ \
|
{ \
|
||||||
patlumpnum = W_CheckNumForName(mapheaderinfo[gamemap-1]->custom); \
|
patlumpnum = W_CheckNumForPatchName(mapheaderinfo[gamemap-1]->custom); \
|
||||||
if (patlumpnum != LUMPERROR) \
|
if (patlumpnum != LUMPERROR) \
|
||||||
lt_patches[idx] = (patch_t *)W_CachePatchNum(patlumpnum, PU_HUDGFX); \
|
lt_patches[idx] = (patch_t *)W_CachePatchNum(patlumpnum, PU_HUDGFX); \
|
||||||
} \
|
} \
|
||||||
if (patlumpnum == LUMPERROR) \
|
if (patlumpnum == LUMPERROR) \
|
||||||
{ \
|
{ \
|
||||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE)) \
|
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE)) \
|
||||||
lt_patches[idx] = (patch_t *)W_CachePatchName(default, PU_HUDGFX); \
|
lt_patches[idx] = (patch_t *)W_CachePatchName(def, PU_HUDGFX); \
|
||||||
else \
|
else \
|
||||||
lt_patches[idx] = (patch_t *)W_CachePatchName(warning, PU_HUDGFX); \
|
lt_patches[idx] = (patch_t *)W_CachePatchName(warning, PU_HUDGFX); \
|
||||||
} \
|
} \
|
||||||
|
|
271
src/w_wad.c
271
src/w_wad.c
|
@ -98,6 +98,7 @@ typedef struct lumpnum_cache_s
|
||||||
{
|
{
|
||||||
char lumpname[32];
|
char lumpname[32];
|
||||||
lumpnum_t lumpnum;
|
lumpnum_t lumpnum;
|
||||||
|
UINT32 hash;
|
||||||
} lumpnum_cache_t;
|
} lumpnum_cache_t;
|
||||||
|
|
||||||
static lumpnum_cache_t lumpnumcache[LUMPNUMCACHESIZE];
|
static lumpnum_cache_t lumpnumcache[LUMPNUMCACHESIZE];
|
||||||
|
@ -1475,6 +1476,63 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
|
||||||
return INT16_MAX;
|
return INT16_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static lumpnum_t CheckLumpInCache(const char *name, boolean longname)
|
||||||
|
{
|
||||||
|
if (longname)
|
||||||
|
{
|
||||||
|
UINT32 hash = quickncasehash(name, 32);
|
||||||
|
|
||||||
|
// Loop backwards so that we check most recent entries first
|
||||||
|
for (INT32 i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
|
||||||
|
{
|
||||||
|
if (lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].hash == hash
|
||||||
|
&& stricmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0)
|
||||||
|
{
|
||||||
|
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
|
||||||
|
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UINT32 hash = quickncasehash(name, 8);
|
||||||
|
|
||||||
|
// Loop backwards so that we check most recent entries first
|
||||||
|
for (INT32 i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
|
||||||
|
{
|
||||||
|
if (lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].hash == hash
|
||||||
|
&& lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname[8] == '\0'
|
||||||
|
&& strnicmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0)
|
||||||
|
{
|
||||||
|
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
|
||||||
|
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return LUMPERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddLumpToCache(lumpnum_t lumpnum, const char *name, boolean longname)
|
||||||
|
{
|
||||||
|
if (longname && strlen(name) >= 32)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
|
||||||
|
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32);
|
||||||
|
if (longname)
|
||||||
|
{
|
||||||
|
strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32);
|
||||||
|
lumpnumcache[lumpnumcacheindex].hash = quickncasehash(name, 32);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8);
|
||||||
|
lumpnumcache[lumpnumcacheindex].hash = quickncasehash(name, 8);
|
||||||
|
}
|
||||||
|
lumpnumcache[lumpnumcacheindex].lumpnum = lumpnum;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// W_CheckNumForName
|
// W_CheckNumForName
|
||||||
// Returns LUMPERROR if name not found.
|
// Returns LUMPERROR if name not found.
|
||||||
|
@ -1487,17 +1545,10 @@ lumpnum_t W_CheckNumForName(const char *name)
|
||||||
if (!*name) // some doofus gave us an empty string?
|
if (!*name) // some doofus gave us an empty string?
|
||||||
return LUMPERROR;
|
return LUMPERROR;
|
||||||
|
|
||||||
// Check the lumpnumcache first. Loop backwards so that we check
|
// Check the lumpnumcache first.
|
||||||
// most recent entries first
|
lumpnum_t cachenum = CheckLumpInCache(name, false);
|
||||||
for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
|
if (cachenum != LUMPERROR)
|
||||||
{
|
return cachenum;
|
||||||
if (!lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname[8]
|
|
||||||
&& strncmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0)
|
|
||||||
{
|
|
||||||
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
|
|
||||||
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// scan wad files backwards so patch lump files take precedence
|
// scan wad files backwards so patch lump files take precedence
|
||||||
for (i = numwadfiles - 1; i >= 0; i--)
|
for (i = numwadfiles - 1; i >= 0; i--)
|
||||||
|
@ -1511,12 +1562,11 @@ lumpnum_t W_CheckNumForName(const char *name)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Update the cache.
|
// Update the cache.
|
||||||
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
|
lumpnum_t lumpnum = (i << 16) + check;
|
||||||
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32);
|
|
||||||
strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8);
|
|
||||||
lumpnumcache[lumpnumcacheindex].lumpnum = (i<<16)+check;
|
|
||||||
|
|
||||||
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
AddLumpToCache(lumpnum, name, false);
|
||||||
|
|
||||||
|
return lumpnum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1534,16 +1584,10 @@ lumpnum_t W_CheckNumForLongName(const char *name)
|
||||||
if (!*name) // some doofus gave us an empty string?
|
if (!*name) // some doofus gave us an empty string?
|
||||||
return LUMPERROR;
|
return LUMPERROR;
|
||||||
|
|
||||||
// Check the lumpnumcache first. Loop backwards so that we check
|
// Check the lumpnumcache first.
|
||||||
// most recent entries first
|
lumpnum_t cachenum = CheckLumpInCache(name, true);
|
||||||
for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
|
if (cachenum != LUMPERROR)
|
||||||
{
|
return cachenum;
|
||||||
if (strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0)
|
|
||||||
{
|
|
||||||
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
|
|
||||||
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// scan wad files backwards so patch lump files take precedence
|
// scan wad files backwards so patch lump files take precedence
|
||||||
for (i = numwadfiles - 1; i >= 0; i--)
|
for (i = numwadfiles - 1; i >= 0; i--)
|
||||||
|
@ -1556,16 +1600,12 @@ lumpnum_t W_CheckNumForLongName(const char *name)
|
||||||
if (check == INT16_MAX) return LUMPERROR;
|
if (check == INT16_MAX) return LUMPERROR;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (strlen(name) < 32)
|
// Update the cache.
|
||||||
{
|
lumpnum_t lumpnum = (i << 16) + check;
|
||||||
// Update the cache.
|
|
||||||
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
|
|
||||||
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32);
|
|
||||||
strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32);
|
|
||||||
lumpnumcache[lumpnumcacheindex].lumpnum = (i << 16) + check;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (i << 16) + check;
|
AddLumpToCache(lumpnum, name, true);
|
||||||
|
|
||||||
|
return lumpnum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1647,6 +1687,159 @@ lumpnum_t W_GetNumForLongName(const char *name)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Same as W_CheckNumForNamePwad, but handles namespaces.
|
||||||
|
//
|
||||||
|
static UINT16 W_CheckNumForPatchNamePwad(const char *name, UINT16 wad, boolean longname)
|
||||||
|
{
|
||||||
|
UINT16 i, start, end;
|
||||||
|
static char uname[8 + 1] = { 0 };
|
||||||
|
UINT32 hash = 0;
|
||||||
|
lumpinfo_t *lump_p;
|
||||||
|
|
||||||
|
if (!TestValidLump(wad,0))
|
||||||
|
return INT16_MAX;
|
||||||
|
|
||||||
|
if (!longname)
|
||||||
|
{
|
||||||
|
strlcpy(uname, name, sizeof uname);
|
||||||
|
strupr(uname);
|
||||||
|
hash = quickncasehash(uname, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SRB2 doesn't have a specific namespace for graphics, which means someone can do weird things
|
||||||
|
// like placing graphics inside a namespace it doesn't make sense for them to be in, like Sounds/ or SOC/
|
||||||
|
// So for now, this checks for lumps OUTSIDE of the flats namespace.
|
||||||
|
// When this situation changes, change the loops below to check for lumps INSIDE the namespaces to look in.
|
||||||
|
// TODO: cache namespace lump IDs
|
||||||
|
if (W_FileHasFolders(wadfiles[wad]))
|
||||||
|
{
|
||||||
|
start = W_CheckNumForFolderStartPK3("Flats/", wad, 0);
|
||||||
|
end = W_CheckNumForFolderEndPK3("Flats/", wad, start);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start = W_CheckNumForMarkerStartPwad("F_START", wad, 0);
|
||||||
|
end = W_CheckNumForNamePwad("F_END", wad, start);
|
||||||
|
if (end != INT16_MAX)
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lump_p = wadfiles[wad]->lumpinfo;
|
||||||
|
|
||||||
|
if (start == INT16_MAX)
|
||||||
|
start = wadfiles[wad]->numlumps;
|
||||||
|
|
||||||
|
for (i = 0; i < start; i++, lump_p++)
|
||||||
|
{
|
||||||
|
if ((!longname && lump_p->hash == hash && !strncmp(lump_p->name, uname, sizeof(uname) - 1))
|
||||||
|
|| (longname && stricmp(lump_p->longname, name) == 0))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end != INT16_MAX && start < end)
|
||||||
|
{
|
||||||
|
lump_p = wadfiles[wad]->lumpinfo + end;
|
||||||
|
|
||||||
|
for (i = end; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||||
|
{
|
||||||
|
if ((!longname && lump_p->hash == hash && !strncmp(lump_p->name, uname, sizeof(uname) - 1))
|
||||||
|
|| (longname && stricmp(lump_p->longname, name) == 0))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// not found.
|
||||||
|
return INT16_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// W_CheckNumForPatchNameInternal
|
||||||
|
// Gets a lump number out of a patch name. Returns LUMPERROR if name not found.
|
||||||
|
//
|
||||||
|
static lumpnum_t W_CheckNumForPatchNameInternal(const char *name, boolean longname)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
lumpnum_t check = INT16_MAX;
|
||||||
|
|
||||||
|
if (!*name) // some doofus gave us an empty string?
|
||||||
|
return LUMPERROR;
|
||||||
|
|
||||||
|
// Check the lumpnumcache first.
|
||||||
|
lumpnum_t cachenum = CheckLumpInCache(name, longname);
|
||||||
|
if (cachenum != LUMPERROR)
|
||||||
|
return cachenum;
|
||||||
|
|
||||||
|
// scan wad files backwards so patch lump files take precedence
|
||||||
|
for (i = numwadfiles - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
check = W_CheckNumForPatchNamePwad(name,(UINT16)i,longname);
|
||||||
|
if (check != INT16_MAX)
|
||||||
|
break; //found it
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check == INT16_MAX) return LUMPERROR;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Update the cache.
|
||||||
|
lumpnum_t lumpnum = (i << 16) + check;
|
||||||
|
|
||||||
|
AddLumpToCache(lumpnum, name, longname);
|
||||||
|
|
||||||
|
return lumpnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// W_CheckNumForPatchName
|
||||||
|
// Wrapper for W_CheckNumForPatchNameInternal(name, false). Returns LUMPERROR if name not found.
|
||||||
|
//
|
||||||
|
lumpnum_t W_CheckNumForPatchName(const char *name)
|
||||||
|
{
|
||||||
|
return W_CheckNumForPatchNameInternal(name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Like W_CheckNumForPatchName, but can find entries with long names.
|
||||||
|
// Wrapper for W_CheckNumForPatchNameInternal(name, true). Returns LUMPERROR if name not found.
|
||||||
|
//
|
||||||
|
lumpnum_t W_CheckNumForLongPatchName(const char *name)
|
||||||
|
{
|
||||||
|
return W_CheckNumForPatchNameInternal(name, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// W_GetNumForPatchName
|
||||||
|
//
|
||||||
|
// Calls W_CheckNumForPatchName, but bombs out if not found.
|
||||||
|
//
|
||||||
|
lumpnum_t W_GetNumForPatchName(const char *name)
|
||||||
|
{
|
||||||
|
lumpnum_t i;
|
||||||
|
|
||||||
|
i = W_CheckNumForPatchName(name);
|
||||||
|
|
||||||
|
if (i == LUMPERROR)
|
||||||
|
I_Error("W_CheckNumForPatchName: %s not found!\n", name);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Like W_GetNumForPatchName, but can find entries with long names
|
||||||
|
//
|
||||||
|
lumpnum_t W_GetNumForLongPatchName(const char *name)
|
||||||
|
{
|
||||||
|
lumpnum_t i;
|
||||||
|
|
||||||
|
i = W_CheckNumForLongPatchName(name);
|
||||||
|
|
||||||
|
if (i == LUMPERROR)
|
||||||
|
I_Error("W_GetNumForLongPatchName: %s not found!\n", name);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// W_CheckNumForNameInBlock
|
// W_CheckNumForNameInBlock
|
||||||
// Checks only in blocks from blockstart lump to blockend lump
|
// Checks only in blocks from blockstart lump to blockend lump
|
||||||
|
@ -2291,10 +2484,10 @@ void *W_CachePatchName(const char *name, INT32 tag)
|
||||||
{
|
{
|
||||||
lumpnum_t num;
|
lumpnum_t num;
|
||||||
|
|
||||||
num = W_CheckNumForName(name);
|
num = W_CheckNumForPatchName(name);
|
||||||
|
|
||||||
if (num == LUMPERROR)
|
if (num == LUMPERROR)
|
||||||
return W_CachePatchNum(W_GetNumForName("MISSING"), tag);
|
return W_CachePatchNum(W_GetNumForPatchName("MISSING"), tag);
|
||||||
return W_CachePatchNum(num, tag);
|
return W_CachePatchNum(num, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2302,10 +2495,10 @@ void *W_CachePatchLongName(const char *name, INT32 tag)
|
||||||
{
|
{
|
||||||
lumpnum_t num;
|
lumpnum_t num;
|
||||||
|
|
||||||
num = W_CheckNumForLongName(name);
|
num = W_CheckNumForLongPatchName(name);
|
||||||
|
|
||||||
if (num == LUMPERROR)
|
if (num == LUMPERROR)
|
||||||
return W_CachePatchNum(W_GetNumForLongName("MISSING"), tag);
|
return W_CachePatchNum(W_GetNumForLongPatchName("MISSING"), tag);
|
||||||
return W_CachePatchNum(num, tag);
|
return W_CachePatchNum(num, tag);
|
||||||
}
|
}
|
||||||
#ifndef NOMD5
|
#ifndef NOMD5
|
||||||
|
|
|
@ -193,6 +193,12 @@ lumpnum_t W_CheckNumForName(const char *name);
|
||||||
lumpnum_t W_CheckNumForLongName(const char *name);
|
lumpnum_t W_CheckNumForLongName(const char *name);
|
||||||
lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR
|
lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR
|
||||||
lumpnum_t W_GetNumForLongName(const char *name);
|
lumpnum_t W_GetNumForLongName(const char *name);
|
||||||
|
|
||||||
|
lumpnum_t W_CheckNumForPatchName(const char *name);
|
||||||
|
lumpnum_t W_CheckNumForLongPatchName(const char *name);
|
||||||
|
lumpnum_t W_GetNumForPatchName(const char *name); // like W_CheckNumForPatchName but I_Error on LUMPERROR
|
||||||
|
lumpnum_t W_GetNumForLongPatchName(const char *name);
|
||||||
|
|
||||||
lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend);
|
lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend);
|
||||||
UINT8 W_LumpExists(const char *name); // Lua uses this.
|
UINT8 W_LumpExists(const char *name); // Lua uses this.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue