Merge branch 'master' into next

This commit is contained in:
Sally Coolatta 2024-03-31 16:33:40 -04:00
commit 27aecdb909
31 changed files with 557 additions and 631 deletions

View file

@ -2905,6 +2905,12 @@ void D_LoadBan(boolean warning)
address = strtok(buffer, " /\t\r\n");
mask = strtok(NULL, " \t\r\n");
if (!address)
{
malformed = true;
continue;
}
if (i == 0 && !strncmp(address, "BANFORMAT", 9))
{
if (mask)

View file

@ -1311,7 +1311,7 @@ void D_SRB2Main(void)
//
// search for maps
//
for (wadnum = 4; wadnum < 6; wadnum++) // fucking arbitrary numbers
for (wadnum = 0; wadnum < mainwads; wadnum++)
{
lumpinfo = wadfiles[wadnum]->lumpinfo;
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lumpinfo++)

View file

@ -1464,7 +1464,7 @@ void Command_Ping_f(void)
if (!server && playeringame[consoleplayer])
{
CONS_Printf("\nYour ping is %d frames (%d ms)\n", playerpingtable[consoleplayer], (INT32)(playerpingtable[i] * (1000.00f / TICRATE)));
CONS_Printf("\nYour ping is %d frames (%d ms)\n", playerpingtable[consoleplayer], (INT32)(playerpingtable[consoleplayer] * (1000.00f / TICRATE)));
}
}

View file

@ -251,7 +251,7 @@ consvar_t cv_ingamecap = {"ingamecap", "0", CV_NETVAR, ingamecap_cons_t, NULL, 0
static CV_PossibleValue_t spectatorreentry_cons_t[] = {{0, "MIN"}, {10*60, "MAX"}, {0, NULL}};
consvar_t cv_spectatorreentry = {"spectatorreentry", "30", CV_NETVAR, spectatorreentry_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t antigrief_cons_t[] = {{20, "MIN"}, {60, "MAX"}, {0, "Off"}, {0, NULL}};
static CV_PossibleValue_t antigrief_cons_t[] = {{20, "MIN"}, {180, "MAX"}, {0, "Off"}, {0, NULL}};
consvar_t cv_antigrief = {"antigrief", "30", CV_NETVAR, antigrief_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_startinglives = {"startinglives", "3", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, startingliveslimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};

View file

@ -94,10 +94,20 @@ typedef struct filetran_s
{
filetx_t *txlist; // Linked list of all files for the node
UINT32 position; // The current position in the file
FILE *currentfile; // The file currently being sent/received
boolean init; // false if we want to reset position / open a new file
} filetran_t;
static filetran_t transfer[MAXNETNODES];
// The files currently being sent/received
typedef struct fileused_s
{
FILE *file;
UINT8 count;
UINT32 position;
} fileused_t;
static fileused_t transferFiles[UINT8_MAX + 1];
// Read time of file: stat _stmtime
// Write time of file: utime
@ -760,8 +770,19 @@ static void SV_EndFileSend(INT32 node)
case SF_FILE: // It's a file, close it and free its filename
if (cv_noticedownload.value)
CONS_Printf("Ending file transfer (id %d) for node %d\n", p->fileid, node);
if (transfer[node].currentfile)
fclose(transfer[node].currentfile);
if (transferFiles[p->fileid].file)
{
if (transferFiles[p->fileid].count > 0)
{
transferFiles[p->fileid].count--;
}
if (transferFiles[p->fileid].count == 0)
{
fclose(transferFiles[p->fileid].file);
transferFiles[p->fileid].file = NULL;
}
}
free(p->id.filename);
break;
case SF_Z_RAM: // It's a memory block allocated with Z_Alloc or the likes, use Z_Free
@ -778,7 +799,7 @@ static void SV_EndFileSend(INT32 node)
free(p);
// Indicate that the transmission is over
transfer[node].currentfile = NULL;
transfer[node].init = false;
filestosend--;
}
@ -842,21 +863,31 @@ void SV_FileSendTicker(void)
ram = f->ram;
// Open the file if it isn't open yet, or
if (!transfer[i].currentfile)
if (transfer[i].init == false)
{
if (!ram) // Sending a file
{
long filesize;
transfer[i].currentfile =
fopen(f->id.filename, "rb");
if (transferFiles[f->fileid].count == 0)
{
// It needs opened.
transferFiles[f->fileid].file =
fopen(f->id.filename, "rb");
if (!transfer[i].currentfile)
I_Error("File %s does not exist",
f->id.filename);
if (!transferFiles[f->fileid].file)
{
I_Error("Can't open file %s: %s",
f->id.filename, strerror(errno));
}
}
fseek(transfer[i].currentfile, 0, SEEK_END);
filesize = ftell(transfer[i].currentfile);
// Increment number of nodes using this file.
I_Assert(transferFiles[f->fileid].count < UINT8_MAX);
transferFiles[f->fileid].count++;
fseek(transferFiles[f->fileid].file, 0, SEEK_END);
filesize = ftell(transferFiles[f->fileid].file);
// Nobody wants to transfer a file bigger
// than 4GB!
@ -865,23 +896,43 @@ void SV_FileSendTicker(void)
if (filesize == -1)
I_Error("Error getting filesize of %s", f->id.filename);
f->size = (UINT32)filesize;
fseek(transfer[i].currentfile, 0, SEEK_SET);
f->size = transferFiles[f->fileid].position = (UINT32)filesize;
}
else // Sending RAM
transfer[i].currentfile = (FILE *)1; // Set currentfile to a non-null value to indicate that it is open
transfer[i].position = 0;
transfer[i].init = true; // Indicate that it is open
}
if (!ram)
{
// Seek to the right position if we aren't already there.
if (transferFiles[f->fileid].position != transfer[i].position)
{
fseek(transferFiles[f->fileid].file, transfer[i].position, SEEK_SET);
}
}
// Build a packet containing a file fragment
p = &netbuffer->u.filetxpak;
size = software_MAXPACKETLENGTH - (FILETXHEADER + BASEPACKETSIZE);
if (f->size-transfer[i].position < size)
size = f->size-transfer[i].position;
if (f->size - transfer[i].position < size)
{
size = f->size - transfer[i].position;
}
if (ram)
{
M_Memcpy(p->data, &f->id.ram[transfer[i].position], size);
else if (fread(p->data, 1, size, transfer[i].currentfile) != size)
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(size), f->id.filename, transfer[i].position, M_FileError(transfer[i].currentfile));
}
else if (fread(p->data, 1, size, transferFiles[f->fileid].file) != size)
{
I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s",
sizeu1(size), f->id.filename, transfer[i].position, M_FileError(transferFiles[f->fileid].file));
transferFiles[f->fileid].position = (UINT32)(transferFiles[f->fileid].position + size);
}
p->position = LONG(transfer[i].position);
// Put flag so receiver knows the total size
if (transfer[i].position + size == f->size)
@ -891,15 +942,18 @@ void SV_FileSendTicker(void)
// Send the packet
if (HSendPacket(i, true, 0, FILETXHEADER + size)) // Reliable SEND
{ // Success
{
// Success
transfer[i].position = (UINT32)(transfer[i].position + size);
if (transfer[i].position == f->size) // Finish?
{
SV_EndFileSend(i);
}
}
else
{ // Not sent for some odd reason, retry at next call
if (!ram)
fseek(transfer[i].currentfile,transfer[i].position, SEEK_SET);
{
// Not sent for some odd reason, retry at next call
// Exit the while (can't send this one so why should i send the next?)
break;
}

View file

@ -529,8 +529,10 @@ void DRPC_UpdatePresence(void)
else
{
// Map name on tool tip
snprintf(mapname, 48, "Map: %s", G_BuildMapTitle(gamemap));
char *title = G_BuildMapTitle(gamemap);
snprintf(mapname, 48, "Map: %s", title);
discordPresence.largeImageText = mapname;
Z_Free(title);
}
if (gamestate == GS_LEVEL && Playing())

View file

@ -164,6 +164,15 @@ char *strcasestr(const char *in, const char *what);
#define HAVE_DOSSTR_FUNCS
#endif
#if defined (__APPLE__)
#define SRB2_HAVE_STRLCPY
#elif defined (__GLIBC_PREREQ)
// glibc 2.38: added strlcpy and strlcat to _DEFAULT_SOURCE
#if __GLIBC_PREREQ(2, 38)
#define SRB2_HAVE_STRLCPY
#endif
#endif
#ifndef HAVE_DOSSTR_FUNCS
int strupr(char *n); // from dosstr.c
int strlwr(char *n); // from dosstr.c
@ -171,7 +180,7 @@ int strlwr(char *n); // from dosstr.c
#include <stddef.h> // for size_t
#ifndef __APPLE__
#ifndef SRB2_HAVE_STRLCPY
size_t strlcat(char *dst, const char *src, size_t siz);
size_t strlcpy(char *dst, const char *src, size_t siz);
#endif

View file

@ -1503,22 +1503,20 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
{
cmd->buttons |= BT_ACCELERATE;
// JOYAXISRANGE is supposed to be 1023 (divide by 1024)
forward += ((axis * forwardmove[1]) >> 10)*2;
forward += ((axis * forwardmove[1]) / (JOYAXISRANGE-1));
}
axis = JoyAxis(AXISBRAKE, ssplayer);
if (InputDown(gc_brake, ssplayer) || (gamepadjoystickmove && axis > 0))
{
cmd->buttons |= BT_BRAKE;
if (cmd->buttons & BT_ACCELERATE || cmd->forwardmove <= 0)
forward -= forwardmove[0]; // 25 - Halved value so clutching is possible
forward -= forwardmove[0]; // 25 - Halved value so clutching is possible
}
else if (analogjoystickmove && axis > 0)
{
cmd->buttons |= BT_BRAKE;
// JOYAXISRANGE is supposed to be 1023 (divide by 1024)
if (cmd->buttons & BT_ACCELERATE || cmd->forwardmove <= 0)
forward -= ((axis * forwardmove[0]) >> 10);
forward -= ((axis * forwardmove[0]) / (JOYAXISRANGE-1));
}
// But forward/backward IS used for aiming.
@ -6747,7 +6745,11 @@ void G_BeginRecording(void)
// Full replay title
demo_p += 64;
snprintf(demo.titlename, 64, "%s - %s", G_BuildMapTitle(gamemap), modeattacking ? "Time Attack" : connectedservername);
{
char *title = G_BuildMapTitle(gamemap);
snprintf(demo.titlename, 64, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername);
Z_Free(title);
}
// demo checksum
demo_p += 16;

View file

@ -479,14 +479,43 @@ void HWR_InitTextureCache(void)
// Callback function for HWR_FreeTextureCache.
static void FreeMipmapColormap(INT32 patchnum, void *patch)
{
GLPatch_t* const grpatch = patch;
GLPatch_t* const pat = patch;
(void)patchnum; //unused
while (grpatch->mipmap->nextcolormap)
// The patch must be valid, obviously
if (!pat)
return;
// The mipmap must be valid, obviously
while (pat->mipmap)
{
GLMipmap_t *grmip = grpatch->mipmap->nextcolormap;
grpatch->mipmap->nextcolormap = grmip->nextcolormap;
if (grmip->grInfo.data) Z_Free(grmip->grInfo.data);
free(grmip);
// Confusing at first, but pat->mipmap->nextcolormap
// at the beginning of the loop is the first colormap
// from the linked list of colormaps.
GLMipmap_t *next = NULL;
// No mipmap in this patch, break out of the loop.
if (!pat->mipmap)
break;
// No colormap mipmaps either.
if (!pat->mipmap->nextcolormap)
break;
// Set the first colormap to the one that comes after it.
next = pat->mipmap->nextcolormap;
if (!next)
break;
pat->mipmap->nextcolormap = next->nextcolormap;
// Free image data from memory.
if (next->grInfo.data)
Z_Free(next->grInfo.data);
next->grInfo.data = NULL;
// Free the old colormap mipmap from memory.
free(next);
}
}
@ -503,7 +532,7 @@ void HWR_FreeTextureCache(void)
// Alam: free the Z_Blocks before freeing it's users
// free all skin after each level: must be done after pfnClearMipMapCache!
// free all patch colormaps after each level: must be done after ClearMipMapCache!
for (i = 0; i < numwadfiles; i++)
M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap);

View file

@ -1639,7 +1639,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (rover->master->flags & ML_TFERLINE)
{
size_t linenum = gr_curline->linedef-gr_backsector->lines[0];
size_t linenum = min((size_t)(gr_curline->linedef-gr_backsector->lines[0]), rover->master->frontsector->linecount);
newline = rover->master->frontsector->lines[0] + linenum;
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture);
}
@ -1798,10 +1798,11 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (rover->master->flags & ML_TFERLINE)
{
size_t linenum = gr_curline->linedef-gr_backsector->lines[0];
size_t linenum = min((size_t)(gr_curline->linedef-gr_backsector->lines[0]), rover->master->frontsector->linecount);
newline = rover->master->frontsector->lines[0] + linenum;
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture);
}
#ifdef ESLOPE //backsides
h = *rover->t_slope ? P_GetZAt(*rover->t_slope, v1x, v1y) : *rover->topheight;
hS = *rover->t_slope ? P_GetZAt(*rover->t_slope, v2x, v2y) : *rover->topheight;
@ -4538,7 +4539,7 @@ void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
#endif
// set top/bottom coords
vis->ty = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset);
vis->ty = FIXED_TO_FLOAT(interp.z + spritecachedinfo[lumpoff].topoffset);
vis->precip = true;
}

View file

@ -1116,6 +1116,10 @@ void HU_Ticker(void)
}
if (cechotimer > 0) --cechotimer;
// Animate the desynch dots
if (hu_resynching)
resynch_ticker++; //tic tic tic tic tic
HU_TickSongCredits();
}

View file

@ -4021,6 +4021,7 @@ void K_RepairOrbitChain(mobj_t *orbit)
// Then recount to make sure item amount is correct
if (orbit->target && orbit->target->player)
{
player_t *player = orbit->target->player;
INT32 num = 0;
mobj_t *cur = orbit->target->hnext;
@ -4030,14 +4031,14 @@ void K_RepairOrbitChain(mobj_t *orbit)
{
prev = cur;
cur = cur->hnext;
if (++num > orbit->target->player->kartstuff[k_itemamount])
if (++num > player->kartstuff[k_itemamount])
P_RemoveMobj(prev);
else
prev->movedir = num;
}
if (orbit->target->player->kartstuff[k_itemamount] != num)
orbit->target->player->kartstuff[k_itemamount] = num;
if (player->kartstuff[k_itemamount] != num)
player->kartstuff[k_itemamount] = num;
}
}

View file

@ -382,7 +382,7 @@ static int lib_cvRegisterVar(lua_State *L)
cvar->PossibleValue = cvpv;
} else
FIELDERROR("PossibleValue", va("%s or CV_PossibleValue_t expected, got %s", lua_typename(L, LUA_TTABLE), luaL_typename(L, -1)))
} else if (cvar->flags & CV_CALL && (i == 5 || (k && fasticmp(k, "func")))) {
} else if ((i == 5 || (k && fasticmp(k, "func")))) {
if (!lua_isfunction(L, 4))
TYPEERROR("func", LUA_TFUNCTION)
lua_getfield(L, LUA_REGISTRYINDEX, "CV_OnChange");

View file

@ -258,6 +258,8 @@ static int lib_iterateSectorThinglist(lua_State *L)
if (!lua_isnil(L, 1))
{
thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
if (P_MobjWasRemoved(thing))
return luaL_error(L, "current entry in thinglist was removed; avoid calling P_RemoveMobj on entries!");
thing = thing->snext;
}
else

View file

@ -5577,7 +5577,11 @@ static void DrawReplayHutReplayInfo(void)
x += 85;
if (mapheaderinfo[demolist[dir_on[menudepthleft]].map-1])
V_DrawString(x, y, V_SNAPTOTOP, G_BuildMapTitle(demolist[dir_on[menudepthleft]].map));
{
char *title = G_BuildMapTitle(demolist[dir_on[menudepthleft]].map);
V_DrawString(x, y, V_SNAPTOTOP, title);
Z_Free(title);
}
else
V_DrawString(x, y, V_SNAPTOTOP|V_ALLOWLOWERCASE|V_TRANSLUCENT, "Level is not loaded.");
@ -6513,16 +6517,36 @@ static char *M_GetConditionString(condition_t cond)
G_TicsToMinutes(cond.requirement, false),
G_TicsToSeconds(cond.requirement));
case UC_MAPVISITED:
return va("Visit %s", G_BuildMapTitle(cond.requirement-1));
{
char *title = G_BuildMapTitle(cond.requirement-1);
char *response = va("Visit %s", title);
Z_Free(title);
return response;
}
case UC_MAPBEATEN:
return va("Beat %s", G_BuildMapTitle(cond.requirement-1));
{
char *title = G_BuildMapTitle(cond.requirement-1);
char *response = va("Beat %s", title);
Z_Free(title);
return response;
}
case UC_MAPALLEMERALDS:
return va("Beat %s w/ all emeralds", G_BuildMapTitle(cond.requirement-1));
{
char *title = G_BuildMapTitle(cond.requirement-1);
char *response = va("Beat %s w/ all emeralds", title);
Z_Free(title);
return response;
}
case UC_MAPTIME:
return va("Beat %s in %i:%02i.%02i", G_BuildMapTitle(cond.extrainfo1-1),
{
char *title = G_BuildMapTitle(cond.extrainfo1-1);
char *response = va("Beat %s in %i:%02i.%02i", title,
G_TicsToMinutes(cond.requirement, true),
G_TicsToSeconds(cond.requirement),
G_TicsToCentiseconds(cond.requirement));
Z_Free(title);
return response;
}
case UC_TOTALEMBLEMS:
return va("Get %d medals", cond.requirement);
case UC_EXTRAEMBLEM:
@ -10154,7 +10178,7 @@ static void M_DrawJoystick(void)
compareval4 = cv_usejoystick4.value;
compareval3 = cv_usejoystick3.value;
compareval2 = cv_usejoystick2.value;
compareval = cv_usejoystick.value
compareval = cv_usejoystick.value;
#endif
if ((setupcontrolplayer == 4 && (i == compareval4))

View file

@ -3142,6 +3142,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage);
if (P_MobjWasRemoved(target))
return (shouldForce == 1); // mobj was removed
if (P_MobjWasRemoved(source))
source = NULL;
if (shouldForce == 1)
force = true;
else if (shouldForce == 2)
@ -3468,6 +3470,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
break;
}
if (P_MobjWasRemoved(target))
return false;
if (!P_MobjWasRemoved(target))
{
target->reactiontime = 0; // we're awake now...

View file

@ -150,6 +150,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam);
void P_SlideCameraMove(camera_t *thiscam);
void P_DemoCameraMovement(camera_t *cam);
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled);
void P_ResetLocalCamAiming(player_t *player);
void P_InitCameraCmd(void);
boolean P_PlayerInPain(player_t *player);
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);

View file

@ -263,6 +263,9 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
I_Error("P_SetMobjState used for player mobj. Use P_SetPlayerMobjState instead!\n(State called: %d)", state);
#endif
if (mobj->player != NULL)
return P_SetPlayerMobjState(mobj, state);
if (recursion++) // if recursion detected,
memset(seenstate = tempstate, 0, sizeof tempstate); // clear state table
@ -590,29 +593,41 @@ void P_ExplodeMissile(mobj_t *mo)
P_RadiusAttack(mo, mo, 96*FRACUNIT);
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale;
explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_pop);
if (!P_MobjWasRemoved(explodemo))
{
P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale;
explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_pop);
}
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale;
explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_dmpain);
if (!P_MobjWasRemoved(explodemo))
{
P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale;
explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_dmpain);
}
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale;
explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_pop);
if (!P_MobjWasRemoved(explodemo))
{
P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale;
explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_pop);
}
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale;
explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_cybdth);
if (!P_MobjWasRemoved(explodemo))
{
P_SetScale(explodemo, mo->scale);
explodemo->destscale = mo->destscale;
explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale);
S_StartSound(explodemo, sfx_cybdth);
}
// Hack: Release an animal.
P_DamageMobj(mo, NULL, NULL, 10000);
@ -3584,6 +3599,9 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
I_Assert(mobj->player != NULL);
I_Assert(!P_MobjWasRemoved(mobj));
if (P_MobjWasRemoved(mobj))
return;
P_MobjCheckWater(mobj);
P_ButteredSlope(mobj);
@ -7051,6 +7069,9 @@ void P_MobjThinker(mobj_t *mobj)
// separate thinker
if (mobj->flags & MF_PUSHABLE || (mobj->info->flags & MF_PUSHABLE && mobj->fuse))
{
if (P_MobjWasRemoved(mobj))
return;
P_MobjCheckWater(mobj);
P_PushableThinker(mobj);
@ -10235,6 +10256,10 @@ void P_RemoveMobj(mobj_t *mobj)
}
}
// clear the reference from the mapthing
if (mobj->spawnpoint)
mobj->spawnpoint->mobj = NULL;
// free block
// DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error.
if (mobj->flags & MF_NOTHINK && !mobj->thinker.next)
@ -10751,6 +10776,7 @@ void P_SpawnPlayer(INT32 playernum)
}
mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER);
I_Assert(mobj != NULL);
(mobj->player = p)->mo = mobj;
mobj->angle = 0;
@ -11363,6 +11389,13 @@ void P_SpawnMapThing(mapthing_t *mthing)
}
mobj = P_SpawnMobj(x, y, z, i);
if (!mobj || P_MobjWasRemoved(mobj))
{
CONS_Alert(CONS_WARNING, "Failed to spawn map thing #%d at %d, %d\n", mthing->type, x>>FRACBITS, y>>FRACBITS);
return;
}
mobj->spawnpoint = mthing;
switch(mobj->type)

View file

@ -895,6 +895,8 @@ void P_PreTicker(INT32 frames)
// Run shield positioning
//P_RunShields();
P_RunOverlays();
P_RunShadows();
P_UpdateSpecials();
P_RespawnSpecials();

View file

@ -829,6 +829,10 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
//
boolean P_PlayerInPain(player_t *player)
{
// If the player doesn't have a mobj, it can't be in pain.
if (!player->mo)
return false;
// no silly, sliding isn't pain
if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate] && player->powers[pw_flashing])
return true;
@ -8005,6 +8009,18 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
return (x == thiscam->x && y == thiscam->y && z == thiscam->z && angle == thiscam->aiming);
}
void P_ResetLocalCamAiming(player_t *player)
{
for (int i = 0; i <= splitscreen; i++)
{
UINT8 id = (i == 0) ? consoleplayer : displayplayers[i];
if (player - players == id)
{
localaiming[i] = 0;
}
}
}
boolean P_SpectatorJoinGame(player_t *player)
{
// Team changing isn't allowed.
@ -8055,6 +8071,9 @@ boolean P_SpectatorJoinGame(player_t *player)
player->ctfteam = changeto;
player->playerstate = PST_REBORN;
//center camera
P_ResetLocalCamAiming(player);
//Reset away view
if (P_IsLocalPlayer(player) && displayplayers[0] != consoleplayer)
displayplayers[0] = consoleplayer;
@ -8079,6 +8098,9 @@ boolean P_SpectatorJoinGame(player_t *player)
player->kartstuff[k_spectatewait] = 0;
player->playerstate = PST_REBORN;
//center camera
P_ResetLocalCamAiming(player);
//Reset away view
if (P_IsLocalPlayer(player) && displayplayers[0] != consoleplayer)
displayplayers[0] = consoleplayer;

View file

@ -23,6 +23,10 @@
#include "z_zone.h"
#include "console.h" // con_startup_loadprogress
#ifdef HWRENDER
#include "hardware/hw_main.h" // for cv_grshearing
#endif
static CV_PossibleValue_t fpscap_cons_t[] = {
#ifdef DEVELOP
// Lower values are actually pretty useful for debugging interp problems!
@ -119,7 +123,11 @@ static void R_SetupFreelook(player_t *player, boolean skybox)
// clip it in the case we are looking a hardware 90 degrees full aiming
// (lmps, network and use F12...)
if (rendermode == render_soft)
if (rendermode == render_soft
#ifdef HWRENDER
|| (rendermode == render_opengl && cv_grshearing.value)
#endif
)
{
G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
}

View file

@ -681,7 +681,7 @@ static void R_DrawRepeatMaskedColumn(column_t *col)
{
while (sprtopscreen < sprbotscreen) {
R_DrawMaskedColumn(col);
if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow
if (sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow
sprtopscreen = INT32_MAX;
else
sprtopscreen += dc_texheight*spryscale;
@ -733,7 +733,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (pfloor->master->flags & ML_TFERLINE)
{
size_t linenum = curline->linedef-backsector->lines[0];
size_t linenum = min((size_t)(curline->linedef-backsector->lines[0]), pfloor->master->frontsector->linecount);
newline = pfloor->master->frontsector->lines[0] + linenum;
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture);
}

View file

@ -46,7 +46,7 @@ extern INT32 msg_id;
// 3D Sound Interface
#include "hardware/hw3sound.h"
#else
static INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
#endif
CV_PossibleValue_t soundvolume_cons_t[] = {{0, "MIN"}, {31, "MAX"}, {0, NULL}};
@ -189,8 +189,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo)
// channel number to use
INT32 cnum;
channel_t *c;
// Find an open channel
for (cnum = 0; cnum < numofchannels; cnum++)
{
@ -202,7 +200,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo)
else if (sfxinfo == channels[cnum].sfxinfo && (sfxinfo->pitch & SF_NOMULTIPLESOUND))
{
return -1;
break;
}
else if (sfxinfo == channels[cnum].sfxinfo && sfxinfo->singularity == true)
{
@ -246,12 +243,6 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo)
}
}
c = &channels[cnum];
// channel is decided to be cnum.
c->sfxinfo = sfxinfo;
c->origin = origin;
return cnum;
}
@ -407,7 +398,6 @@ void S_StopSoundByID(void *origin, sfxenum_t sfx_id)
if (channels[cnum].sfxinfo == &S_sfx[sfx_id] && channels[cnum].origin == origin)
{
S_StopChannel(cnum);
break;
}
}
}
@ -428,28 +418,42 @@ void S_StopSoundByNum(sfxenum_t sfxnum)
if (channels[cnum].sfxinfo == &S_sfx[sfxnum])
{
S_StopChannel(cnum);
break;
}
}
}
static INT32 S_ScaleVolumeWithSplitscreen(INT32 volume)
{
fixed_t root = INT32_MAX;
if (splitscreen == 0)
{
return volume;
}
root = FixedSqrt((splitscreen + 1) * (FRACUNIT/3));
return FixedDiv(
volume * FRACUNIT,
root
) / FRACUNIT;
}
void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
{
const INT32 initial_volume = volume;
INT32 sep, pitch, priority, cnum;
sfxinfo_t *sfx;
const boolean reverse = (stereoreverse.value ^ encoremode);
const mobj_t *origin = (const mobj_t *)origin_p;
const boolean reverse = (stereoreverse.value ^ encoremode);
const INT32 initial_volume = (origin ? S_ScaleVolumeWithSplitscreen(volume) : volume);
listener_t listener = {0,0,0,0};
listener_t listener2 = {0,0,0,0};
listener_t listener3 = {0,0,0,0};
listener_t listener4 = {0,0,0,0};
sfxinfo_t *sfx;
INT32 sep, pitch, priority, cnum;
boolean anyListeners = false;
boolean itsUs = false;
INT32 i;
mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo;
mobj_t *listenmobj2 = NULL;
mobj_t *listenmobj3 = NULL;
mobj_t *listenmobj4 = NULL;
listener_t listener[MAXSPLITSCREENPLAYERS];
mobj_t *listenmobj[MAXSPLITSCREENPLAYERS];
if (sound_disabled || !sound_started)
return;
@ -458,27 +462,29 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
if (sfx_id == sfx_None)
return;
if (players[displayplayers[0]].awayviewtics)
listenmobj = players[displayplayers[0]].awayviewmobj;
if (splitscreen)
for (i = 0; i <= splitscreen; i++)
{
listenmobj2 = players[displayplayers[1]].mo;
if (players[displayplayers[1]].awayviewtics)
listenmobj2 = players[displayplayers[1]].awayviewmobj;
player_t *player = &players[displayplayers[i]];
if (splitscreen > 1)
memset(&listener[i], 0, sizeof (listener[i]));
listenmobj[i] = NULL;
if (i == 0 && democam.soundmobj)
{
listenmobj3 = players[displayplayers[2]].mo;
if (players[displayplayers[2]].awayviewtics)
listenmobj3 = players[displayplayers[2]].awayviewmobj;
listenmobj[i] = democam.soundmobj;
}
else if (player->awayviewtics)
{
listenmobj[i] = player->awayviewmobj;
}
else
{
listenmobj[i] = player->mo;
}
if (splitscreen > 2)
{
listenmobj4 = players[displayplayers[3]].mo;
if (players[displayplayers[3]].awayviewtics)
listenmobj4 = players[displayplayers[3]].awayviewmobj;
}
if (origin && origin == listenmobj[i])
{
itsUs = true;
}
}
@ -490,75 +496,32 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
};
#endif
if (camera[0].chase && !players[displayplayers[0]].awayviewtics)
for (i = 0; i <= splitscreen; i++)
{
listener.x = camera[0].x;
listener.y = camera[0].y;
listener.z = camera[0].z;
listener.angle = camera[0].angle;
player_t *player = &players[displayplayers[i]];
if (camera[i].chase && !player->awayviewtics)
{
listener[i].x = camera[i].x;
listener[i].y = camera[i].y;
listener[i].z = camera[i].z;
listener[i].angle = camera[i].angle;
anyListeners = true;
}
else if (listenmobj[i])
{
listener[i].x = listenmobj[i]->x;
listener[i].y = listenmobj[i]->y;
listener[i].z = listenmobj[i]->z;
listener[i].angle = listenmobj[i]->angle;
anyListeners = true;
}
}
else if (listenmobj)
if (origin && anyListeners == false)
{
listener.x = listenmobj->x;
listener.y = listenmobj->y;
listener.z = listenmobj->z;
listener.angle = listenmobj->angle;
}
else if (origin)
// If a mobj is trying to make a noise, and no one is around to hear it, does it make a sound?
return;
if (listenmobj2)
{
if (camera[1].chase && !players[displayplayers[1]].awayviewtics)
{
listener2.x = camera[1].x;
listener2.y = camera[1].y;
listener2.z = camera[1].z;
listener2.angle = camera[1].angle;
}
else
{
listener2.x = listenmobj2->x;
listener2.y = listenmobj2->y;
listener2.z = listenmobj2->z;
listener2.angle = listenmobj2->angle;
}
}
if (listenmobj3)
{
if (camera[2].chase && !players[displayplayers[2]].awayviewtics)
{
listener3.x = camera[2].x;
listener3.y = camera[2].y;
listener3.z = camera[2].z;
listener3.angle = camera[2].angle;
}
else
{
listener3.x = listenmobj3->x;
listener3.y = listenmobj3->y;
listener3.z = listenmobj3->z;
listener3.angle = listenmobj3->angle;
}
}
if (listenmobj4)
{
if (camera[3].chase && !players[displayplayers[3]].awayviewtics)
{
listener4.x = camera[3].x;
listener4.y = camera[3].y;
listener4.z = camera[3].z;
listener4.angle = camera[3].angle;
}
else
{
listener4.x = listenmobj4->x;
listener4.y = listenmobj4->y;
listener4.z = listenmobj4->z;
listener4.angle = listenmobj4->angle;
}
}
// check for bogus sound #
@ -577,37 +540,51 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
// Initialize sound parameters
pitch = NORM_PITCH;
priority = NORM_PRIORITY;
sep = NORM_SEP;
if (splitscreen && origin)
volume = FixedDiv(volume<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS;
i = 0; // sensible default
if (splitscreen && listenmobj2) // Copy the sound for the split player
{
// Check to see if it is audible, and if not, modify the params
if (origin && origin != listenmobj2)
if (origin && !itsUs)
{
INT32 rc;
rc = S_AdjustSoundParams(listenmobj2, origin, &volume, &sep, &pitch, sfx);
boolean audible = false;
if (splitscreen > 0)
{
fixed_t recdist = INT32_MAX;
UINT8 j = 0;
if (!rc)
goto dontplay; // Maybe the other player can hear it...
for (; j <= splitscreen; j++)
{
fixed_t thisdist = INT32_MAX;
if (origin->x == listener2.x && origin->y == listener2.y)
sep = NORM_SEP;
if (!listenmobj[j])
{
continue;
}
thisdist = P_AproxDistance(listener[j].x - origin->x, listener[j].y - origin->y);
if (thisdist >= recdist)
{
continue;
}
recdist = thisdist;
i = j;
}
}
if (listenmobj[i])
{
audible = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, &pitch, sfx);
}
if (!audible)
{
return;
}
}
else if (!origin)
// Do not play origin-less sounds for the second player.
// The first player will be able to hear it just fine,
// we really don't want it playing twice.
goto dontplay;
else
sep = NORM_SEP;
// try to find a channel
cnum = S_getChannel(origin, sfx);
if (cnum < 0)
return; // If there's no free channels, it's not gonna be free for player 1, either.
// This is supposed to handle the loading/caching.
// For some odd reason, the caching is done nearly
@ -616,185 +593,40 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
// cache data if necessary
// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
if (!sfx->data)
{
sfx->data = I_GetSfx(sfx);
}
// increase the usefulness
if (sfx->usefulness++ < 0)
{
sfx->usefulness = -1;
}
// Avoid channel reverse if surround
if (reverse
#ifdef SURROUND
&& sep != SURROUND_SEP
#endif
)
sep = (~sep) & 255;
// Assigns the handle to one of the channels in the
// mix/output buffer.
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
}
dontplay:
if (splitscreen > 1 && listenmobj3) // Copy the sound for the third player
{
// Check to see if it is audible, and if not, modify the params
if (origin && origin != listenmobj3)
)
{
INT32 rc;
rc = S_AdjustSoundParams(listenmobj3, origin, &volume, &sep, &pitch, sfx);
if (!rc)
goto dontplay3; // Maybe the other player can hear it...
if (origin->x == listener3.x && origin->y == listener3.y)
sep = NORM_SEP;
sep = (~sep) & 255;
}
else if (!origin)
// Do not play origin-less sounds for the second player.
// The first player will be able to hear it just fine,
// we really don't want it playing twice.
goto dontplay3;
else
sep = NORM_SEP;
// try to find a channel
// At this point it is determined that a sound can and should be played, so find a free channel to play it on
cnum = S_getChannel(origin, sfx);
if (cnum < 0)
return; // If there's no free channels, it's not gonna be free for player 1, either.
// This is supposed to handle the loading/caching.
// For some odd reason, the caching is done nearly
// each time the sound is needed?
// cache data if necessary
// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
if (!sfx->data)
sfx->data = I_GetSfx(sfx);
// increase the usefulness
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
// Avoid channel reverse if surround
if (reverse
#ifdef SURROUND
&& sep != SURROUND_SEP
#endif
)
sep = (~sep) & 255;
// Assigns the handle to one of the channels in the
// mix/output buffer.
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
}
dontplay3:
if (splitscreen > 2 && listenmobj4) // Copy the sound for the split player
{
// Check to see if it is audible, and if not, modify the params
if (origin && origin != listenmobj4)
{
INT32 rc;
rc = S_AdjustSoundParams(listenmobj4, origin, &volume, &sep, &pitch, sfx);
if (!rc)
goto dontplay4; // Maybe the other player can hear it...
if (origin->x == listener4.x && origin->y == listener4.y)
sep = NORM_SEP;
return; // If there's no free channels, there won't be any for anymore players either
}
else if (!origin)
// Do not play origin-less sounds for the second player.
// The first player will be able to hear it just fine,
// we really don't want it playing twice.
goto dontplay4;
else
sep = NORM_SEP;
// try to find a channel
cnum = S_getChannel(origin, sfx);
if (cnum < 0)
return; // If there's no free channels, it's not gonna be free for player 1, either.
// This is supposed to handle the loading/caching.
// For some odd reason, the caching is done nearly
// each time the sound is needed?
// cache data if necessary
// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
if (!sfx->data)
sfx->data = I_GetSfx(sfx);
// increase the usefulness
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
// Avoid channel reverse if surround
if (reverse
#ifdef SURROUND
&& sep != SURROUND_SEP
#endif
)
sep = (~sep) & 255;
// Assigns the handle to one of the channels in the
// mix/output buffer.
// Now that we know we are going to play a sound, fill out this info
channels[cnum].sfxinfo = sfx;
channels[cnum].origin = origin;
channels[cnum].volume = initial_volume;
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
}
dontplay4:
// Check to see if it is audible, and if not, modify the params
if (origin && origin != listenmobj)
{
INT32 rc;
rc = S_AdjustSoundParams(listenmobj, origin, &volume, &sep, &pitch, sfx);
if (!rc)
return;
if (origin->x == listener.x && origin->y == listener.y)
sep = NORM_SEP;
}
else
sep = NORM_SEP;
// try to find a channel
cnum = S_getChannel(origin, sfx);
if (cnum < 0)
return;
// This is supposed to handle the loading/caching.
// For some odd reason, the caching is done nearly
// each time the sound is needed?
// cache data if necessary
// NOTE: set sfx->data NULL sfx->lump -1 to force a reload
if (!sfx->data)
sfx->data = I_GetSfx(sfx);
// increase the usefulness
if (sfx->usefulness++ < 0)
sfx->usefulness = -1;
// Avoid channel reverse if surround
if (reverse
#ifdef SURROUND
&& sep != SURROUND_SEP
#endif
)
sep = (~sep) & 255;
// Assigns the handle to one of the channels in the
// mix/output buffer.
channels[cnum].volume = initial_volume;
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
}
void S_StartSound(const void *origin, sfxenum_t sfx_id)
@ -884,7 +716,6 @@ void S_StopSound(void *origin)
if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
{
S_StopChannel(cnum);
break;
}
}
}
@ -900,23 +731,13 @@ static INT32 actualmidimusicvolume;
void S_UpdateSounds(void)
{
INT32 audible, cnum, volume, sep, pitch;
INT32 cnum, volume, sep, pitch;
boolean audible = false;
channel_t *c;
INT32 i;
listener_t listener;
listener_t listener2;
listener_t listener3;
listener_t listener4;
mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo;
mobj_t *listenmobj2 = NULL;
mobj_t *listenmobj3 = NULL;
mobj_t *listenmobj4 = NULL;
memset(&listener, 0, sizeof(listener_t));
memset(&listener2, 0, sizeof(listener_t));
memset(&listener3, 0, sizeof(listener_t));
memset(&listener4, 0, sizeof(listener_t));
listener_t listener[MAXSPLITSCREENPLAYERS];
mobj_t *listenmobj[MAXSPLITSCREENPLAYERS];
// Update sound/music volumes, if changed manually at console
if (actualsfxvolume != cv_soundvolume.value)
@ -933,7 +754,7 @@ void S_UpdateSounds(void)
{
#ifndef NOMUMBLE
// Stop Mumble cutting out. I'm sick of it.
I_UpdateMumble(NULL, listener);
I_UpdateMumble(NULL, listener[0]);
#endif
// Stop cutting FMOD out. WE'RE sick of it.
@ -944,47 +765,31 @@ void S_UpdateSounds(void)
if (dedicated || sound_disabled)
return;
if (players[displayplayers[0]].awayviewtics)
listenmobj = players[displayplayers[0]].awayviewmobj;
if (splitscreen)
for (i = 0; i <= splitscreen; i++)
{
listenmobj2 = players[displayplayers[1]].mo;
if (players[displayplayers[1]].awayviewtics)
listenmobj2 = players[displayplayers[1]].awayviewmobj;
player_t *player = &players[displayplayers[i]];
if (splitscreen > 1)
memset(&listener[i], 0, sizeof (listener[i]));
listenmobj[i] = NULL;
if (i == 0 && democam.soundmobj)
{
listenmobj3 = players[displayplayers[2]].mo;
if (players[displayplayers[2]].awayviewtics)
listenmobj3 = players[displayplayers[2]].awayviewmobj;
listenmobj[i] = democam.soundmobj;
continue;
}
if (splitscreen > 2)
{
listenmobj4 = players[displayplayers[3]].mo;
if (players[displayplayers[3]].awayviewtics)
listenmobj4 = players[displayplayers[3]].awayviewmobj;
}
if (player->awayviewtics)
{
listenmobj[i] = player->awayviewmobj;
}
else
{
listenmobj[i] = player->mo;
}
}
if (camera[0].chase && !players[displayplayers[0]].awayviewtics)
{
listener.x = camera[0].x;
listener.y = camera[0].y;
listener.z = camera[0].z;
listener.angle = camera[0].angle;
}
else if (listenmobj)
{
listener.x = listenmobj->x;
listener.y = listenmobj->y;
listener.z = listenmobj->z;
listener.angle = listenmobj->angle;
}
#ifndef NOMUMBLE
I_UpdateMumble(players[consoleplayer].mo, listener);
I_UpdateMumble(players[consoleplayer].mo, listener[0]);
#endif
#ifdef HW3SOUND
@ -996,57 +801,23 @@ void S_UpdateSounds(void)
}
#endif
if (listenmobj2)
for (i = 0; i <= splitscreen; i++)
{
if (camera[1].chase && !players[displayplayers[1]].awayviewtics)
{
listener2.x = camera[1].x;
listener2.y = camera[1].y;
listener2.z = camera[1].z;
listener2.angle = camera[1].angle;
}
else
{
listener2.x = listenmobj2->x;
listener2.y = listenmobj2->y;
listener2.z = listenmobj2->z;
listener2.angle = listenmobj2->angle;
}
}
player_t *player = &players[displayplayers[i]];
if (listenmobj3)
{
if (camera[2].chase && !players[displayplayers[2]].awayviewtics)
if (camera[i].chase && !player->awayviewtics)
{
listener3.x = camera[2].x;
listener3.y = camera[2].y;
listener3.z = camera[2].z;
listener3.angle = camera[2].angle;
listener[i].x = camera[i].x;
listener[i].y = camera[i].y;
listener[i].z = camera[i].z;
listener[i].angle = camera[i].angle;
}
else
else if (listenmobj[i])
{
listener3.x = listenmobj3->x;
listener3.y = listenmobj3->y;
listener3.z = listenmobj3->z;
listener3.angle = listenmobj3->angle;
}
}
if (listenmobj4)
{
if (camera[3].chase && !players[displayplayers[3]].awayviewtics)
{
listener4.x = camera[3].x;
listener4.y = camera[3].y;
listener4.z = camera[3].z;
listener4.angle = camera[3].angle;
}
else
{
listener4.x = listenmobj4->x;
listener4.y = listenmobj4->y;
listener4.z = listenmobj4->z;
listener4.angle = listenmobj4->angle;
listener[i].x = listenmobj[i]->x;
listener[i].y = listenmobj[i]->y;
listener[i].z = listenmobj[i]->z;
listener[i].angle = listenmobj[i]->angle;
}
}
@ -1063,83 +834,60 @@ void S_UpdateSounds(void)
pitch = NORM_PITCH;
sep = NORM_SEP;
if (splitscreen && c->origin)
volume = FixedDiv(volume<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS;
// check non-local sounds for distance clipping
// or modify their params
if (c->origin && ((c->origin != players[consoleplayer].mo)
|| (splitscreen && c->origin != players[displayplayers[1]].mo)
|| (splitscreen > 1 && c->origin != players[displayplayers[2]].mo)
|| (splitscreen > 2 && c->origin != players[displayplayers[3]].mo)))
if (c->origin)
{
// Whomever is closer gets the sound, but only in splitscreen.
if (splitscreen)
boolean itsUs = false;
for (i = splitscreen; i >= 0; i--)
{
const mobj_t *soundmobj = c->origin;
fixed_t recdist = -1;
INT32 i, p = -1;
if (c->origin != listenmobj[i])
continue;
for (i = 0; i <= splitscreen; i++)
{
fixed_t thisdist = -1;
if (i == 0 && listenmobj)
thisdist = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y);
else if (i == 1 && listenmobj2)
thisdist = P_AproxDistance(listener2.x-soundmobj->x, listener2.y-soundmobj->y);
else if (i == 2 && listenmobj3)
thisdist = P_AproxDistance(listener3.x-soundmobj->x, listener3.y-soundmobj->y);
else if (i == 3 && listenmobj4)
thisdist = P_AproxDistance(listener4.x-soundmobj->x, listener4.y-soundmobj->y);
else
continue;
if (recdist == -1 || (thisdist != -1 && thisdist < recdist))
{
recdist = thisdist;
p = i;
}
}
if (p != -1)
{
if (p == 1)
{
// Player 2 gets the sound
audible = S_AdjustSoundParams(listenmobj2, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
else if (p == 2)
{
// Player 3 gets the sound
audible = S_AdjustSoundParams(listenmobj3, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
else if (p == 3)
{
// Player 4 gets the sound
audible = S_AdjustSoundParams(listenmobj4, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
else
{
// Player 1 gets the sound
audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
}
if (audible)
I_UpdateSoundParams(c->handle, volume, sep, pitch);
else
S_StopChannel(cnum);
}
itsUs = true;
}
else if (listenmobj && !splitscreen)
if (itsUs == false)
{
// In the case of a single player, he or she always should get updated sound.
audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch,
c->sfxinfo);
const mobj_t *origin = c->origin;
i = 0;
if (splitscreen > 0)
{
fixed_t recdist = INT32_MAX;
UINT8 j = 0;
for (; j <= splitscreen; j++)
{
fixed_t thisdist = INT32_MAX;
if (!listenmobj[j])
{
continue;
}
thisdist = P_AproxDistance(listener[j].x - origin->x, listener[j].y - origin->y);
if (thisdist >= recdist)
{
continue;
}
recdist = thisdist;
i = j;
}
}
if (listenmobj[i])
{
audible = S_AdjustSoundParams(
listenmobj[i], c->origin,
&volume, &sep, &pitch,
c->sfxinfo
);
}
if (audible)
I_UpdateSoundParams(c->handle, volume, sep, pitch);
@ -1242,54 +990,38 @@ fixed_t S_CalculateSoundDistance(fixed_t sx1, fixed_t sy1, fixed_t sz1, fixed_t
// If the sound is not audible, returns a 0.
// Otherwise, modifies parameters and returns 1.
//
INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch,
boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch,
sfxinfo_t *sfxinfo)
{
fixed_t approx_dist;
angle_t angle;
listener_t listensource;
const boolean reverse = (stereoreverse.value ^ encoremode);
fixed_t approx_dist;
listener_t listensource;
INT32 i;
(void)pitch;
if (!listener)
return false;
if (listener == players[displayplayers[0]].mo && camera[0].chase)
// Init listensource with default listener
listensource.x = listener->x;
listensource.y = listener->y;
listensource.z = listener->z;
listensource.angle = listener->angle;
for (i = 0; i <= splitscreen; i++)
{
listensource.x = camera[0].x;
listensource.y = camera[0].y;
listensource.z = camera[0].z;
listensource.angle = camera[0].angle;
}
else if (splitscreen && listener == players[displayplayers[1]].mo && camera[1].chase)
{
listensource.x = camera[1].x;
listensource.y = camera[1].y;
listensource.z = camera[1].z;
listensource.angle = camera[1].angle;
}
else if (splitscreen > 1 && listener == players[displayplayers[2]].mo && camera[2].chase)
{
listensource.x = camera[2].x;
listensource.y = camera[2].y;
listensource.z = camera[2].z;
listensource.angle = camera[2].angle;
}
else if (splitscreen > 2 && listener == players[displayplayers[3]].mo && camera[3].chase)
{
listensource.x = camera[3].x;
listensource.y = camera[3].y;
listensource.z = camera[3].z;
listensource.angle = camera[3].angle;
}
else
{
listensource.x = listener->x;
listensource.y = listener->y;
listensource.z = listener->z;
listensource.angle = listener->angle;
// If listener is a chasecam player, use the camera instead
if (listener == players[displayplayers[i]].mo && camera[i].chase)
{
listensource.x = camera[i].x;
listensource.y = camera[i].y;
listensource.z = camera[i].z;
listensource.angle = camera[i].angle;
break;
}
}
if (sfxinfo->pitch & SF_OUTSIDESOUND) // Rain special case
@ -1339,30 +1071,37 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v
approx_dist = FixedDiv(approx_dist,2*FRACUNIT);
if (approx_dist > S_CLIPPING_DIST)
return 0;
return false;
// angle of source to listener
angle = R_PointToAngle2(listensource.x, listensource.y, source->x, source->y);
if (angle > listensource.angle)
angle = angle - listensource.angle;
if (source->x == listensource.x && source->y == listensource.y)
{
*sep = NORM_SEP;
}
else
angle = angle + InvAngle(listensource.angle);
{
// angle of source to listener
angle_t angle = R_PointToAngle2(listensource.x, listensource.y, source->x, source->y);
if (reverse)
angle = InvAngle(angle);
if (angle > listensource.angle)
angle = angle - listensource.angle;
else
angle = angle + InvAngle(listensource.angle);
if (reverse)
angle = InvAngle(angle);
#ifdef SURROUND
// Produce a surround sound for angle from 105 till 255
if (surround.value == 1 && (angle > ANG105 && angle < ANG255 ))
*sep = SURROUND_SEP;
else
// Produce a surround sound for angle from 105 till 255
if (surround.value == 1 && (angle > ANG105 && angle < ANG255 ))
*sep = SURROUND_SEP;
else
#endif
{
angle >>= ANGLETOFINESHIFT;
{
angle >>= ANGLETOFINESHIFT;
// stereo separation
*sep = 128 - (FixedMul(S_STEREO_SWING, FINESINE(angle))>>FRACBITS);
// stereo separation
*sep = 128 - (FixedMul(S_STEREO_SWING, FINESINE(angle))>>FRACBITS);
}
}
// volume calculation
@ -1374,9 +1113,6 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v
*vol = FixedMul(*vol * FRACUNIT / 255, n) / S_ATTENUATOR;
}
if (splitscreen)
*vol = FixedDiv((*vol)<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS;
return (*vol > 0);
}

View file

@ -53,7 +53,7 @@ ifdef FREEBSD
OPTS+=-DLINUX -DFREEBSD -I/usr/X11R6/include
SDL_CONFIG?=sdl11-config
LDFLAGS+=-L/usr/X11R6/lib
LIBS+=-lipx -lkvm
LIBS+=-lkvm -lexecinfo
endif
#

View file

@ -90,7 +90,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#include <kvm.h>
#endif
#include <nlist.h>
#include <sys/vmmeter.h>
#include <sys/sysctl.h>
#endif
#endif
@ -3804,40 +3804,17 @@ static long get_entry(const char* name, const char* buf)
UINT32 I_GetFreeMem(UINT32 *total)
{
#ifdef FREEBSD
struct vmmeter sum;
kvm_t *kd;
struct nlist namelist[] =
{
#define X_SUM 0
{"_cnt"},
{NULL}
};
if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL)
{
if (total)
*total = 0L;
return 0;
}
if (kvm_nlist(kd, namelist) != 0)
{
kvm_close (kd);
if (total)
*total = 0L;
return 0;
}
if (kvm_read(kd, namelist[X_SUM].n_value, &sum,
sizeof (sum)) != sizeof (sum))
{
kvm_close(kd);
if (total)
*total = 0L;
return 0;
}
kvm_close(kd);
u_int v_free_count, v_page_size, v_page_count;
size_t size = sizeof(v_free_count);
sysctlbyname("vm.stats.vm.v_free_count", &v_free_count, &size, NULL, 0);
size = sizeof(v_page_size);
sysctlbyname("vm.stats.vm.v_page_size", &v_page_size, &size, NULL, 0);
size = sizeof(v_page_count);
sysctlbyname("vm.stats.vm.v_page_count", &v_page_count, &size, NULL, 0);
if (total)
*total = sum.v_page_count * sum.v_page_size;
return sum.v_free_count * sum.v_page_size;
*total = v_page_count * v_page_size;
return v_free_count * v_page_size;
#elif defined (SOLARIS)
/* Just guess */
if (total)

View file

@ -42,7 +42,7 @@
#ifdef HAVE_IMAGE
#include "SDL_image.h"
#elif 1
#elif (!defined(__APPLE__))
#define LOAD_XPM //I want XPM!
#include "IMG_xpm.c" //Alam: I don't want to add SDL_Image.dll/so
#define HAVE_IMAGE //I have SDL_Image, sortof

View file

@ -90,6 +90,7 @@ static UINT32 fading_timer;
static UINT32 fading_duration;
static INT32 fading_id;
static void (*fading_callback)(void);
static boolean fading_do_callback;
#ifdef HAVE_LIBGME
static Music_Emu *gme;
@ -106,6 +107,7 @@ static void var_cleanup(void)
is_fading = false;
fading_callback = NULL;
fading_do_callback = false;
internal_volume = 100;
}
@ -202,6 +204,13 @@ void I_ShutdownSound(void)
void I_UpdateSound(void)
{
if (fading_do_callback)
{
if (fading_callback)
(*fading_callback)();
fading_callback = NULL;
fading_do_callback = false;
}
}
/// ------------------------
@ -526,9 +535,8 @@ static UINT32 get_adjusted_position(UINT32 position)
static void do_fading_callback(void)
{
if (fading_callback)
(*fading_callback)();
fading_callback = NULL;
// TODO: Should I use a mutex here or something?
fading_do_callback = true;
}
/// ------------------------

View file

@ -16,7 +16,7 @@
#include <string.h>
#include "doomdef.h"
#if !defined (__APPLE__)
#ifndef SRB2_HAVE_STRLCPY
// Like the OpenBSD version, but it doesn't check for src not being a valid
// C string.

View file

@ -11,7 +11,7 @@
/* https://tools.ietf.org/html/rfc5389 */
#if defined (__linux__)
#if defined (__unix__)
#include <sys/random.h>
#elif defined (_WIN32)
#define _CRT_RAND_S

View file

@ -1862,7 +1862,7 @@ static int W_VerifyWAD(FILE *fp, lumpchecklist_t *checklist, boolean status)
continue;
for (j = 0; j < NUMSPRITES; j++)
if (sprnames[j] && !strncmp(lumpinfo.name, sprnames[j], 4)) // Sprites
if (!strncmp(lumpinfo.name, sprnames[j], 4)) // Sprites
continue;
if (! W_VerifyName(lumpinfo.name, checklist, status))

View file

@ -242,7 +242,7 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits,
void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
#endif
{
size_t extrabytes = (1<<alignbits) - 1;
size_t extrabytes = (1<<alignbits) - (sizeof(size_t)*8 > (UINT32) alignbits); // only subtract 1 if the bit shift did not cause an overflow
size_t padsize = 0;
memblock_t *block;
void *ptr;