Merge remote-tracking branch 'origin/blankart-dev' into bigwipes

This commit is contained in:
GenericHeroGuy 2025-08-10 00:05:26 +02:00
commit cf73d0dd83
18 changed files with 761 additions and 438 deletions

View file

@ -1381,8 +1381,8 @@ void F_TitleScreenDrawer(void)
// Draw that sky!
if (curbgcolor >= 0)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor);
else if (!curbghide || !titlemapinaction || gamestate == GS_WAITINGPLAYERS)
F_SkyScroll(curbgxspeed, curbgyspeed, curbgname);
//else if (!curbghide || !titlemapinaction || gamestate == GS_WAITINGPLAYERS)
//F_SkyScroll(curbgxspeed, curbgyspeed, curbgname);
// Don't draw outside of the title screen, or if the patch isn't there.
if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)

View file

@ -428,9 +428,32 @@ filestatus_t filesearch(char *filename, const char *startpath, UINT64 wantedhash
// okay, now we actually want searchpath to incorporate d_name
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
#if defined(__linux__) || defined(__FreeBSD__)
if (dent->d_type == DT_UNKNOWN && lstat(searchpath, &fsstat) == 0)
{
if (S_ISDIR(fsstat.st_mode))
dent->d_type = DT_DIR;
else if (S_ISLNK(fsstat.st_mode))
dent->d_type = DT_LNK;
}
// Symlinks aren't always directory symlinks. Dunno if this would resolve recursive
// symlinks, but i think stat already does that
if (dent->d_type == DT_LNK && stat(searchpath, &fsstat) == 0 && !S_ISDIR(fsstat.st_mode))
{
dent->d_type = DT_UNKNOWN;
}
// Linux and FreeBSD has a special field for file type on dirent, so use that to speed up lookups.
// FIXME: should we also follow symlinks?
if ((dent->d_type == DT_DIR && depthleft) || (dent->d_type == DT_LNK && depthleft))
#else
// if we wanna follow symlinks we can check with FILE_ATTRIBUTE_REPARSE_POINT
DWORD fileattr = GetFileAttributes(searchpath);
if (fileattr == INVALID_FILE_ATTRIBUTES)
; // was the file (re)moved? can't stat it
else if (S_ISDIR(fsstat.st_mode) && depthleft)
else if ((fileattr & FILE_ATTRIBUTE_DIRECTORY) && depthleft)
#endif
{
searchpathindex[--depthleft] = strlen(searchpath) + 1;
dirhandle[depthleft] = opendir(searchpath);

View file

@ -938,7 +938,7 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, boolean digital)
deadzone = (JOYAXISRANGE * cv_deadzone[p].value) / FRACUNIT;
deviceID = cv_usejoystick[p].value;
deviceID = I_GetJoystickDeviceIndexForPlayer(p) + 1;
retrygetcontrol:
for (i = 0; i < MAXINPUTMAPPING; i++)
@ -1056,7 +1056,7 @@ static void G_DoCameraTurn(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer, player
if (player->mo)
cmd->angle = K_GetKartTurnValue(player, cmd->angle);
cmd->angle *= realtics;
if (P_CanPlayerTurn(player, cmd))
@ -1315,7 +1315,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
cmd->sidemove = MAXPLMOVE;
else if (cmd->sidemove < -MAXPLMOVE)
cmd->sidemove = -MAXPLMOVE;
if (cmd->turning > KART_FULLTURN)
cmd->turning = KART_FULLTURN;
else if (cmd->turning < -KART_FULLTURN)
@ -2375,9 +2375,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
boolean followerready;
INT32 followerskin;
UINT16 followercolor;
mobj_t *follower; // old follower, will probably be removed by the time we're dead but you never know.
INT32 charflags;
UINT32 followitem;
@ -2394,7 +2394,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
tic_t starposttime; // The time of the last cheatcheck you hit
INT32 prevcheck; // Distance from Previous Legacy Checkpoint
INT32 nextcheck; // Distace to Next Legacy Checkpoint
INT32 exiting;
INT32 khudcardanimation;
INT16 totalring;
@ -2542,7 +2542,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
wanted = players[player].wanted;
rings = players[player].rings;
kickstartaccel = players[player].kickstartaccel;
nocontrol = players[player].nocontrol;
laps = players[player].laps;
@ -2552,7 +2552,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
exiting = players[player].exiting;
khudcardanimation = (exiting > 0) ? players[player].karthud[khud_cardanimation] : 0;
starpostx = players[player].starpostx;
starposty = players[player].starposty;
starpostz = players[player].starpostz;
@ -2579,7 +2579,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
{
follower = NULL;
}
spectatorreentry = players[player].spectatorreentry;
grieftime = players[player].grieftime;
@ -2622,7 +2622,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->starposttime = starposttime;
p->prevcheck = prevcheck;
p->nextcheck = nextcheck;
p->exiting = exiting;
p->karthud[khud_cardanimation] = khudcardanimation;
@ -2654,7 +2654,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->ringvolume = 255;
p->ringtransparency = 255;
p->spectatorreentry = spectatorreentry;
p->grieftime = grieftime;
p->griefstrikes = griefstrikes;
@ -2732,7 +2732,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
if (songcredit)
S_ShowMusicCredit();
if (leveltime > (starttime + (TICRATE/2)) && !p->spectator)
p->respawn = 48; // Respawn effect
}
@ -2795,7 +2795,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
}
void G_MovePlayerToSpawnOrStarpost(INT32 playernum, boolean starpost)
{
{
if ((leveltime > starttime) && starpost)
P_MovePlayerToStarpost(playernum);
else
@ -3121,10 +3121,10 @@ void G_DoReborn(INT32 playernum)
{
// respawn at the start
mobj_t *oldmo = NULL;
if (player->spectator)
;
else if ((player->starpostnum || ((player->nextwaypoint != NULL) && player->starposttime))
else if ((player->starpostnum || ((player->nextwaypoint != NULL) && player->starposttime))
|| ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) && player->laps)) // SRB2kart
starpost = true;
@ -4563,7 +4563,7 @@ void G_LoadGameData(void)
if (vspowerlevel[i] < PWRLVRECORD_MIN || vspowerlevel[i] > PWRLVRECORD_MAX)
goto datacorrupt;
}
modded = READUINT8(save.p);
// Aha! Someone's been screwing with the save file!

View file

@ -14,6 +14,7 @@
#include "doomdef.h"
#include "doomstat.h"
#include "g_input.h"
#include "i_system.h"
#include "keys.h"
#include "hu_stuff.h" // need HUFONT start & end
#include "d_net.h"
@ -38,7 +39,7 @@ consvar_t cv_turnsmooth = CVAR_INIT ("turnsmoothing", "Off", CV_SAVE, turnsmooth
// current state of the keys
// JOYAXISRANGE for fully pressed, 0 for not pressed
INT32 gamekeydown[MAXDEVICES][NUMINPUTS];
boolean deviceResponding[MAXDEVICES];
boolean deviceResponding[MAXDEVICES];
// several key codes (or virtual key) per game control
INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING];
@ -100,7 +101,7 @@ INT32 G_GetDevicePlayer(INT32 deviceID)
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
if (deviceID == cv_usejoystick[i].value)
if (deviceID == I_GetJoystickDeviceIndexForPlayer(i) + 1)
{
return i;
}

View file

@ -460,24 +460,22 @@ static void HWR_GenerateTexture(GLMapTexture_t *grtex, INT32 texnum, boolean noe
UINT8 *colormap = colormaps;
INT32 i;
INT32 i, idx;
boolean skyspecial = false; //poor hack for Legacy large skies..
texture = textures[texnum];
grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY;
grtex->mipmap.format = textureformat;
// hack the Legacy skies..
if (texture->name[0] == 'S' &&
texture->name[1] == 'K' &&
texture->name[2] == 'Y' &&
(texture->name[4] == 0 ||
texture->name[5] == 0)
)
if (memcmp(texture->name, "SKY", 3) == 0 &&
(texture->name[4] == 0 || texture->name[5] == 0))
{
skyspecial = true;
grtex->mipmap.flags = TF_WRAPXY; // don't use the chromakey for sky
grtex->mipmap.flags &= ~TF_CHROMAKEYED; // don't use the chromakey for sky
grtex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ...
}
else
grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY;
grtex->mipmap.width = (UINT16)texture->width;
grtex->mipmap.height = (UINT16)texture->height;
@ -501,14 +499,14 @@ static void HWR_GenerateTexture(GLMapTexture_t *grtex, INT32 texnum, boolean noe
RGBA_t col;
col = V_GetColor(HWR_PATCHES_CHROMAKEY_COLORINDEX);
for (j = 0; j < blockheight; j++)
for (idx = 0, j = 0; j < blockheight; j++)
{
for (i = 0; i < blockwidth; i++)
for (i = 0; i < blockwidth; i++, idx++)
{
block[4*(j*blockwidth+i)+0] = col.s.red;
block[4*(j*blockwidth+i)+1] = col.s.green;
block[4*(j*blockwidth+i)+2] = col.s.blue;
block[4*(j*blockwidth+i)+3] = 0xff;
block[4*idx+0] = col.s.red;
block[4*idx+1] = col.s.green;
block[4*idx+2] = col.s.blue;
block[4*idx+3] = 0xff;
}
}
}

View file

@ -6184,7 +6184,7 @@ consvar_t cv_glspritebillboarding = CVAR_INIT ("gr_spritebillboarding", "On", CV
consvar_t cv_glskydome = CVAR_INIT ("gr_skydome", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_glfiltermode = CVAR_INIT ("gr_filtermode", "Nearest", CV_SAVE|CV_CALL, glfiltermode_cons_t, CV_glfiltermode_OnChange);
consvar_t cv_glanisotropicmode = CVAR_INIT ("gr_anisotropicmode", "1", CV_CALL, glanisotropicmode_cons_t, CV_glanisotropic_OnChange);
consvar_t cv_glanisotropicmode = CVAR_INIT ("gr_anisotropicmode", "1", CV_SAVE|CV_CALL, glanisotropicmode_cons_t, CV_glanisotropic_OnChange);
consvar_t cv_glsolvetjoin = CVAR_INIT ("gr_solvetjoin", "On", 0, CV_OnOff, NULL);

View file

@ -1880,11 +1880,14 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
INT32 w = pTexInfo->width, h = pTexInfo->height;
INT32 i, j;
INT32 idx;
const GLubyte *pImgData = (const GLubyte *)pTexInfo->data;
const GLvoid *ptex = NULL;
RGBA_t *tex = NULL;
GLint texformat = 0;
// Generate a new texture name.
if (!num)
{
@ -1895,85 +1898,84 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
//GL_DBG_Printf("UpdateTexture %d %x\n", (INT32)num, pImgData);
if ((pTexInfo->format == GL_TEXFMT_P_8) || (pTexInfo->format == GL_TEXFMT_AP_88))
texformat = textureformatGL;
const GLTextureFormat_t texinfoformat = pTexInfo->format;
switch (texinfoformat)
{
AllocTextureBuffer(pTexInfo);
ptex = tex = textureBuffer;
case GL_TEXFMT_P_8:
case GL_TEXFMT_AP_88:
AllocTextureBuffer(pTexInfo);
ptex = tex = textureBuffer;
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++)
const int chromakeyed = (pTexInfo->flags & TF_CHROMAKEYED);
for (idx = 0, j = 0; j < h; j++)
{
if ((*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX) &&
(pTexInfo->flags & TF_CHROMAKEYED))
for (i = 0; i < w; i++, idx++)
{
tex[w*j+i].s.red = 0;
tex[w*j+i].s.green = 0;
tex[w*j+i].s.blue = 0;
tex[w*j+i].s.alpha = 0;
pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it
}
else
{
tex[w*j+i].s.red = myPaletteData[*pImgData].s.red;
tex[w*j+i].s.green = myPaletteData[*pImgData].s.green;
tex[w*j+i].s.blue = myPaletteData[*pImgData].s.blue;
tex[w*j+i].s.alpha = myPaletteData[*pImgData].s.alpha;
}
if (chromakeyed && (*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX))
{
tex[idx].s = (byteColor_t){0, 0, 0, 0};
pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it
}
else
{
tex[idx].s = myPaletteData[*pImgData].s;
}
pImgData++;
pImgData++;
if (pTexInfo->format == GL_TEXFMT_AP_88)
{
if (!(pTexInfo->flags & TF_CHROMAKEYED))
tex[w*j+i].s.alpha = *pImgData;
if (texinfoformat != GL_TEXFMT_AP_88 || chromakeyed)
continue;
tex[idx].s.alpha = *pImgData;
pImgData++;
}
}
}
}
else if (pTexInfo->format == GL_TEXFMT_RGBA)
{
// Directly upload the texture data without any kind of conversion.
ptex = pImgData;
}
else if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88)
{
AllocTextureBuffer(pTexInfo);
ptex = tex = textureBuffer;
break;
case GL_TEXFMT_RGBA:
// Directly upload the texture data without any kind of conversion.
ptex = pImgData;
break;
case GL_TEXFMT_ALPHA_INTENSITY_88:
AllocTextureBuffer(pTexInfo);
ptex = tex = textureBuffer;
texformat = GL_RGBA;
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++)
for (idx = 0, j = 0; j < h; j++)
{
tex[w*j+i].s.red = *pImgData;
tex[w*j+i].s.green = *pImgData;
tex[w*j+i].s.blue = *pImgData;
pImgData++;
tex[w*j+i].s.alpha = *pImgData;
pImgData++;
for (i = 0; i < w; i++, idx++)
{
tex[idx].s.red = *pImgData;
tex[idx].s.green = *pImgData;
tex[idx].s.blue = *pImgData;
pImgData++;
tex[idx].s.alpha = *pImgData;
pImgData++;
}
}
}
}
else if (pTexInfo->format == GL_TEXFMT_ALPHA_8) // Used for fade masks
{
AllocTextureBuffer(pTexInfo);
ptex = tex = textureBuffer;
break;
case GL_TEXFMT_ALPHA_8: // Used for fade masks
AllocTextureBuffer(pTexInfo);
ptex = tex = textureBuffer;
texformat = GL_RGBA;
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++)
// 255 because the fade mask is modulated with the screen texture, so alpha affects it while the colours don't
memset(&tex->s, 255, sizeof(byteColor_t)*w*h);
for (idx = 0, j = 0; j < h; j++)
{
tex[w*j+i].s.red = 255; // 255 because the fade mask is modulated with the screen texture, so alpha affects it while the colours don't
tex[w*j+i].s.green = 255;
tex[w*j+i].s.blue = 255;
tex[w*j+i].s.alpha = *pImgData;
pImgData++;
for (i = 0; i < w; i++, idx++)
{
tex[idx].s.alpha = *pImgData++;
}
}
}
break;
default:
GL_MSG_Warning("UpdateTexture: bad format %d\n", texinfoformat);
break;
}
else
GL_MSG_Warning("UpdateTexture: bad format %d\n", pTexInfo->format);
if (!(pTexInfo->flags & TF_BRIGHTMAP))
{
@ -1985,8 +1987,10 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
pglBindTexture(GL_TEXTURE_2D, num);
tex_downloaded = num;
const int transparent = (pTexInfo->flags & TF_TRANSPARENT);
// disable texture filtering on any texture that has holes so there's no dumb borders or blending issues
if (pTexInfo->flags & TF_TRANSPARENT)
if (transparent)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@ -1997,70 +2001,25 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
}
if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88)
if (MipMap && !transparent) // No mipmaps on transparent stuff
{
//pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
if (MipMap)
{
pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
if (pTexInfo->flags & TF_TRANSPARENT)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
//pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR);
}
pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
if (update)
pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
else
{
if (update)
pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
else
pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
}
}
else if (pTexInfo->format == GL_TEXFMT_ALPHA_8)
{
//pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
if (MipMap)
{
pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
if (pTexInfo->flags & TF_TRANSPARENT)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
//pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR);
}
else
{
if (update)
pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
else
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
}
pglTexImage2D(GL_TEXTURE_2D, 0, texformat, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
// Control the mipmap level of detail
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5);
}
else
{
if (MipMap)
{
pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
// Control the mipmap level of detail
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail
if (pTexInfo->flags & TF_TRANSPARENT)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5);
}
if (update)
pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
else
{
if (update)
pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
else
pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
}
pglTexImage2D(GL_TEXTURE_2D, 0, texformat, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
}
if (pTexInfo->flags & TF_WRAPX)

View file

@ -310,6 +310,8 @@ const char *I_LocateWad(void);
*/
void I_GetJoystickEvents(UINT8 index);
INT32 I_GetJoystickDeviceIndexForPlayer(UINT8 pnum);
/** \brief Checks if the mouse needs to be grabbed
*/
void I_UpdateMouseGrab(void);

View file

@ -2054,92 +2054,210 @@ void EV_DoCrushFloorOnce(mtag_t tag, fixed_t speed)
// jff 2/22/98 new type to move floor and ceiling in parallel
//
void EV_DoElevator(mtag_t tag, line_t *line, elevator_e elevtype)
{
// This function is deprecated.
// Use any of the following functions directly, instead.
switch (elevtype)
{
case elevateDown:
EV_DoElevateDown(tag);
break;
case elevateUp:
EV_DoElevateUp(tag);
break;
case elevateHighest:
EV_DoElevateHighest(tag);
break;
case elevateContinuous:
EV_DoContinuousElevator(
tag,
line->args[1] << (FRACBITS - 2),
line->args[2],
line->args[3],
(line->args[4] == 0)
);
break;
case bridgeFall:
EV_DoBridgeFall(tag);
break;
default:
break;
}
}
static elevator_t *CreateElevatorThinker(sector_t *sec)
{
elevator_t *elevator = NULL;
if (sec->floordata || sec->ceilingdata)
{
return NULL;
}
elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &elevator->thinker);
// make sure other thinkers won't get started over this one
sec->floordata = elevator;
sec->ceilingdata = elevator;
// set up some generic aspects of the floormove_t
elevator->thinker.function.acp1 = (actionf_p1)T_MoveElevator;
elevator->distance = 1; // Always crush unless otherwise
elevator->sector = sec;
// interpolation
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, false);
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, true);
return elevator;
}
void EV_DoElevateDown(mtag_t tag)
{
INT32 secnum = -1;
sector_t *sec;
elevator_t *elevator;
// act on all sectors with the given tag
TAG_ITER_SECTORS(tag, secnum)
{
elevator_t *elevator = NULL;
sec = &sectors[secnum];
// If either floor or ceiling is already activated, skip it
if (sec->floordata || sec->ceilingdata)
continue;
// create and initialize new elevator thinker
elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &elevator->thinker);
sec->floordata = elevator;
sec->ceilingdata = elevator;
elevator->thinker.function.acp1 = (actionf_p1)T_MoveElevator;
elevator->type = elevtype;
elevator->sourceline = line;
elevator->distance = 1; // Always crush unless otherwise
elevator->sector = sec;
// set up the fields according to the type of elevator action
switch (elevtype)
elevator = CreateElevatorThinker(sec);
if (elevator == NULL)
{
// elevator down to next floor
case elevateDown:
elevator->direction = -1;
elevator->speed = ELEVATORSPEED/2; // half speed
elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight);
break;
// elevator up to next floor
case elevateUp:
elevator->direction = 1;
elevator->speed = ELEVATORSPEED/4; // quarter speed
elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight);
break;
// elevator up to highest floor
case elevateHighest:
elevator->direction = 1;
elevator->speed = ELEVATORSPEED/4; // quarter speed
elevator->floordestheight = P_FindHighestFloorSurrounding(sec);
break;
case elevateContinuous:
elevator->origspeed = line->args[1] << (FRACBITS - 2);
elevator->speed = elevator->origspeed;
elevator->low = !line->args[4]; // go down first unless args[4] is set
if (elevator->low)
{
elevator->direction = 1;
elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight);
}
else
{
elevator->direction = -1;
elevator->floordestheight = P_FindNextLowestFloor(sec,sec->floorheight);
}
elevator->floorwasheight = elevator->sector->floorheight;
elevator->ceilingwasheight = elevator->sector->ceilingheight;
elevator->delay = line->args[3];
elevator->delaytimer = line->args[2]; // Initial delay
break;
case bridgeFall:
elevator->direction = -1;
elevator->speed = ELEVATORSPEED*4; // quadruple speed
elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight);
break;
default:
break;
continue;
}
elevator->ceilingdestheight = elevator->floordestheight + sec->ceilingheight - sec->floorheight;
elevator->type = elevateDown;
// interpolation
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, false);
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, true);
elevator->direction = -1;
elevator->speed = ELEVATORSPEED/2; // half speed
elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight);
elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight);
}
}
void EV_DoElevateUp(mtag_t tag)
{
INT32 secnum = -1;
sector_t *sec;
TAG_ITER_SECTORS(tag, secnum)
{
elevator_t *elevator = NULL;
sec = &sectors[secnum];
elevator = CreateElevatorThinker(sec);
if (elevator == NULL)
{
continue;
}
elevator->type = elevateDown;
elevator->direction = 1;
elevator->speed = ELEVATORSPEED/4; // quarter speed
elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight);
elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight);
}
}
void EV_DoElevateHighest(mtag_t tag)
{
INT32 secnum = -1;
sector_t *sec;
TAG_ITER_SECTORS(tag, secnum)
{
elevator_t *elevator = NULL;
sec = &sectors[secnum];
elevator = CreateElevatorThinker(sec);
if (elevator == NULL)
{
continue;
}
elevator->type = elevateHighest;
elevator->direction = 1;
elevator->speed = ELEVATORSPEED/4; // quarter speed
elevator->floordestheight = P_FindHighestFloorSurrounding(sec);
elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight);
}
}
void EV_DoContinuousElevator(mtag_t tag, fixed_t speed, INT32 delayInit, INT32 delay, boolean lowFirst)
{
INT32 secnum = -1;
sector_t *sec;
TAG_ITER_SECTORS(tag, secnum)
{
elevator_t *elevator = NULL;
sec = &sectors[secnum];
elevator = CreateElevatorThinker(sec);
if (elevator == NULL)
{
continue;
}
elevator->type = elevateContinuous;
elevator->origspeed = speed;
elevator->speed = elevator->origspeed;
elevator->low = lowFirst; // go down first unless args[4] is set
if (elevator->low)
{
elevator->direction = 1;
elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight);
}
else
{
elevator->direction = -1;
elevator->floordestheight = P_FindNextLowestFloor(sec,sec->floorheight);
}
elevator->floorwasheight = elevator->sector->floorheight;
elevator->ceilingwasheight = elevator->sector->ceilingheight;
elevator->delay = delay;
elevator->delaytimer = delayInit; // Initial delay
elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight);
}
}
void EV_DoBridgeFall(mtag_t tag)
{
INT32 secnum = -1;
sector_t *sec;
TAG_ITER_SECTORS(tag, secnum)
{
elevator_t *elevator = NULL;
sec = &sectors[secnum];
elevator = CreateElevatorThinker(sec);
if (elevator == NULL)
{
continue;
}
elevator->type = bridgeFall;
elevator->direction = -1;
elevator->speed = ELEVATORSPEED*4; // quadruple speed
elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight);
elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight);
}
}

View file

@ -2864,7 +2864,6 @@ static void SaveElevatorThinker(savebuffer_t *save, const thinker_t *th, const U
WRITEFIXED(save->p, ht->delaytimer);
WRITEFIXED(save->p, ht->floorwasheight);
WRITEFIXED(save->p, ht->ceilingwasheight);
WRITEUINT32(save->p, SaveLine(ht->sourceline));
}
static void SaveCrumbleThinker(savebuffer_t *save, const thinker_t *th, const UINT8 type)
@ -4201,7 +4200,6 @@ static thinker_t* LoadElevatorThinker(savebuffer_t *save, actionf_p1 thinker, bo
ht->delaytimer = READFIXED(save->p);
ht->floorwasheight = READFIXED(save->p);
ht->ceilingwasheight = READFIXED(save->p);
ht->sourceline = LoadLine(READUINT32(save->p));
if (ht->sector && setplanedata)
{

View file

@ -3150,7 +3150,13 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
break;
case 428: // Start floating platform movement
EV_DoElevator(args[0], line, elevateContinuous);
EV_DoContinuousElevator(
args[0],
args[1] << (FRACBITS - 2),
args[2],
args[3],
(args[4] == 0)
);
break;
case 429: // Crush planes once

View file

@ -890,7 +890,6 @@ struct elevator_t
fixed_t delaytimer;
fixed_t floorwasheight; // Height the floor WAS at
fixed_t ceilingwasheight; // Height the ceiling WAS at
line_t *sourceline;
};
typedef enum
@ -1039,6 +1038,12 @@ void EV_DoBounceFloor(mtag_t tag, boolean crush, fixed_t crushHeight, fixed_t cr
void EV_DoCrushFloorOnce(mtag_t tag, fixed_t speed);
void EV_DoElevator(mtag_t tag, line_t *line, elevator_e elevtype);
void EV_DoElevateDown(mtag_t tag);
void EV_DoElevateUp(mtag_t tag);
void EV_DoElevateHighest(mtag_t tag);
void EV_DoContinuousElevator(mtag_t tag, fixed_t speed, INT32 delayInit, INT32 delay, boolean lowFirst);
void EV_DoBridgeFall(mtag_t tag);
void EV_CrumbleChain(sector_t *sec, ffloor_t *rover);
void EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);

View file

@ -99,6 +99,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
{
INT32 count;
UINT8 *dest;
const INT32 vidwidth = vid.width;
count = dc->yh - dc->yl;
@ -107,7 +108,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
return;
}
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
if ((unsigned)dc->x >= (unsigned)vidwidth || dc->yl < 0 || dc->yh >= vid.height)
{
return;
}
@ -210,7 +211,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
// Use columnofs LUT for subwindows?
//dest = ylookup[dc_yl] + columnofs[dc_x];
dest = &topleft[dc->yl * vid.width + dc->x];
dest = &topleft[dc->yl * vidwidth + dc->x];
count++;
@ -235,7 +236,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
while (--count > 0)
{
*dest = R_DrawColumnPixel<Type>(dc, dest, frac>>FRACBITS);
dest += vid.width;
dest += vidwidth;
frac += fracstep;
}
}
@ -280,7 +281,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
*dest = R_DrawColumnPixel<Type>(dc, dest, n);
}
dest += vid.width;
dest += vidwidth;
// Avoid overflow.
if (fracstep > 0x7FFFFFFF - frac)
@ -305,12 +306,12 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
{
*dest = R_DrawColumnPixel<Type>(dc, dest, (frac>>FRACBITS) & heightmask);
dest += vid.width;
dest += vidwidth;
frac += fracstep;
*dest = R_DrawColumnPixel<Type>(dc, dest, (frac>>FRACBITS) & heightmask);
dest += vid.width;
dest += vidwidth;
frac += fracstep;
}
@ -348,6 +349,7 @@ void R_DrawFogColumn(drawcolumndata_t *dc)
INT32 count;
UINT8 *dest;
const INT32 vidwidth = vid.width;
count = dc->yh - dc->yl;
@ -355,21 +357,21 @@ void R_DrawFogColumn(drawcolumndata_t *dc)
if (count < 0)
return;
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
if ((unsigned)dc->x >= (unsigned)vidwidth || dc->yl < 0 || dc->yh >= vid.height)
return;
// Framebuffer destination address.
// Use ylookup LUT to avoid multiply with ScreenWidth.
// Use columnofs LUT for subwindows?
//dest = ylookup[dc_yl] + columnofs[dc_x];
dest = &topleft[dc->yl*vid.width + dc->x];
dest = &topleft[dc->yl*vidwidth + dc->x];
// Determine scaling, which is the only mapping to be done.
do
{
// Simple. Apply the colormap to what's already on the screen.
*dest = dc->colormap[*dest];
dest += vid.width;
dest += vidwidth;
}
while (count--);
}
@ -386,21 +388,22 @@ void R_DrawDropShadowColumn(drawcolumndata_t *dc)
INT32 count;
UINT8 *dest;
const INT32 vidwidth = vid.width;
count = dc->yh - dc->yl + 1;
if (count <= 0) // Zero length, column does not exceed a pixel.
return;
dest = &topleft[dc->yl*vid.width + dc->x];
dest = &topleft[dc->yl*vidwidth + dc->x];
const UINT8 *transmap_offset = dc->transmap + (dc->shadowcolor << 8);
while ((count -= 2) >= 0)
{
*dest = *(transmap_offset + (*dest));
dest += vid.width;
dest += vidwidth;
*dest = *(transmap_offset + (*dest));
dest += vid.width;
dest += vidwidth;
}
if (count & 1)
@ -414,13 +417,14 @@ void R_DrawColumn_Flat(drawcolumndata_t *dc)
INT32 count;
UINT8 color = dc->lightmap[dc->r8_flatcolor];
UINT8 *dest;
const INT32 vidwidth = vid.width;
count = dc->yh - dc->yl;
if (count < 0) // Zero length, column does not exceed a pixel.
return;
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
if ((unsigned)dc->x >= (unsigned)vidwidth || dc->yl < 0 || dc->yh >= vid.height)
return;
// Framebuffer destination address.
@ -428,14 +432,14 @@ void R_DrawColumn_Flat(drawcolumndata_t *dc)
// Use columnofs LUT for subwindows?
//dest = ylookup[dc_yl] + columnofs[dc_x];
dest = &topleft[dc->yl*vid.width + dc->x];
dest = &topleft[dc->yl*vidwidth + dc->x];
count++;
do
{
*dest = color;
dest += vid.width;
dest += vidwidth;
}
while (--count);
}

View file

@ -25,7 +25,7 @@ using namespace libdivide;
// <Callum> 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size)
#define MAXFLATBYTES 4194303
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / ds->zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan[viewssnum]))
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vidwidth / ds->zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan[viewssnum]))
enum DrawSpanType
{
@ -147,6 +147,7 @@ static void R_DrawSpanTemplate(drawspandata_t* ds)
UINT8 *dest;
UINT8 *dsrc;
const INT32 vidwidth = vid.width;
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
@ -174,7 +175,7 @@ static void R_DrawSpanTemplate(drawspandata_t* ds)
dest = ylookup[ds->y] + columnofs[ds->x1];
if constexpr (Type & DS_RIPPLE)
{
dsrc = screens[1] + (ds->y + ds->bgofs) * vid.width + ds->x1;
dsrc = screens[1] + (ds->y + ds->bgofs) * vidwidth + ds->x1;
}
else
{
@ -262,6 +263,7 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
UINT8 *colormap;
UINT8 *dest;
UINT8 *dsrc;
const INT32 vidwidth = vid.width;
float startz, startu, startv;
float izstep, uzstep, vzstep;
@ -298,7 +300,7 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
dest = ylookup[ds->y] + columnofs[ds->x1];
if constexpr (Type & DS_RIPPLE)
{
dsrc = screens[1] + (ds->y + ds->bgofs) * vid.width + ds->x1;
dsrc = screens[1] + (ds->y + ds->bgofs) * vidwidth + ds->x1;
}
else
{
@ -437,6 +439,7 @@ static void R_DrawNPO2SpanTemplate(drawspandata_t* ds)
UINT8 *dest;
UINT8 *dsrc;
const INT32 vidwidth = vid.width;
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
size_t count = (ds->x2 - ds->x1 + 1);
@ -453,7 +456,7 @@ static void R_DrawNPO2SpanTemplate(drawspandata_t* ds)
if constexpr (Type & DS_RIPPLE)
{
dsrc = screens[1] + (ds->y + ds->bgofs) * vid.width + ds->x1;
dsrc = screens[1] + (ds->y + ds->bgofs) * vidwidth + ds->x1;
}
else
{
@ -521,6 +524,7 @@ static void R_DrawTiltedNPO2SpanTemplate(drawspandata_t* ds)
UINT8 *colormap;
UINT8 *dest;
UINT8 *dsrc;
const INT32 vidwidth = vid.width;
float startz, startu, startv;
float izstep, uzstep, vzstep;
@ -555,7 +559,7 @@ static void R_DrawTiltedNPO2SpanTemplate(drawspandata_t* ds)
if constexpr (Type & DS_RIPPLE)
{
dsrc = screens[1] + (ds->y + ds->bgofs) * vid.width + ds->x1;
dsrc = screens[1] + (ds->y + ds->bgofs) * vidwidth + ds->x1;
}
else
{
@ -769,13 +773,14 @@ void R_DrawFogSpan(drawspandata_t* ds)
UINT8 *colormap;
UINT8 *dest;
const INT32 vidwidth = vid.width;
size_t count;
colormap = ds->colormap;
//dest = ylookup[ds_y] + columnofs[ds_x1];
dest = &topleft[ds->y *vid.width + ds->x1];
dest = &topleft[ds->y *vidwidth + ds->x1];
count = ds->x2 - ds->x1 + 1;
@ -807,6 +812,7 @@ void R_DrawFogSpan_Tilted(drawspandata_t* ds)
INT32 tiltlighting[MAXVIDWIDTH];
UINT8 *dest = ylookup[ds->y] + columnofs[ds->x1];
const INT32 vidwidth = vid.width;
// Lighting is simple. It's just linear interpolation from start to end
{
@ -845,6 +851,7 @@ void R_DrawTiltedSpan_Flat(drawspandata_t* ds)
int width = ds->x2 - ds->x1;
double iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx);
INT32 tiltlighting[MAXVIDWIDTH];
const INT32 vidwidth = vid.width;
UINT8 *dest = ylookup[ds->y];

View file

@ -76,11 +76,7 @@ CV_PossibleValue_t cv_renderer_t[] = {
{0, NULL}
};
#ifdef HWRENDER
consvar_t cv_renderer = CVAR_INIT ("renderer", "OpenGL", CV_SAVE|CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer);
#else
consvar_t cv_renderer = CVAR_INIT ("renderer", "Software", CV_SAVE|CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer);
#endif
static void SCR_ChangeFullscreen(void);

View file

@ -144,16 +144,32 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#define UNIXBACKTRACE
#endif
// Locations for searching for main.pk3
const char *wadDefaultPaths[] = {
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2Kart-V2"
#define DEFAULTWADLOCATION2 "/usr/local/games/SRB2Kart-V2"
#define DEFAULTWADLOCATION3 "/usr/share/games/SRB2Kart-V2"
#define DEFAULTWADLOCATION4 "/usr/games/SRB2Kart-V2"
#define DEFAULTSEARCHPATH1 "/usr/local/games"
#define DEFAULTSEARCHPATH2 "/usr/games"
#define DEFAULTSEARCHPATH3 "/usr/local"
"/usr/local/share/games/SRB2Kart-V2",
"/usr/local/games/SRB2Kart-V2",
"/usr/share/games/SRB2Kart-V2",
"/usr/games/SRB2Kart-V2",
#elif defined (_WIN32)
"c:\\games\\SRB2Kart-V2",
"\\games\\SRB2Kart-V2",
#endif
NULL
};
// Folders to recurse through looking for main.pk3
const char *wadSearchPaths[] = {
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
"/usr/local/games",
"/usr/games",
"/usr/local",
#elif defined (_WIN32)
"c:\\games",
"\\games",
#endif
NULL
};
/** \brief WAD file to look for
*/
@ -1098,6 +1114,20 @@ INT32 I_GetJoystickDeviceIndex(SDL_GameController *dev)
return -1;
}
INT32 I_GetJoystickDeviceIndexForPlayer(UINT8 pnum)
{
SDL_Joystick *joystick = NULL;
joystick = SDL_GameControllerGetJoystick(JoyInfo[pnum].dev);
if (joystick)
{
return SDL_JoystickInstanceID(joystick);
}
return -1;
}
void I_UpdateJoystickDeviceIndex(UINT8 player)
{
///////////////////////////////////////////////
@ -2401,15 +2431,29 @@ static const char *searchWad(const char *searchDir)
return NULL;
}
#define CHECKWADPATH(ret) \
do { \
I_OutputMsg(",%s", ret); \
if (isWadPathOk(ret)) \
return ret; \
} while (0)
#define SEARCHWAD(str) \
do { \
WadPath = searchWad(str); \
if (WadPath) \
return WadPath; \
} while (0)
/** \brief go through all possible paths and look for main.pk3
\return path to main.pk3 if any
*/
*
* \return path to main.pk3 if any
*/
static const char *locateWad(void)
{
const char *envstr;
const char *WadPath;
int i;
I_OutputMsg("SRB2WADDIR");
// does SRB2WADDIR exist?
@ -2417,108 +2461,46 @@ static const char *locateWad(void)
return envstr;
#ifndef NOCWD
I_OutputMsg(",.");
// examine current dir
strcpy(returnWadPath, ".");
I_OutputMsg(",%s", returnWadPath);
if (isWadPathOk(returnWadPath))
return NULL;
#endif
#ifdef DEFAULTDIR
I_OutputMsg(",HOME/" DEFAULTDIR);
// examine user jart directory
if ((envstr = I_GetEnv("HOME")) != NULL)
{
sprintf(returnWadPath, "%s" PATHSEP DEFAULTDIR, envstr);
if (isWadPathOk(returnWadPath))
return returnWadPath;
}
#endif
#ifdef __APPLE__
OSX_GetResourcesPath(returnWadPath);
I_OutputMsg(",%s", returnWadPath);
if (isWadPathOk(returnWadPath))
{
return returnWadPath;
}
CHECKWADPATH(returnWadPath);
#endif
// examine default dirs
#ifdef DEFAULTWADLOCATION1
I_OutputMsg("," DEFAULTWADLOCATION1);
strcpy(returnWadPath, DEFAULTWADLOCATION1);
if (isWadPathOk(returnWadPath))
return returnWadPath;
#endif
#ifdef DEFAULTWADLOCATION2
I_OutputMsg("," DEFAULTWADLOCATION2);
strcpy(returnWadPath, DEFAULTWADLOCATION2);
if (isWadPathOk(returnWadPath))
return returnWadPath;
#endif
#ifdef DEFAULTWADLOCATION3
I_OutputMsg("," DEFAULTWADLOCATION3);
strcpy(returnWadPath, DEFAULTWADLOCATION3);
if (isWadPathOk(returnWadPath))
return returnWadPath;
#endif
#ifdef DEFAULTWADLOCATION4
I_OutputMsg("," DEFAULTWADLOCATION4);
strcpy(returnWadPath, DEFAULTWADLOCATION4);
if (isWadPathOk(returnWadPath))
return returnWadPath;
#endif
#ifdef DEFAULTWADLOCATION5
I_OutputMsg("," DEFAULTWADLOCATION5);
strcpy(returnWadPath, DEFAULTWADLOCATION5);
if (isWadPathOk(returnWadPath))
return returnWadPath;
#endif
#ifdef DEFAULTWADLOCATION6
I_OutputMsg("," DEFAULTWADLOCATION6);
strcpy(returnWadPath, DEFAULTWADLOCATION6);
if (isWadPathOk(returnWadPath))
return returnWadPath;
#endif
#ifdef DEFAULTWADLOCATION7
I_OutputMsg("," DEFAULTWADLOCATION7);
strcpy(returnWadPath, DEFAULTWADLOCATION7);
if (isWadPathOk(returnWadPath))
return returnWadPath;
#endif
for (i = 0; wadDefaultPaths[i]; i++)
{
strcpy(returnWadPath, wadDefaultPaths[i]);
CHECKWADPATH(returnWadPath);
}
#ifndef NOHOME
// find in $HOME
I_OutputMsg(",HOME");
I_OutputMsg(",HOME/" DEFAULTDIR);
if ((envstr = I_GetEnv("HOME")) != NULL)
{
WadPath = searchWad(envstr);
if (WadPath)
return WadPath;
char *tmp = static_cast<char*>(malloc(strlen(envstr) + sizeof(PATHSEP) + sizeof(DEFAULTDIR)));
strcpy(tmp, envstr);
strcat(tmp, PATHSEP);
strcat(tmp, DEFAULTDIR);
CHECKWADPATH(tmp);
free(tmp);
}
#endif
#ifdef DEFAULTSEARCHPATH1
// find in /usr/local
I_OutputMsg(", in:" DEFAULTSEARCHPATH1);
WadPath = searchWad(DEFAULTSEARCHPATH1);
if (WadPath)
return WadPath;
#endif
#ifdef DEFAULTSEARCHPATH2
// find in /usr/games
I_OutputMsg(", in:" DEFAULTSEARCHPATH2);
WadPath = searchWad(DEFAULTSEARCHPATH2);
if (WadPath)
return WadPath;
#endif
#ifdef DEFAULTSEARCHPATH3
// find in ???
I_OutputMsg(", in:" DEFAULTSEARCHPATH3);
WadPath = searchWad(DEFAULTSEARCHPATH3);
if (WadPath)
return WadPath;
#endif
#endif
// search paths
for (i = 0; wadSearchPaths[i]; i++)
{
I_OutputMsg(", in:%s", wadSearchPaths[i]);
SEARCHWAD(wadSearchPaths[i]);
}
// if nothing was found
return NULL;
}
@ -2535,8 +2517,10 @@ const char *I_LocateWad(void)
{
// change to the directory where we found main.pk3
#if defined (_WIN32)
waddir = _fullpath(NULL, waddir, MAX_PATH);
SetCurrentDirectoryA(waddir);
#else
waddir = realpath(waddir, NULL);
if (chdir(waddir) == -1)
I_OutputMsg("Couldn't change working directory\n");
#endif

View file

@ -682,7 +682,7 @@ static INT32 SDLJoyAxis(const Sint16 axis, UINT8 pid)
}
else
{
raxis = (JoyInfo[pid].scale != 1) ? ((raxis / JoyInfo[pid].scale) * JoyInfo[pid].scale) : raxis;
raxis = (abs(JoyInfo[pid].scale) > 1) ? ((raxis / JoyInfo[pid].scale) * JoyInfo[pid].scale) : raxis;
#ifdef SDL_JDEADZONE
if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE)

View file

@ -714,27 +714,15 @@ static UINT8 hudminusalpha[11] = { 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5};
static const UINT8 *v_colormap = NULL;
static const UINT8 *v_translevel = NULL;
static inline UINT8 standardpdraw(const UINT8 *dest, const UINT8 *source, fixed_t ofs)
{
(void)dest; return source[ofs>>FRACBITS];
}
static inline UINT8 mappedpdraw(const UINT8 *dest, const UINT8 *source, fixed_t ofs)
{
(void)dest; return *(v_colormap + source[ofs>>FRACBITS]);
}
static inline UINT8 translucentpdraw(const UINT8 *dest, const UINT8 *source, fixed_t ofs)
{
return *(v_translevel + ((source[ofs>>FRACBITS]<<8)&0xff00) + (*dest&0xff));
}
static inline UINT8 transmappedpdraw(const UINT8 *dest, const UINT8 *source, fixed_t ofs)
{
return *(v_translevel + (((*(v_colormap + source[ofs>>FRACBITS]))<<8)&0xff00) + (*dest&0xff));
}
#define STANDARDDRAW 1
#define MAPPEDDRAW 2
#define TRANSLUCENTDRAW 3
#define TRANSMAPPEDDRAW 4
// Draws a patch scaled to arbitrary size.
void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap)
{
UINT8 (*patchdrawfunc)(const UINT8*, const UINT8*, fixed_t);
UINT8 patchdrawtype;
UINT32 alphalevel, blendmode;
fixed_t col, ofs, colfrac, rowfrac, fdup, vdup;
@ -744,6 +732,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
const UINT8 *source, *deststop;
fixed_t pwidth; // patch width
fixed_t offx = 0; // x offset
const INT32 vidwidth = vid.width;
const cliprect_t *clip = V_GetClipRect();
@ -759,7 +748,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
}
#endif
patchdrawfunc = standardpdraw;
patchdrawtype = STANDARDDRAW;
if ((blendmode = ((scrn & V_BLENDMASK) >> V_BLENDSHIFT)))
blendmode++; // realign to constants
@ -776,13 +765,13 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
return;
}
if ((v_translevel = R_GetBlendTable(blendmode, alphalevel)))
patchdrawfunc = translucentpdraw;
patchdrawtype = TRANSLUCENTDRAW;
v_colormap = NULL;
if (colormap)
{
v_colormap = colormap;
patchdrawfunc = (v_translevel) ? transmappedpdraw : mappedpdraw;
patchdrawtype = (v_translevel) ? TRANSMAPPEDDRAW : MAPPEDDRAW;
}
dupx = vid.dupx;
@ -858,7 +847,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
V_AdjustXYWithSnap(&x, &y, scrn, dupx, dupy);
}
desttop += (y*vid.width) + x;
desttop += (y*vidwidth) + x;
}
if (pscale != FRACUNIT) // scale width properly
@ -882,91 +871,324 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
{
if (x+pwidth-offx < (clip ? clip->left : 0)) // don't draw off the left of the screen (WRAP PREVENTION)
break;
if (x+pwidth-offx >= (clip ? clip->right : vid.width)) // don't draw off the right of the screen (WRAP PREVENTION)
if (x+pwidth-offx >= (clip ? clip->right : vidwidth)) // don't draw off the right of the screen (WRAP PREVENTION)
continue;
}
else
{
if (x+offx < (clip ? clip->left : 0)) // don't draw off the left of the screen (WRAP PREVENTION)
continue;
if (x+offx >= (clip ? clip->right : vid.width)) // don't draw off the right of the screen (WRAP PREVENTION)
if (x+offx >= (clip ? clip->right : vidwidth)) // don't draw off the right of the screen (WRAP PREVENTION)
break;
}
column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[col>>FRACBITS]));
while (column->topdelta != 0xff)
switch (patchdrawtype)
{
fixed_t offy = 0;
topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
dest = desttop;
if (scrn & V_FLIP)
dest = deststart + (destend - dest);
topdelta = FixedInt(FixedMul(topdelta << FRACBITS, vdup));
dest += topdelta * vid.width;
if (scrn & V_VFLIP)
{
for (ofs = (column->length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac, ++offy)
case STANDARDDRAW:
while (column->topdelta != 0xff)
{
if (clip != NULL)
fixed_t offy = 0;
topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
dest = desttop;
if (scrn & V_FLIP)
dest = deststart + (destend - dest);
topdelta = FixedInt(FixedMul(topdelta << FRACBITS, vdup));
dest += topdelta * vidwidth;
if (scrn & V_VFLIP)
{
const INT32 cy = y + topdelta - offy;
if (cy < clip->top) // don't draw off the top of the clip rect
for (ofs = (column->length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac, ++offy)
{
dest += vid.width;
continue;
if (clip != NULL)
{
const INT32 cy = y + topdelta - offy;
if (cy < clip->top) // don't draw off the top of the clip rect
{
dest += vidwidth;
continue;
}
if (cy >= clip->bottom) // don't draw off the bottom of the clip rect
{
dest += vidwidth;
continue;
}
}
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = source[ofs>>FRACBITS];
dest += vidwidth;
}
if (cy >= clip->bottom) // don't draw off the bottom of the clip rect
}
else
{
for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac, ++offy)
{
dest += vid.width;
continue;
if (clip != NULL)
{
const INT32 cy = y + topdelta + offy;
if (cy < clip->top) // don't draw off the top of the clip rect
{
dest += vidwidth;
continue;
}
if (cy >= clip->bottom) // don't draw off the bottom of the clip rect
{
dest += vidwidth;
continue;
}
}
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = source[ofs>>FRACBITS];
dest += vidwidth;
}
}
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = patchdrawfunc(dest, source, ofs);
dest += vid.width;
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
}
else
{
for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac, ++offy)
break;
case MAPPEDDRAW:
while (column->topdelta != 0xff)
{
if (clip != NULL)
fixed_t offy = 0;
topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
dest = desttop;
if (scrn & V_FLIP)
dest = deststart + (destend - dest);
topdelta = FixedInt(FixedMul(topdelta << FRACBITS, vdup));
dest += topdelta * vidwidth;
if (scrn & V_VFLIP)
{
const INT32 cy = y + topdelta + offy;
if (cy < clip->top) // don't draw off the top of the clip rect
for (ofs = (column->length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac, ++offy)
{
dest += vid.width;
continue;
if (clip != NULL)
{
const INT32 cy = y + topdelta - offy;
if (cy < clip->top) // don't draw off the top of the clip rect
{
dest += vidwidth;
continue;
}
if (cy >= clip->bottom) // don't draw off the bottom of the clip rect
{
dest += vidwidth;
continue;
}
}
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = *(v_colormap + source[ofs>>FRACBITS]);
dest += vidwidth;
}
if (cy >= clip->bottom) // don't draw off the bottom of the clip rect
}
else
{
for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac, ++offy)
{
dest += vid.width;
continue;
if (clip != NULL)
{
const INT32 cy = y + topdelta + offy;
if (cy < clip->top) // don't draw off the top of the clip rect
{
dest += vidwidth;
continue;
}
if (cy >= clip->bottom) // don't draw off the bottom of the clip rect
{
dest += vidwidth;
continue;
}
}
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = *(v_colormap + source[ofs>>FRACBITS]);
dest += vidwidth;
}
}
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = patchdrawfunc(dest, source, ofs);
dest += vid.width;
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
}
break;
column = (const column_t *)((const UINT8 *)column + column->length + 4);
case TRANSMAPPEDDRAW:
while (column->topdelta != 0xff)
{
fixed_t offy = 0;
topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
dest = desttop;
if (scrn & V_FLIP)
dest = deststart + (destend - dest);
topdelta = FixedInt(FixedMul(topdelta << FRACBITS, vdup));
dest += topdelta * vidwidth;
if (scrn & V_VFLIP)
{
for (ofs = (column->length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac, ++offy)
{
if (clip != NULL)
{
const INT32 cy = y + topdelta - offy;
if (cy < clip->top) // don't draw off the top of the clip rect
{
dest += vidwidth;
continue;
}
if (cy >= clip->bottom) // don't draw off the bottom of the clip rect
{
dest += vidwidth;
continue;
}
}
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = *(v_translevel + (((*(v_colormap + source[ofs>>FRACBITS]))<<8)&0xff00) + (*dest&0xff));
dest += vidwidth;
}
}
else
{
for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac, ++offy)
{
if (clip != NULL)
{
const INT32 cy = y + topdelta + offy;
if (cy < clip->top) // don't draw off the top of the clip rect
{
dest += vidwidth;
continue;
}
if (cy >= clip->bottom) // don't draw off the bottom of the clip rect
{
dest += vidwidth;
continue;
}
}
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = *(v_translevel + (((*(v_colormap + source[ofs>>FRACBITS]))<<8)&0xff00) + (*dest&0xff));
dest += vidwidth;
}
}
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
break;
case TRANSLUCENTDRAW:
while (column->topdelta != 0xff)
{
fixed_t offy = 0;
topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
dest = desttop;
if (scrn & V_FLIP)
dest = deststart + (destend - dest);
topdelta = FixedInt(FixedMul(topdelta << FRACBITS, vdup));
dest += topdelta * vidwidth;
if (scrn & V_VFLIP)
{
for (ofs = (column->length << FRACBITS)-1; dest < deststop && ofs >= 0; ofs -= rowfrac, ++offy)
{
if (clip != NULL)
{
const INT32 cy = y + topdelta - offy;
if (cy < clip->top) // don't draw off the top of the clip rect
{
dest += vidwidth;
continue;
}
if (cy >= clip->bottom) // don't draw off the bottom of the clip rect
{
dest += vidwidth;
continue;
}
}
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = *(v_translevel + ((source[ofs>>FRACBITS]<<8)&0xff00) + (*dest&0xff));
dest += vidwidth;
}
}
else
{
for (ofs = 0; dest < deststop && ofs < (column->length << FRACBITS); ofs += rowfrac, ++offy)
{
if (clip != NULL)
{
const INT32 cy = y + topdelta + offy;
if (cy < clip->top) // don't draw off the top of the clip rect
{
dest += vidwidth;
continue;
}
if (cy >= clip->bottom) // don't draw off the bottom of the clip rect
{
dest += vidwidth;
continue;
}
}
if (dest >= screens[scrn&V_SCREENMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = *(v_translevel + ((source[ofs>>FRACBITS]<<8)&0xff00) + (*dest&0xff));
dest += vidwidth;
}
}
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
break;
}
}
}